I recommend against using switch_root
for this purpose. It's really designed only for use by the initramfs to switch from the initramfs to the real root and for no other purpose. You can see evidence of that specialized purpose in the following warning found on its manpage:
WARNING: switch_root removes recursively all files and directories on
the current root filesystem.
That's there so that the memory used by the initramfs (which is a tmpfs) can be recovered after the initramfs switches to the real root. (By the way, the reason it's built in to switch_root
rather than part of the initramfs shell scripts is that it's the only opportunity to do it: after the old root is no longer in use and while the binary is still briefly hanging on to a file descriptor that refers to it.) Do you really want switch_root
to rm -rf
your old root filesystem? I guess maybe you don't mind since you plan to remake the fileysstem afterwards anyway, but it's not optimal.
Also, your usage of switch_root
is incorrect: the argument after /ramroot
should be a command to run (in the new root), not the name of a directory. But that's not the source of your problem.
It's not clear from the mount(2) manpage exactly what the source of your EINVAL
error is, but I'm not surprised to see it fail: since your use case is not the expected one for switch_root
, it's probably not well tested & supported. I guess that there could be something about the old filesystem still being in use (has open references to it) that prevents the MS_MOVE
mount from working.
You could try the following things to see if they will work, but I think there's a good chance that none of them will:
- Make extra sure there is nothing running on the system that is holding references to the old root filesystem (not even a
sshd
for your connection to the machine). You can probably arrange for an SSH session into the machine that does not depend on the old root filesystem using various chroot
tricks after copying al the SSH server infrastructure to the new root filesystem, but it will be gymnastics.
- Use
exec
to invoke switch_root
. It's designed to be invoked that way.
- Use a tmpfs filesystem instead of a ext2 one. For what you are trying to do, there's no reason to use an ext2 filesystem on top of a ramdisk. You might as well just use tmpfs (like initramfs does).
The better way to do what you are trying to do is to use the machine's console and use the real initramfs to do your work. This of course requires that you have working console access to the machine. Boot with something like break=bottom
in the kernel command line, and the initramfs will give you a chance to do what you need while running under the ramfs. You'll want to copy the tools you need into the initramfs before you do it.
In the end, if you can afford to do it, it's much easier and safer to do these things under a rescue system. I can think of good reasons to use the aforementioned break
trick to do the work under an initramfs (e.g. you have remote serial console access but no opportunity to insert a USB key with a rescue system and no support for net-booting a rescue system) but it's dangerous if you make a mistake (you'll lose access and need a trip to the datacentre anyway).