提交 840191f6 编写于 作者: S shawn_he

update doc

Signed-off-by: Nshawn_he <shawn.he@huawei.com>
上级 9de0768f
......@@ -2,11 +2,11 @@
## System Startup
### System Startup Interrupted Due to "parse failed!" Error
### Device Startup Interrupted Due to "parse failed!" Error
**Symptom**
During system startup, the error message "[Init] InitReadCfg, parse failed! please check file /etc/init.cfg format." is displayed, and the startup is interrupted, as shown in the following figure.
During device startup, the error message "[Init] InitReadCfg, parse failed! please check file /etc/init.cfg format." is displayed, and the startup is interrupted, as shown in the following figure.
**Figure 1** Error information
......@@ -14,34 +14,32 @@ During system startup, the error message "[Init] InitReadCfg, parse failed! plea
**Possible Cause**
During modification of the **init.cfg** file, required commas (,) or parentheses are missing or unnecessary ones are added. As a result, the file's JSON format becomes invalid.
The content of the **init.cfg** file does not comply with the JSON specifications.
**Solution**
Check the **init.cfg** file and ensure that its format meets the JSON specifications.
### System Restarted Repeatedly
### Device Restarted Repeatedly
**Symptom**
After the image burning is complete, the system restarts over and over again.
The device restarts over and over again upon startup.
**Possible Cause**
Each service started by the init process has the **importance** attribute, as described in Table 3 in [init Module](../subsystems/subsys-boot-init.md).
Each service started by the init process has the **importance** attribute, as described in [Parameters](../subsystems/subsys-boot-init-service.md#parameters).
- If the attribute value is **0**, the init process does not need to restart the development board when the current service process exits.
- If the attribute value is **0**, the init process does not need to restart the device when the current service process exits.
- If the attribute value is **1**, the init process needs to restart the development board when the current service process exits.
During the startup of a service whose **importance** is **1**, if the service exits due to a process crash or an error, the init process automatically restarts the development board.
- If the attribute value is **1**, the init process needs to restart the device when the current service process exits.
**Solution**
1. View logs to identify the service that encounters a process crash or exits due to an error, rectify the issue, and then burn the image again.
2. Alternatively, change the value of **importance** to **0** for the service that exits due to a process crash or an error, and then burn the image again. In this way, the development board will not be restarted even if the service exits.
2. Change the value of **importance** to **0** for the service that exits due to a process crash or an error, and then burn the image again.
### **SetParameter** or **GetParameter** Failed with Correct Parameters Passed
......@@ -50,6 +48,10 @@ During the startup of a service whose **importance** is **1**, if the service ex
Calling **SetParameter** or **GetParameter** fails when correct parameters are passed.
**System Type**
liteos-a
**Possible Cause**
Permission verification has been enabled for **SetParameter** and **GetParameter**. If the UID of the caller is greater than **1000**, that is, the caller does not have the API call permission, calling an API will fail even if correct parameters are passed.
......@@ -58,7 +60,6 @@ Permission verification has been enabled for **SetParameter** and **GetParameter
No action is required.
### ueventd Service Failed to Obtain a Socket upon Startup
**Symptom**
......@@ -71,15 +72,14 @@ After the ueventd service is started, the error message "Failed to get uevent so
**Possible Cause**
The ueventd service is started on demand. Upon startup, it first needs to check the environment variables for **fd** of the socket created by the init process. The preceding error information will be displayed if the ueventd service fails to obtain environment variables. The possible causes are as follows:
The ueventd service is started on demand. Upon startup, it first needs to check the environment variables for **fd** of the socket created by the init process. The preceding error information will be displayed if the ueventd service fails to obtain environment variables. The possible causes are as follows:
1. No socket has been configured for the ueventd service in the **.cfg** file. As a result, the init process does not create a socket for the ueventd service, and no socket ID is present in environment variables.
2. If a socket has been configured for the ueventd service in the **.cfg** file, it is probable that the ueventd service is also configured in another **.cfg** file but no socket is designated for it.
**Solution**
For case 1, configure a socket for the ueventd service in the **.cfg** file. For details, see [Development Guidelines](https://gitee.com/openharmony/docs/blob/master/en/device-dev/subsystems/subsys-boot-init.md#development-guidelines).
For case 2, check all **.cfg** files for any duplicate ueventd service and delete it. Retain only one ueventd service with valid configuration.
1. For case 1, configure a socket for the ueventd service in the **.cfg** file. For details, see [Socket Configuration for the ueventd Service](../subsystems/subsys-boot-init-service.md#parameters).
2. For case 2, check all **.cfg** files for any duplicate ueventd service and delete it. Retain only one ueventd service with valid configuration.
### ueventd Service Exits Because of a Socket Polling Timeout
......@@ -103,18 +103,18 @@ The service configuration in JSON format cannot be correctly parsed, and the err
**Possible Cause**
The service configuration is not in the JSON format. This can result in a **.cfg** file parsing error, leading to a service parsing failure. For a service configured with the **ondemand** attribute, the **critical** attribute is set to **1**, or the first value in the **critical** attribute array is set to **1**. When the **ondemand** attribute is configured, the service is started on demand by default. The service exits when it is idle. However, when the **critical** attribute is configured, the service is regarded as a critical system service and is not allowed to exit. Therefore, a conflict occurs if both attributes are configured the same service.
When the **ondemand** attribute is configured, a service is started on demand by default. This attribute, however, is mutually exclusive with the **critical** attribute. If both of them are configured, a conflict will occur, resulting in a failure to resolve the service.
**Solution**
Check whether the service needs to be started on demand. If not, do not configure the **ondemand** attribute. If yes, do not configure the **critical** attribute along with the **ondemand** attribute. To limit the number of times that a critical service exits abnormally, set the first value in the **critical** attribute array to **0** and then add a limitation on the exit times. For example, **"critical": [0, 15, 5]** means that, if a service exits for more than 15 times within 5s, the service will not be started and the system will not be restarted.
1. If a service does not need to be started on demand, leave the **ondemand** attribute unspecified.
2. If a service needs to be started on demand, leave the **critical** attribute unspecified or disable the **critical** attribute after you configure the **ondemand** attribute.
### Parallel Startup Is Not Effective for Services Configured with the ondemand Attribute
**Symptom**
Services configured with the **ondemand** attribute are not started in the parallel startup phase, regardless of whether **start-mode** is set to **boot**, **normal**, or the default value.
Services configured with the **ondemand** attribute are not started in the parallel startup phase, regardless of the **start-mode** settings.
**Possible Cause**
......@@ -132,17 +132,17 @@ When an SA service is configured with the **ondemand** attribute, the samgr proc
**Possible Cause**
At the initial implementation of on-demand startup, **SystemAbilityManager::CheckSystemAbility(int32_t systemAbilityId)** is used for all SA services. To distinguish SA services that are started on demand, **LoadSystemAbility(int32_t systemAbilityId, const sptr& callback)** provided by the samgr process is added. If an SA service is not started on demand, it is probable that the original API is used by mistake.
At the initial implementation of on-demand startup for SA services, **SystemAbilityManager::CheckSystemAbility(int32_t systemAbilityId)** is used for all SA services. To distinguish SA services that are started on demand, **LoadSystemAbility(int32_t systemAbilityId, const sptr& callback)** provided by the samgr process is added. If an SA service is not started on demand, it is probable that the original API is used by mistake.
**Solution**
Use **LoadSystemAbility(int32_t systemAbilityId, const sptr& callback)** for any SA service that needs to be started on demand.
### Improper DAC Configuration
### Improper caps Configuration
**Symptom**
Improper DAC configuration leads to a configuration error. The error information is as follows:
Improper caps configuration leads to a configuration error. The error information is as follows:
```
4.619955] [pid=1 0][Init][ERROR][init_capability.c:119]service=multimodalinput not support caps = CAP_DC_OVERRIDE caps 41
[ 4.620014] [pid=1 0][Init][ERROR][init_service_manager.c:818]GetServiceSecon secon section not found, skip
......@@ -151,65 +151,45 @@ Improper DAC configuration leads to a configuration error. The error information
```
**Possible Cause**
1. Max attributes are present in the **caps** configuration.
2. Parsing of attributes carrying CAP and non-CAP prefixes is not supported.
3. The **const** attribute configuration is invalid.
**Solution**
1. The caps configuration is not supported by the kernel.
2. The configuration in the **.cfg** file is incorrect.
1. Enable parsing of attributes carrying CAP and non-CAP prefixes.
2. Remove max attributes from the **caps** configuration.
3. Add a correct **const** attribute file.
**System Version**
### Invalid critical Attribute Configuration
**Symptom**
The configuration of the **critical** attribute does not take effect.
**Possible Cause**
1. The format of the **critical** attribute is valid.
2. The services configured with the **critical** attribute are not started.
3. The modified configuration file is not effective.
OpenHarmony-3.0-LTS
**Solution**
1. Correct the format of the **critical** attribute.
2. Start the services configured with the **critical** attribute.
3. Modify the configuration file based on the device type. The configuration file is **init.cfg** for Hi3516 and **init.without_two_stages.cfg** for RK3568.
1. For case 1, leave **caps** unspecified.
2. For case 2, correctly configure **caps** by referring to the definition of the **capStrCapNum** data structure in **base/startup/init_lite/services/init/init_capability.c**.
### On-demand Startup Not Supported for Socket Processes
### Sandbox Not Enabled
**Symptom**
On-demand startup is not supported for socket processes.
After **hdc shell param get const.sandbox** is run, it is found that the value of **const.sandbox** is not **enable**.
**Possible Cause**
The **DISABLE_INIT_TWO_STAGES** macro setting is invalid for on-demand startup of the ueventd process.
None.
**Solution**
Enable **socket** in **startUeventd** so that socket validity check is added to the socket creation function.
Set **const.sandbox** to **enable** in **base/startup/init_lite/services/etc/param/ohos.para**. For details, see [Sandbox Management](../subsystems/subsys-boot-init-sandbox.md).
### Small System Compilation Alarm
### How to Check the Sandbox Mounting Status
**Symptom**
The alarm information is as follows:
warning: implicit declaration of function 'usleep' is invalid in C99
warning: implicit declaration of function 'setgroups' is invalid in C99
None.
**Possible Cause**
The header file is incorrect or the *GNU***SOURCE** macro is disabled.
None.
**Solution**
Check whether the corresponding header file is correct. If yes, check whether the *GNU***SOURCE** macro is enabled.
Enter the hdc shell mode on the device. Then, run the **sandbox -s service_name** command to move the current service to the sandbox, and run shell commands such as **ls** to view the sandbox directory. For details, see the [sandbox command description](../subsystems/subsys-boot-init-plugin.md).
## Application Spawning
......@@ -239,13 +219,13 @@ Applications fail to be started by running the cold start command.
**Possible Cause**
1. The cold start does not take effect.
2. The cold start command is incorrect.
1. Cold start is not enabled.
2. The parameter of the cold start command is incorrect.
**Solution**
1. Enable cold start by setting **param set appspawn.cold.boot true**.
2. Make sure that the cold start command is correct.
1. For case 1, run **param get appspawn.cold.boot** to check the cold start switch and run **param set appspawn.cold.boot true** to enable cold start.
2. For case 2, correct the parameter of the cold start command.
### Failed to Create the Application Sandbox
......@@ -266,3 +246,5 @@ The system UI freezes at the OpenHarmony startup animation, the calculator appli
1. Check the error information in the hilog file, and correct the corresponding JSON files.
2. Verify the PID of the application, the code logic of the sandbox creation process, and the JSON configuration.
For details, see [Application Sandbox Development Procedure](../subsystems/subsys-boot-appspawn.md#development-procedure).
# init Configuration File
## Overview
### Function
The init configuration file is in JSON format and is used to configure commands and services required for system startup. Upon system startup, the Init process parses the init configuration file and runs the commands in it to start the corresponding services.
### Basic Concepts
1. Group configuration file: A group configuration file is named in the format of **device.xxxx.group.cfg**. It consists of three parts, **jobs**, **services**, and **groups**. It is available only for the standard system. Such a file is used to configure the jobs and services that can be executed. The partition that holds the file is determined based on the **bootgroup** attribute in cmdline. Currently, the following groups are supported:
- ​device.boot.group: default configuration, which is used to trigger all jobs and services in the configuration file.
- device.charge.group: charge mode, which is used to trigger only the allowed jobs and services in the configuration file.
2. Startup configuration file: **init.cfg** file, which consists of three parts, **jobs**, **services**, and **import**.
- services (for the Linux kernel only): native services supported by the system. For details about the service configuration, see [Service Management](subsys-boot-init-service.md).
- jobs: collection of commands to be executed. For details about jobs, see [Job Management](subsys-boot-init-jobs.md).
- import (for the Linux kernel only). command used to import **.cfg** files. It helps reduce the size of **.cfg** files for implementing different functions.
### Constraints
Only the small system and standard system are supported.
## How to Develop
### Use Cases
Upon startup, the init process first initializes the system and then parses the configuration file. The system classifies the configuration files into three types:
1. init.cfg: default configuration file, which is defined by the init process and parsed first.
2. /system/etc/init/*.cfg: configuration file defined by each subsystem.
3. /vendor/etc/init/*.cfg: configuration file defined by vendors.
If you need to add a configuration file, define its content as you want and copy it to the corresponding directory.
### How to Develop
1. Define the configuration file.
```
{
"import" : [ ],
"jobs" : [ ],
"services" : [ ]
}
```
2. Copy the configuration file to the corresponding directory based on the system type.
For the standard system:
```
ohos_prebuilt_etc("misc.cfg") {
source = "//base/startup/init_lite/services/etc/misc.cfg"
relative_install_dir = "init"
part_name = "init"
}
```
For the small system:
```
copy("init_configs") {
sources = [ "init_liteos_a_3516dv300.cfg" ]
outputs = [ "$root_out_dir/config/init.cfg" ]
}
```
### Development Example
The following is a template for defining a **.cfg** file.
```
{
"import" : [
"/etc/example1.cfg",
"/etc/example2.cfg"
],
"jobs" : [{
"name" : "jobName1",
"cmds" : [
"start serviceName",
"mkdir dir1"
]
}, {
"name" : "jobName2",
"cmds" : [
"chmod 0755 dir1",
"chown root root dir1"
]
}
],
"services" : [{
"name" : "serviceName",
"path" : ["/system/bin/serviceName"]
}
]
}
```
1. .cfg file: configuration file written in the JSON format. If the services or commands in it do not take effect, check whether the content format is correct.
2. import: command used to import **.cfg** files. The files are parsed immediately after their path is parsed.
3. example1.cfg: **.cfg** file to be imported.
4. serviceName: service name, which is user-defined.
5. /system/bin/serviceName: full path and parameters of the executable file of the current service, in array format.
6. jobName1: job name, which is user-defined.
# Job Management
## Overview
### Function
A job is a set of commands in the **.cfg** file of the init module. A maximum of 4096 jobs can be added. Jobs can be configured in the [.cfg file](subsys-boot-init-cfg.md). Generally, jobs are executed during initialization to serve the normal startup of services or the initialization of specific basic functions.
### Basic Concepts
A job can be configured in the **init.cfg** file or the custom **.cfg** file of the module. The parser of the init process aggregates commands of the jobs with the same name into one job. For jobs with the same name, the init process only ensures that the commands in the **init.cfg** file are executed in preference. It does not guarantee the execution sequence of commands in other **.cfg** files.
- Common job
A job executed in a fixed phase during init process startup, for example, pre-init, init, or post-init.
- pre-init: pre-initialization phase. Key services on which other services depend, such as ueventd, watchdog, and hilogd, are started in this phase. The mounting of data partitions is also done in this phase.
- init: main phase of the initialization process. In this phase, a large number of commands are executed, and services in the **boot** group (first group) are started concurrently by the **init** group. Some important services related to system functions are also started in this phase.
- post-init: post-initialization phase. In this phase, the **trigger** command is used to invoke the execution of other phases, which can be regarded as independent phases, or the post-init phase as a whole. In this phase, a large number of commands are executed, and the **normal** group (the second group) is started by the **init** group. Most services configured in the **.cfg** files are started in this phase.
- Custom job (for standard system or higher)
A job triggered based on specific rules. You can add commands to the job as required and run the **trigger** command to invoke the execution of commands in the job.
- Conditional job (for standard system or higher)
A job triggered based on specific conditions. You can add conditions to a job so that the job is executed when the conditions are met.
A condition is a combination of system parameter values and supports operations such as **&&** and **||**, for example, **"condition": "sys.usb.config = none && sys.usb.configfs = 0"**. When defining commands for a job, you can add attributes in the format of **param:xxx** to form different commands.
### Constraints
With the system parameter module, the standard system is able to support basic, conditional, and custom jobs. The small system supports only basic jobs.
## How to Develop
### Use Cases
A job is a command set, where you can manage the commands to be executed. A maximum of 4096 commands can be added to a command set. During the init startup process, the execution of jobs helps ensure normal running of services.
### Parameters
**Table 1** Command set description
<table border="0" cellpadding="0" cellspacing="0" width="770" style="border-collapse: collapse;table-layout:fixed;width:578pt;border-spacing: 0px;font-variant-ligatures: normal; font-variant-caps: normal;orphans: 2;text-align:start;widows: 2;-webkit-text-stroke-width: 0px; text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial">
<tbody>
<tr height="39" style="height:18.0pt">
<th height="24" class="xl6521952" width="140" style="height:18.0pt;width:105pt">
Command
</td>
<th class="xl6521952" width="215" style="border-left:none;width:161pt">
Format and Example
</td>
<th class="xl6521952" width="225" style="border-left:none;width:169pt">
Description
</td>
<th class="xl6521952" width="190" style="border-left:none;width:143pt">
Supported System Type
</td>
</tr>
<tr height="231" style="height:173.25pt">
<td height="231" class="xl6621952" width="140" style="height:173.25pt;border-top: none;width:105pt">
mkdir
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
mkdir&nbsp; target folder [mode] [owner] [group]<br>Example:<br>mkdir&nbsp;/storage/myDirectory<br>mkdir /storage/myDirectory 0755 root root
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Creates a folder. **mkdir** and the target folder must be separated by only one space. Folders cannot be created recursively.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="277" style="mso-height-source:userset;height:207.75pt">
<td height="277" class="xl6621952" width="140" style="height:207.75pt;border-top: none;width:105pt">
chmod
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
chmod *permission* *target*<br>Example:<br>chmod 0600 /storage/myFile.txt<br>chmod 0750 /storage/myDir
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Modifies the permission, which must be in the **0*****xxx*** format. **chmod**, *permission*, and *target* must be separated by only one space.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="295" style="mso-height-source:userset;height:221.25pt">
<td height="295" class="xl6621952" width="140" style="height:221.25pt;border-top: none;width:105pt">
chown
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
chown uid gid *target*<br>Example:<br>chown 900 800 /storage/myDir<br>chown 100 100 /storage/myFile.txt
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Modifies the owner group. **chown**, **uid**, **gid**, and *target* must be separated by only one space.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="355" style="mso-height-source:userset;height:266.25pt">
<td height="355" class="xl6621952" width="140" style="height:266.25pt;border-top: none;width:105pt">
mount
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
mount&nbsp;fileSystemType&nbsp;src&nbsp;dst&nbsp;flags&nbsp;data<br>Example:<br>mount&nbsp;vfat&nbsp;/dev/mmcblk0&nbsp;/sdc&nbsp;rw,umask=000<br>mount&nbsp;jffs2&nbsp;/dev/mtdblock3&nbsp;/storage&nbsp;nosuid
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Mounts devices. Every two parameters must be separated by only one space. <br>For details about **flags**, see the **mountFlagMap[]** array of the **mountFlagMap** function in **base/startup/init_lite/services/init/init_common_cmds.c**. The **data** field is optional.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="238" style="mso-height-source:userset;height:178.5pt">
<td height="238" class="xl6621952" width="140" style="height:178.5pt;border-top: none;width:105pt">
start
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
start *serviceName*<br>Example:<br>start foundationstart
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Starts services. *serviceName* must be contained in the **services** array.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="264" style="mso-height-source:userset;height:198.0pt">
<td height="264" class="xl6621952" width="140" style="height:198.0pt;border-top: none;width:105pt">
export
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
export *key value*<br>Example:<br>export TEST /data/test
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Sets environment variables. **key** and **value** respectively indicate the environment variable and its value.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
rm
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
rm *filename*<br>Example:<br>rm /data/testfile
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Deletes a file. **filename** indicates the absolute file path.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
rmdir
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
rmdir *dirname*<br>Example:<br>rmdir /data/testdir
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Deletes a directory. **dirname** indicates the absolute path of the directory.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
stop
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
stop *servicename*<br>Example:<br>stop console
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Stops a service. **servicename** indicates the name of the service to stop.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="280" style="mso-height-source:userset;height:210.0pt">
<td height="280" class="xl6621952" width="140" style="height:210.0pt;border-top: none;width:105pt">
copy
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
copy *oldfile* *newfile*<br>Example:<br>copy /data/old /data/new
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Copies a file. **oldfile** and **newfile** respectively indicate the old and new absolute file paths.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="382" style="mso-height-source:userset;height:286.5pt">
<td height="382" class="xl6621952" width="140" style="height:286.5pt;border-top: none;width:105pt">
reset
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
reset *servicename*<br>Example:<br>reset console
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Resets a service. **servicename** indicates the name of the service to reset. If the service has not been started, this command will start the service. If the service is running, the command will stop the service and then restart it.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="363" style="mso-height-source:userset;height:272.25pt">
<td height="363" class="xl6621952" width="140" style="height:272.25pt;border-top: none;width:105pt">
reboot
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
reboot *subsystem*<br>Example:<br>reboot updater
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Restarts the system. <strong>subsystem</strong> is optional. If it is not specified, the device enters the current system upon restarting. If it is specified, the device enters the corresponding subsystem upon restarting. For example, if you run **reboot updater**, the device enters the updater subsystem upon restarting.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
sleep
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
sleep *time*<br>Example:<br>sleep 5
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Enters the sleep mode. <strong>time</strong> indicates the sleep time. <br>To avoid impact on services, exercise caution when running this command.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
domainname
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
domainname *name*<br>Example:<br>domainname localdomain
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Sets the domain name.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
hostname
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
hostname *name*<br>Example:<br>hostname localhost
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Sets the host name.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="116" style="height:87.0pt">
<td height="116" class="xl6621952" width="140" style="height:87.0pt;border-top: none;width:105pt">
wait
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
wait *filepath*<br>Example:<br>wait /data/testfile or wait /data/testfile 5
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Waits for commands. The waiting time must not exceed 5 seconds.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
setrlimit
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
setrlimit resource *curValue* *maxValue*<br>Example:<br>setrlimit RLIMIT_CPU 10 100
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Sets resource usage restrictions. <br>For details, see the **resource[]** array of the **DoSetrlimit** function in **base/startup/init_lite/services/init/init_common_cmds.c**.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="228" style="mso-height-source:userset;height:171.0pt">
<td height="228" class="xl6621952" width="140" style="height:171.0pt;border-top: none;width:105pt">
exec
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
exec *Path of the executable file* *Parameters passed by the executable file*<br>Example:<br>exec /system/bin/udevadm trigger
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Runs an executable file. The command must not contain more than 10 parameters.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small and standard systems
</td>
</tr>
<tr height="231" style="height:173.25pt">
<td height="231" class="xl6621952" width="140" style="height:173.25pt;border-top: none;width:105pt">
mknode
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
mknod name { b | c } *Major* *Minor*<br>Example:<br>mknod path b 0644 1 9
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Creates an index node corresponding to a directory entry and a special file.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
makedev
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
makedev *major* *minor*<br>Example:<br>makedev -v update
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Creates a static device node, which is usually in the **/dev** directory.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="231" style="height:173.25pt">
<td height="231" class="xl6621952" width="140" style="height:173.25pt;border-top: none;width:105pt">
symlink
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
symlink target link_name<br>Example<br>symlink /proc/self/fd/0 /dev/stdin
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Creates a symbolic link.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="139" style="height:104.25pt">
<td height="139" class="xl6621952" width="140" style="height:104.25pt;border-top: none;width:105pt">
trigger
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
trigger *jobName*<br>Example<br>trigger early-fs
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Triggers a job.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="116" style="height:87.0pt">
<td height="116" class="xl6621952" width="140" style="height:87.0pt;border-top: none;width:105pt">
insmod
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
insmod <ko name> [-f] [options]<br>Example<br>insmod xxx.ko
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Loads a kernel module file.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="277" style="height:207.75pt">
<td height="277" class="xl6621952" width="140" style="height:207.75pt;border-top: none;width:105pt">
setparam
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
setparam *paramname* *paramvalue*<br>Example:<br>setparam sys.usb.config hdc
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Sets system parameters.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="231" style="height:173.25pt">
<td height="231" class="xl6621952" width="140" style="height:173.25pt;border-top: none;width:105pt">
load_persist_params
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
load persist params<br>Example:<br>load_persist_params&nbsp;
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Loads **persist** parameters. There must be one and only one space after the **load_persist_params** command.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="208" style="height:156.0pt">
<td height="208" class="xl6621952" width="140" style="height:156.0pt;border-top: none;width:105pt">
load_param
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
load *params*<br>Example:<br>load_param /data/test.normal.para
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Loads the parameters from a file to the memory.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="278" style="mso-height-source:userset;height:208.5pt">
<td height="278" class="xl6621952" width="140" style="height:208.5pt;border-top: none;width:105pt">
load_access_token_id
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
load_access_token_id&nbsp;
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Writes the access token to the **data/service/el0/access_token/nativetoken.json** file. There is one and only one space after **load_access_token_id**.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="139" style="height:104.25pt">
<td height="139" class="xl6621952" width="140" style="height:104.25pt;border-top: none;width:105pt">
ifup
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
ifup *NIC*<br>Example:<br>ifup eth0
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Activates the specified NIC.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="208" style="height:156.0pt">
<td height="208" class="xl6621952" width="140" style="height:156.0pt;border-top: none;width:105pt">
mount_fstab
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
mount_fstab fstab.test<br>Example:<br>mount_fstab /vendor/etc/fstab.test
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Mounts partitions based on the **fstab** file.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="208" style="height:156.0pt">
<td height="208" class="xl6621952" width="140" style="height:156.0pt;border-top: none;width:105pt">
umount_fstab
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
umount_fstab fstab.test<br>Example:<br>umount_fstab /vendor/etc/fstab.test
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Unmounts partitions based on the **fstab** file.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="162" style="height:121.5pt">
<td height="162" class="xl6621952" width="140" style="height:121.5pt;border-top: none;width:105pt">
restorecon
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
restorecon *file or dir*<br>Example:<br>restorecon /file
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Reloads the SELinux context.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="254" style="height:190.5pt">
<td height="254" class="xl6621952" width="140" style="height:190.5pt;border-top: none;width:105pt">
stopAllServices
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
stopAllServices [bool]<br>Example:<br>stopAllServices false<br>stopAllServices
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Stops all services.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="162" style="height:121.5pt">
<td height="162" class="xl6621952" width="140" style="height:121.5pt;border-top: none;width:105pt">
umount
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
umount *path*<br>Example:<br>umount /vendor
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Unmounts a mounted device.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
sync
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
sync&nbsp;
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Writes data to the disk synchronously. There is only one and only one space after **sync**.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
timer_start
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
timer_start *serviceName*<br>Example:<br>timer_start console
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Starts the service timer.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="185" style="height:138.75pt">
<td height="185" class="xl6621952" width="140" style="height:138.75pt;border-top: none;width:105pt">
timer_stop
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
timer_stop *serviceName*<br>Example:<br>timer_stop console
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Stops the service timer.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="162" style="height:121.5pt">
<td height="162" class="xl6621952" width="140" style="height:121.5pt;border-top: none;width:105pt">
init_global_key
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
init_global_key *path*<br>Example:<br>init_global_key /data
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Initializes the encryption key of the data partition file.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="70" style="height:52.5pt">
<td height="70" class="xl6621952" width="140" style="height:52.5pt;border-top:none; width:105pt">
init_main_user
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
init_main_user
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Encrypts the main user directory.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="162" style="height:121.5pt">
<td height="162" class="xl6621952" width="140" style="height:121.5pt;border-top: none;width:105pt">
mkswap
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
mkswap *file*<br>Example:<br>mkswap /swapfile1
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Creates a swap partition on a file or device.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="162" style="height:121.5pt">
<td height="162" class="xl6621952" width="140" style="height:121.5pt;border-top: none;width:105pt">
swapon
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
swapon *file*<br>Example:<br>swapon /swapfile1
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Activates the swap space.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="162" style="height:121.5pt">
<td height="162" class="xl6621952" width="140" style="height:121.5pt;border-top: none;width:105pt">
mksandbox
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
mksandbox *fileName*<br>Example:<br>mksandbox system
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Creates a sandbox.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Standard system
</td>
</tr>
<tr height="384" style="mso-height-source:userset;height:288.0pt">
<td height="384" class="xl6621952" width="140" style="height:288.0pt;border-top: none;width:105pt">
loadcfg
</td>
<td class="xl6621952" width="215" style="border-top:none;border-left:none; width:161pt">
loadcfg&nbsp;filePath<br>Example:<br>loadcfg&nbsp;/patch/fstab.cfg
</td>
<td class="xl6621952" width="225" style="border-top:none;border-left:none; width:169pt">
Loads other **.cfg** files. The maximum size of the target file (only **/patch/fstab.cfg** supported currently) is 50 KB. Each line in the /patch/fstab.cfg file is a command. The command types and formats must comply with their respective requirements mentioned in this table. A maximum of 20 commands are allowed.
</td>
<td class="xl6621952" width="190" style="border-top:none;border-left:none; width:143pt">
Small system
</td>
</tr><!--[endif]-->
</tbody>
</table>
### Available APIs
Job management is a part of the init startup process. It is a process-based function that completely serves the init startup process. It does not provide any functional APIs for other modules. It works in a way similar to command group management and does not provide help for other types of management. The following describes the job management APIs.
**Table 2** Description of job parsing APIs
<table border="0" cellpadding="0" cellspacing="0" width="968" style="border-collapse: collapse;table-layout:fixed;width:727pt;orphans: 2;widows: 2;-webkit-text-stroke-width: 0px; text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; box-sizing: border-box;border-spacing: 0px;word-break:initial;font-variant-ligatures: normal; font-variant-caps: normal">
<tbody>
<tr height="39" style="height:29.25pt;box-sizing: border-box">
<th height="39" class="xl6320252" width="249" style="height:29.25pt;width:187pt">
API
</th>
<th class="xl6420252" width="235" style="width:176pt;border-image: initial">
Input Parameter
</th>
<th class="xl6420252" width="106" style="width:80pt;border-image: initial">
Return Value
</th>
<th class="xl6420252" width="200" style="width:150pt;border-image: initial">
Description
</th>
<th class="xl6520252" width="170" style="width:134pt;border-image: initial">
Supported System Type
</th>
</tr>
<tr height="99" style="mso-height-source:userset;height:74.25pt;box-sizing: border-box">
<td height="99" class="xl6620252" width="249" style="height:74.25pt;width:187pt; border-image: initial;box-sizing: border-box">
void ParseAllJobs(const cJSON *fileRoot)
</td>
<td class="xl6720252" width="235" style="width:176pt;border-image: initial; box-sizing: border-box">
const cJSON *fileRoot
</td>
<td class="xl6720252" width="106" style="width:80pt;border-image: initial; box-sizing: border-box">
void
</td>
<td class="xl6720252" width="200" style="width:150pt;border-image: initial; box-sizing: border-box">
Provides the general entry for parsing jobs.
</td>
<td class="xl6720252" width="170" style="width:134pt;border-image: initial; box-sizing: border-box">
Small and standard systems
</td>
</tr>
<tr height="147" style="mso-height-source:userset;height:110.25pt;box-sizing: border-box">
<td height="147" class="xl6820252" width="249" style="height:110.25pt;width:187pt; border-image: initial;box-sizing: border-box">
static void ParseJob(const cJSON <span style="mso-spacerun:yes">&nbsp;</span>*jobItem, Job *resJob)
</td>
<td class="xl6920252" width="235" style="width:176pt;border-image: initial; box-sizing: border-box">
const cJSON *jobItem, Job *resJob
</td>
<td class="xl6920252" width="106" style="width:80pt;border-image: initial; box-sizing: border-box">
void
</td>
<td class="xl7020252" width="200" style="width:150pt;border-image: initial; box-sizing: border-box">
Checks whether a job exists and parses **cmds** in it.
</td>
<td class="xl6920252" width="170" style="width:134pt;border-image: initial; box-sizing: border-box">
Small system
</td>
</tr>
<tr height="177" style="mso-height-source:userset;height:132.75pt;box-sizing: border-box">
<td height="177" class="xl6620252" width="249" style="height:132.75pt;width:187pt; border-image: initial;box-sizing: border-box">
int GetCmdLinesFromJson(const cJSON *root, CmdLines **cmdLines)
</td>
<td class="xl6720252" width="235" style="width:176pt;border-image: initial; box-sizing: border-box">
const cJSON *root, CmdLines **cmdLines
</td>
<td class="xl6720252" width="106" style="width:80pt;border-image: initial; box-sizing: border-box">
int
</td>
<td class="xl6720252" width="200" style="width:150pt">
Parses **cmds** in the job. This API is used for the small system. It does not apply to the standard system because the **trigger** command and **condition** attribute are involved.
</td>
<td class="xl6720252" width="170" style="width:134pt;border-image: initial; box-sizing: border-box">
Small and standard systems
</td>
</tr>
<tr height="171" style="mso-height-source:userset;height:128.25pt;box-sizing: border-box">
<td height="171" class="xl6820252" width="249" style="height:128.25pt;width:187pt; border-image: initial;box-sizing: border-box">
int ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *jobName))
</td>
<td class="xl6920252" width="235" style="width:176pt;border-image: initial; box-sizing: border-box">
const cJSON *fileRoot, int (*checkJobValid)(const char *jobName)
</td>
<td class="xl6920252" width="106" style="width:80pt;border-image: initial; box-sizing: border-box">
int
</td>
<td class="xl6920252" width="200" style="width:150pt;border-image: initial; box-sizing: border-box">
Parses the **Trigger** command in the job.
</td>
<td class="xl6920252" width="170" style="width:134pt;border-image: initial; box-sizing: border-box">
Standard system
</td>
</tr>
<tr height="210" style="mso-height-source:userset;height:157.5pt;box-sizing: border-box">
<td height="210" class="xl6620252" width="249" style="height:157.5pt;width:187pt; border-image: initial;box-sizing: border-box">
static int ParseTrigger_(const TriggerWorkSpace *workSpace, const cJSON *triggerItem, int (*checkJobValid)(const char *jobName))
</td>
<td class="xl6720252" width="235" style="width:176pt;border-image: initial; box-sizing: border-box">
const TriggerWorkSpace *workSpace, const cJSON *triggerItem, int (*checkJobValid)(const char *jobName)
</td>
<td class="xl6720252" width="106" style="width:80pt;border-image: initial; box-sizing: border-box">
int
</td>
<td class="xl6720252" width="200" style="width:150pt">
Obtains the job name, condition attribute, and **cmds** command group. Jobs are stored in a hash table, and commands are stored in a queue structure.
</td>
<td class="xl6720252" width="170" style="width:134pt;border-image: initial; box-sizing: border-box">
Standard system
</td>
</tr><!--[endif]-->
</tbody>
</table>
**Table 3** Description of the job triggering APIs
<table border="0" cellpadding="0" cellspacing="0" width="906" style="border-collapse: collapse;table-layout:fixed;width:681pt;box-sizing: border-box;border-spacing: 0px; word-break:initial;font-variant-ligatures: normal;font-variant-caps: normal; orphans: 2;widows: 2;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial; text-decoration-style: initial;text-decoration-color: initial">
<tbody>
<tr height="39" style="height:35.25pt;box-sizing: border-box">
<th height="47" class="xl6322245" width="239" style="height:35.25pt;width:153pt">
API
</th>
<th class="xl6322245" width="235" style="border-left:none;width:178pt">
Input Parameter
</th>
<th class="xl6322245" width="106" style="border-left:none;width:80pt">
Return Value
</th>
<th class="xl6322245" width="200" style="border-left:none;width:128pt">
Description
</th>
<th class="xl6322245" width="170" style="border-left:none;width:133pt">
Supported System Type
</th>
</tr>
<tr height="257" style="mso-height-source:userset;height:192.75pt;box-sizing: border-box">
<td height="257" class="xl6422245" width="204" style="height:192.75pt;border-top: none;width:153pt;box-sizing: border-box">
void PostTrigger(EventType type, const char *content, uint32_t contentLen)
</td>
<td class="xl6422245" width="235" style="border-top:none;border-left:none; width:178pt;box-sizing: border-box">
EventType type, const char *content, uint32_t contentLen
</td>
<td class="xl6422245" width="106" style="border-top:none;border-left:none; width:80pt;box-sizing: border-box">
void
</td>
<td class="xl6422245" width="170" style="border-top:none;border-left:none; width:128pt;box-sizing: border-box">
Verifies the validity of the job name and sends a job triggering event.
</td>
<td class="xl6422245" width="170" style="border-top:none;border-left:none; width:133pt;box-sizing: border-box">
Standard system
</td>
</tr>
<tr height="323" style="height:242.25pt;box-sizing: border-box">
<td height="323" class="xl6522245" width="204" style="height:242.25pt;border-top: none;width:153pt;box-sizing: border-box">
static void SendTriggerEvent(int type, const char *content, uint32_t contentLen)
</td>
<td class="xl6522245" width="235" style="border-top:none;border-left:none; width:178pt;box-sizing: border-box">
int type, const char *content, uint32_t contentLen
</td>
<td class="xl6522245" width="106" style="border-top:none;border-left:none; width:80pt;box-sizing: border-box">
void
</td>
<td class="xl6522245" width="170" style="border-top:none;border-left:none; width:128pt;box-sizing: border-box">
Performs functions such as system control and starting or stopping of services based on system parameters.
</td>
<td class="xl6522245" width="170" style="border-top:none;border-left:none; width:133pt;box-sizing: border-box">
Standard system
</td>
</tr>
<tr height="188" style="mso-height-source:userset;height:141.0pt;box-sizing: border-box">
<td height="188" class="xl6422245" width="204" style="height:141.0pt;border-top: none;width:153pt;box-sizing: border-box">
static void DoTriggerCmd(const struct CmdArgs *ctx)
</td>
<td class="xl6422245" width="235" style="border-top:none;border-left:none; width:178pt;box-sizing: border-box">
const struct CmdArgs *ctx
</td>
<td class="xl6422245" width="106" style="border-top:none;border-left:none; width:80pt;box-sizing: border-box">
void
</td>
<td class="xl6422245" width="170" style="border-top:none;border-left:none; width:128pt;box-sizing: border-box">
Executes the **trigger** command.
</td>
<td class="xl6422245" width="170" style="border-top:none;border-left:none; width:133pt;box-sizing: border-box">
Standard system
</td>
</tr>
<tr height="258" style="mso-height-source:userset;height:193.5pt;box-sizing: border-box">
<td height="258" class="xl6522245" width="204" style="height:193.5pt;border-top: none;width:153pt;box-sizing: border-box">
void DoTriggerExec(const char *triggerName)
</td>
<td class="xl6522245" width="235" style="border-top:none;border-left:none; width:178pt;box-sizing: border-box">
const char *triggerName
</td>
<td class="xl6522245" width="106" style="border-top:none;border-left:none; width:80pt;box-sizing: border-box">
void
</td>
<td class="xl6522245" width="170" style="border-top:none;border-left:none; width:128pt;box-sizing: border-box">
Finds a command group based on the job name and pushes the commands in the command group to the execution queue. This API is available only for the standard system.
</td>
<td class="xl6522245" width="170" style="border-top:none;border-left:none; width:133pt;box-sizing: border-box">
Standard system
</td>
</tr>
<tr height="254" style="height:190.5pt;box-sizing: border-box">
<td height="254" class="xl6422245" width="204" style="height:190.5pt;border-top: none;width:153pt;box-sizing: border-box">
void DoJob(const char *jobName)
</td>
<td class="xl6422245" width="235" style="border-top:none;border-left:none; width:178pt;box-sizing: border-box">
const char *jobName
</td>
<td class="xl6422245" width="118" style="border-top:none;border-left:none; width:80pt;box-sizing: border-box">
void
</td>
<td class="xl6422245" width="170" style="border-top:none;border-left:none; width:128pt;box-sizing: border-box">
Matches a job based on the job name and invokes **DoCmdByIndex** to execute the commands in the job.
</td>
<td class="xl6422245" width="170" style="border-top:none;border-left:none; width:133pt;box-sizing: border-box">
Small system
</td>
</tr>
<tr height="208" style="height:156.0pt;box-sizing: border-box">
<td height="208" class="xl6522245" width="204" style="height:156.0pt;border-top: none;width:153pt;box-sizing: border-box">
void DoCmdByIndex(int index, const char *cmdContent)
</td>
<td class="xl6522245" width="235" style="border-top:none;border-left:none; width:178pt;box-sizing: border-box">
int index, const char *cmdContent
</td>
<td class="xl6522245" width="118" style="border-top:none;border-left:none; width:80pt;box-sizing: border-box">
void
</td>
<td class="xl6522245" width="170" style="border-top:none;border-left:none; width:128pt;box-sizing: border-box">
Combines parameters and commands.
</td>
<td class="xl6522245" width="170" style="border-top:none;border-left:none; width:133pt;box-sizing: border-box">
Small and standard systems
</td>
</tr><!--[endif]-->
</tbody>
</table>
### Development Example
The following is the template for configuring **jobs** in the **.cfg** file. You can use it to verify the job management function.
```
{
"jobs" : [{ // Basic job
"name" : "stage1",
"cmds" : [
"start service1",
"mkdir dir1"
]
}, { // Conditional job
"name" : "param:test.name1=0",
"condition" : "test.name1=0",
"cmds" : [
"chmod 0755 dir1",
"chown root root dir1"
]
}, { // Custom job
"name" : "param:test.name2=*",
"condition" : "test.name2=*",
"cmds" : [
"chmod 0644 dir1",
"chown system system dir1"
]
}
]
}
```
The differences in job configuration are described as follows:
1. **name** and **cmds** are mandatory for a job, and **cmds** must contain commands supported by the system.
2. **condition** is an optional attribute of a job. It indicates that the job is triggered only when the specified condition is met; that is, the job will not be invoked in a specific phase by the code or the **trigger** command.
3. The job name must comply with the specified rules. For a job whose condition is a system parameter, its name is prefixed with **param:**.
4. Commands in a renamed job can be executed only after being triggered by the **trigger** command in other executable job command groups. By default, the **trigger** command is executed in the post-init phase.
5. An existing job name can be used in different files. Jobs with the same name are regarded as the same job. When jobs with the same name are executed, the commands in these jobs are executed together.
6. For a conditional job, a condition is usually a system parameter. You can set a specific value so that the job is triggered when the condition is met. You can also set the value to an asterisk (*) so that the job is triggered whenever the condition is met, regardless of the parameter value.
7. For the small system, the commands in a job cannot be triggered by the **trigger** command in the post-init phase.
# Plug-in Management
## Overview
### Basic Concepts
- Introduction to begetctl
For details, see [begetctl Commands](#table14737791480).
- bootchart plug-in
The bootchart plug-in is an open source tool used to evaluate system performance during Linux startup. It automatically collects information such as the CPU usage, disk throughput, and process status, and displays the evaluation result in graphics to facilitate system startup optimization.
### Constraints
bootchart is available only for the standard system, and begetctl is available for both the small system and the standard system.
## How to Develop
### Parameters
**Table 1** Description of begetctl commands
| Command| Format and Example| Description|
| :---------- | :---------- |:--------|
| init group test [stage] | init group test | For details about **stage**, see **ServiceStatus**.|
| param ls [-r] [name] | Displays system parameters.<br>Example:<br>begetctl param ls persist.sys.usb | N/A|
| param get [name] | Obtains system parameter information.<br>Example:<br>begetctl param get<br>param get| N/A|
| param set name value| Sets system parameters.<br>Example:<br>begetctl param set ohos.servicectrl.display 1<br>param set ohos.servicectrl.display 1| N/A|
| param wait name [value] [timeout] | Waits for system parameters.<br>Example:<br>begetctl param wait persist.sys.usb.config hdc<br>param wait persist.sys.usb.config hdc| The default value of **timeout** is **30**.|
| param dump [verbose] | Dumps system parameter information.<br>Example:<br>begetctl param dump<br>param dump| N/A|
| param shell [name] | Enters the param shell.<br>Example:<br>begetctl param shell<br>param shell| N/A|
| timer_stop servicename | Stops the service timer.<br>Example:<br>begetctl timer_stop appspawn | The value of **servicename** can contain a maximum of 96 characters.|
| timer_start servicename timeout | Starts the service timer.<br>Example:<br>begetctl timer_start appspawn | The value of **servicename** can contain a maximum of 96 characters. The default value of **timeout** is **10**.|
| start_service servicename | Starts a service.<br>Example:<br>begetctl start_service appspawn<br>start_service appspawn| N/A|
| stop_service servicename | Stops a service.<br>Example:<br>begetctl stop_service appspawn<br>stop_service appspawn| N/A|
| service_control start servicename | Starts a service.<br>Example:<br>begetctl service_control start appspawn<br>service_control start appspawn| N/A|
| service_control stop servicename | Stops a service.<br>Example:<br>begetctl service_control stop appspawn<br>service_control stop appspawn | N/A|
| misc_daemon --write_logo xxx.rgb | Writes the startup logo.<br>Example:<br>begetctl misc_daemon --write_logo logo.rgb<br>misc_daemon --write_logo logo.rgb| The maximum size of an RGB file is **1024*2038**. Only Hi3516D V300 is supported.|
| reboot | Restarts the system.<br>Example:<br>begetctl reboot<br>reboot|N/A|
| reboot shutdown | Shuts down the system.<br>Example:<br>begetctl reboot shutdown<br>reboot shutdown|N/A|
| reboot suspend | Suspends the system.<br>Example:<br>begetctl reboot suspend<br>reboot suspend| N/A|
| reboot updater | Restarts the system and enters updater.<br>Example:<br>begetctl reboot updater<br>reboot updater| N/A|
| reboot updater[:options] | Restarts the system and enters updater.<br>Example:<br>begetctl reboot updater<br>reboot updater| N/A|
| reboot flashd | Restarts the system and enters flashd.<br>Example:<br>begetctl reboot flashd<br>reboot flashd| N/A|
| reboot flashd[:options] | Restarts the system and enters flashd.<br>Example:<br>begetctl reboot flashd<br>reboot flashd| N/A|
| reboot charging | Restarts the system and enters charging.<br>Example:<br>begetctl reboot charging<br>reboot charging| N/A|
| reboot loader | Restarts the system and enters the burning mode.<br>Example:<br>begetctl reboot loader<br>reboot loader| N/A|
| bootchart stop | Stops chart analysis.<br>Example:<br>begetctl bootchart stop | Only rk3568 is supported.|
| bootchart start | Starts chart analysis.<br>Example:<br>begetctl bootchart start | N/A|
| bootchart disable | Disables chart analysis.<br>Example:<br>begetctl bootchart disable | N/A|
| bootchart enable | Enables chart analysis.<br>Example:<br>begetctl bootchart enable | N/A|
| sandbox -s service_name | Moves a service into the sandbox.<br>Example:<br>sandbox -s foundation | N/A|
| sandbox -p process_name | Moves a process into the sandbox.<br>Example:<br>sandbox -p /bin/sh | N/A|
| sandbox -n sandbox_name | Enters the configured system or chipset sandbox.<br>Example:<br>sandbox -n system | N/A|
| sandbox -h | sandbox command help | N/A|
## How to Develop
### Available APIs
**Table 1** Description of APIs
| API| Description|
| ---------- | ---------- |
| void PluginExecCmdByName(const char *name, const char *cmdContent) | Starts the plug-in by name.|
| void PluginExecCmdByCmdIndex(int index, const char *cmdContent) | Starts the plug-in by index.|
| int PluginExecCmd(const char *name, int argc, const char **argv) | Starts the plug-in by command.|
| int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd) | Adds the plug-in installation command.|
### How to Develop
Add a plug-in. The following uses bootchart as an example:
1. Install the **.so** file and define an independent file to implement the following functions:
```c
static int bootchartEarlyHook(int stage, int prio, void *cookie)
{
char enable[4] = {}; // 4 enable size
uint32_t size = sizeof(enable);
SystemReadParam("persist.init.bootchart.enabled", enable, &size);
if (strcmp(enable, "1") != 0) {
PLUGIN_LOGI("bootchart disabled.");
return 0;
}
InitModuleMgrInstall("libbootchart");
PLUGIN_LOGI("bootchart enabled.");
return 0;
}
MODULE_CONSTRUCTOR(void)
{
// Depends on parameter service
InitAddPostPersistParamLoadHook(0, bootchartEarlyHook);
}
```
2. Compile the static library **libbootchart_static** and add it to the **static_modules** group.
```
group("static_modules") {
if (!defined(ohos_lite)) {
deps = [ ":libbootchart_static" ]
}
}
```
3. Initialize the bootchart plug-in.
```c
static int BootchartInit(void)
{
if (g_executorId == -1) {
g_executorId = AddCmdExecutor("bootchart", DoBootchartCmd);
PLUGIN_LOGI("BootchartInit executorId %d", g_executorId);
}
return 0;
}
MODULE_CONSTRUCTOR(void)
{
PLUGIN_LOGI("DoBootchartStart now ...");
BootchartInit();
}
```
4. Exit the bootchart plug-in.
```c
MODULE_DESTRUCTOR(void)
{
PLUGIN_LOGI("DoBootchartStop now ...");
DoBootchartStop();
BootchartExit();
}
```
5. Run the bootchart command.
```c
static int DoBootchartCmd(int id, const char *name, int argc, const char **argv)
{
PLUGIN_LOGI("DoBootchartCmd argc %d %s", argc, name);
...
return 0;
}
```
### Development Example
Prerequisites
1. Prepare the bootchart test environment. Specifically, install Python and pycairo by running **pip install pycairo** on Linux.
2. Decompress **bootchart-master.tar**.
tar -zxvf bootchart-master.tar
Procedure
1. Start the system.
2. Run the **begetctl bootchart enable** command.
3. Restart the system.
4. Run the **begetctl bootchart stop** command.
5. Run the **begetctl bootchart disable** command.
6. Export the following files from the **/data/bootchart** directory and save them to the **bootchart** folder:<br>
header<br>
proc_diskstats.log<br>
proc_ps.log<br>
proc_stat.log<br>
7. Run the **tar -zcvf bootchart.tgz *** command to compress the **bootchart.tgz** file (available only for Linux) and copy the compressed file to the **linux:bootchart-master** directory.
8. Run the following command in the **bootchart-master** directory:
```
python3 pybootchartgui.py -f pdf bootchart.tgz
```
Expected Result
<br>A **bootchart.pdf** file is generated in the **bootchart-master** directory.
# Sandbox Management
## Overview
### Function
OpenHarmony supports two types of sandbox, namely, system sandbox and chipset sandbox.
### Basic Concepts
The system sandbox and chipset sandbox are created in the init module. Native services choose to enter the system sandbox or chipset sandbox based on their functions. Sandbox components can be isolated through the **mount** attribute if **mount-bind-paths** or **mount-bind-files** is set for them in configuration files such as **system-sandbox.json** and **chipset-sandbox.json**. In addition, a sandbox debugging tool is provided to facilitate sandbox debugging, verification, and optimization. For details about commands, see [Description of begetctl Commands](subsys-boot-init-plugin.md#parameters).
### Constraints
The sandbox management module is available only for the standard system.
## How to Develop
### Parameters
**Table 1** Parameters in the sandbox configuration file
| JSON Prefix| Description|
| ---------- | ---------- |
| sandbox-root | Root directory of the sandbox.|
| mount-bind-paths | Directory to mount.|
| mount-bind-files | File to mount.|
| src-path | Source path of the directory or file to mount.|
| sandbox-path | Target path in the sandbox.|
| sandbox-flags | Mount flag. The default value is **bind rec**.|
| target-name | Directory to link.|
| link-name | Target link in the sandbox.|
**Table 2** Description of sandbox configuration files
| Sandbox Configuration File| Description|
| -------- | -------- |
| chipset-sandbox64.json | Chipset sandbox configuration file for the 64-bit system|
| chipset-sandbox.json | Chipset sandbox configuration file for the 32-bit system|
| system-sandbox64.json | System sandbox configuration file for the 64-bit system|
| system-sandbox.json | System sandbox configuration file for the 32-bit system|
### Available APIs
Logical storage structure of the sandbox:
```c++
// Main functions
// name is "system" or "chipset"
bool InitSandboxWithName(const char *name); // Parsing to the JSON structure
typedef struct {
mountlist_t *mounts; // Directory to mount
mountlist_t *fileMounts; // File to mount
linklist_t *links; // Directory to link
char *rootPath; // Root path of the sandbox: /mnt/sandbox/system|vendor|xxx
char name[MAX_BUFFER_LEN]; // Sandbox name, for example, system sandbox or chipset sandbox
bool isCreated; // Sandbox creation flag
int ns; // namespace
} sandbox_t;
```
### How to Develop
1. Create a sandbox.
- Create a system or chipset sandbox and configure the corresponding **system-sandbox.json** or **chipset-sandbox.json** file. For details about how to configure the JSON file, see [Sandbox JSON File Configuration](#sandbox).
- By default, the sandbox function of a service is enabled. If you do not want to move the service to the sandbox, set **sandbox** to **0** in the **.cfg** file. Otherwsie, set **sandbox** to **1**.
```
"sandbox" : 1
```
2. Modify the JSON file configuration of the sandbox.
- Go to the **/system/etc/sandbox/** directory, and run **cat system-sandbox.json** and **cat chipset-sandbox.json**.
If you are using a 64-bit system, run **cat system-sandbox64.json** and **cat chipset-sandbox64.json** instead.
- Modify the sandbox configuration files in the **base/startup/init_lite/interfaces/innerkits/sandbox** directory. After that, restart the system.
### Development Example
Sandbox JSON File Configuration
```json
{
"sandbox-root" : "/mnt/sandbox/system",
"mount-bind-paths" : [{
"src-path" : "/system/lib/ndk",
"sandbox-path" : "/system/lib/ndk",
"sandbox-flags" : [ "bind", "rec", "private" ]
}],
"mount-bind-files" : [{
"src-path" : "/system/lib/ld-musl-aarch64.so.1",
"sandbox-path" : "/system/lib/ld-musl-aarch64.so.1",
"sandbox-flags" : [ "bind", "rec", "private" ]
}],
"symbol-links" : [{
"target-name" : "/vendor/lib",
"link-name" : "/lib"
}]
}
```
## FAQs
### Failed to Create a Sandbox
**Symptom**
**Sandbox %s has not been created.** is printed in the dmesg or hilog.
**Cause Analysis**
Creating a sandbox failed because of a mounting and linking error.
**Solution**
1. Check whether the JSON file is correctly configured.
2. Check whether the created sandbox is supported.
# Service Management
## Overview
### Function
Service configuration allows you to configure services on demand to create different value-added services. Currently, the following value-added services are supported: startup control, on-demand startup, command execution, scheduled startup, FD proxy, and [sandbox](subsys-boot-init-sandbox.md).
### Basic Concepts
- init service parameter options
For details, see [Description of service Fields](#table14737791471).
- init service startup control (for standard system or higher)
The init process classifies services into three types based on service configurations and starts the services in different phases.
- **boot**: services that need to be preferentially started in the system. This type of services are started in the init phase.
- **normal**: common services in the system. This type of services are started in the post-init phase. This is the default service type.
- **condition**: services that are started by running the startup command. You can add the **start xxxx** command to **jobs** to start the corresponding service.
- init service command execution (for standard system or higher)
The init module provides the service command execution function, which allows services to execute different commands in different phases.
- **on-start**: execution of commands after the service process is forked. The on-start job is executed in the subprocess of the service and affects only the subprocess.
- **on-stop**: execution of commands in the init process when the service is stopped.
- **on-restart**: execution of commands in the init process when the service is restarted.
The following is an example of service configuration:
```
"services" : [{
"name" : "serviceName",
"path" : ["/system/bin/serviceName"]
"jobs" : {
"on-boot" : "boot",
"on-start" : "services:serviceName_start",
"on-stop" : "services:serviceName_stop",
"on-restart" : "services:serviceName_restart"
}
},
```
With the parallel startup and command execution capabilities, processes can be started concurrently.
- init service on-demand startup
If on-demand startup is enabled, the init process starts a service only when it is required. The **ondemand** attribute is used to determine whether to enable on-demand startup for a service.
The following is an example configuration of the **ondemand** attribute:
```
"services" : [{
"name" : "serviceName",
"path" : ["/system/bin/serviceName"]
"ondemand" : true
}]
```
- SA process on-demand startup
For details, see [samgr Usage](https://gitee.com/openharmony/distributedschedule_samgr/blob/master/README.md).
- Socket process on-demand startup
1. The init process creates a socket for socket processes in the pre-fork phase and listens to read/write events on this socket.
2. If a read/write event is received over the socket, the init process starts the native service corresponding to the socket process, cancels event listening on the socket, and transfers the socket to the corresponding native service for management.
3. The native service automatically exits if no more packets need to be processed. When reclaiming subprocesses, the init process starts event listening over the socket again based on the service configuration.
- Hot-swap service process on-demand startup
The hot-swap service process can be started to process hot swap events based on system parameter changes.
- Enhanced init process startup and recycling
The CPU core binding, priority, MAC address, and AccessToken information of the service process can be configured in the configuration file during process startup.
- Support of CPU core binding for service processes (through modification of the **\*.cfg** file)
- Support of priority setting for service processes (through modification of the **\*.cfg** file)
- Support of MAC address setting (that is, SELinux tag setting) for service processes (through modification of the **\*.cfg** file)
- Support of AccessToken setting for service processes and distributed capability setting for system service processes (through modification of the **\*.cfg** file)
- Support of the suppression mechanism for service processes (through modification of the **\*.cfg** file)
The following is the example configuration for enhanced init process startup and recycling:
```
"services" : [{
"name" : "serviceName",
"path" : ["/system/bin/serviceName"]
"importance" : 1, // Priority setting for service processes
"cpucore" : [0], // CPU binding for service processes
"critical" : [1, 5, 10], // Suppression for service processes
"apl" : "normal", // Ability privilege level setting for service processes
"d-caps" : ["OHOS_DMS"], // Distributed capability setting for service processes
"secon" : "u:r:distributedsche:s0" // SELinux tag setting for service processes. In this example, u:r:distributedsche:s0 is the SELinux tag.
}
```
- init service FD proxy (for standard system or higher)
FD proxy is an extended mechanism for on-demand startup. It can ensure that the FD state handle is not lost before the service process exits. Specifically, a service process sends the FD to the init process before it exits, and then reclaims the FD from the init process when it is started again.
This mechanism is implemented using the API provided by the init process. Before a service process exits, it can call the related API to send the FD to the init process over the socket that supports IPC communication. After the service process is restarted, the init process returns the corresponding FD handle to it in the same way. For details about the APIs, see [FD Proxy APIs](#table14737791479).
- Scheduled startup
Scheduled startup means to start a service at the specified time. If the service has been started, it will not be started again. For details about the command, see [Description of begetctl Commands](subsys-boot-init-plugin.md#parameters).
```
timer_start servicename timeout
```
- Sandbox
For details, see [Sandbox Management](subsys-boot-init-sandbox.md).
### Constraints
The service management module is available only for the mini system and standard system.
## How to Develop
### Use Cases
By parsing the ***.cfg** file, you can obtain **service** fields, and then set and start the service.
### Parameters
**Table 1** Description of service fields
<table border="0" cellpadding="0" cellspacing="0" width="737" style="border-collapse: collapse;table-layout:fixed;width:554pt;border-spacing: 0px;font-variant-ligatures: normal; font-variant-caps: normal;orphans: 2;widows: 2;-webkit-text-stroke-width: 0px; text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial">
<tbody>
<tr height="24" style="height:18.0pt">
<th height="24" class="xl6521805" width="126" style="height:18.0pt;width:95pt">
Name
</th>
<th class="xl6521805" width="196" style="border-left:none;width:147pt">
Description
</th>
<th class="xl6521805" width="242" style="border-left:none;width:182pt">
Remarks
</th>
<th class="xl6521805" width="173" style="border-left:none;width:130pt">
Supported System Type
</th>
</tr>
<tr height="111" style="mso-height-source:userset;height:83.25pt">
<td height="111" class="xl6621805" width="126" style="height:83.25pt;border-top: none;width:95pt">
name
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Name of the current service. (Mandatory)
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: string. The value cannot be empty and can contain a maximum of 32 bytes.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="185" style="mso-height-source:userset;height:138.75pt">
<td height="185" class="xl6621805" width="126" style="height:138.75pt;border-top: none;width:95pt">
path
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Full path (including parameters) of the executable file for the current service. This is an array. (Mandatory)
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
The first element is the path of the executable file, and the maximum number of elements is 20.<br>
Each element is a string that contains a maximum of 64 bytes.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="71" style="mso-height-source:userset;height:53.25pt">
<td height="71" class="xl6621805" width="126" style="height:53.25pt;border-top: none;width:95pt">
uid
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
User ID (UID) of the current service process.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: int or string.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="93" style="mso-height-source:userset;height:69.75pt">
<td height="93" class="xl6621805" width="126" style="height:69.75pt;border-top: none;width:95pt">
gid
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Group ID (GID) of the current service process.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: int, int[], string, or string array.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="218" style="mso-height-source:userset;height:163.5pt">
<td height="218" class="xl6621805" width="126" style="height:163.5pt;border-top: none;width:95pt">
once
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Whether the current service process is a one-off process.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
**1**: The current service process is a one-off process. If the process exits, the init process does not restart it.<br>
**0**: The current service process is not a one-off process. If the process exits, the init process restarts it upon receiving the SIGCHLD signal.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="182" style="mso-height-source:userset;height:136.5pt">
<td height="182" class="xl6621805" width="126" style="height:136.5pt;border-top: none;width:95pt">
importance
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Current service priority.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Standard system: The service priority ranges from -20 to 19. A value beyond the range is invalid.<br>
Small system: The value **0** indicates an unimportant process and a value greater than **0** indicates an important process.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="219" style="mso-height-source:userset;height:164.25pt">
<td height="219" class="xl6621805" width="126" style="height:164.25pt;border-top: none;width:95pt">
caps
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Capabilities required by the current service. They are evaluated based on the capabilities supported by the security subsystem and configured in accordance with the principle of least permission.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: number or string array. If you set the value to a number, use the standard Linux capability. If you set the value to a string array, use the standard macro name.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="405" style="mso-height-source:userset;height:303.75pt">
<td height="405" class="xl6621805" width="126" style="height:303.75pt;border-top: none;width:95pt">
critical
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Suppression mechanism for services. If the number of times a service is restarted exceeds the value N within the specified period T, the system will be restarted.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Standard system:<br>Type: int array, for example, **"critical": [M, N, T]**.<br>- **M**: enable flag (**0**: disable; **1**: enable).<br>- **N**: number of times the service is started.<br>- **T**: period of time, in seconds.<br> Both **M** and **N** are greater than **0**.<br>
Small and standard systems:<br>Type: int, for example, **"critical": M**.<br>M: enable flag (**0**: disable; **1**: enable).<br> By default, **N** is **4** and **T** is **20**.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Standard system
</td>
</tr>
<tr height="173" style="mso-height-source:userset;height:129.75pt">
<td height="173" class="xl6621805" width="126" style="height:129.75pt;border-top: none;width:95pt">
cpucore
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Number of CPU cores bound to the service.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: int array, for example, **"cpucore": [N1, N2, ...]**. **N1** and **N2** indicate the indices of the CPU cores to be bound. For a single-core device, **cpucore** is **0**.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Standard system
</td>
</tr>
<tr height="116" style="mso-height-source:userset;height:87.0pt">
<td height="116" class="xl6621805" width="126" style="height:87.0pt;border-top: none;width:95pt">
d-caps
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Distributed service capability (for standard system or higher)
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: string array, for example, **"d-caps": ["OHOS_DMS"]**.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Standard system
</td>
</tr>
<tr height="182" style="mso-height-source:userset;height:136.5pt">
<td height="182" class="xl6621805" width="126" style="height:136.5pt;border-top: none;width:95pt">
apl
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Ability privilege level (for standard system or higher).
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: string, for example, **"apl": "system_core"**. The value can be **system_core** (default), **normal**, or **system_basic**.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Standard system
</td>
</tr>
<tr height="193" style="mso-height-source:userset;height:144.75pt">
<td height="193" class="xl6621805" width="126" style="height:144.75pt;border-top: none;width:95pt">
start-mode
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Service startup mode (for standard system or higher).
</td>
<td class="xl6721805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: string, for example, **"start-mode": "condition"**. The value can be **boot**, **normal**, or **condition**. For details, see init Service Startup Control.</a>
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Standard system
</td>
</tr>
<tr height="147" style="mso-height-source:userset;height:110.25pt">
<td height="147" class="xl6621805" width="126" style="height:110.25pt;border-top: none;width:95pt">
ondemand
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Whether on-demand startup is enabled.
</td>
<td class="xl6721805" width="242" style="border-top:none;border-left:none; width:182pt">
Type: bool, for example, **"ondemand": true**. This feature is available only for the small system running the Linux kernel. For details, see init Service On-Demand Startup.</a>
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="72" style="mso-height-source:userset;height:54.0pt">
<td height="72" class="xl6621805" width="126" style="height:54.0pt;border-top:none; width:95pt">
disable
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Reserved.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
None.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Small and standard systems
</td>
</tr>
<tr height="106" style="mso-height-source:userset;height:79.5pt">
<td height="106" class="xl6621805" width="126" style="height:79.5pt;border-top: none;width:95pt">
sandbox
</td>
<td class="xl6621805" width="196" style="border-top:none;border-left:none; width:147pt">
Whether the sandbox function is enabled.
</td>
<td class="xl6621805" width="242" style="border-top:none;border-left:none; width:182pt">
**1** (default): Enable the sandbox function.
**0**: Disable the sandbox function.
</td>
<td class="xl6621805" width="173" style="border-top:none;border-left:none; width:130pt">
Standard system
</td><!--[endif]-->
</tr>
</tbody>
</table>
**Table 2** Description of socket fields
| Name| Description|
| -------- | -------- |
| name | Name of the socket. It does not need to be the same as the service name. The value must not be empty and can contain a maximum of 32 bytes.|
| family | Address family to which the socket belongs. Currently, the AF_UNIX and AF_NETLINK families are supported.|
| type | Socket type. Currently, connection-based sockets, SOCK_SEQPACKET and SOCK_STREAM, and UDP-based connectionless socket, SOCK_DGRAM, are supported.|
| protocol | Protocol used for socket communication. Unless otherwise required, set the value to **default** so that the socket automatically selects a proper protocol based on the socket address family and socket type. In addition to the default protocol, the NETLINK_KOBJECT_UEVENT protocol is also supported.|
| permissions | Permissions of the socket node file. This field is valid only for sockets that have entity node files, such as the AF_UNIX address family.|
| uid | User ID of the socket node file. This field is valid only for sockets that have entity node files, such as the AF_UNIX address family.|
| gid | Group ID of the socket node file. This field is valid only for sockets that have entity node files, such as the AF_UNIX address family.|
| option | Socket option. This field is passed when **setsockopt** is called. Currently, the available options include **SOCKET_OPTION_PASSCRED**, **SOCKET_OPTION_RCVBUFFORCE**, **SOCK_CLOEXEC**, and **SOCK_NONBLOCK**.|
### Available APIs
**Table 3** FD proxy APIs<a name="table14737791479"></a>
| API | Function| Description |
| ---------- | ---------- |--------|
| int *ServiceGetFd(const char *serviceName, size_t *outfdCount) | Obtains the proxy FD from the init process.| Return value: Returns the pointer to the fd array if the operation is successful; returns **NULL** otherwise. (Note: Manual release is required.)<br>Arguments:<br> **serviceName**: service name.<br>**outfdCount**: length of the returned fd array.|
| int ServiceSaveFd(const char *serviceName, int *fds, int fdCount) | Requests the init process for FD proxy.| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> **fds**: pointer to the FD array for FD proxy.<br>**fdCount**: length of the FD array
| int ServiceSaveFdWithPoll(const char *serviceName, int *fds, int fdCount) | Requests FD proxy in poll mode.| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> **fds**: pointer to the FD array.<br> **fdCount**: length of the FD array.
**Table 4** Service control APIs
| API| Function| Description|
| :---------- | :---------- |:--------|
| int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc) | Configures service parameters.| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> **action**: service action, which can be **start**, **stop**, or **restart**.<br> **extArgv**: parameter array.<br> **extArgc**: number of parameters.|
| int ServiceControl(const char *serviceName, int action) | Controls the service behavior.| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> **action**: service action, which can be **start**, **stop**, or **restart**.|
| int ServiceWaitForStatus(const char *serviceName, ServiceStatus status, int waitTimeout) | Waiting for service status| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br>**serviceName**: service name.<br> **status**: service status.<br> **waitTimeout**: waiting timeout interval.|
| int ServiceSetReady(const char *serviceName) | Sets a service as being ready.| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.|
| int StartServiceByTimer(const char *serviceName, uint64_t timeout) | Starts a service by timer.| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> timeout: timeout interval.|
| int StopServiceTimer(const char *serviceName) | Stops a service timer.| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.|
### How to Develop
The following describes how to add a system service named **MySystemApp**:
```
{
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"mkdir /storage/MyDir", // Create a folder before starting the MySystemApp service. This operation is executed in the pre-init job.
"chmod 0600 /storage/MyDir", // Modify the permission because the MySystemApp service requires that only the current user and its owner group have the read and write permissions on the file.
"chown 10 10 /storage/MyDir"
]
}, {
"name" : "init",
"cmds" : [
"start MySystemApp" // Start the MySystemApp service in the init job.
]
}, {
"name" : "post-init",
"cmds" : [] // Do not configure the post-init job because no other operations are required after the MySystemApp system service is started.
}
],
"services" : [{
"name" : "MySystemApp", // Name of the system service
"path" : ["/bin/MySystemAppExe", "param1", "param2", "param3"], // The executable file path of the MySystemApp service is /bin/MySystemAppExe. To start the service, three parameters ("param1", "param2", and "param3") need to be passed.
"socket" : [{
"name" : "ueventd",
"family" : "AF_NETLINK",
"type" : "SOCK_DGRAM",
"protocol" : "NETLINK_KOBJECT_UEVENT",
"permissions" : "0660",
"uid" : "system",
"gid" : "system",
"option" : [
"SOCKET_OPTION_PASSCRED",
"SOCKET_OPTION_RCVBUFFORCE",
"SOCK_CLOEXEC",
"SOCK_NONBLOCK"
]
}],
"uid" : 20, // UID of the MySystemApp service: 20
"gid" : 20, // GID of the MySystemApp service: 20
"once" : 0, // Not a one-off process of the MySystemApp service. If MySystemApp exits, the init process needs to restart it.
"importance" : 0, // Not a key system process of the MySystemApp service. If MySystemApp exits, the init process does not need to restart the development board.
"caps" : [], // Do not perform capability-related operations because capabilities are not required by the MySystemApp service.
"start-mode" : "condition",
"critical": [1, 2, 10], // Configure the critical field for MySystemApp system services. You need to pass three parameters, wherein, 1 means to enable system restarting, 2 means the number of times the critical service is restarted, and 10 means the time within which the critical service is restarted.
"cpucore" : [0, 1], // The device has two cores and both of them are bound to the CPU.
"apl" : "system_core",
"d-caps" : ["OHOS_DMS"],
"jobs" : {
"on-boot" : "boot",
"on-start" : "services:MySystemApp_start",
"on-stop" : "services:MySystemApp_stop",
"on-restart" : "services:MySystemApp_restart"
}
}
]
}
```
After the configuration is complete, compile the package to burn the board.
1. Run the **task -a** command for liteos-a or **ps** for Linux to check whether the MySystemApp service process is started.
2. Run the **kill** command to kill the MySystemApp process, and verify that the process will be restarted.
3. Run the **kill** command to kill the MySystemApp process, and verify that the development board will not be restarted.
## FAQs
### Service Not Exist
**Symptom**
"Failed get servName" is recorded in the kernel log.
**Cause Analysis**
After a code review on the init process, it is found that the service does not exist.
**Solution**
1. Check whether the service is correctly configured in the **.cfg** file.
2. Check whether the **.cfg** file of the service is loaded normally.
3. Check whether the format of the **.cfg** file is correct.
### Requesting FD Proxy for Other Services Failed
**Symptom**
"Service' xxx '(pid = xxx) is not valid or request with unexpected process(pid = xxx)" is recorded in the kernel log.
**Cause Analysis**
The kernel log is printed by the init process. After a code review on the init process, it is found that FD proxy is requested for other services.
**Solution**
Request FD proxy for the current service, but not other services.
# Parameter Management
## Overview
### Function
The parameter management module, namely, sysparam, provides an easy-to-use key-value pair access interface for system services to configure service functions based on their own system parameters.
### Basic Concepts
Figure 1 System parameter operation primitives
![System parameter operation primitives](figure/system-parameter-operation-primitives.png)
**Table 1** Description of system parameter operation primitives
| Operation Primitive| Description|
| -------- | -------- |
| get | Obtains the value of a system parameter. |
| set | Sets the value of a system parameter. |
| wait | Waits for value change of a system parameter synchronously.|
| watch | Observes value change of a system parameter asynchronously.|
#### System Parameter Definition
- Naming format
A system parameter name consists of multiple segments in dotted notation. Each segment can be a string that consists of letters, digits, and underscores (_). The total length cannot exceed 96 bytes. System parameter names are categorized into the following two types.
**Table 2** System parameter names
| Type| Name| Example| Description|
| -------- | -------- | -------- | -------- |
| Name| Parameter Name | const.product.**name** | Complete system parameter name. It does not end with a period (.). |
| Directory| Parameter Directory | const.product **.** | Name of the directory storing system parameters with the same prefix. It ends with a period (.).|
- Type
System parameters are categorized into three types.
**Table 3** System parameter types
| Type| Prefix| Description|
| -------- | -------- | -------- |
| Constant| const. | Constant parameter, which will not be changed once a value is assigned. The value can contain a maximum of 4,096 bytes (including the terminator).|
| Writable| Others| Writable parameter, which will be lost after system restart. The value can contain a maximum of 96 bytes (including the terminator).|
| Persistent| persist. | Writable and persistent parameter, which will not be lost after system restart. The value can contain a maximum of 96 bytes (including the terminator).|
The general naming format is as follows:
```
[ const | persist ].$sub_system.$desc
```
**$sub_system** is the name of the subsystem or module.
**$desc** indicates the description of a system parameter. The description can contain multiple segments in dotted notation.
#### Definition Rules
Each subsystem defines the system parameters of its own modules, including the system parameter name, default value, and access permission information.
- System parameter value definition file
- The system parameter value definition file ends with the **.para** extension. An example of the file format is as follows:
```shell
# This is comment
const.product.name=OHOS-PRODUCT
const.os.version.api=26
const.telephony.enable=false|true
const.test.withblank=My Value
const.test.withcomment=MyValue # This should be ommitted
const.test.multiline="This is a multiline parameter.
Line2 value.
Last line."
```
- You must use a complete system parameter command when assigning a value for a system parameter. The following table describes the value assignment modes.
**Table 4** Value assignment modes
| Type| Example| Description|
| -------- | -------- | -------- |
| String | const.product.name=OHOS-PRODUCT | A multi-line string must be enclosed in double quotation marks ("").|
| Number | const.os.version.api=26 | Numbers do not need to be enclosed in quotation marks.|
| Boolean | const.telephony.enable=false | A Boolean value can be **0**, **1**, **false**, or **true**.|
- DAC definition file
Currently, access permissions of system parameters are managed in Discretionary Access Control (DAC) mode. The access permission definition file ends with the **.para.dac** extension. The following is an example:
```java
const.product.="root:root:660"
```
As shown above, we can use **parameter directory** to define the same access permission for system parameters with the same prefix. The DAC information is divided into three segments, user, group, and UGO rule information, which are separated using a semicolon (:).
The following figure shows the structure of the UGO rule information.
**Figure 2** UGO rule information
![UGO rule](figure/dac-definition.png)
- Loading sequence
The following table provides the sequence of loading system parameters.
**Table 5** System parameter loading sequence
| Type| Path| Description|
| -------- | -------- | -------- |
| Kernel parameters | /proc/cmdline | Convert some values of kernel parameters into system parameters. Specifically, convert all **ohospara.xxx=valXXX** parameters to **ohos.boot.xxx=valXXX** parameters.|
| OS system parameters| /system/etc/param/ohos_const/*.para | Load the definition file containing OS constants preferentially. |
| Vendor parameters| /vendor/etc/param/*.para | Load the system parameters defined by vendors with the secondary priority. |
| System parameters| /system/etc/param/*.para | Load the parameters defined by each subsystem. If a system parameter already exists, ignore it.|
| Persistent parameters| /data/parameters/ | If persistent parameters exist, load them at last. Persistent parameters will overwrite the default system parameters that have been loaded.|
### Constraints
The service management module is available only for the mini system and standard system.
## How to Develop
### Use Cases
You can set specific system parameters as needed to meet your service demand.
### Available APIs
- Shell commands
You can operate system parameters directly by using shell commands. This operation mode is available only for the standard system. The following table lists the shell commands.
**Table 6** Description of shell commands
| Command| Description|
| -------- | -------- |
| param get [**key**] | Obtains the system parameter value of the specified key. If no key name is specified, all system parameter values will be returned.|
| param set **key value** | Sets the specified value for the specified key.|
| param wait **key** **value** | Waits for the system parameter value of the specified key to match the specified value. Fuzzy match is supported. For example, ***** indicates any value, and **val*** indicates matching of only the first three val characters.|
| param watch | Observes value change of a system parameter asynchronously.|
- syspara APIs
The following table lists the APIs used to obtain system parameter values. The return result is a const string and the free operation is not supported.
**Table 7** Description of syspara APIs
| API| Description|
| -------- | -------- |
| int&nbsp;GetParameter(const&nbsp;char\*&nbsp;key,&nbsp;const&nbsp;char\*&nbsp;def,&nbsp;char\*&nbsp;value,&nbsp;unsigned&nbsp;int&nbsp;len) | Obtains system parameters.|
| int&nbsp;SetParameter(const&nbsp;char\*&nbsp;key,&nbsp;const&nbsp;char\*&nbsp;value) | Sets or updates system parameters.|
| const&nbsp;char\*&nbsp;GetDeviceType(void) | Obtains the device type.|
| const&nbsp;char\*&nbsp;GetManufacture(void) | Obtains the device manufacturer.|
| const&nbsp;char\*&nbsp;GetBrand(void) | Obtains the device brand.|
| const&nbsp;char\*&nbsp;GetMarketName(void) | Obtains the device marketing name.|
| const&nbsp;char\*&nbsp;GetProductSeries(void) | Obtains the device series name.|
| const&nbsp;char\*&nbsp;GetProductModel(void) | Obtains the device authentication model.|
| const&nbsp;char\*&nbsp;GetSoftwareModel(void) | Obtains the device software model.|
| const&nbsp;char\*&nbsp;GetHardwareModel(void) | Obtains the device hardware model.|
| const&nbsp;char\*&nbsp;GetHardwareProfile(void) | Obtains the device hardware profile.|
| const&nbsp;char\*&nbsp;GetSerial(void) | Obtains the device serial number (SN).|
| const&nbsp;char\*&nbsp;GetOSFullName(void) | Obtains the operating system name.|
| const&nbsp;char\*&nbsp;GetDisplayVersion(void) | Obtains the software version visible to users.|
| const&nbsp;char\*&nbsp;GetBootloaderVersion(void) | Obtains the bootloader version of this device.|
| const&nbsp;char\*&nbsp;GetSecurityPatchTag(void) | Obtains the security patch tag.|
| const&nbsp;char\*&nbsp;GetAbiList(void) | Obtains the list of application binary interfaces (ABIs) supported on this device.|
| int&nbsp;GetSdkApiVersion(void) | Obtains the SDK API level that matches the current system software.|
| int&nbsp;GetFirstApiVersion(void) | Obtains the first SDK API level of the system software.|
| const&nbsp;char\*&nbsp;GetIncrementalVersion(void) | Obtains the incremental version.|
| const&nbsp;char\*&nbsp;GetVersionId(void) | Obtains the version ID.|
| const&nbsp;char\*&nbsp;GetBuildType(void) | Obtains the build type.|
| const&nbsp;char\*&nbsp;GetBuildUser(void) | Obtains the build account user name.|
| const&nbsp;char\*&nbsp;GetBuildHost(void) | Obtains the build host name.|
| const&nbsp;char\*&nbsp;GetBuildTime(void) | Obtains the build time.|
| const&nbsp;char\*&nbsp;GetBuildRootHash(void) | Obtains the buildroot hash value of this version.|
| const&nbsp;char\*&nbsp;GetOsReleaseType(void) | Obtains the system release type.|
| int&nbsp;GetDevUdid(char&nbsp;\*udid,&nbsp;int&nbsp;size) | Obtains the device identifier (UDID).|
| const char *AclGetSerial(void); | Obtains the device SN (with ACL check).|
| int AclGetDevUdid(char *udid, int size); | Obtains the UDID (with ACL check).|
### How to Develop
1. System parameter definition
You can define default system parameters and implement permission control on them by configuring the subsystem or product **.para** and **.para.dac** files.
​ On a standard system, use the **ohos_prebuilt_para** template to install the configuration file to the **/etc/param/** directory. The following is an example of the GN script:
```go
import("//base/startup/init_lite/services/etc/param/param_fixer.gni")
ohos_prebuilt_para("ohos.para") {
source = "//base/startup/init_lite/services/etc/ohos.para"
part_name = "init"
module_install_dir = "etc/param"
}
ohos_prebuilt_para("ohos.para.dac") {
source = "//base/startup/init_lite/services/etc/ohos.para.dac"
part_name = "init"
module_install_dir = "etc/param"
}
```
On a small system, run the **copy** command to copy the corresponding system parameter definition file to the **system/etc/param** directory.
```go
copy("ohos.para") {
sources = [ "//base/startup/init_lite/services/etc/param/ohos.para" ]
outputs = [ "$root_out_dir/system/etc/param/ohos.para" ]
}
copy("ohos.para.dac") {
sources = [ "//base/startup/init_lite/services/etc/param/ohos.para.dac" ]
outputs = [ "$root_out_dir/system/etc/param/ohos.para.dac" ]
}
```
On a mini system, convert all defined default system parameters into header files through **action** and compile them into the system.
```go
action("lite_const_param_to") {
script = "//base/startup/init_lite/scripts/param_cfg_to_code.py"
args = [
"--source",
rebase_path(
"//base/startup/init_lite/services/etc_lite/param/ohos_const/ohospara"),
"--dest_dir",
rebase_path("$root_out_dir/gen/init_lite/"),
"--priority",
"0",
]
outputs = [ "$target_gen_dir/${target_name}_param_cfg_to_code.log" ]
}
```
2. Development example
```
// set && get
char key1[] = "rw.sys.version";
char value1[] = "10.1.0";
int ret = SetParameter(key1, value1);
char valueGet1[128] = {0};
ret = GetParameter(key1, "version=10.1.0", valueGet1, 128);
// get sysparm
char* value1 = GetDeviceType();
printf("Product type =%s\n", value1);
char* value2 = GetManufacture();
printf("Manufacture =%s\n", value2);
char* value3 = GetBrand();
printf("GetBrand =%s\n", value3);
char* value4 = GetMarketName();
printf("MarketName =%s\n", value4);
char* value5 = GetProductSeries();
printf("ProductSeries =%s\n", value5);
char* value6 = GetProductModel();
printf("ProductModel =%s\n", value6);
char* value7 = GetSoftwareModel();
printf("SoftwareModel =%s\n", value7);
char* value8 = GetHardwareModel();
printf("HardwareModel =%s\n", value8);
char* value9 = GetHardwareProfile();
printf("Software profile =%s\n", value9);
char* value10 = GetSerial();
printf("Serial =%s\n", value10);
char* value11 = GetOSFullName();
printf("OS name =%s\n", value11);
char* value12 = GetDisplayVersion();
printf("Display version =%s\n", value12);
char* value13 = GetBootloaderVersion();
printf("bootloader version =%s\n", value13);
char* value14 = GetSecurityPatchTag();
printf("secure patch level =%s\n", value14);
char* value15 = GetAbiList();
printf("abi list =%s\n", value15);
int value16 = GetFirstApiVersion();
printf("first api level =%d\n", value16);
char* value17 = GetIncrementalVersion();
printf("Incremental version = %s\n", value17);
char* value18 = GetVersionId();
printf("formal id =%s\n", value18);
char* value19 = GetBuildType();
printf("build type =%s\n", value19);
char* value20 = GetBuildUser();
printf("build user =%s\n", value20);
char* value21 = GetBuildHost();
printf("Build host = %s\n", value21);
char* value22 = GetBuildTime();
printf("build time =%s\n", value22);
char* value23 = GetBuildRootHash();
printf("build root later..., %s\n", value23);
char* value24 = GetOsReleaseType();
printf("OS release type =%s\n", value24);
char* value25 = GetOsReleaseType();
printf("OS release type =%s\n", value25);
char value26[65] = {0};
GetDevUdid(value26, 65);
printf("device udid =%s\n", value26);
```
# init Module
## Introduction
- **[init Configuration File](subsys-boot-init-cfg.md)**
The init module starts key service processes during system startup. If you would like to add a system service that automatically starts upon system startup, you can add a configuration file named in the **xxx.cfg** format. The system automatically analyzes the **.cfg** file and starts the corresponding service.
- **[Job Management](subsys-boot-init-jobs.md)**
- Configuration file of the init module
- **[Service Management](subsys-boot-init-service.md)**
The configuration file of the init module, that is, **init.cfg**, contains service names, executable file paths, permissions, and other information of all key system services that need to be started by the init process. The file can be found in **/etc/** after burning is complete. The file is in JSON format, and its size cannot exceed 100 KB.
- **[Parameter Management](subsys-boot-init-sysparam.md)**
After the init process starts, it reads the **/etc/init.cfg** file, parses the content in JSON format, and loads system services in sequence based on the parsing result.
- **[Sandbox Management](subsys-boot-init-sandbox.md)**
If you need to add a key service to a module, you can also add the **.cfg** file of the module. The file will be copied to the **/system/etc/init** directory during compilation.
The init process scans the **.cfg** files in the **/etc/init** directory and parses them one by one. The following describes the file scanning rules and format.
- File scanning rules
For the mini and standard systems, the same API is used for scanning **.cfg** files. The code is as follows:
```
void ReadConfig(void)
{
// parse cfg
if (InChargerMode() == 1) {
ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
ReadFileInDir(OTHER_CHARGE_PATH, ".cfg", ParseInitCfg, NULL);
} else if (InUpdaterMode() == 0) {
ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
ReadFileInDir(OTHER_CFG_PATH, ".cfg", ParseInitCfg, NULL);
ReadFileInDir("/vendor/etc/init", ".cfg", ParseInitCfg, NULL);
} else {
ReadFileInDir("/etc", ".cfg", ParseInitCfg, NULL);
}
}
```
The macro definition in the code is as follows:
```
#define INIT_CONFIGURATION_FILE "/etc/init.cfg"
#define OTHER_CHARGE_PATH "/system/etc/charge"
#define OTHER_CFG_PATH "/system/etc/init"
```
The following describes how the init process scans **.cfg** files in normal system startup. File scanning in charging mode and update mode is beyond the scope of this document.
1. Call the file parsing API to parse the **/etc/init.cfg** file, because this file is one that needs to be preferentially parsed.
2. Traverse the **.cfg** files in the **/etc/init** directory, and call the parsing API to parse the file when a **.cfg** file is matched. (**/etc** is a symbolic link pointing to **/system/etc** and can be regarded as an equivalent.)
3. Traverse the **.cfg** files in the **/vendor/etc/init** directory, and call the parsing API to parse the file when a **.cfg** file is matched. The **.cfg** files in this directory are usually related to the hardware platform.
- File format
The **.cfg** file format is as follows:
```
{
"import" : [
"/etc/init.xxx.cfg",
"/vendor/etc/init.${ohos.boot.hardware}.cfg"
],
"jobs" : [{
"name" : "example-stage",
"cmds" : [
"write /example/file 0",
"start example"
]
}
],
"services" : [{
"name" : "example",
"path" : ["/system/bin/example"],
}
]
}
```
As mentioned earlier, a **.cfg** file is a text file in JSON format. For the startup module, the init process is required to parse the following types of JSON objects in the **.cfg** file: **import**, **jobs**, and **services**. The three types of JSON objects are described as follows:
1. **import**: other **.cfg** files into the current **.cfg** file. These files will be parsed in sequence after the current **.cfg** file is parsed.
2. **jobs**: command set with a name. Execution of a job is the process of executing commands in **cmds** one by one in sequence. Details about how to trigger a job will be provided in the following sections.
3. **services**: a collection of services. The simplest service can be one that has only a name and an executable file path. The basic logic of a service is to fork a subprocess in the init process and then run the executable file of the service in the subprocess. Services form the core of the startup module. The service configuration in the **.cfg** file also includes various attributes and service control modes. More details will be provided in the following sections.
- init service startup control (for standard system or higher)<a name = "section56901555918">
The init process classifies services into three types based on service configurations and starts the services in different phases.
- **boot**: services that need to be preferentially started in the system. This type of services are started in the init phase.
- **normal**: common services in the system. This type of services are started in the post-init phase. This is the default service type.
- **condition**: services that are started based on the specified conditions. You can run the **start xxx** command to start such a service. Generally, this type of services are started in a condition job or in a certain phase of the init process.
If dependencies exist between services or between services and commands, you need to use **condition** to describe services. For example:
```
"services" : [{
"name" : "serviceName",
"start-mode" : "condition",
},
```
- init parallel service control (for standard system or higher)<a name="section56901555919"></a>
The init module provides the parallel service processing function, which allows services to execute jobs in different phases.
- **on-start**: a job executed after the service process is forked. The on-start jobs of different services can be executed in parallel. (The on-start job is executed in the subprocess of the service and affects only the subprocess.)
- **on-stop**: a job executed when the service is stopped.
- **on-restart**: a job executed when the service is restarted.
The following is the example configuration:
```
"services" : [{
"name" : "serviceName",
"jobs" : {
"on-boot" : "boot",
"on-start" : "services:serviceName_start",
"on-stop" : "services:serviceName_stop",
"on-restart" : "services:serviceName_restart"
}
},
```
- init on-demand startup (for standard system or higher)<a name="section56901555920"></a>
Services managed by the init process can be started on demand. Such services are not automatically started during system startup. Instead, they are started by the init process only when a certain event occurs. Typical events that trigger service startup are as follows: Messages are sent over the socket listened by the init process. The samgr process receives a request from the client and needs to start the SA service.
The **ondemand** attribute indicates whether a service is started on demand. If this attribute is set to **true** for a service, the service does not need to be started by running the **start** command. Instead, it is started only when the corresponding event occurs.
The following is the example configuration:
```
"services" : [{
"name" : "serviceName",
"ondemand" : true,
}]
```
- SA process on-demand startup
1. When an application requests an SA handle, the samgr process checks whether the process to which the SA belongs can be dynamically started.
2. If the SA process needs to be started, the samgr process blocks the request. After the init process starts and registers the SA process, the samgr process returns the SA handle.
- Socket process on-demand startup
1. The init process creates a socket for socket processes in the pre-fork phase and listens to network events on this socket.
2. When messages are detected on the socket, the init process starts the socket process for message processing. The init process then stops listening to network data over the socket and waits until the socket process completes message processing.
3. If no more messages need to be processed, the socket process can automatically exit. After that, the init process reclaims the subprocess and listens to network data over the socket again.
- The hot swap service process is started as required. Hot swap events can be started as required based on system parameter changes.
- Enhanced init process startup and recycling
The CPU core binding, priority, MAC address, and AccessToken information of the service process can be configured in the configuration file during process startup.
- Support of CPU core binding for service processes (through modification of the **\*.cfg** file)
- Support of priority setting for service processes (through modification of the **\*.cfg** file)
- Support of MAC address setting (that is, SELinux tag setting) for service processes (through modification of the **\*.cfg** file)
- Support of AccessToken setting for service processes and distributed capability setting for system service processes (through modification of the **\*.cfg** file)
- Support of the suppression mechanism for service processes (through modification of the **\*.cfg** file)
The following is the example configuration for enhanced init process startup and recycling:
```
"services" : [{
"name" : "serviceName",
"importance" : 1, // Priority setting for service processes
"cpucore" : [0], // CPU binding for service processes
"critical" : [1, 5, 10], // Suppression for service processes
"apl" : "normal", // Ability privilege level setting for service processes
"d-caps" : ["OHOS_DMS"], // Distributed capability setting for service processes
"secon" : "u:r:distributedsche:s0" // SELinux tag setting for service processes. In this example, u:r:distributedsche:s0 is the SELinux tag.
},
```
- init fd proxy (for standard system or higher)
fd proxy is an extended mechanism for on-demand startup. It can ensure that the fd state handle is not lost before the service process exits. Specifically, a service process sends the fd to the init process before it exits, and then reclaims the fd from the init process when it is started again.
This mechanism is implemented using the API provided by the init process. Before a service process exits, it can call the related API to send the fd to the init process over the socket that supports IPC communication. After the service process is restarted, the init process returns the corresponding fd handle to it in the same way. For details about the APIs, see [fd Proxy APIs](#table14737791479).
- init job
A job provided by the init process. It is actually a set of commands. A job can be configured in the **init.cfg** file or the custom **.cfg** file of the module. The parser of the init process aggregates commands of the jobs with the same name into one job. For jobs with the same name, the init process only ensures that the commands in the **init.cfg** file are executed in preference. It does not guarantee the execution sequence of commands in other **.cfg** files.
- Common job: A job executed in a fixed phase during init process startup, for example, pre-init, init, or post-init.
- Custom job: A job is triggered based on certain rules.
- Job: A user-defined job, which can be executed using the **trigger** command.
- Control job (for standard system or higher): A job triggered based on specified conditions. You can set trigger conditions in such a job. When the corresponding attribute values meet the trigger conditions, the job will be triggered. &amp;&amp; and || operations are supported for trigger conditions, and these operations can be used in flexible combinations as needed.
- bootchart plug-in
The bootchart plug-in is an open source tool used to evaluate system performance during Linux startup. It automatically collects information such as the CPU usage, disk throughput, and process status, and displays the evaluation result in graphics to facilitate system startup optimization. For details about the commands provided by begetctl, see [begetctl Command Description](#table14737791480).
The following describes how to use begetctl in detail.
Prerequisites
1. Prepare the test environment by installing Python and PyCairo in Linux.
pip install pycairo
2. Decompress bootchart-master.tar.
tar -zxvf bootchart-master.tar
The operation procedure is as follows:
1. Start the system.
2. Run the **begetctl bootchart enable** command.
3. Restart the system.
4. Run the **begetctl bootchart stop** command.
5. Run the **begetctl bootchart disable** command.
6. Export the following files from the **/data/bootchart** directory: <br>
header<br>
proc_diskstats.log<br>
proc_ps.log<br>
proc_stat.log<br>
Save the files to the **bootchart** folder.
7. Run the tar -zcvf bootchart.tgz * command to compress the bootchart.tgz file (only the Linux version is supported) and copy the compressed file to the linux:bootchart-master directory.
8. Go to the
**bootchart-master** directory
and run the **python3 pybootchartgui.py -f pdf bootchart.tgz** command.<br>
Expected result: <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A **bootchart.pdf** file is generated in the **bootchart-master** directory.
## Development Guidelines
1. Configure the **jobs** array.
The init module completes the system startup in three phases:
- **pre-init**: operations required before system services are started, for example, mounting a file system, creating a folder, and modifying permissions.
- **init**: operations required for starting system services.
- **post-init**: operations required after system services are started.
```
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"mkdir /testdir",
"chmod 0700 /testdir",
"chown 99 99 /testdir",
"mount vfat /dev/mmcblk0p0 /testdir2 noexec nosuid" // mount command (format: mount file system type source target flags data)
]
}, {
"name" : "init",
"cmds" : [
"start service1",
]
}, {
"name" : "post-init",
"cmds" : []
}
]
```
**Table 1** Job description
| Job | Description |
| :-------- | :-------- |
| pre-init | Job that is executed first. Operations (for example, creating a folder) required before the process startup are executed in the pre-init job. |
| init | Job that is executed in between. Operations (for example, service startup) are executed in this job. |
| post-init | Job that is finally executed. Operations (for example, mounting the device after the driver initialization) required after the process startup are executed in this job. A single job can hold a maximum of 30 commands (Only <strong>start</strong>, <strong>mkdir</strong>, <strong>chmod</strong>, <strong>chown</strong>, <strong>mount</strong>, and <strong>loadcfg</strong> are supported currently). The command name and parameters (128 bytes or less) must be separated by only one space. |
**Table 2** Commands supported by a job
| Command | Format and Example | Description | System Type |
| -------- | -------- | -------- | -------- |
| mkdir | mkdir <i>target folder</i><br/>Example:<br/>mkdir /storage/myDirectory | Creates a folder. <strong>mkdir</strong> and the target folder must be separated by only one space. | Small and standard |
| chmod | chmod <i>permission</i> <i>target</i><br/>Example:<br/>chmod 0600 /storage/myFile.txt<br/>chmod 0750 /storage/myDir | Modifies the permission, which must be in the <strong>0xxx</strong> format. <strong>chmod</strong>, <i>permission</i>, and <i>target</i> must be separated by only one space. | Small and standard |
| chown | chown uid gid <i>target</i><br/>Example:<br/>chown 900 800 /storage/myDir<br/>chown 100 100 /storage/myFile.txt | Modifies the owner group. <strong>chown</strong>, <strong>uid</strong>, <strong>gid</strong>, and <i>target</i> must be separated by only one space. | Small and standard |
| mount | mount fileSystemType src dst flags data<br/>Example:<br/>mount vfat /dev/mmcblk0 /sdc rw,umask=000<br/>mount jffs2 /dev/mtdblock3 /storage nosuid | Mounts devices. Every two parameters must be separated by only one space. Currently, supported flags include <strong>nodev</strong>, <strong>noexec</strong>, <strong>nosuid</strong>, <strong>rdonly</strong>, and optionally <strong>data</strong>. | Small and standard |
| start | start serviceName<br/>Example:<br/>start foundation<br/>start shell | Starts services. <strong>start</strong> must be followed by <i>serviceName</i>, and <i>serviceName</i> must be contained in the <strong>services</strong> array. | Small and standard |
| export | export key value<br/>Example:<br/>export TEST /data/test | Exports environment variables. <strong>key</strong> and <strong>value</strong> respectively indicate the environment variable and its value. | Small and standard |
| rm | rm filename<br/>Example:<br/>rm /data/testfile | Removes a file. <strong>filename</strong> indicates the absolute file path. | Small and standard |
| rmdir | rmdir dirname<br/>Example:<br/>rmdir /data/testdir | Removes a directory. <strong>dirname</strong> indicates the absolute path of the directory. | Small and standard | write | write filename value<br/>Example:<br/>write /data/testfile 0 | Writes a file. <strong>filename</strong> and <strong>value</strong> respectively indicate the absolute file path and the string to write. | Small and standard |
| stop | stop servicename<br/>Example:<br/>stop console | Stops a service. <strong>servicename</strong> indicates the name of the service to stop. | Small and standard |
| copy | copy oldfile newfile<br/>Example:<br/>copy /data/old /data/new | Copies a file. <strong>oldfile</strong> and <strong>newfile</strong> respectively indicate the old and new absolute file paths. | Small and standard |
| reset | reset servicename<br/>Example:<br/>reset console | Resets a service. <strong>servicename</strong> indicates the name of the service to reset. If the service has not been started, this command will start the service. If the service is running, the command will stop the service and then restart it. | Small and standard |
| reboot | reboot *subsystem*<br/>Example:<br/>reboot updater | Restarts the system. <strong>subsystem</strong> is optional. If it is not specified, the device enters the current system upon restarting. If it is specified, the device enters the correspoding subsystem upon restarting. For example, if you run **reboot updater**, the device enters the updater subsystem upon restarting. | Small and standard |
| sleep | sleep time<br/>Example:<br/>sleep 5 | Enters the sleep state. <strong>time</strong> indicates the sleep time. | Small and standard |
| domainname | domainname name<br/>Example:<br/>domainname localdomain | Sets a domain name. | Small and standard |
| hostname | hostname name<br/>Example:<br/>hostname localhost | Sets a host name. | Small and standard |
| wait | wait PID<br/>Example:<br/>wait pid | Waits for a command. | Small and standard |
| setrlimit | setrlimit resource curValue maxValue | Sets limitations on resource usage. | Small and standard |
| write | write path content<br/>Example:<br/>write /proc/sys/kernel/sysrq 0 | Writes a file. | Small and standard |
| exec | exec *Path of the executable file* *Parameters passed by the executable file*<br/>Example:<br/>exec /system/bin/udevadm trigger | Runs an executable file. | Small and standard |
| mknode | mknod name { b \| c } Major Minor<br/>Example:<br/>mknod path b 0644 1 9 | Creates an index node corresponding to a directory entry and a special file. For details, see the **mknod** command. | Standard |
| makedev | makedev major minor<br/>Example:<br/>makedev -v update | Creates a static device node, which is usually in the **/dev** directory. | Standard |
| symlink | symlink path1 path2<br/>Example:<br/>symlink /proc/self/fd/0 /dev/stdin | Creates a symbolic link. | Standard |
| trigger | trigger jobName<br/>Example:<br/>trigger early-fs | Triggers a job. | Standard |
| insmod | insmod *ko file*<br/>Example:<br/>insmod *xxx*.ko| Loads a kernel module file. | Standard |
| setparam | setparam *paramname* *paramvalue*<br/>Example:<br/>setparam sys.usb.config hdc | Sets a system parameter. | Standard |
| load_persist_params | load persist params<br/>Example:<br/>load_persist_params&nbsp; | Loads **persist** parameters. There must be one and only one space after the **load_persist_params** command. | Standard |
| load_param | load params<br/>Example:<br/>load_param /data/test.normal.para | Loads the parameters from a file to the memory. | Standard |
| load_access_token_id | Example:<br/>load_access_token_id&nbsp; | Writes the access token to the **data/service/el0/access_token/nativetoken.json** file. There is one and only one space after **load_access_token_id**. | Standard |
| ifup | ifup *NIC*<br/>Example:<br/>ifup eth0 | Activates the specified NIC. | Standard |
| mount_fstab | mount_fstab fstab.test<br/>Example:<br/>mount_fstab /vendor/etc/fstab.test | Mounts partitions based on the **fstab** file. | Standard |
| umount_fstab | umount_fstab fstab.test<br/>Example:<br/>umount_fstab /vendor/etc/fstab.test | Unmounts partitions based on the **fstab** file. | Standard |
| restorecon | restorecon file or dir<br/>Example:<br/>restorecon /file | Reloads the SELinux context. | Standard |
| stopAllServices | stopAllServices [bool]<br/>Example:<br/>stopAllServices false<br/>stopAllServices | Stops all services. | Standard |
| umount |umount path<br/>Example:<br/>umount /vendor | Unmounts a mounted device. | Standard |
| sync | Example:<br/>sync&nbsp; | Writes data to the disk synchronously. There is only one and only one space after **sync**. | Standard |
| timer_start | timer_start serviceName<br/>Example:<br/>timer_start console | Starts the service timer. | Standard |
| timer_stop | timer_stop serviceName<br/>Example:<br/>timer_stop console | Stops the service timer. | Standard |
| init_global_key | init_global_key path<br/>Example:<br/>init_global_key /data | Initializes the encryption key of the data partition file. | Standard |
| init_main_user | Example:<br/>init_main_user| Encrypts the main user directory. | Standard |
| mkswap | mkswap file<br/>Example:<br/>mkswap /swapfile1 | Creates a swap partition on a file or device. | Standard |
| swapon | swapon file<br/>Example:<br/>swapon /swapfile1 | Activates the swap space. | Standard |
| loadcfg | loadcfg *filePath*<br/>Example:<br/>loadcfg /patch/fstab.cfg | Loads other <strong>.cfg</strong> files. The maximum size of the target file (Only /patch/fstab.cfg supported currently) is 50 KB. Each line in the /patch/fstab.cfg file is a command. The command types and formats must comply with their respective requirements mentioned in this table. A maximum of 20 commands are allowed. | Small |
2. Configure the <strong>services</strong> array, which holds all system services that need to be started by the init process.
```
"services" : [{
"name" : "service1",
"path" : ["/bin/process1", "param1", "param2"],
"uid" : 1,
"gid" : 1,
"once" : 0,
"importance" : 1,
"caps" : [0, 1, 2, 5],
"start-mode" : "condition",
"cpucore" : [0],
"critical" : [0, 5, 10],
"apl" : "normal",
"d-caps" : ["OHOS_DMS"],
"jobs" : {
"on-boot" : "boot",
"on-start" : "services:service1_start",
"on-stop" : "services:service1_stop",
"on-restart" : "services:service1_restart"
}
}, {
"name" : "service2",
"path" : "/bin/process2",
"uid" : 2,
"gid" : 2,
"once" : 1,
"importance" : 0,
"caps" : [ ],
"cpucore" : 0,
"critical" : [ ],
"apl" : "normal",
"d-caps" : [ ]
}]
```
**Table 3** Service field description<a name="table14737791471"></a>
| Field | Description | Value | System Type |
| ---------- |-------- | --------| --------|
| name | Name of the current service. | Type: string. The value cannot be empty and can contain a maximum of 32 bytes. | Small and standard |
| path | Full path (including parameters) of the current service's executable file, in array. | The first element is the path of the executable file, and the maximum number of elements is 20. <br>Each element is a string that contains a maximum of 64 bytes. | Small and standard |
| uid | User ID (UID) of the current service process. | Type: int | Small and standard |
| gid | Group ID (GID) of the current service process. | Type: int | Small and standard |
| once | Whether the current service process is a one-off process. | **1**: The current service process is a one-off process. If the process exits, the init process does not restart it. <br>**0**: The current service process is not a one-off process. If the process exits, the init process restarts it upon receiving the SIGCHLD signal. | Small and standard |
| importance | Current service priority. | Standard system: <br>The service priority ranges from **-20** to **19**. A value beyond the range is invalid. <br>Small-scale system:<br>**0**: unimportant process<br>non-0: important process | Small and standard |
| caps | Capabilities required by the current service. They are evaluated based on the capabilities supported by the security subsystem and configured in accordance with the principle of least permission. | Type: number or string array. If you set the value to a number, use the standard Linux capability. If you set the value to a string array, use the standard macro name. | Small and standard |
| critical | Suppression mechanism for services. If the number of times a service is restarted exceeds the value N within the specified period T, the system will be restarted. | Standard system:<br>Type: int array, for example, **"critical": [M, N, T]**.<br>- **M**: enable flag (**0**: disable; **1**: enable).<br>- N: number of times the service is started.<br>- **T**: period of time, in seconds. <br>Both **M** and **N** must be greater than **0**.<br>Small and standard systems:<br>Type: int, for example, **"critical": M**.<br>**M**: enable flag (**0**: disable; **1**: enable).<br>By default, **N** is **4** and **T** is **20**. | Small and standard |
| cpucore | Number of CPU cores to be bound to the service. | Type: int array, for example, **"cpucore": [N1, N2, ...]**. **N1** and **N2** indicate the indices of the CPU cores to be bound.<br>For a single-core device, **cpucore** is **0**. | Small and standard |
| d-caps | Service distribution capability. (Available only for the standard system or higher) | Type: string array, for example, **"d-caps": ["OHOS_DMS"]**. | Standard |
| apl | Ability privilege level. (Available only for the standard system or higher) | Type: string, for example, **"apl": "system_core"**. <br>The value can be **system_core** (default), **normal**, or **system_basic**. | Standard |
| start-mode | Service startup mode. (Available only for the standard system or higher) | Type: string, for example, **"start-mode": "condition"**. <br>The value can be **boot**, **normal**, or **condition**. For details, see [init service startup control](#section56901555918). | Standard |
| jobs | Jobs that can be executed by the current service in different phases. | For details, see [init parallel control](#section56901555919). | Small and standard |
| ondemand | Whether to enable on-demand service startup. |Type: bool, for example, **"ondemand": true**. For small systems, this feature is available only on the Linux kernel. For details, see [init on-demand startup](#section56901555920). | Small and standard |
| disable | Reserved. | | Small and standard |
3. Add socket and on-demand startup configurations for a service.
You can configure the **socket** attribute for a service in the JSON format. If a service is configured with the **socket** attribute, the init process will create a socket for the service upon startup. The socket creation time depends on whether on-demand startup is enabled for the service.
- If on-demand startup is enabled, the init process creates the socket based on the socket configuration obtained from parsing the service.
- If on-demand startup is disabled, the init process creates a socket before executing the executable file to start the service.
No matter whether on-demand startup is enabled, a service needs to obtain the handle of the socket created by the init process upon startup, so that it can take over the socket from the init process.
If on-demand startup is enabled, the init process can also take future processing. Specifically, after creating a socket based on the parsed socket configuration, the init process checks whether the **ondemand** attribute of the service is **true**. If yes, the init process listens to messages sent over the socket in polling mode. When a message is received, the init process stops listening and starts the service to take over the socket and process message.
The following uses the ueventd service as an example to explain how to add socket and on-demand startup configurations.
```
"services" : [{
"name" : "ueventd",
"path" : ["/system/bin/ueventd"],
"socket" : [{
"name" : "ueventd",
"family" : "AF_NETLINK",
"type" : "SOCK_DGRAM",
"protocol" : "NETLINK_KOBJECT_UEVENT",
"permissions" : "0660",
"uid" : "system",
"gid" : "system",
"option" : [
"SOCKET_OPTION_PASSCRED",
"SOCKET_OPTION_RCVBUFFORCE",
"SOCK_CLOEXEC",
"SOCK_NONBLOCK"
]
}],
"critical" : [ 0, 5, 15],
"ondemand" : true,
"start-mode" : "condition"
}]
```
**Table 4** Socket field description
|Field| Description|
| -------- | -------- |
|name|Name of the socket. It does not need to be the same as the service name. The value must not be empty and can contain a maximum of 32 bytes. |
|family|Address family to which the socket belongs. Currently, the AF_UNIX and AF_NETLINK families are supported. |
|type|Socket type. Currently, connection-based sockets, SOCK_SEQPACKET and SOCK_STREAM, and UDP-based connectionless socket, SOCK_DGRAM, are supported. |
|protocol|Protocol used for socket communication. Unless otherwise required, set the value to **default** so that the socket automatically selects a proper protocol based on the socket address family and socket type. In addition to the default protocol, the NETLINK_KOBJECT_UEVENT protocol is also supported. |
|permissions|Permissions of the socket node file. This field is valid only for sockets that have entity node files, such as the AF_UNIX address family. |
|uid|User ID of the socket node file. This field is valid only for sockets that have entity node files, such as the AF_UNIX address family. |
|gid|Group ID of the socket node file. This field is valid only for sockets that have entity node files, such as the AF_UNIX address family. |
|option|Socket option. This field is passed when **setsockopt** is called. Currently, the available options include **SOCKET_OPTION_PASSCRED**, **SOCKET_OPTION_RCVBUFFORCE**, **SOCK_CLOEXEC**, and **SOCK_NONBLOCK**. |
**Table 5** fd proxy APIs<a name="table14737791479"></a>
| API | Description|Parameters |
| ---------- | ---------- |--------|
| int *ServiceGetFd(const char *serviceName, size_t *outfdCount) | Obtains the fd from the init process. | Return value: Returns the pointer to the fd array if the operation is successful; returns **NULL** otherwise. (Note: Manual release is required.)<br>Arguments:<br> **serviceName**: service name.<br>**outfdCount**: length of the returned fd array. |
| int ServiceSaveFd(const char *serviceName, int *fds, int fdCount) | Requests the init process for fd proxy. | Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> **fds**: pointer to the fd array for fd proxy.<br>**fdCount**: length of the fd array
| int ServiceSaveFdWithPoll(const char *serviceName, int *fds, int fdCount) | Requests fd proxy in poll mode. | Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> **fds**: pointer to the fd array.<br> **fdCount**: length of the fd array.
** Table 6** Service control APIs
| API | Description| Parameters |
| :---------- | :---------- |:--------|
| int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc) | Configures service parameters. | Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> **action**: service action, which can be **start**, **stop**, or **restart**.<br> **extArgv**: parameter array.<br> **extArgc**: number of parameters. |
| int ServiceControl(const char *serviceName, int action) | Controls the service behavior. | Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> **action**: service action, which can be **start**, **stop**, or **restart**. |
| int ServiceWaitForStatus(const char *serviceName, ServiceStatus status, int waitTimeout) | Waiting for service status| Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br>**serviceName**: service name.<br> **status**: service status.<br> **waitTimeout**: waiting timeout interval. |
| int ServiceSetReady(const char *serviceName) | Sets a service as being ready. | Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name. |
| int StartServiceByTimer(const char *serviceName, uint64_t timeout) | Starts a service by timer. | Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name.<br> timeout: timeout interval. |
| int StopServiceTimer(const char *serviceName) | Stops a service timer. | Return value: Returns **0** if the operation is successful; returns **-1** otherwise.<br> Arguments:<br> **serviceName**: service name. |
**Table 7** begetctl commands<a name="table14737791480"></a>
| Command| Format and Example| Description|
| :---------- | :---------- |:--------|
| init group test [stage] | Initializes a group test.<br/>Example:<br/>init group test| For details about **stage**, see **ServiceStatus**. |
| param ls [-r] [name] | Displays system parameters.<br/>Example:<br>begetctl param ls persist.sys.usb | N/A|
| param get [name] | Obtains system parameter information<br/>Example:<br>begetctl param get<br/>param get| N/A|
| param set name value| Sets system parameters.<br/>Example:<br>begetctl param set ohos.servicectrl.display 1<br/>param set ohos.servicectrl.display 1| N/A|
| param wait name [value] [timeout] | Waits for system parameters.<br/>Example:<br>begetctl param wait persist.sys.usb.config hdc<br/>param wait persist.sys.usb.config hdc| The default value of **timeout** is **30**. |
| param dump [verbose] | Dumps system parameter information.<br/>Example:<br>begetctl param dump<br/>param dump| N/A|
| param shell [name] | Enters the parameter shell.<br/>Example:<br>begetctl param shell<br/>param shell| N/A|
| timer_stop servicename | Stops the service timer.<br/>Example:<br>begetctl timer_stop appspawn | The value of **servicename** can contain a maximum of 96 characters. |
| timer_start servicename timeout | Starts the service timer.<br/>Example:<br>begetctl timer_start appspawn | The value of **servicename** can contain a maximum of 96 characters. The default value of **timeout** is **10**. |
| start_service servicename | Starts a service.<br/>Example:<br>begetctl start_service appspawn<br/>start_service appspawn| N/A|
| stop_service servicename | Stops a service.<br/>Example:<br>begetctl stop_service appspawn<br/>stop_service appspawn| N/A|
| service_control start servicename | Starts a service.<br/>Example:<br>begetctl service_control start appspawn<br/>service_control start appspawn| N/A|
| service_control stop servicename | Stops a service.<br/>Example:<br>begetctl service_control stop appspawn<br/>service_control stop appspawn | N/A|
| misc_daemon --write_logo xxx.rgb | Writes the startup logo.<br/>Example:<br>begetctl misc_daemon --write_logo logo.rgb<br/>misc_daemon --write_logo logo.rgb| The maximum size of an RGB file is **1024*2038**. Only Hi3516D V300 is supported. |
| reboot | Restarts the system.<br/>Example:<br>begetctl reboot<br/>reboot|N/A|
| reboot shutdown | Shuts down the system.<br/>Example:<br>begetctl reboot shutdown<br/>reboot shutdown|N/A|
| reboot suspend | Suspends the system.<br/>Example:<br>begetctl reboot suspend<br/>reboot suspend| N/A|
| reboot updater | Restarts the system and enters updater.<br/>Example:<br>begetctl reboot updater<br/>reboot updater| N/A|
| reboot updater[:options] | Restarts the system and enters updater.<br/>Example:<br>begetctl reboot updater<br/>reboot updater| N/A|
| reboot flashd | Restarts the system and enters flashd.<br/>Example:<br>begetctl reboot flashd<br/>reboot flashd| N/A|
| reboot flashd[:options] | Restarts the system and enters flashd.<br/>Example:<br>begetctl reboot flashd<br/>reboot flashd| N/A|
| reboot charging | Restarts the system and enters the charging mode.<br/>Example:<br>begetctl reboot charging<br/>reboot charging| N/A|
| reboot loader | Restarts the system and enters the burning mode.<br/>Example:<br>begetctl reboot loader<br/>reboot loader| N/A|
| bootchart stop | Stops chart analysis.<br/>Example:<br>begetctl bootchart stop | Only rk3568 is supported. |
| bootchart start | Starts chart analysis.<br/>Example:<br>begetctl bootchart start | N/A|
| bootchart disable | Disables chart analysis.<br/>Example:<br>begetctl bootchart disable | N/A|
| bootchart enable | Enables chart analysis.<br/>Example:<br>begetctl bootchart enable | N/A|
## Development Example
The following uses the MySystemApp service as an example to illustrate how to use the init process to start a system service.
```
{
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"mkdir /storage/MyDir", // Create a folder before starting the MySystemApp service. This operation is executed in the pre-init job.
"chmod 0600 /storage/MyDir", // Modify the permission because the MySystemApp service requires that only the current user and its owner group have the read and write permissions on the file.
"chown 10 10 /storage/MyDir"
]
}, {
"name" : "init",
"cmds" : [
"start MySystemApp" // Start the MySystemApp service in the init job.
]
}, {
"name" : "post-init",
"cmds" : [] // Do not configure the post-init job because no other operations are required after the MySystemApp system service is started.
}
],
"services" : [{
"name" : "MySystemApp", // Name of the system service
"path" : ["/bin/MySystemAppExe", "param1", "param2", "param3"], // The executable file path of the MySystemApp service is /bin/MySystemAppExe. To start the service, three parameters ("param1", "param2", and "param3") need to be passed.
"uid" : 20, // The UID of the MySystemApp service is 20.
"gid" : 20, // The GID of the MySystemApp service is 20.
"once" : 0, // Not a one-off process of the MySystemApp service. If MySystemApp exits, the init process needs to restart it.
"importance" : 0, // Not a key system process of the MySystemApp service. If MySystemApp exits, the init process does not need to restart the development board.
"caps" : [] // Do not perform capability-related operations because capabilities are not required by the MySystemApp service.
"start-mode" : "condition",
"critical": [1, 2, 10], // Configure the critical field for MySystemApp system services. You need to pass three parameters, wherein, 1 means to enable system restarting, 2 means the number of times the critical service is restarted, and 10 means the time within which the critical service is restarted.
"cpucore" : [0, 1], // The device has two cores and both of them are bound to the CPU.
"apl" : "system_core",
"d-caps" : ["OHOS_DMS"],
"jobs" : {
"on-boot" : "boot",
"on-start" : "services:MySystemApp_start",
"on-stop" : "services:MySystemApp_stop",
"on-restart" : "services:MySystemApp_restart"
}
}
]
}
```
After the configuration is complete, compile the package to burn the board.
1. Run the **task -a** command for liteos-a or **ps** for Linux to check whether the MySystemApp service process is started.
2. Run the **kill** command to kill the MySystemApp process, and verify that the process will be restarted.
3. Run the **kill** command to kill the MySystemApp process, and verify that the development board will not be restarted.
## FAQs
### Service Not Exist
**Symptom**
"Failed get servName" is printed in the kernel log.
**Cause Analysis**
The kernel log is printed by the init process. After a code review on the init process, it is found that the service does not exist.
**Solution**
1. Check whether the service is correctly configured in the **.cfg** file.
2. Check whether the **.cfg** file of the service is loaded normally.
3. Check whether the format of the **.cfg** file is correct.
### Requesting fd Proxy for Other Services Failed
**Symptom**
"Service \' xxx \'(pid = xxx) is not valid or request with unexpected process(pid = xxx)" is printed in the kernel log.
**Cause Analysis**
The kernel log is printed by the init process. After a code review on the init process, it is found that fd proxy is requested for other services.
**Solution**
Request fd proxy for the current service, but not other services.
### No ondemand Configuration
**Symptom**
"service: %s had started already" is printed in the kernel log.
**Cause Analysis**
The kernel log is printed by the init process. After a code review on the init process, it is found that **ondemand** is not configured for the service.
**Solution**
Correct the service configuration in the **.cfg** file as follows: "ondemand" : true
- **[Plug-in Management](subsys-boot-init-plugin.md)**
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册