2

My goal is to unmount the root disk so I can format it. To do this, I want to switch root from the hard disk to some other root. I have chosen to use the files from the initramfs (which contains a minimal root file system) to create a rootfs to switch back to.

I'm doing this on a clean install of Ubuntu 16.04.

The following commands create a ramdisk and copies the contents of the initramfs onto the ramdisk.

dd if=/dev/zero of=/dev/ram bs=1k count=209715
mke2fs -vm0 /dev/ram 209715
mount -t ext2 /dev/ram /ramroot/
cd /ramroot/
zcat /boot/initrd.img-4.4.0-47-generic | cpio -idmv
mkdir old-root

However when I do the switch_root command I get "Invalid argument"

root@ubuntu-512mb-nyc3-01:/ramroot# switch_root /ramroot /ramroot/old-root
switch_root: failed to mount moving /run to /ramroot/run: Invalid argument
switch_root: forcing unmount of /run
switch_root: failed to mount moving /ramroot to /: Invalid argument
switch_root: failed. Sorry.

What am I doing wrong?

2

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

  • The context is that I am writing a boot script that can be run on any Ubuntu machine, with the objective of formatting the disk and writing a new operating system onto the disk. I have no control over any part of the boot process prior to running my boot script. I thought pivot_root and switch_root were used not only within the boot process, but were designed for tasks like this. Why do you suggest that it's not intended for other purposes except handover during boot? – Duke Dougal Nov 27 '16 at 9:10
  • @DukeDougal for one thing, the fact that switch_root does the equivalent of an rm -rf on the old root is a smoking gun that it's solely designed for the use case where the old root is a tmpfs and you want to recover the associated memory. – Celada Nov 27 '16 at 9:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.