problem with running "kill -QUIT 1" from init

Denys Vlasenko vda.linux at googlemail.com
Fri Jan 30 01:55:10 UTC 2009


On Friday 30 January 2009 01:05, Aras Vaichas wrote:
> Denys Vlasenko wrote:
> > Can you show me you /etc/inittab
> > and describe what you are doing, what do you expect to see
> > and what do you see instead?
> >
> > I have qemy image and can try to reproduce it, as soon
> > as I will know what to do.
> >
> > Please also specify your busybox version and attach
> > busybox .config you used to build the binary.
> >   
> I'm doing a major version upgrade and I have chosen to reflash the whole 
> filing system with a JFFS2 image. For this to happen reliably, I need to 
> unmount the root filing system.
> 
> The old systems are running busybox version 1.1.0-pre1.
> 
> The tutorial at denx.de recommends that I send a "kill -QUIT 1" to tell 
> init to call "console::restart:/sbin/init" which will handle the rootfs 
> unmount.
> 
> Unfortunately, the systems that I need to upgrade do not have a restart 
> option in the inittab file.
> 
> Old inittab
> # /etc/inittab: init(8) configuration.
> ::sysinit:/etc/init/rcS
> ::respawn:/bin/busybox getty 115200 ttyS0 ansi
> ::shutdown:/bin/sync
> ::shutdown:/bin/umount -a -r
> 
> I made a new inittab called inittab.new which has a restart option.
> 
> # /etc/inittab: init(8) configuration.
> ::sysinit:/etc/init/rcS
> ::respawn:/bin/busybox getty 115200 ttyS0 ansi
> ::shutdown:/bin/sync
> console::restart:/sbin/init
> 
> 
> My upgrade script is in two parts. The first part is called by 
> /etc/init/rcS. The second part resides in a temporary rootfs, and it is 
> called by the restart option.
> 
> ----- First script -----
> 
> #!/bin/sh
> 
> # install new inittab
> cp inittab.new /etc/inittab
> 
> # instruct init to reload the new inittab
> kill -1 1

Hmm. I see why it doesn't work: in init.c:

        /* Now run everything that needs to be run */
        /* First run the sysinit command */
        run_actions(SYSINIT);
        /* Next run anything that wants to block */
        run_actions(WAIT);
        /* Next run anything to be run only once */
        run_actions(ONCE);
        /* Redefine SIGHUP to reread /etc/inittab */
        signal(SIGHUP, ENABLE_FEATURE_USE_INITTAB ? reload_signal : SIG_IGN);
        /* Now run the looping stuff for the rest of forever */
        ...

See? SIGHUP handler is installed only after 'sysinit' and 'wait'
actions have finished and and 'once' action was started
(init doesn't wait for 'once' to finish).

This was actually intended.
Say, if sysinit has completed, and then wait
script sent SIGHUP to init - what to do then?
We can reload /etc/inittab, but what do we do?
Start over from sysinit?
Or ignore sysinit entries and run only wait?
Or skip wait too?

Author used the simplest solution: SIGHUP does not work
in these actions at all.

> # rootfs stuff happens here, copy over static busybox, create links to 
> it, cd to temporary directory
> ... SNIP ...
> 
> # create a link from /sbin/init to our part2 installer
> ln -s ../install_part2 init
> 
> # move the old root out of the way
> ./bin/pivot_root . oldroot
...

The solution could be to start a child, and then let sysinit
script to exit, leaving child to run:

...
/the/helper/script.sh &
exit

and in /the/helper/script.sh, you sleep for, say 2 seconds,
and then do "kill -HUP 1" etc... At this time, init will react
to SIGHUP.

Although I wonder: since you are creating new inittab on the filesystem
(it's not readonly or something), and you obviously reboot you device
(IOW: you don't have a requirement to not reboot it),
why can't you just replace /etc/inittab and reboot?
--
vda


More information about the busybox mailing list