switch_root

From: Laurent Bercot <ska-skaware_at_skarnet.org>
Date: Tue, 15 Oct 2013 08:28:56 +0100

> http://searchcode.com/codesearch/view/27282163

  Oh, I know that implementation. Piece of code with the usual mistakes
such as calling access() before execv(), yay.

  The thing with switch_root is that it performs several
basic operations - that already exist as standalone executable
programs - in one unique utility; and most of those operations
are destructive, i.e. you cannot undo them. It is counter-intuitive
to me to have such operations in a unique C utility; I've always
implemented those things as scripts.

If I were to have a s6-switch_root utility, it would most likely be
a script, and I would advise you to write your own, specifically
tailored to your own needs. If I had to perform switch_root without
access to busybox or toybox, with only my own software to rely on,
then I'd probably do something like this:
  (warning: off the top of my head, absolutely untested)

s6-switch_root newroot prog...
(must be executed in /, and newroot must be a direct subdir of /)
-----
#!/command/execlineb
importas -i new 1 shift elgetpositionals emptyenv -P
foreground { s6-mkdir -p $new/proc $new/sys $new/dev }
if { s6-mount -o move /proc $new/proc }
if { s6-mount -o move /sys $new/sys }
if { s6-mount -o move /dev $new/dev }
if
{
   forbacktickx -pe0 dir { s6-ls -a0 -x $new / } $new/command/import dir
   $new/command/s6-rmrf $dir
}
$new/command/cd $new
./command/if { ./command/s6-mount -o move . / }
s6-chroot $new
$_at_
-----

  Yeah, it's ugly. You have to access some binaries in the new root, while
you're deleting them in the old root and afterwards. But I'd still do it
over writing a C program for that, because it's a lot more flexible - which
is vital when you're at this stage of system development without any safety
net and need the shortest possible debug cycles.
  The ugliness really comes from the inability to pivot_root initramfs.
pivot_root is great, because you can clean up *after* the root change, in
your new environment, so everything is pretty safe. If you cannot pivot_root,
you have to clean up *before* the root change, so you're walking on thin ice
the whole time.
  When I had to do this at work, I created a tmpfs under the new root (which I
needed to do anyway), dumped all my static binaries from the old root into it,
and performed the root change as early as possible, easily cleaning up the tmpfs
afterwards. Not exactly refined, but it worked and spared me a lot of headaches.

  But initramfs is one of those harmful mutant Linux features - it looks awesome
and you can see zillions of use for it, but it always ends up being more trouble
(as in complexity) than it's worth, and you can always do without it. If you're
designing an embedded system, then you should boot directly on your real root fs
(which is of course read-only) and work in a tmpfs within your real system. If
you need to swap root filesystems (for instance for firmware updates) then you
can always pivot_root. KISS, especially in those early boot stages.

-- 
  Laurent
Received on Tue Oct 15 2013 - 07:28:56 UTC

This archive was generated by hypermail 2.3.0 : Sun May 09 2021 - 19:38:49 UTC