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