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
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.
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).