Short answer -- there is as far as I know no out of the box working solution for your specific requirements. You will have to adjust each initramfs of each distribution to support your specific needs.
Long answer -- yes it is possible. Nowadays most Linux distributions use an initramfs which will be loaded into memory by the bootloader and then unpacked by the kernel. There it will run /sbin/init
which is responsible for setting up the early userspace (running udev, loading modules, starting plymouth, asking for crypto passphrase, setting up the network for network mounts, … you name it). As you can run your own scripts and evaluate custom boot parmaters.
Example for Debian
If you are using Debian (should be the same with Ubuntu) you should be able to place a script in /etc/initramfs-tools/scripts/init-bottom/
which will be executded before init is started. For more information about the script, the different directories and the layout have a look at man initramfs-tools. You will have to adjust rootmnt
and add the target directory.
Sample (untested) script which should be installed either as /etc/initramfs-tools/scripts/local-bottom/00-myroot
or /usr/share/initramfs-tools/scripts/init-top/00-myroot
:
#!/bin/sh -e
PREREQS=""
prereqs() { echo "$PREREQS"; }
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
for opt in $(cat /proc/cmdline); do
case $opt in
rootdir=*)
new_mntdir="${opt#rootdir=}"
;;
esac
done
if [ -n "$new_mntdir" ] ; then
echo rootmnt="$rootmnt/$new_mntdir" >> /conf/param.conf
fi
The idea is to adjust rootmnt
which is used in the initramfs init
script to start/execute the real init. As the root device is already mounted in the init-bootom
stage you can just adjust/alter the target directory.
To use this script just add a new boot parameter, copy the script, make it executable, regenerate your initramfs and add a boot parameter for your Linux distribution, e.g. rootdir=/Ubuntu_Precise
.
An attempt at an online solution, but its not quite there.
The setup (in e.g. /tmp
directory, as root):
LOWER=$HOME
mkdir u1 w1 o1 O
mount -t overlay overlay -o lowerdir=$LOWER,upperdir=u1,workdir=w1 o1
mount --bind o1 O
Then you can work in O
directory, which is an overlay over $LOWER
. When you want to do the snapshot:
mkdir u2 w2 o2
mount -t overlay overlay -o lowerdir=o1,upperdir=u2,workdir=w2 o2
(Note that nested overlays like this won't work on older kernels).
But then I want some way to atomically change the bind mount at O
to point to o2
instead of o1
. I don't know how to do this other than:
umount O
mount --bind o2 O
(Not atomic; there is a window where O
is unmounted).
Ideally, running processes could continue to run without knowing that the underlying filesystem of O
had changed from o1
to o2
. I don't know if this is possible, or whether changing the underlying filesystem of O
like this will disrupt open applications too much. I need to investigate further.
Then, once O
has been redirected to o2
, we can remount o1
read-only as a precaution, then perform an offline merge using for example rdiffdir or overlayfs-tools.
Finally, we would want some way to atomically remount o2
as lowerdir=$HOME,upperdir=u2,workdir=w2
so that o1
, u1
and w1
(all now empty dirs) could be removed. Again, I don't know if this is possible.
Otherwise, we can achieve snapshots by just nesting overlays deeper and deeper and leaving the overlay and upper dirs for each mounted without attempting to merge or cleanup. But there is probably a limit to the number of nested overlays that can be mounted. And at some point, we still need to merge the layers downwards if we want to persist changes.
Best Answer
Apparently, many tools (among them udev) will soon require a /run/ directory that is mounted early (as tmpfs). Arch developers introduced /run last month to prepare for this.
There is more detail here: http://www.h-online.com/open/news/item/Linux-distributions-to-include-run-directory-1219006.html
[1] From thread on the Arch Projects ML