Re-Exec init after pivot_root

Denis Vlasenko vda.linux at googlemail.com
Tue Mar 20 17:29:19 PDT 2007


Hi Zoban,

On Tuesday 20 March 2007 22:01, Zoban Gubich wrote:
> On 3/19/07, Denis Vlasenko <vda.linux at googlemail.com> wrote:
> > Hi Mark,
> >
> > On Monday 19 March 2007 03:12, Mark Hinds wrote:
> > > rexec_signal does much of what shutdown does, except
> > > when its done it exec's /sbin/init, and boom - we're
> > > running in fresh init in the new pivot'd rootfs and can
> > > do as I please to the JFFS2 rootfs.
> > >
> > > Questions:
> > > 1. Does this make sense?
> >
> > Don't know, because I didn't fully understand what exactly
> > are you trying to achieve. You pivot-rooted to tmpfs, and
> > then... you want to send SIGINT to init in order to re-exec it?
> > why? I obviously miss something here...

Now I even more puzzled, because this mail is a reply, but apparently
from a *different person*. !?

> I tried doing the shutdown stuff external to init, but in the end
> /mnt/oldroot/bin/busybox is still what init is running from.
> This means I can't umount /mnt/oldroot, which intern means
> I can't/shouldn't flash_eraseall /dev/mtd1 so I can do a rootfs
> update.

You are not saying that /dev/mtd1 is containing /mnt/oldroot/bin/busybox.
Why? It is not making understanding your situation easier.

> Perhaps I should further clarify that my system boots to a read-only jffs2
> rootfs.
> This seems clean and simple to me, but does necessitate the
> pivot_root/re-exec init
> thing so I can re-write the jffs rootfs for major SW updates.

I think you can use 'restart' action in inittab.

::restart:/path/to/re/exec

It is triggered by HUP or QUIT sig:

        signal(SIGHUP, exec_signal);
        signal(SIGQUIT, exec_signal);

It kills all processes (shutdown_system()) and then
execs specified process:

static void exec_signal(int sig ATTRIBUTE_UNUSED)
{
        struct init_action *a, *tmp;
        sigset_t unblock_signals;

        for (a = init_action_list; a; a = tmp) {
                tmp = a->next;
                if (a->action & RESTART) {
                        shutdown_system();

                        /* unblock all signals, blocked in shutdown_system() */
                        sigemptyset(&unblock_signals);
                        sigaddset(&unblock_signals, SIGHUP);
                        sigaddset(&unblock_signals, SIGQUIT);
                        sigaddset(&unblock_signals, SIGCHLD);
                        sigaddset(&unblock_signals, SIGUSR1);
                        sigaddset(&unblock_signals, SIGUSR2);
                        sigaddset(&unblock_signals, SIGINT);
                        sigaddset(&unblock_signals, SIGTERM);
                        sigaddset(&unblock_signals, SIGCONT);
                        sigaddset(&unblock_signals, SIGSTOP);
                        sigaddset(&unblock_signals, SIGTSTP);
                        sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);

                        /* Open the new terminal device */
                        open_stdio_to_tty(a->terminal, 0);

                        messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command);
                        BB_EXECLP(a->command, a->command, NULL);

                        message(L_CONSOLE | L_LOG, "Cannot run '%s': %s",
                                        a->command, strerror(errno));
                        sleep(2);
                        init_reboot(RB_HALT_SYSTEM);
                        loop_forever();
...

--
vda


More information about the busybox mailing list