7

I have a folder containing certain files. Is there a way to mount it onto /, so that the contents of a given directory appear in the corresponding locations in /?

In my case, the directories contain the files related to an application -- it does not have directories like /dev and /proc.

I tried creating a bind mount in the following manner:

mount --bind ~/applications/firefox /

However, this does not do anything at all. Unlike what has been speculated in the comments, it does not have any adverse effect either.


The motivation for this is that I have a number of custom applications that I want to install cleanly on mission-critical systems. Understandbly, I want to keep the related management to a minimum. I obtain the filesystem layout of the application install with a unionfs-fuse + chroot method, but then I still have to deal with the problem of the applications' files mingling with those of the system. Mounting certain directories onto / would help me to keep the filesystem clean.

While this method of installing software may seem perverted, there is a distro named "Porteus" which installs software in exactly this manner (and for the same reasons), however, they are known to use a patched kernel along with aufs. However, I cannot use a custom kernel on the systems.

  • 1
    Unless ~/application has a complete OS (including /dev and all), this kind of mount is likely to crash/hang your system. I assume you have try this mount being root ? – Archemar May 30 '15 at 14:38
  • 1
    Tell us what you are really trying to accomplish - maybe there are other ways. – guntbert May 30 '15 at 14:44
  • @guntbert, I've added an explanation according to your request. – user2064000 May 30 '15 at 17:21
  • Search for the overlay filezystem. – ott-- May 30 '15 at 18:56
2

What you're asking to do is done at least once on just about every commonly configured Linux system out there. Most use the tool made available by busybox called switch_root:

What switch_root does is delete all the files out of rootfs (to free up the memory) and then chroot into a new filesystem and exec a new init process out of the new filesystem.

This happens during system initialization. When a linux system is booted the kernel brings the system up in stages. At first the kernel is executed in memory by some other system - such as a bootloader or the firmware - and at this point the kernel is kind of just left to fend for itself - with no real frame-of-reference for the system on which it was just executed.

This is what the initramfs image usually appended to its memory space (but possibly also directly compiled into the kernel) is designed to handle. The initramfs is a real linux root (complete w/ /dev and /proc and what-have-you) filesystem image - it is the first root filesystem ever mounted by a linux kernel. It includes a root filesystem archive containing any/all system-specific modules/configuration files that are necessary to get the kernel on its feet - to bootstrap it.

Anyway, the kernel mounts that archive as rootfs (basically a tmpfs) and then does whatever is necessary to find some other / and mount that one over it. It does this every time you boot your system. It can do it again, and without resorting to unnecessary hacks like unionfs or aufs - both of which are likely to engender all kinds of implementation-specific complications and configuration details (which is not to mention instability).

In the quoted switch_root description above you'll probably notice the phrase delete all of the files out of rootfs. Obviously this would not be a desirable behavior when switching out of a disk-based rootfs. But it only happens that way with switch_root to free the memory for the ram-based filesystem anyway - and is completely unnecessary. Here is some more from the earlier quoted article:

The following shell script fragment demonstrates how to use switch_root:

   # First, find and mount the new filesystem.

   mkdir /newroot
   mount /dev/whatever /newroot

   # Unmount everything else you've attached to rootfs.  (Moving the filesystems
   # into newroot is something useful to do with them.)

   mount --move /sys /newroot/sys
   mount --move /proc /newroot/proc
   mount --move /dev /newroot/dev

   # Now switch to the new filesystem, and run /sbin/init out of it.  Don't
   # forget the "exec" here, because you want the new init program to inherit
   # PID 1.

   exec switch_root /newroot /sbin/init

As you can see above, handling the /dev, /proc, and /sys related problems can be very simply accomplished. If you were to layer any of mount --moved mounts, by the way, you would have to deal not only with mtab and mount but also whatever other complications are introduced by your layering system. It is more simple to do just as you describe in the question - mount root from somewhere else.

You'll need to do basically all of the stuff that happens in a typical initramfs configuration and very little else - (which is not meant to include Debian or Redhat's initramfs images - both of which are way over-engineered). The only real issue you might encounter is how to get PID1 to follow suit - if you leave your system's init stranded on some orphaned rootfs very weird stuff could soon start happening on your system. The obvious way to handle this is to prepare from initramfs on. Just make sure that your hard-disk's init process is prepared to exec another later down the road when you want to switch roots. If you're using a systemd init then this complication is already handled for you:

systemctl --help
...
switch-root ROOT [INIT]         Change to a different root file system
...

If you are using a systemd-based init you should study the unit files in /usr/lib/systemd/system/initrd* to get an idea of what the commonly scripted systemd-style switch-root situation is like.

Another way to go about it might be to mimic busybox's switch_root in initramfs - but to leave out the part where you delete all of the initial root's files. Arch Linux systems configured with systemd in initramfs do this. On those, the initramfs root mounts itself into /newroot's /run/initramfs before doing the switch-root and is what the system falls back to at shutdown to cleanly handle sleep/suspend and similar. That may be the best way to go for your case, actually - just a tiny, ram-persistent root-system which you ping-pong off of for your various individually rooted applications.

2

Don't try to mount over /, make yourself a "new" (fake,read-only) one:

I have done something similar. At the time I used AUFS, but this should also work with overlayfs and/or unionfs-fuse:

  • make a folder (e.g.) ~/apps/_App1_FakeRoot
  • Unionfs mount / (root) read-only under ~/apps/_App1 read-write on mountpoint ~/apps/_App1_FakeRoot.
  • chroot into the FakeRoot, run your app.

In my specific case I had used something like the above to unify several layers, including a (ram)disk for (temporary) writes.

Specific syntax will depend on whatever implementation of a unioning FS you (can) use. You may have to mount yourself also another /proc /sys /dev/pts in the chroot, depending, on what you app needs. It is also possible, that some types of programs just will not run in such a chroot, perhaps if the want to do hardware-level things

(If your particular unionfs implementation does not want to use / as read-only Base, you may get around it by first read-only bind-mounting yourself a "root-filesystem" somewhere to use as a base for your Apps.)

0

mount --bind ~/applications/firefox / would shadow the whole directory tree, including /dev, /proc and so on. It would make everything that's shadowed inaccessible. It isn't working because you can't bind-mount a directory where it would shadow itself.

You want to mix what's already in your directory tree and another directory tree. This is called a union mount. There are several union filesystems available for Linux; aufs is present in non-ancient kernels; unionfs-fuse is available wherever FUSE is. Aufs supports the root directory as the mount point, but Unionfs-fuse. For your use case, a union mount onto /usr should be sufficient.

  • 1
    aufs does support / as the mount point. There is fsprotect that does that, and I think that many live Linux distributions use it to overlay persistent data over an immutable root filesystem on read only media. The gymnastics you have to go through to obtain an aufs root filesystem are best done in early boot scripts of course, usually in the initramfs. – Celada May 31 '15 at 16:47
  • "It isn't working because you can't bind-mount a directory where it would shadow itself" - wrong. unshare -rm, mount --bind /tmp / succeeds. As does unshare -rm, mount --bind /usr/lib /usr. – sourcejedi Oct 13 '18 at 11:56

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.