[systemd-devel] systemd-tmpfiles subvolume handling vs. changing default btrfs root

Ignaz Forster iforster at suse.de
Wed Jun 27 11:02:47 UTC 2018


Hello,

when using systemd-tmpfiles' feature to create subvolumes it will always 
create the new subvolume as a child of the subvolume of the given path. 
This however may not always be the expected parent, especially when 
using btrfs snapshots to switch between various system states.

Example layout:
===============

Let's assume the following subvolume layout (a simplified openSUSE layout):

ID	parent	top level	path	
--	------	---------	----
257	5	5		<FS_TREE>/@
258	257	257		<FS_TREE>/@/var
259	257	257		<FS_TREE>/@/.snapshots/1/snapshot
260	257	257		<FS_TREE>/@/.snapshots/2/snapshot
261	257	257		<FS_TREE>/@/.snapshots/3/snapshot

A corresponding /etc/fstab could look like this:

/dev/sdx	/	btrfs	defaults	0	0
/dev/sdx	/var	btrfs	subvol=@/var	0	0

with the default btrfs subvolume set to "261".
The third snapshot would thus be the root file system, with /var mounted 
on top of it.


The problem:
============

Creating "/var/test" would create a new entry like
262	258	258		@/var/test
as expected.
However creating "/opt" would create an entry similar to the following:
263	261	261		@/.snapshots/3/snapshot/opt

This is not good, as two things will happen now:
* When changing the snapshot (e.g. by reverting back to an old snapshot 
or creating a new one) /opt won't be visible any more (without manually 
mounting it), as it is not nested into the existing structure any more
* The third snapshot cannot be deleted without removing the subvolume first


Possible solutions:
===================

Let's have a look at the default btrfs layouts of some distributions.

Fedora 28 (Server):
ID	parent	top lvl	path	
--	------	-------	----	
257	5	5	<FS_TREE>/root

Ubuntu 18.04:
257	5	5	<FS_TREE>/@
258	5	5	<FS_TREE>/@home

openSUSE Leap 15:
257	5	5	<FS_TREE>/@
258	257	257	<FS_TREE>/@/var
259	257	257	<FS_TREE>/@/usr/local
260	257	257	<FS_TREE>/@/tmp
261	257	257	<FS_TREE>/@/srv
262	257	257	<FS_TREE>/@/root
263	257	257	<FS_TREE>/@/opt
264	257	257	<FS_TREE>/@/home
265	257	257	<FS_TREE>/@/boot/grub2/x86_64-efi
266	257	257 	<FS_TREE>/@/boot/grub2/i386-pc
267	257	257	<FS_TREE>/@/.snapshots
411	267	267	<FS_TREE>/@/.snapshots/138/snapshot
412	267	267	<FS_TREE>/@/.snapshots/139/snapshot


Option 1:
---------
Go back the path and check for subvolumes where the parent ID is "5". 
This would work for the default btrfs layout of these three 
distributions and is easy to implement, but would break in the 
hypothetical case if someone would create snapshot directories directly 
as children of ID 5, e.g.
257	5	5	<FS_TREE>/@
258	5	5	<FS_TREE>/@home
259	5	5	<FS_TREE>/@snapshot1

Option 2:
---------
A variant would be to keep the current behaviour except when the parent 
ID would be a snapshot (by checking if a parent UUID is set?); in this 
case the snapshot would be created as a child of ID 5.

I can't think of any case where automatically creating a subvolume below 
a snapshot is a good idea, so in theory this sounds like best approach.


In any case a corresponding implementation would mean additional 
handling for generating an fstab entry and mounting the subvolume if the 
subvolume is not created as a subdirectory of an existing subvolume.


Would this be an approach that would be acceptable upstream? Please note 
that I'm not a btrfs expert, so I may be missing something.
-- 
Ignaz Forster <iforster at suse.com>
Research Engineer
SUSE Linux GmbH, Maxfeldstr. 5, D-90409 Nürnberg
Tel: +49-911-74053-281;  https://www.suse.com/
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard,
Graham Norton, HRB 21284 (AG Nürnberg)


More information about the systemd-devel mailing list