switch_root and centos
rob at landley.net
Thu Dec 31 10:39:32 UTC 2009
You'd think this would be a FAQ by now...
The following shell script is more or less what switch_root is doing, minus
the sanity checks (and ignoring the -c console handling):
find / -type f -xdev | xargs rm -f
find / -type d -depth -xdev | xargs rmdir
mount --move . /
I.E. delete the contents of initramfs to free up the memory, chroot into the
new directory, and exec the new init.
In practice, deleting your old /bin and /lib directories before doing the
chroot leaves a shell script sort of hanging before it does chroot, and I've
seen it made to work by statically linking things and running binaries out of
the new directory before you've chrooted into it, but just having it be one
executable is a lot less fiddly.
However, doing any variant of "find / | xargs rm" is EXTREMELY DANGEROUS, and a
good way to eat your development system if you ever let your guard down, so
switch_root has some fairly stringent sanity checks:
1) The new root directory can't be the same filesystem as / (or its contents
would get deleted before you switched into it).
2) The old / has to be a ramfs or tmpfs. (Sort of the point of deleting its
contents to free space.)
3) You must be running as PID 1.
If any of these aren't true, you're not using it right anyway, and it aborts
rather than potentially eat your development system.
That clear anything up?
On Monday 14 December 2009 14:53:07 Michael Di Domenico wrote:
> Mount move what though? I thought switchroot was support to do that
> under the covers, basically swapping
> /dev/ram0 rootfs /
> /dev/hda ext3 /newroot
> then do a chroot into /
Nope. If you have any other filesystems mounted under /, moving them into the
new filesystem (or unmounting them) is your job.
> and then run what? this seems to be where i'm getting stuck... :(
switch_root does a chroot for you. It's rm -rf, mount --move, and chroot all
> though once the above fails and i end up back in busybox i see
> /dev/ram0 /
> /dev/hda /
If you're using a ramdisk instead of a ramfs, switch_root is the wrong tool.
The rm -rf behavior frees space from a ramfs. But a ram disk takes the same
amount of space whether its contents are being used or not, that's a ram based
_block_device_ (of fixed size). Not a dynamically resizing ram based
initrd != initramfs.
The reason you see both at / is the mount --move is essentially going to
overmount. (Note that the directory you mount a filesystem on doesn't have to
be empty. You can even have one filesystem mounted on top of another. The old
contents of the directory are hidden until you unmount the new filesystem.)
Note that "rootfs" is the ramfs instance that the initramfs cpio archive
populates. It's always there, about the same way PID 1 is always there, and
attempts to unmount it would be ignored the same way PID 1 ignores unhandled
signals (even kill -9).
When you're using another root filesystem, it's mounted over rootfs, but if you
"cat /proc/mounts" rootfs should always be the first entry in that.
Latency is more important than throughput. It's that simple. - Linus Torvalds
More information about the busybox