systemd-nspawn has an interesting
--ephemeral option that sets up temporary
copy-on-write filesystem snapshots on filesystems that support it, like btrfs.
Using copy on write means that one could perform maintenance on the source chroots, without disrupting existing CI sessions.
btrfs and copy on write
btrfs snapshots work on subvolumes.
As I understand it, if one uses
btrfs subvolume create instead of
what is inside the resulting directory is managed as a subvolume that can be
snapshotted and managed in all sorts of interesting ways.
I managed to delete a subvolume equally well with
btrfs subvolume delete and
btrfs subvolume snapshot src dst is similar to
cp -a, but it makes a
copy-on-write snapshot of a btrfs subvolume.
If I change nspawn-runner to manage each chroot in its own subvolume, I should
be able to build on all these features, and
systemd-nspawn should be able to
do that, too.
There's a cute shortcut to migrate a subdirectory to a subvolume: create the
subvolume, then use
cp -r --reflink to populate the subvolume with the
systemd-nspawn and btrfs
systemd-nspawn makes it do all the transient
copy-on-write work automatically:
# systemd-nspawn -xD buster Spawning container buster-7fd47ac79296c5d3 on /var/lib/nspawn-runner/t/.#machine.buster0939fbc61fcbca28. Press ^] three times within 1s to kill container. root@buster-7fd47ac79296c5d3:~# mkdir foo root@buster-7fd47ac79296c5d3:~# ls -la total 12 drwx------ 1 root root 62 Mar 13 16:30 . drwxr-xr-x 1 root root 154 Mar 13 16:26 .. -rw------- 1 root root 102 Mar 13 16:26 .bash_history -rw-r--r-- 1 root root 570 Mar 13 16:26 .bashrc -rw-r--r-- 1 root root 148 Mar 13 16:26 .profile drwxr-xr-x 1 root root 0 Mar 13 16:30 foo root@buster-7fd47ac79296c5d3:~# logout Container buster-7fd47ac79296c5d3 exited successfully. root@runner2:/var/lib/nspawn-runner/t# ls -la buster/root/ totale 12 drwx------ 1 root root 56 mar 13 16:26 . drwxr-xr-x 1 root root 154 mar 13 16:26 .. -rw------- 1 root root 102 mar 13 16:26 .bash_history -rw-r--r-- 1 root root 570 mar 13 16:26 .bashrc -rw-r--r-- 1 root root 148 mar 13 16:26 .profile
It also works on a directory that is not a subvolume, making reflinks of its contents instead of a subvolume snapshot, although this has a performance penalty on setup:
Snapshotting a subvolume:
# time systemd-nspawn -xD buster ls Spawning container buster-7ab8f4123420b5d5 on /var/lib/nspawn-runner/t/.#machine.bustercd54ef4971229ff5. Press ^] three times within 1s to kill container. bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var Container buster-7ab8f4123420b5d5 exited successfully. real 0m0,164s user 0m0,032s sys 0m0,014s
Reflink-ing a subdirectory:
# time systemd-nspawn -xD buster ls Spawning container buster-ebc9dc77db0c972d on /var/lib/nspawn-runner/.#machine.buster2ecbcbd1a1a058b8. Press ^] three times within 1s to kill container. bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var Container buster-ebc9dc77db0c972d exited successfully. real 0m3,022s user 0m0,326s sys 0m2,406s
Detecting filesystem type
I can change nspawn-runner to use btrfs-specific features only when
/var/lib/nspawn-runner is on btrfs. Here's a command to detect the filesystem
# stat -f -c %T /var/lib/nspawn-runner/ btrfs
I've refactored nspawn-runner splitting backend and frontend code, and
implementing multiple backends based on what's the filesystem type of
It works really nicely, and with no special configuration required: if
/var/lib/nspawn-runner is on btrfs, things run faster, with less kludges, and
one can do maintenance on the base chroots without interfering with running CI
The next step is making it easier to configure
and maintain chroots. For example, it should be possible to maintain a rolling
sid chroot without the need to manually log into it to run