Check the service argv array bound before reading the current entry in the debug dump loop. A full argument array may not have an in-array NULL terminator, so the old condition could read one entry past the array while CONFIG_SYSTEM_NXINIT_DEBUG is enabled.
Signed-off-by: Old-Ding <35417409+Old-Ding@users.noreply.github.com>
Fix argument parsing in init_parse_arguments() to properly handle
multiple quoted arguments like 'echo "arg1" "arg2"' by skipping
quote characters after processing them.
Signed-off-by: fangpeina <fangpeina@xiaomi.com>
The init process has blocked all signals, spawned services would
inherit that mask. This could cause services to miss important
signals like SIGTERM during graceful shutdown.
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Pending all signals(SIGCHLD) when ppoll() is not invoked to
avoid race conditions.
Case reproduction
Set examples/hello as a service that exits immediately after startup.
```init.rc
on boot
start hello
service hello hello
restart_period 0
```
Log - without this patch:
# Service hello only restarts about 100 times, ppoll is not woken up
# after the hello process with PID 119 exits.
[ 4.391274] [ 2] [ 0] init_main: service 'hello' pid 118 exited status 0
[ 4.401423] [ 2] [ 0] init_main: started service 'hello' pid 119
Log - with this patch:
# ppoll() can still be woken up normally after tens of thousands of
# restarts of service hello in stress test.
[ 268.447747] [ 2] [ 0] init_main: service 'hello' pid 34503 exited status 0
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Any string ending with whitespace passed to init_parse_arguments()
could cause the parser to advance past the string boundary and read
unintended memory content.
- " echo "A" \0& echo "B" should be parsed
as a command with two argvs instand of five.
- "command arg " may lead to uncertain results.
Signed-off-by: fangpeina <fangpeina@xiaomi.com>
reap_process() referenced an undeclared identifier 'wtatus' on
the WIFSIGNALED branch (typo of 'wstatus'). Some toolchains then
flagged a -Wmaybe-uninitialized on the surrounding wstatus use.
Correct the typo so WIFSIGNALED/WTERMSIG operate on the actual
wstatus value returned by waitpid().
Signed-off-by: fangpeina <fangpeina@xiaomi.com>
action.c uses clock_gettime(CLOCK_MONOTONIC, ...) but did not
pull in <nuttx/clock.h> directly, which fails to build on
configurations where the header is not transitively included.
Add the missing #include.
Signed-off-by: fangpeina <fangpeina@xiaomi.com>
When ETC_ROMFS is disabled to reduce the bin size, we can provide the init.rc
file via a pseudo-file in the boards/vendor directory. For example:
- CONFIG_ETC_ROMFS=n
- CONFIG_PSEUDOFS_FILE=y
- CONFIG_DISABLE_PSEUDOFS_OPERATIONS=n
```C
FAR const char *init_rc =
"on init\n"
" start console\n";
"service console sh\n"
" restart_period 100\n";
int fd = open("/etc/init.d/init.rc", O_WRONLY | O_CREAT);
/* ... */
ssize_t n = write(fd, init_rc, strlen(init_rc) + 1);
/* ... */
close(fd);
```
The last character '\0' in the file content will be treated as a new line,
and the number of parsed parameters will be zero (abnormal, there should be
at least one keyword).
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Empty lines in init.rc caused parsing to fail with -EINVAL because init_parse_arguments() returns 0 for empty strings, triggering the 'argc < 1' error path in init_action_parse() and accessing uninitialized argv[0] in init_service_parse().
Fix by skipping empty lines and lines containing only whitespace before attempting to match section keywords or calling parser callbacks.
Fixesapache/nuttx-apps#3513
Signed-off-by: hanzj <hanzhijian@zepp.com>
Without debug enabled, the code would not compile due to checking
`WIFEXITED(wstatus)` when `wstatus` was uninitialized.
Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
The init.rc file path is now configurable to allow users to choose where
to put the startup script. This is useful for devices that mount
external media to a special directory like `/sd`.
Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
Would not compile due to typo in macro describing service name length.
Change ensures that:
* We do not malloc an extra `len` bytes since this is already allocated
as part of the struct
* The name string always has a null terminating byte
Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
FIx
Add support for the reboot_on_failure option to the service.
When the execution of a command within a certain action fails (returning
a non-zero status code), NxInit will continue to execute subsequent commands or
actions and will not proactively terminate the startup process. To implement
the functionality of "terminating the startup process after a command
execution fails", there are two methods:
a. Execute conditional statements (if/then/else/fi) via exec command,
but this depends on sh:
```
on init
exec -- set +e; \
mount -t fatfs /dev/data /data ; \
if [ $? -ne 0 ] ; \
then \
echo "failed" ; \
reboot ; \
else \
echo "succeed" ; \
fi;
```
b. Via service's oneshot + reboot_on_failure:
/* Although the example uses sh, it does not depend on it and can be
* replaced with any other Builtin Apps.
*/
```
on init
exec_start mkdir_tmp
ls /tmp
service mkdir_tmp sh -c "mkdir /tmp"
reboot_on_failure 0
oneshot
```
Test
- RC
service console sh
class core
override
> reboot_on_failure 0
restart_period 10000
- Runtime
[ 0.150000] [ 3] [ 0] init_main: == Dump Services ==
...
[ 0.170000] [ 3] [ 0] init_main: Service 0x40486ea0 name 'console' path 'sh'
[ 0.170000] [ 3] [ 0] init_main: pid: 0
[ 0.170000] [ 3] [ 0] init_main: arguments:
[ 0.170000] [ 3] [ 0] init_main: [0] 'service'
[ 0.170000] [ 3] [ 0] init_main: [1] 'console'
[ 0.170000] [ 3] [ 0] init_main: [2] 'sh'
[ 0.170000] [ 3] [ 0] init_main: classes:
[ 0.170000] [ 3] [ 0] init_main: 'core'
[ 0.170000] [ 3] [ 0] init_main: restart_period: 10000
> [ 0.170000] [ 3] [ 0] init_main: reboot_on_failure: 0
[ 0.170000] [ 3] [ 0] init_main: flags:
[ 0.170000] [ 3] [ 0] init_main: 'override'
...
[ 0.380000] [ 3] [ 0] init_main: started service 'console' pid 4
...
nsh> kill -9 4
[ 8.060000] [ 3] [ 0] init_main: service 'console' flag 0x20000004 add 0x4
[ 8.060000] [ 3] [ 0] init_main: -flag 'running'
[ 8.060000] [ 3] [ 0] init_main: service 'console' flag 0x20000000 add 0x8
[ 8.060000] [ 3] [ 0] init_main: +flag 'restarting'
> [ 8.060000] [ 3] [ 0] init_main: Error reboot on failure of service 'console' reason 0
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Format: exec_start <service>
Start the specified service and pause the processing of any additional
initialization commands until the service completes its execution. This
command operates similarly to the `exec` command; the key difference is
that it utilizes an existing service definition rather than requiring
the `exec` argument vector.
This feature is particularly intended for use with the `reboot_on_failure`
built-in command to perform all types of essential checks during system boot.
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This component (abbreviated as "NxInit") is specifically developed
for NuttX and intended for system initialization. While we have
adopted the Android Init Language among various syntax options,
this is a brand-new implementation—it is not a port or variant of
Android Init.
Refer to the implementation of Android Init Language, consists of five broad
classes of statements: Actions, Commands, Services, Options, and Imports.
Actions support two types of triggers: event and action. Action triggers also
support runtime triggering. Services support lifecycle management, including
automatic restart (at specified intervals), and starting/stopping
individually or by class. Import supports files or directories, and we may
add a static method in the future. The following are some differences:
1. The Android Init Language treats lines starting with `#` as comments,
while we use a preprocessor to handle comments.
2. For action commands, we can omit "exec" and directly execute
built-in apps or nsh builtins.
3. Regarding the property service, users can either adapt it by self or
directly use the preset NVS-based properties.
4. Only part of standard action commands and service options are
implemented currlently.
To enable system/nxinit:
```diff
-CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_ENTRYPOINT="init_main"
+CONFIG_SYSTEM_NXINIT=y
```
For format and additional details, refer to:
https://android.googlesource.com/platform/system/core/+/
master/init/README.md
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>