#963 Issue closed: make it safe against wrong btrfs subvolumes on SLES12

Labels: enhancement, cleanup, fixed / solved / done

jsmeix opened issue at 2016-08-16 09:45:

This is a follow-up of https://github.com/rear/rear/issues/944
that intends to make it generically safe against btrfs subvolumes
which are wrongly created under the '@/.snapshots/' subvolume.

In https://github.com/rear/rear/issues/944 the specific wrongly
created '@/.snapshots/1/snapshot/var/lib/machines' subvolume
is skipped from recreation during "rear recover".

But that is neither a generic solution for SLES12
not is skipping during "rear recover" the best place.

This issue intends to do it better in two ways:

Any normal subvolume below '@/.snapshots/' is wrong there
(cf. https://github.com/rear/rear/issues/944#issuecomment-238239926
how to create a btrfs subvolume in compliance with
the SLES12 default brtfs structure)
so that any normal subvolume below '@/.snapshots/'
must be detected during "rear mkbackup"
and either automatically excluded from recreation
or perhaps "rear mkbackup" should even error out
in such cases.

This way the issue is handled for any such wrong subvolumes
(i.e. the 'any' makes it work generically for SLES12)
and the issue is detected early during "rear mkbackup"
when the user can fix his wrong subvolumes setup
(and not during "rear recover" when it is loo late to fix it).

jsmeix commented at 2016-08-16 10:09:

For the fun of it:

Here a script to create a normal btrfs subvolume
in compliance with the SLES12 default brtfs structure:

#!/bin/bash
set -u -e -o pipefail
# the code below fails if there is a leading slash:
mysubvol=${1#/}
# find out what subvolume on what device node is mounted at '/':
output=( $(findmnt -nrv -t btrfs -o TARGET,SOURCE,FSROOT | grep '^/ ' ) )
# TARGET is '/' (by grep)
# SOURCE is the device node that is mounted at the target '/':
device=${output[1]}
# FSROOT is the subvolume that is mounted at the target '/':
fsroot=${output[2]}
# if a '/@/.snapshots/...' subvolume is mounted at the target '/'
# we assume the SLE12 btrfs default structure is used:
if [[ $fsroot == "/@/.snapshots/"* ]] ; then
  # mount btrfs at its root subvolume:
  btrfsroot=$( mktemp -d /tmp/btrfsroot.XXXXXXXXXX )
  mount -t btrfs -o subvolid=0 $device $btrfsroot
  # create subvolume under /@/:
  mkdir -p $btrfsroot/@/$( dirname $mysubvol )
  btrfs subvolume create $btrfsroot/@/$mysubvol
  # btrfs at its root subvolume is no longer needed:
  umount $btrfsroot
  rmdir $btrfsroot
  # mount subvolume:
  output=( $( btrfs subvolume list -a / | grep "/@/$mysubvol" ) )
  id=${output[1]}
  mkdir -p /$mysubvol
  mount -t btrfs -o subvolid=$id $device /$mysubvol
  # make entry in /etc/fstab:
  if ! grep -q "subvol=@/$mysubvol" /etc/fstab ; then
    uuid=$( for l in /dev/disk/by-uuid/* ; do readlink -e $l | grep -q $device && basename $l ; done )
    echo "UUID=$uuid /$mysubvol btrfs subvol=@/$mysubvol 0 0" >>/etc/fstab
  fi
else
  echo "Unexpected exit: No '/@/.snapshots/...' subvolume mounted at '/'."
  exit 99
fi

Furthermore there is the "mksubvolume" command
that does basically the same:

# mksubvolume /var/lib/mystuff
# btrfs subvolume list -a / | grep mystuff
ID 296 gen 543 top level 257 path <FS_TREE>/@/var/lib/mystuff
# findmnt -t btrfs -o TARGET,SOURCE | grep mystuff
`-/var/lib/mystuff        /dev/sda2[/@/var/lib/mystuff]
# grep mystuff /etc/fstab 
UUID=... /var/lib/mystuff btrfs subvol=@/var/lib/mystuff 0 0

but currently mksubvolume has no support to automatically
create parent directories (cf. "mkdir -p" in the above script)

# mksubvolume /var/mystuff/mysubvol
failure (parent of target does not exist)

when the parent directory "/var/mystuff/" does not yet exist.

jsmeix commented at 2016-08-16 15:40:

With https://github.com/rear/rear/pull/966 merged
this issue is fixed - at least for me it runs like clockwork.


[Export of Github issue for rear/rear.]