| configure(ConfigOption config) | boolean | Sets the configuration options for application event logging.<br/>The value **true** indicates that the operation is successful, and value **false** indicates the opposite. |
| configure(ConfigOption config) | boolean | Sets the configuration options for application event logging.<br>The value **true** indicates that the operation is successful, and value **false** indicates the opposite. |
## How to Develop
## How to Develop
...
@@ -69,4 +69,10 @@ In this example, an application event is logged after the application startup ex
...
@@ -69,4 +69,10 @@ In this example, an application event is logged after the application startup ex
}
}
```
```
2. Tap the run button on the application UI to run the project.
2. Tap the run button on the application UI to run the project.
\ No newline at end of file
## Samples
The following sample is provided to help you better understand how to develop the application event logging feature:
-[`JsDotTest`: Event Logging Test (JavaScript) (API 7)](https://gitee.com/openharmony/app_samples/tree/master/DFX/JsDotTest)
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.
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<aname="section56901555917"></a>
- Configuration file of the init module
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.
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.
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.
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:
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)<aname="section56901555918"></a>
- init service startup control (for standard system or higher)<aname = "section56901555918">
The init process classifies services into three types based on service configurations and starts the services in different phases.
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 after the init phase is complete.
-**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. These services are started after the init command is executed successfully. This is the default service type.
-**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 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.
-**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:
If dependencies exist between services or between services and commands, you need to use **condition** to describe services. For example:
```
```
"services" : [{
"services" : [{
"name" : "service1",
"name" : "serviceName",
"path" : ["/bin/process1", "param1", "param2"],
"uid" : 1,
"gid" : 1,
"once" : 0,
"importance" : 1,
"caps" : [0, 1, 2, 5],
"start-mode" : "condition",
"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>
- 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.
The init module provides the parallel service processing function, which allows services to execute jobs in different phases.
...
@@ -52,172 +100,197 @@
...
@@ -52,172 +100,197 @@
-**on-stop**: a job executed when the service is stopped.
-**on-stop**: a job executed when the service is stopped.
-**on-restart**: a job executed when the service is restarted.
-**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)<aname="section56901555920"></a>
- 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.
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 **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
The following is the example configuration:
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.
"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
- 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.
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.
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.
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.
- Hot-swap service process on-demand startup
- Enhanced init process startup and recycling
<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.
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 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 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 MAC address setting (that is, SELinux tag setting) for service processes (through modification of the **\*.cfg** file)
- Support of the suppression mechanism 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>
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.
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.
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<aname="section56901555923"></a>
- 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.
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.
- 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.
- Custom job: A job is triggered based on certain rules.
- job: A user-defined job, which can be executed using the **trigger** command.
- 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.
- 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>
- bootchart plug-in
1. Configure the **jobs** array.
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 init module completes the system startup in three phases:
The following describes how to use begetctl in detail.
- **pre-init**: operations required before system services are started, for example, mounting a file system, creating a folder, and modifying permissions.
**Prerequisites**
- **init**: operations required for starting system services.
1. Prepare the test environment by installing Python and PyCairo in Linux.
- **post-init**: operations required after system services are started.
pip install pycairo
2. Decompress bootchart-master.tar.
```
tar -zxvf bootchart-master.tar
**Operation 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: <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>
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" : [{
"jobs" : [{
"name" : "pre-init",
"name" : "pre-init",
"cmds" : [
"cmds" : [
"mkdir /testdir",
"mkdir /testdir",
"chmod 0700 /testdir",
"chmod 0700 /testdir",
"chown 99 99 /testdir",
"chown 99 99 /testdir",
"mount vfat /dev/mmcblk0p0 /testdir2 noexec nosuid" // mount command (format: mount file system type source target flags data)
"mount vfat /dev/mmcblk0p0 /testdir2 noexec nosuid" // mount command (format: mount file system type source target flags data)
| 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. |
</th>
| init | Job that is executed in between. Operations (for example, service startup) are executed in this job. |
</tr>
| 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. |
| Command | Format and Example | Description | System Type |
<tdclass="cellrowborder"valign="top"width="86.6%"headers="mcps1.2.3.1.2 "><pid="p18115019284"><aname="p18115019284"></a><aname="p18115019284"></a>Job that is executed first. Operations (for example, creating a folder) required before the process startup are executed in the pre-init job.</p>
| -------- | -------- | -------- | -------- |
</td>
| 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 |
</tr>
| 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 |
</td>
| 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 |
<tdclass="cellrowborder"valign="top"width="86.6%"headers="mcps1.2.3.1.2 "><pid="p14818016288"><aname="p14818016288"></a><aname="p14818016288"></a>Job that is executed in between. Operations (for example, service startup) are executed in this job.</p>
| 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 |
</td>
| 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 |
</tr>
| 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 |
</td>
| 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 |
<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>
| 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 |
</td>
| 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 |
</tr>
| 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 |
</tbody>
| sleep | sleep time<br/>Example:<br/>sleep 5 | Enters the sleep state. <strong>time</strong> indicates the sleep time. | Small and standard |
</table>
| 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 |
**Table 2** Commands supported by a job<aname="table122681439144112"></a>
| 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 |
</th>
| write | write path content<br/>Example:<br/>write /proc/sys/kernel/sysrq 0 | Writes a file. | Small and standard |
<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>
| 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 |
</th>
| 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 |
</th>
| symlink | symlink path1 path2<br/>Example:<br/>symlink /proc/self/fd/0 /dev/stdin | Creates a symbolic link. | Standard |
</tr>
| trigger | trigger jobName<br/>Example:<br/>trigger early-fs | Triggers a job. | Standard |
</thead>
| 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 |
</td>
| load_persist_params | load persist params<br/>Example:<br/>load_persist_params | Loads **persist** parameters. There must be one and only one space after the **load_persist_params** command. | Standard |
| load_access_token_id | Example:<br/>load_access_token_id | 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 |
</td>
| ifup | ifup *NIC*<br/>Example:<br/>ifup eth0 | Activates the specified NIC. | Standard |
<tdclass="cellrowborder"valign="top"width="38.019999999999996%"headers="mcps1.2.4.1.3 "><pid="p56817536457"><aname="p56817536457"></a><aname="p56817536457"></a>Creates a folder. <strong>mkdir</strong> and the target folder must be separated by only one space.</p>
| mount_fstab | mount_fstab fstab.test<br/>Example:<br/>mount_fstab /vendor/etc/fstab.test | Mounts partitions based on the **fstab** file. | Standard |
</td>
| umount_fstab | umount_fstab fstab.test<br/>Example:<br/>umount_fstab /vendor/etc/fstab.test | Unmounts partitions based on the **fstab** file. | Standard |
</tr>
| restorecon | restorecon file or dir<br/>Example:<br/>restorecon /file | Reloads the SELinux context. | Standard |
| timer_stop | timer_stop serviceName<br/>Example:<br/>timer_stop console | Stops the service timer. | Standard |
</td>
| init_global_key | init_global_key path<br/>Example:<br/>init_global_key /data | Initializes the encryption key of the data partition file. | Standard |
<tdclass="cellrowborder"valign="top"width="38.019999999999996%"headers="mcps1.2.4.1.3 "><pid="p2023822074614"><aname="p2023822074614"></a><aname="p2023822074614"></a>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.</p>
| init_main_user | Example:<br/>init_main_user| Encrypts the main user directory. | Standard |
</td>
| mkswap | mkswap file<br/>Example:<br/>mkswap /swapfile1 | Creates a swap partition on a file or device. | Standard |
</tr>
| 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 |
<tdclass="cellrowborder"valign="top"width="38.019999999999996%"headers="mcps1.2.4.1.3 "><pid="p18408185817467"><aname="p18408185817467"></a><aname="p18408185817467"></a>Modifies the owner group. <strong>chown</strong>, <strong>uid</strong>, <strong>gid</strong>, and <i>target</i> must be separated by only one space.</p>
<tdclass="cellrowborder"valign="top"width="38.019999999999996%"headers="mcps1.2.4.1.3 "><pid="p11976107144710"><aname="p11976107144710"></a><aname="p11976107144710"></a>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>.</p>
<tdclass="cellrowborder"valign="top"width="38.019999999999996%"headers="mcps1.2.4.1.3 "><pid="p4350121915488"><aname="p4350121915488"></a><aname="p4350121915488"></a>Starts services. <i>serviceName</i> must be contained in the <strong>services</strong> array.</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" : [{
"services" : [{
"name" : "service1",
"name" : "service1",
"path" : ["/bin/process1", "param1", "param2"],
"path" : ["/bin/process1", "param1", "param2"],
...
@@ -230,7 +303,7 @@
...
@@ -230,7 +303,7 @@
"cpucore" : [0],
"cpucore" : [0],
"critical" : [0, 5, 10],
"critical" : [0, 5, 10],
"apl" : "normal",
"apl" : "normal",
"d-caps" : ["OHOS_DMS"]
"d-caps" : ["OHOS_DMS"],
"jobs" : {
"jobs" : {
"on-boot" : "boot",
"on-boot" : "boot",
"on-start" : "services:service1_start",
"on-start" : "services:service1_start",
...
@@ -250,107 +323,131 @@
...
@@ -250,107 +323,131 @@
"apl" : "normal",
"apl" : "normal",
"d-caps" : [ ]
"d-caps" : [ ]
}]
}]
```
```
**Table 3** Service field description<aname="table14737791471"></a>
**Table 3** Service field description<a name="table14737791471"></a>
| name | Name of the current service. | Type: string. The value cannot be empty and can contain a maximum of 32 bytes. | Small and standard |
</th>
| 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 |
</tr>
| uid | User ID (UID) of the current service process. | Type: int | Small and standard |
</thead>
| 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 |
</td>
| 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 |
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p1173818913714"><aname="p1173818913714"></a><aname="p1173818913714"></a>Name of the current service. The value cannot be empty and can contain a maximum of 32 bytes.</p>
| 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 |
</td>
| 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 |
</tr>
| 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 |
</td>
| 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 |
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p1073815910717"><aname="p1073815910717"></a><aname="p1073815910717"></a>Full path (including parameters) of the executable file for the current service. This is an array. Ensure that the first element is the path of the executable file, the maximum number of elements is 20, and each element is a string that contains a maximum of 64 bytes.</p>
| 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 |
</td>
| jobs | Jobs that can be executed by the current service in different phases. | For details, see [init parallel control](#section56901555919). | Small and standard |
</tr>
| 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 |
3. Add socket and on-demand startup configurations for a service.
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p107387920711"><aname="p107387920711"></a><aname="p107387920711"></a>User ID (UID) of the current service process.</p>
</td>
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.
</tr>
- 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.
</td>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p12738691479"><aname="p12738691479"></a><aname="p12738691479"></a>Group ID (GID) of the current service process.</p>
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.
</td>
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.
</td>
<tdclass="cellrowborder"valign="top"width="83.36%"headers="mcps1.2.3.1.2 "><pid="p18548317195715"><aname="p18548317195715"></a><aname="p18548317195715"></a>Whether the current service process is a one-off process.</p>
```
<pid="p103571840105812"><aname="p103571840105812"></a><aname="p103571840105812"></a><strong>1</strong>: The current service process is a one-off process. If the process exits, the init process does not restart it.</p>
"services" : [{
<pid="p5831191431116"><aname="p5831191431116"></a><aname="p5831191431116"></a><strong>0</strong>: The current service process is not a one-off process. If the process exits, the init process restarts it upon receiving the SIGCHLD signal.</p>
"name" : "ueventd",
<pid="p378912714010"><aname="p378912714010"></a><aname="p378912714010"></a>Note: If a non-one-off process exits for five consecutive times within four minutes, the init process will no longer restart it at the fifth exit.</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>
<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>
| -------- | -------- |
</td>
|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. |
</tr>
|family|Address family to which the socket belongs. Currently, the AF_UNIX and AF_NETLINK families are supported. |
</tr>
|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. |
</td>
|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. |
<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>
|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. |
</td>
|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. |
</tr>
|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**. |
<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>
| API | Description|Parameters |
</td>
| ---------- | ---------- |--------|
</tr>
| 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
</td>
| 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.
<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>
| 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. |
</td>
| 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**. |
</tr>
| 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. |
</tbody>
| 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. |
</table>
| 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. |
| 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
| init group test [stage] | Initializes a group test.<br/>Example:<br/>init group test| For details about **stage**, see **ServiceStatus**. |
| 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.
| param ls [-r] [name] | Displays system parameters.<br/>Example:<br>begetctl param ls persist.sys.usb | N/A|
| 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**.
| 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|
## Development Example<a name="section56901555925"></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**. |
| 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**. |
| 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|
The following uses the MySystemApp service as an example to illustrate how to use the init process to start a system service.
```
{
{
"jobs" : [{
"jobs" : [{
"name" : "pre-init",
"name" : "pre-init",
...
@@ -379,6 +476,9 @@
...
@@ -379,6 +476,9 @@
"caps" : [] // Do not perform capability-related operations because capabilities are not required by the MySystemApp service.
"caps" : [] // Do not perform capability-related operations because capabilities are not required by the MySystemApp service.
"start-mode" : "condition",
"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.
"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" : {
"jobs" : {
"on-boot" : "boot",
"on-boot" : "boot",
"on-start" : "services:MySystemApp_start",
"on-start" : "services:MySystemApp_start",
...
@@ -388,48 +488,64 @@
...
@@ -388,48 +488,64 @@
}
}
]
]
}
}
```
```
After the configuration is complete, compile the package to burn the board.
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.
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.
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
## FAQ<a name="section56901555926"></a>
**Symptom**
### Service Not Exist<a name="section56901555927"></a>
"Service \' xxx \'(pid = xxx) is not valid or request with unexpected process(pid = xxx)" is printed in the kernel log.
 **Symptom**<br>
**Cause Analysis**
   "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 fd proxy is requested for other services.
   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>
**Solution**
   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>
Request fd proxy for the current service, but not other services.
 **Symptom**
   "Service \' xxx \'(pid = xxx) is not valid or request with unexpected process(pid = xxx)" is recorded in the kernel log.
### No ondemand Configuration
 **Cause Analysis**<br>
**Symptom**
   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>
"service: %s had started already" is printed in the kernel log.
   Request fd proxy for the current service, but not other services.
### No ondemand Configuration<a name="section56901555929"></a> is not configured for the service.
**Cause Analysis**
 **Symptom**<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.
   "service: %s had started already" is recorded in the kernel log.
 **Cause Analysis**<br>
**Solution**
   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
   Correct the service configuration in the **.cfg** file as follows: "ondemand" : true