Re-Exec init after pivot_root

Alberto Donato alberto.donato at gmail.com
Wed Mar 21 09:27:53 UTC 2007


Hi all,

On 3/21/07, Denis Vlasenko <vda.linux at googlemail.com> wrote:
> 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

I agree with Denis. I'm using the same process to update a system
partition on an embedded system using another one as update system.
Basically these are the steps:

mount $UPDATE_PARTITION $UPDATE_DIR
cd $UPDATE_DIR
pivot_root . old_root
chroot . /bin/kill -QUIT 1 &

the /etc/fstab file contains the restart action as suggested by Denis,
so init is re-executed after killing all other processes.
The /etc/rc script of the new root filesystem is free to umount
/old_root and overwrite the old root filesystem.

Alberto

> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://busybox.net/cgi-bin/mailman/listinfo/busybox
>



More information about the busybox mailing list