can't switch_root inside initramfs

LEVAI Daniel leva at ecentrum.hu
Mon Aug 31 09:05:40 UTC 2009


On Sunday 30 August 2009 01.47.55 you wrote:
> On Saturday 29 August 2009 03:23:18 LEVAI Daniel wrote:
> > Hi!
> >
> >
> > I have this gzipped cpio file as my initramfs, which has a /init and it
> > has a /mnt/target directory as the final rootfs.
> >
> > ----------------### /init ###----------------
> > #!/bin/sh
> >
> > /bin/busybox --install -s
> >
> > mount -t proc proc /proc
> > mount -t sysfs sysfs /sys
> >
> > echo "Loading modules..."
> > for module in tg3 r8169 e1000e;do
> >         modprobe $module
> > done
> >
> > ifconfig eth0 up
> > udhcpc eth0
> >
> > [... some network transfers with tftp ...]
> >
> > rm -Rf /mnt/target/*
> >
> > cd /mnt/target/
> > bunzip2 -c /"${FILENAME}" |cpio -dimuHcrc
> >
> > exec switch_root -c /dev/console /mnt/target/ /sbin/init
> > ----------------### /init ###----------------
> >
> >
> > After the switch_root I get this error:
> > switch_root: bad newroot /mnt/target
> > Kernel panic - not syncing: Attempted to kill init!
> >
> >
> > The newroot (/mnt/target) resides in the ramfs itself
>
> There's your problem.  What switch_root does is move from one filesystem to
> another.  It does an rm -rf on the initramfs to empty it so it can be
> mounted over by the new filesystem without wasting memory, it's just that
> this delete pass won't descend into other filesystems.  So if your new
> directory is in the same filesystem as the old root, everything in it will
> be deleted.
I see!

> In addition, the new filesystem has to be an actual mounted filesystem (a
> tmpfs works fine) because it does a mount --move on it, which you can't do
> with a subdirectory.  (The syscall would fail.)
>
> It seems like what you want to do is a --bind mount instead of a --move
> mount, and you want to exclude that subdirectory from being deleted even
> though it's in the same filesystem.  That requires significant changes to
> the switch_root source code.
Thanks for the clarification!

> You can also just call chroot instead of switch_root, which should do what
> you want.  It just won't do the cleanup steps, so you'll be wasting some
> memory and have a slightly unnecessarily complicated kernel internal mount
> tree.
Thanks again, greate infos, I really appreciate these!


Daniel

-- 
LÉVAI Dániel
PGP key ID = 0x4AC0A4B1
Key fingerprint = D037 03B9 C12D D338 4412  2D83 1373 917A 4AC0 A4B1


More information about the busybox mailing list