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 the service to the **init.cfg** file.
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.
## Configuration File of the init Module<a name="section56901555917"></a>
- Configuration file of the init module<aname="section56901555917"></a>
The configuration file **init.cfg** of the init module 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 is stored in the code repository **vendor/huawei/camera/init\_configs/**, and can be found in **/etc/** after burning is complete. The file is in JSON format, and its size cannot exceed 100 KB.
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.
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.
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.
## Development Guidelines<a name="section15371931131117"></a>
If you need to add a key service to a module, you can also add the **.cfg** file of the module. During compilation, copy the file to the **/system/etc/init** directory. The init process will parse the **.cfg** file and starts the corresponding service.
1. Configure the **jobs** array.
- init service startup control (for standard system or higher)<aname="section56901555918"></a>
The init module completes the system startup in three phases:
The init process classifies services into three types based on service configurations and starts the services in different 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.
-**boot**: services that need to be preferentially started in the system. This type of services are started after the init phase is complete.
-**normal**: common services in the system. These services are started after the init command is executed successfully. This is the default service type.
-**condition**: services with special requirements. 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.
Each of the preceding phases is represented by a job, which corresponds to a command set. The init module initializes the system by executing the commands in each job in sequence. The **pre-init** job is executed first, then the **init** job, and finally the **post-init** job.
If dependencies exist between services or between services and commands, you need to use **condition** to describe services. For example:
```
"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"
}
},
```
- init parallel service control (for standard system or higher)<aname="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.
- init on-demand startup (for standard system or higher)<aname="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.
- 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.
- Hot-swap service process on-demand startup
<br>  The hot-swap service process can be started to process hot swap events based on system parameter changes.
- Enhanced init process startup and recycling<aname="section56901555921"></a>
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 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)
- init fd proxy (for standard system or higher)<aname="section56901555922"></a>
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.
- init job<aname="section56901555923"></a>
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.
```
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"mkdir /testdir",
"chmod 0700 /testdir",
"chown 99 99 /testdir",
"mkdir /testdir2",
"mount vfat /dev/mmcblk0p0 /testdir2 noexec nosuid" // mount command (format: mount file system type source target flags data)
]
- 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. && and || operations are supported for trigger conditions, and these operations can be used in flexible combinations as needed.
## Development Guidelines<a name="section56901555924"></a>
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)
<td class="cellrowborder" valign="top" width="86.6%" headers="mcps1.2.3.1.2 "><p id="p18116016285"><a name="p18116016285"></a><a name="p18116016285"></a>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.</p>
<tdclass="cellrowborder"valign="top"width="86.6%"headers="mcps1.2.3.1.2 "><pid="p18116016285"><aname="p18116016285"></a><aname="p18116016285"></a>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.</p>
</td>
</tr>
</tbody>
</table>
A single job can hold a maximum of 30 commands (only **start**, **mkdir**, **chmod**, **chown**, **mount**, and **loadcfg** are supported currently). The command name and parameters (128 bytes or less) must be separated by only one space.
<th class="cellrowborder" valign="top" width="51.83%" id="mcps1.2.4.1.2"><p id="p3381142134118"><a name="p3381142134118"></a><a name="p3381142134118"></a>Format and Example</p>
<thclass="cellrowborder"valign="top"width="51.83%"id="mcps1.2.4.1.2"><pid="p3381142134118"><aname="p3381142134118"></a><aname="p3381142134118"></a>Format and Example</p>
<td class="cellrowborder" valign="top" width="38.019999999999996%" headers="mcps1.2.4.1.3 "><p id="p13986141320510"><a name="p13986141320510"></a><a name="p13986141320510"></a>Loads other <strong>.cfg</strong> files. The maximum size of the target file (only
<strong>/patch/fstab.cfg</strong> supported currently) is 50 KB. Each line in the <strong>/patch/fstab.cfg</strong> 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.</p>
<tdclass="cellrowborder"valign="top"width="38.019999999999996%"headers="mcps1.2.4.1.3 "><pid="p13986141320510"><aname="p13986141320510"></a><aname="p13986141320510"></a>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.</p>
</td>
</tr>
</tbody>
</table>
2. Configure the <strong>services</strong> array, which holds all system services (a maximum of 100) 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]
}, {
"name" : "service2",
"path" : "/bin/process2",
"uid" : 2,
"gid" : 2,
"once" : 1,
"importance" : 0,
"caps" : [ ]
}
]
```
2. Configure the <strong>services</strong> array, which holds all system services (a maximum of 100) that need to be started by the init process.
**Table 3** Fields in the services array
```
"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<aname="table14737791471"></a>
<td class="cellrowborder" valign="top" width="83.36%" headers="mcps1.2.3.1.2 "><p id="p166448210816"><a name="p166448210816"></a><a name="p166448210816"></a>Whether the current service process is a key system process.</p>
<p id="p8572182712811"><a name="p8572182712811"></a><a name="p8572182712811"></a><strong>0</strong>: The current service process is not a key system process. If it exits, the init process does not reset or restart the system.</p>
<p id="p11861032111516"><a name="p11861032111516"></a><a name="p11861032111516"></a><strong>1</strong>: The current service process is a key system process. If it exits, the init process resets and restarts the system.</p>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p166448210816"><aname="p166448210816"></a><aname="p166448210816"></a>Standard system:<br>Priority of a service process. The value ranges from <strong>-20</strong> to <strong>19</strong>.<br>Small system:<br><strong>0</strong>: non-critical process<br><strong>1</strong>: critical process</p>
@@ -215,13 +298,57 @@ After the init process starts, it reads the **/etc/init.cfg** file, parses the c
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p489313618173"><aname="p489313618173"></a><aname="p489313618173"></a>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. Currently, a maximum of 100 values can be configured.</p>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p489313618173"><aname="p489313618173"></a><aname="p489313618173"></a>Whether to enable system restarting when a critical service fails to be restarted for a specified number of times. If this field is enabled, the critical service will be started in M seconds. If the restarting fails for N times, the system will be restarted. The default value of N is <strong>4</strong> and that of M is <strong>20</strong>. (Only for standard system or higher. Configuration: [0, 2, 10], in int array.)<aname="section56901555917"></a><aname="section56901555917"></a></p>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p489313618173"><aname="p489313618173"></a><aname="p489313618173"></a>Number of CPU cores bound to the service. The value is an int array.<aname="section56901555917"></a><aname="section56901555917"></a></p>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p489313618173"><aname="p489313618173"></a><aname="p489313618173"></a>Distributed capabilities (Only for standard system or higher)<aname="section56901555917"></a><aname="section56901555917"></a></p>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p489313618173"><aname="p489313618173"></a><aname="p489313618173"></a>Ability privilege level: <strong>system_core</strong>, <strong>normal</strong>, or <strong>system_basic</strong>. The default value is <strong>system_core</strong>. (Only for the standard system or higher).<aname="section56901555917"></a><aname="section56901555917"></a></p>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p489313618173"><aname="p489313618173"></a><aname="p489313618173"></a>Service startup mode. For details, see init Service Startup Control. (Only for standard system or higher)<aname="section56901555917"></a><aname="section56901555917"></a></p>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p489313618173"><aname="p489313618173"></a><aname="p489313618173"></a>Jobs that can be executed by the current service in different phases. For details, see init Service Parallel Service Control. (Only for standard system or higher)<aname="section56901555917"></a></p>
</td>
</tr>
</tbody>
</table>
**Table 4** APIs
| API | Function|Description |
| :---------- | :---------- |:--------|
| 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>Input 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> Input arguments:<br>**serviceName**: service name.<br>**fds**: pointer to the fd array for fd proxy.<br>**fdCount**: length of the fd array
| 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> Input 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> Input arguments:<br> **serviceName**: service name.<br> **action**: service action, which can be **start**, **stop**, or **restart**.
## Development Example<a name="section173413113565"></a>
## Development Example<a name="section56901555925"></a>
The following uses the MySystemApp service as an example to illustrate how to use the init process to start a system service.
The following uses the MySystemApp service as an example to illustrate how to use the init process to start a system service.
```
{
...
...
@@ -250,6 +377,14 @@ The following uses the MySystemApp service as an example to illustrate how to us
"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.
"jobs" : {
"on-boot" : "boot",
"on-start" : "services:MySystemApp_start",
"on-stop" : "services:MySystemApp_stop",
"on-restart" : "services:MySystemApp_restart"
}
}
]
}
...
...
@@ -260,3 +395,41 @@ 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 then verify that the process will be restarted.
3. Run the **kill** command to kill the MySystemApp process, and then verify that the development board will not be restarted.
## FAQ<a name="section56901555926"></a>
### Service Not Exist<a name="section56901555927"></a>
 **Symptom**<br>
   "Failed get servName" is recorded in the kernel log.
 **Cause Analysis**<br>
   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**<br>
   1. Check whether the service is correctly configured in the **.cfg** file. <br>
   2. Check whether the **.cfg** file of the service is loaded normally. <br>
   3. Check whether the format of the **.cfg** file is correct.
### Requesting FD Proxy for Other Services Failed<a name="section56901555928"></a>
 **Symptom**
   "Service \' xxx \'(pid = xxx) is not valid or request with unexpected process(pid = xxx)" is recorded in the kernel log.
 **Cause Analysis**<br>
   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**<br>
   Request fd proxy for the current service, but not other services.
### No ondemand Configuration<a name="section56901555929"></a> is not configured for the service.
 **Symptom**<br>
   "service: %s had started already" is recorded in the kernel log.
 **Cause Analysis**<br>
   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**<br>
   Correct the service configuration in the **.cfg** file as follows: "ondemand" : true