upstart shell magic for exec line
Maxim Nikulin
m.a.nikulin at gmail.com
Wed Jun 12 09:37:54 UTC 2013
Hi.
Debugging https://bugs.launchpad.net/bugs/1181789 I have traced that
service may be launched with different argv array on first and later
start invocations. The deep consequence is a log file open for writing
when root filesystem must be remount readonly during shutdown.
Job .conf file (quotes around "exec" are crucial):
expect fork
exec /bin/sh -c "exit"
First 'initctl start' invocation, argv argument of
init/job_process.c:job_process_spawn()
{0x809b730 "/bin/sh", 0x809e448 "-e", 0x809e758 "-c",
0x809e4c8 "exec /bin/sh -c \"exit\"", 0x809b548 "/bin/sh"}
Second call:
{0x809b730 "/bin/sh", 0x809f0f8 "-e", 0x809e758 "-c",
0x809e950 "/bin/sh -c \"exit\"", 0x809ef90 "/bin/sh"}
Note that exec is missed second time.
I think it is due to line 268 of init/job_process.c
> /* At the end, always set proc->script to TRUE, even if the user didn't
> * explicitly set it (when using shell variables). That way tests
> * can reliably check for shell-specific behaviour.
> */
> proc->script = TRUE;
As a result 'exec' is added only during the first start of service
(line 219):
> /* If the process wasn't originally marked to be run through
> * a shell, prepend exec to the script so that the shell
> * gets out of the way after parsing.
> */
> if (proc->script) {
> script = NIH_MUST (nih_strdup (NULL, proc->command));
> } else {
> script = NIH_MUST (nih_sprintf (NULL, "exec %s",
> proc->command));
> }
The result is the following process tree
> 20131 pts/1 S+ 0:00 | \_ gdb --args ./init --confdir /tmp/conf --logdir /tmp/log --no-sessions --session
> 20137 pts/1 t 0:00 | \_ /home/u/src/ureadahead/upstart-1.8/init/init --confdir /tmp/conf --logdir /tmp/log --no-sessions --session
> 20635 ? ts 0:00 | \_ /bin/sh -e -c /bin/sh -c "exit" /bin/sh
> 20647 ? t 0:00 | \_ /bin/sh -e -c /bin/sh -c "exit" /bin/sh
Upstart catches fork for the second shell and believes that the process
is started. (Should not it notice that the new process exits immediately?)
Are there any side effects of removing the line 268?
proc->script = TRUE;
(Besides test for shell characters on each start)
--
Maxim Nikulin
More information about the upstart-devel
mailing list