File adaptions_for_btrfs_for_SLE12.diff of Package rear116.100
--- usr/share/rear/layout/save/GNU/Linux/23_filesystem_layout.sh.orig 2014-01-20 09:43:46.000000000 +0100
+++ usr/share/rear/layout/save/GNU/Linux/23_filesystem_layout.sh 2014-06-18 11:19:56.000000000 +0200
@@ -94,8 +94,178 @@ Log "Saving Filesystem layout."
# in case of btrfs we could deal with subvolumes - subvol option needed or not?
case "$fstype" in
btrfs)
- subvol=$(btrfs subvolume show $mountpoint | grep "Name:" | awk '{print $2}')
- [[ ! -z "$subvol" ]] && options="$options,subvol=$subvol"
+ # The below two commands seems to be made for Fedora 19 (cf. https://github.com/rear/rear/issues/233)
+ # but they do not work for SUSE SLE12 so that the following two commands are hereby disabled:
+ #subvol=$(btrfs subvolume show $mountpoint | grep "Name:" | awk '{print $2}')
+ #[[ ! -z "$subvol" ]] && options="$options,subvol=$subvol"
+ # Instead commands that work for SUSE SLE12 are run:
+ # Let's see what the SLE12 installer does when installing the original system
+ # when installing a SLE12 default system on one harddisk with btrfs
+ # (see https://bugzilla.novell.com/show_bug.cgi?id=879111):
+ # ----------------------------------------------------------------------------------------------------------------------------
+ # root@sle12 # grep -o 'Executing:"/sbin/btrfs.*' /var/log/YaST2/y2log-1
+ # Executing:"/sbin/btrfs filesystem show"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl/@'"
+ # Executing:"/sbin/btrfs subvolume list '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl'"
+ # Executing:"/sbin/btrfs subvolume set-default 257 '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/boot/grub2/i386-pc'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/boot/grub2/x86_64-efi'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/home'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/opt'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/srv'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/tmp'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/usr/local'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/var/crash'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/var/lib/mailman'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/var/lib/named'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/var/lib/pgsql'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/var/log'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/var/opt'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/var/spool'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/var/tmp'"
+ # ----------------------------------------------------------------------------------------------------------------------------
+ # root@sle12 # btrfs subvolume list -a /
+ # ID 257 gen 387 top level 5 path <FS_TREE>/@
+ # ID 258 gen 235 top level 257 path @/boot/grub2/i386-pc
+ # ID 259 gen 49 top level 257 path @/boot/grub2/x86_64-efi
+ # ID 260 gen 238 top level 257 path @/home
+ # ID 261 gen 30 top level 257 path @/opt
+ # ID 262 gen 238 top level 257 path @/srv
+ # ID 263 gen 390 top level 257 path @/tmp
+ # ID 264 gen 238 top level 257 path @/usr/local
+ # ID 265 gen 49 top level 257 path @/var/crash
+ # ID 266 gen 49 top level 257 path @/var/lib/mailman
+ # ID 267 gen 49 top level 257 path @/var/lib/named
+ # ID 268 gen 49 top level 257 path @/var/lib/pgsql
+ # ID 269 gen 391 top level 257 path @/var/log
+ # ID 270 gen 49 top level 257 path @/var/opt
+ # ID 271 gen 392 top level 257 path @/var/spool
+ # ID 272 gen 313 top level 257 path @/var/tmp
+ # ID 275 gen 376 top level 257 path @/.snapshots
+ # ID 276 gen 59 top level 275 path <FS_TREE>/@/.snapshots/1/snapshot
+ # ID 277 gen 121 top level 275 path <FS_TREE>/@/.snapshots/2/snapshot
+ # ID 278 gen 183 top level 275 path <FS_TREE>/@/.snapshots/3/snapshot
+ # ----------------------------------------------------------------------------------------------------------------------------
+ # root@sle12 # btrfs subvolume get-default /
+ # ID 257 gen 588 top level 5 path @
+ # ----------------------------------------------------------------------------------------------------------------------------
+ # root@sle12 # grep btrfs /etc/fstab
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 / btrfs defaults 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /boot/grub2/i386-pc btrfs subvol=@/boot/grub2/i386-pc 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /boot/grub2/x86_64-efi btrfs subvol=@/boot/grub2/x86_64-efi 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /home btrfs subvol=@/home 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /opt btrfs subvol=@/opt 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /srv btrfs subvol=@/srv 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /tmp btrfs subvol=@/tmp 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /usr/local btrfs subvol=@/usr/local 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /var/crash btrfs subvol=@/var/crash 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /var/lib/mailman btrfs subvol=@/var/lib/mailman 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /var/lib/named btrfs subvol=@/var/lib/named 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /var/lib/pgsql btrfs subvol=@/var/lib/pgsql 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /var/log btrfs subvol=@/var/log 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /var/opt btrfs subvol=@/var/opt 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /var/spool btrfs subvol=@/var/spool 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /var/tmp btrfs subvol=@/var/tmp 0 0
+ # UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /.snapshots btrfs subvol=@/.snapshots 0 0
+ # ----------------------------------------------------------------------------------------------------------------------------
+ # root@sle12 # mount | grep btrfs
+ # /dev/sda2 on / type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /.snapshots type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /var/tmp type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /var/opt type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /var/spool type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /var/log type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /var/lib/mailman type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /var/lib/pgsql type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /var/lib/named type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /var/crash type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /usr/local type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /opt type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /srv type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /home type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /tmp type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /boot/grub2/x86_64-efi type btrfs (rw,relatime,space_cache)
+ # /dev/sda2 on /boot/grub2/i386-pc type btrfs (rw,relatime,space_cache)
+ # ----------------------------------------------------------------------------------------------------------------------------
+ # Note that for SLE12 there is a somewhat hidden '/@' btrfs subvolume created
+ # (/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl/@')
+ # that is then made the default btrfs subvolume
+ # (/sbin/btrfs subvolume set-default 257 '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl')
+ # which results that a plain "btrfs subvolume list /" hides the '/@' in its output
+ # so that one must use "btrfs subvolume list -a /" plus "btrfs subvolume get-default /"
+ # to find out this hidden special '/@' btrfs subvolume.
+ # The default btrfs subvolume gets mounted when no subvolume is specified for the mount comand.
+ # This means the entry "UUID=7ab751c6-b075-4066-9403-c225fdda91d6 / btrfs defaults 0 0" in /etc/fstab
+ # belongs to the default btrfs subvolume '/@' that is mounted at the mount point '/'.
+ # According to https://btrfs.wiki.kernel.org/index.php/UseCases
+ # ---------------------------------------------------------------------------------------------------------------------
+ # How do I mount the real root of the filesystem once I've made another subvolume the default?
+ # mount -o subvolid=0 <filesystem> <mount-point>
+ # With kernel 3.2 and newer you can specify subvol=/some/PATH for the subvolume to mount
+ # mount -o subvol=/path/to/subvol /dev/sdx /mnt
+ # The PATH is always relative to the toplevel subvolume, ie. independent of currently set default subvolume.
+ # ---------------------------------------------------------------------------------------------------------------------
+ # the other entries in /etc/fstab like "UUID=7ab751c6-b075-4066-9403-c225fdda91d6 /home btrfs subvol=@/home 0 0"
+ # mount the btrfs subvolume '@/home' (relative to the toplevel subvolume) at the mount point '/home'
+ # where in case of btrfs the mount point '/home' is relative to '/' which is relative to the default subvolume.
+ # Because at '/' the default btrfs subvolume '/@' is already mounted it results in the end that
+ # the btrfs subvolume '@/home' gets mounted at the btrfs filesystem's absolute path '/@/home'
+ # where "the btrfs filesystem's absolute path" means the path from the btrfs filesystem toplevel point of view
+ # asshown in the following example (on a SLE12 default installation):
+ # ----------------------------------------------------------------------------------------------------------------------------
+ # root@sle12 # ls /
+ # bin boot dev etc home lib lib64 media mnt opt proc root run sbin selinux .snapshots srv sys tmp usr var
+ #
+ # root@sle12 # mkdir /tmp/btrfs-filesystem-toplevel
+ #
+ # root@sle12 # mount -t btrfs -o subvolid=0 /dev/sda2 /tmp/btrfs-filesystem-toplevel
+ #
+ # root@sle12 # ls /tmp/btrfs-filesystem-toplevel
+ # @
+ #
+ # root@sle12 # ls /tmp/btrfs-filesystem-toplevel/@
+ # bin boot dev etc home lib lib64 media mnt opt proc root run sbin selinux .snapshots srv sys tmp usr var
+ #
+ # root@sle12 # ls /home
+ # johannes
+ #
+ # root@sle12 # ls /tmp/btrfs-filesystem-toplevel/home
+ # ls: cannot access /tmp/btrfs-filesystem-toplevel/home: No such file or directory
+ #
+ # root@sle12 # ls /tmp/btrfs-filesystem-toplevel/@/home
+ # johannes
+ # ----------------------------------------------------------------------------------------------------------------------------
+ # This hidden '/@' btrfs subvolume and filesystem toplevel directory is specific for SLE12 (it is not in openSUSE 13.1).
+ # The following code works only for SLE12 because it uses the '@' as delimiter:
+ allsubvolumes=$( btrfs subvolume list -a $mountpoint | grep -o 'path [^ ]*' | cut -s -d '@' -f2 )
+ snapshotsubvolumes=$( btrfs subvolume list -as $mountpoint | grep -o 'path [^ ]*' | cut -s -d '@' -f2 )
+ # btrfs subvolumes can be nested, for example btrfs subvolumes could be like
+ # /normalsubvolume
+ # /snapshotsubvolume
+ # /basesubvolume
+ # /basesubvolume/subsubvolume
+ # /basesubvolume/subsnapshotsubvolume
+ # Therefore careful testing whether or not a subvolume is a "normal" subvolume or a snapshot subvolume
+ # is required to exclude snapshot subvolumes from being recreated because it is currently not possible
+ # to recreate btrfs snapshot subvolumes as snapshot subvolumes containing files with the content
+ # from the time when the original btrfs snapshot subvolumes have been created on the original system.
+ # Do not "optimize" the below simple and (hopefully) failsafe code unless you know exactly what you do:
+ for subvolume in $allsubvolumes
+ do for snapshot in $snapshotsubvolumes
+ do if test "$subvolume" = "$snapshot"
+ then subvolume=""
+ fi
+ done
+ if test -n "$subvolume"
+ then if test -z "$normalsubvolumes"
+ then normalsubvolumes="$subvolume"
+ else normalsubvolumes="$normalsubvolumes;$subvolume"
+ fi
+ fi
+ done
+ if test -n "$normalsubvolumes"
+ then options="$options,normalsubvolumes=$normalsubvolumes"
+ fi
;;
esac
echo -n " options=$options"
--- usr/share/rear/layout/prepare/GNU/Linux/13_include_filesystem_code.sh.orig 2013-12-20 15:51:30.000000000 +0100
+++ usr/share/rear/layout/prepare/GNU/Linux/13_include_filesystem_code.sh 2014-06-18 15:36:07.000000000 +0200
@@ -91,10 +91,18 @@ EOF
fi
;;
btrfs)
+ if test "/" != "$mp"
+ then
+ LogPrint "Skipping creating $fstype filesystem on $device because mountpoint $mp is not / (for SLE12 btrfs is only supported for /)"
+ else
cat >> $LAYOUT_CODE <<EOF
LogPrint "Creating $fstype-filesystem $mp on $device"
# if $device is already mounted, skip
-mount | grep -q $device || mkfs -t $fstype $device
+# mkfs.btrfs needs an explicit '-f' (same as mkfs.xfs) to
+# force overwrite when an existing filesystem is detected
+# otherwise "rear recover" fails here with an error
+# see https://bugzilla.novell.com/show_bug.cgi?id=878870
+mount | grep -q $device || mkfs -t $fstype -f $device
EOF
if [ -n "$label" ] ; then
echo "mount | grep -q $device || btrfs filesystem label $device $label >&2" >> $LAYOUT_CODE
@@ -121,7 +129,8 @@ EOF
fi # end of [ "$uuid" != "\$new_uuid" ]
EOF
fi
- ;;
+ fi
+ ;;
vfat)
cat >> $LAYOUT_CODE <<EOF
LogPrint "Creating $fstype-filesystem $mp on $device"
@@ -170,33 +179,122 @@ EOF
case $fstype in
btrfs)
- # check the $value for subvols (other then root)
- subvol=$(echo $value | awk -F, '/subvol=/ { print $NF}') # empty or something like 'subvol=root'
- if [ -z "$subvol" ]; then
- echo "mkdir -p /mnt/local$mp" >> $LAYOUT_CODE
- echo "mount$mountopts $device /mnt/local$mp" >> $LAYOUT_CODE
- elif [ "$subvol" = "subvol=root" ]; then
- echo "# btrfs subvolume 'root' is a special case" >> $LAYOUT_CODE
- echo "# before we can create subvolumes we must mount a btrfs device on /mnt" >> $LAYOUT_CODE
- echo "mount | grep btrfs | grep -q '/mnt' || mount $device /mnt" >> $LAYOUT_CODE
- echo "# create the root btrfs subvolume" >> $LAYOUT_CODE
- echo "btrfs subvolume create /mnt/root" >> $LAYOUT_CODE
- echo "mkdir -p /mnt/local$mp" >> $LAYOUT_CODE
- echo "# umount subvol 0 as it will be remounted as /mnt/local" >> $LAYOUT_CODE
- echo "umount /mnt" >> $LAYOUT_CODE
- echo "mount$mountopts $device /mnt/local$mp" >> $LAYOUT_CODE
- else
- echo "# btrfs subvolume creates sub-directory itself" >> $LAYOUT_CODE
- echo "btrfs subvolume create /mnt/local$mp" >> $LAYOUT_CODE
- # just mounting it with subvol=xxx will probably fail with an cryptic error:
- # mount: mount(2) failed: No such file or directory
- # we need to mount it with its subvol-id - not a joke
- # even its not yet mounted we can view it - see http://www.funtoo.org/BTRFS_Fun
- echo "btrfs_id=\$(btrfs subvolume list /mnt/local$mp | tail -1 | awk '{print \$2}')" >> $LAYOUT_CODE
- echo "mountopts=\" -o subvolid=\${btrfs_id}\"" >> $LAYOUT_CODE
- echo "mount\$mountopts $device /mnt/local$mp" >> $LAYOUT_CODE
+ if test "/" != "$mp"
+ then
+ LogPrint "Skipping creating $fstype filesystem on $device because mountpoint $mp is not / (for SLE12 btrfs is only supported for /)"
+ else
+ # The below commands seems to be made for Fedora 19 (cf. https://github.com/rear/rear/issues/233)
+ # but they do not work for SUSE SLE12 so that the following commands are hereby disabled:
+ ## check the $value for subvols (other then root)
+ #subvol=$(echo $value | awk -F, '/subvol=/ { print $NF}') # empty or something like 'subvol=root'
+ #if [ -z "$subvol" ]; then
+ # echo "mkdir -p /mnt/local$mp" >> $LAYOUT_CODE
+ # echo "mount$mountopts $device /mnt/local$mp" >> $LAYOUT_CODE
+ #elif [ "$subvol" = "subvol=root" ]; then
+ # echo "# btrfs subvolume 'root' is a special case" >> $LAYOUT_CODE
+ # echo "# before we can create subvolumes we must mount a btrfs device on /mnt" >> $LAYOUT_CODE
+ # echo "mount | grep btrfs | grep -q '/mnt' || mount $device /mnt" >> $LAYOUT_CODE
+ # echo "# create the root btrfs subvolume" >> $LAYOUT_CODE
+ # echo "btrfs subvolume create /mnt/root" >> $LAYOUT_CODE
+ # echo "mkdir -p /mnt/local$mp" >> $LAYOUT_CODE
+ # echo "# umount subvol 0 as it will be remounted as /mnt/local" >> $LAYOUT_CODE
+ # echo "umount /mnt" >> $LAYOUT_CODE
+ # echo "mount$mountopts $device /mnt/local$mp" >> $LAYOUT_CODE
+ #else
+ # echo "# btrfs subvolume creates sub-directory itself" >> $LAYOUT_CODE
+ # echo "btrfs subvolume create /mnt/local$mp" >> $LAYOUT_CODE
+ # # just mounting it with subvol=xxx will probably fail with an cryptic error:
+ # # mount: mount(2) failed: No such file or directory
+ # # we need to mount it with its subvol-id - not a joke
+ # # even its not yet mounted we can view it - see http://www.funtoo.org/BTRFS_Fun
+ # echo "btrfs_id=\$(btrfs subvolume list /mnt/local$mp | tail -1 | awk '{print \$2}')" >> $LAYOUT_CODE
+ # echo "mountopts=\" -o subvolid=\${btrfs_id}\"" >> $LAYOUT_CODE
+ # echo "mount\$mountopts $device /mnt/local$mp" >> $LAYOUT_CODE
+ #fi
+ # Instead commands that work for SUSE SLE12 are run:
+ # When there are btrfs subvolumes $mountopts contains them in the form (cf. the example below) without the ':
+ # ' -o rw,relatime,space_cache,normalsubvolumes=/normalsubvolume;/basesubvolume;/basesubvolume/subsubvolume'
+ # so that the btrfs subvolumes must be removed from $mountopts:
+ realmountopts=$( echo $mountopts | sed -e 's/,normalsubvolumes=[^,]*//' )
+ # In the example realmountopts is now '-o rw,relatime,space_cache' (no longer with a leading ' ').
+ # The following two commands are basically the same (realmountopts versus mountopts) as in the default/fallback case:
+ echo "mkdir -p /mnt/local$mp" >> $LAYOUT_CODE
+ echo "mount -t btrfs $realmountopts $device /mnt/local$mp" >> $LAYOUT_CODE
+ # Remember what the SLE12 installer does when installing the original system
+ # when installing a SLE12 default system on one harddisk with btrfs
+ # (see the comment in usr/share/rear/layout/save/GNU/Linux/23_filesystem_layout.sh):
+ # -------------------------------------------------------------------------------------------------------
+ # # grep -o 'Executing:"/sbin/btrfs.*' /var/log/YaST2/y2log-1
+ # Executing:"/sbin/btrfs filesystem show"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl/@'"
+ # Executing:"/sbin/btrfs subvolume list '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl'"
+ # Executing:"/sbin/btrfs subvolume set-default 257 '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl'"
+ # Executing:"/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-YH5GVp/@/boot/grub2/i386-pc'"
+ # ...
+ # -------------------------------------------------------------------------------------------------------
+ # This means that for SLE12 there is a mysterious '/@' btrfs subvolume created
+ # (/sbin/btrfs subvolume create '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl/@')
+ # that is then made the default btrfs subvolume
+ # (/sbin/btrfs subvolume set-default 257 '/tmp/libstorage-9vKYd4/tmp-mp-IoBzwl').
+ # This hidden '/@' btrfs subvolume is specific for SLE12 (it is not in openSUSE 13.1).
+ # Therefore the following code works only for SLE12:
+ echo "# Creating SLE12 specific '/@' btrfs subvolume" >> $LAYOUT_CODE
+ echo "btrfs subvolume create /mnt/local/@" >> $LAYOUT_CODE
+ echo "# Making the '/@' subvolume the default subvolume" >> $LAYOUT_CODE
+ echo "# The '/@' subvolume is currently the only subvolume" >> $LAYOUT_CODE
+ echo "# Get the ID of the '/@' subvolume to set it as default subvolume" >> $LAYOUT_CODE
+ echo "subvolumeID=\$( btrfs subvolume list /mnt/local | head -n1 | cut -d ' ' -f2 )" >> $LAYOUT_CODE
+ echo "# Set the '/@' subvolume as default subvolume using its subvolume ID" >> $LAYOUT_CODE
+ echo "btrfs subvolume set-default \$subvolumeID /mnt/local" >> $LAYOUT_CODE
+ # After the '/@' subvolume was set as default subvolume,
+ # remount the btrfs filesystem where currently the filesystem toplevel is mounted at /mnt/local/
+ # but now the '/@' default subvolume must be mounted at /mnt/local/:
+ echo "# Remount the '/@' default subvolume at /mnt/local/" >> $LAYOUT_CODE
+ echo "umount /mnt/local$mp" >> $LAYOUT_CODE
+ echo "mount -t btrfs $realmountopts $device /mnt/local$mp" >> $LAYOUT_CODE
+ # Recreate "normal" btrfs subvolumes (btrfs snapshot subvolumes have been excluded):
+ # btrfs subvolumes can be nested, for example btrfs subvolumes could be like
+ # /subvolume
+ # /basesubvolume
+ # /basesubvolume/subsubvolume
+ # The subvolumes in the above example would be provided as an option in $value of the form
+ # this=foo,normalsubvolumes=/subvolume;/basesubvolume;/basesubvolume/subsubvolume,that=bar
+ # options in $value are separated by ',' and the subvolumes are separated by '=' and ';'
+ # which will fail when there are subvolumes with ',' or '=' or ';' in its name
+ # so that admins who use such characters for their subvolume names get hereby
+ # an exercise in using failsafe names and/or how to fix quick and dirty code ;-)
+ # The sorting makes sure that /basesubvolume comes before /basesubvolume/subsubvolume
+ # so that /basesubvolume gets created before /basesubvolume/subsubvolume:
+ normalsubvolumes=$( echo $value | grep -o 'normalsubvolumes=[^,]*' | cut -d '=' -f2 | tr ';' '\n' | sort )
+ # In the example normalsubvolumes contains now "/basesubvolume\n/basesubvolume/subsubvolume\n/subvolume"
+ if test -n "$normalsubvolumes"
+ then echo "# Begin creating and mounting normal btrfs subvolumes..." >> $LAYOUT_CODE
+ for subvolume in $normalsubvolumes
+ do if test -n "$subvolume"
+ then
+ # e.g. for "btrfs subvolume create /foo/bar/baz" /foo/bar/ must exist
+ # but "baz" must not exist because btrfs subvolume creates "baz" itself
+ # when "baz" already exists, it fails with "ERROR: '/foo/bar/baz' exists".
+ subvolumepath=${subvolume%/*}
+ if test -n "$subvolumepath"
+ then echo "# Creating '$subvolumepath' directory" >> $LAYOUT_CODE
+ echo "mkdir -p /mnt/local/$subvolumepath" >> $LAYOUT_CODE
+ fi
+ echo "# btrfs subvolume creates last (sub-)directory in '$subvolume' itself" >> $LAYOUT_CODE
+ echo "# Creating btrfs subvolume '$subvolume' as '@$subvolume'" >> $LAYOUT_CODE
+ echo "btrfs subvolume create /mnt/local/$subvolume" >> $LAYOUT_CODE
+ echo "# Creating '$subvolume' mountpoint" >> $LAYOUT_CODE
+ echo "mkdir -p /mnt/local/$subvolume" >> $LAYOUT_CODE
+ echo "# Mounting btrfs subvolume '@$subvolume' at '$subvolume' mountpoint" >> $LAYOUT_CODE
+ # Note that the subvolume path for the subvol mount option is relative to the toplevel subvolume
+ # and the toplevel subvolume is the default subvolume that was above set to /mnt/local:
+ echo "mount -t btrfs -o subvol=@$subvolume $realmountopts $device /mnt/local$subvolume" >> $LAYOUT_CODE
+ fi
+ done
+ echo "# End creating and mounting normal btrfs subvolumes." >> $LAYOUT_CODE
fi
- ;;
+ fi
+ ;;
*)
echo "mkdir -p /mnt/local$mp" >> $LAYOUT_CODE
echo "mount$mountopts $device /mnt/local$mp" >> $LAYOUT_CODE
--- usr/share/rear/layout/prepare/default/61_exclude_from_restore.sh.orig 2012-02-23 16:57:55.000000000 +0100
+++ usr/share/rear/layout/prepare/default/61_exclude_from_restore.sh 2014-07-04 11:50:40.000000000 +0200
@@ -5,6 +5,55 @@
: > $TMP_DIR/restore-exclude-list.txt
for component in "${EXCLUDE_RECREATE[@]}" ; do
+ if test "fs" = ${component%%:*}
+ then # Skip filesystem components that are btrfs subvolumes from being
+ # automatically added to restore-exclude-list.txt
+ # because btrfs subvolumes should be listed in EXCLUDE_RECREATE
+ # to avoid that "rear recover" is 'Creating btrfs-filesystem'
+ # by default also for every mounted btrfs subvolume
+ # see https://bugzilla.novell.com/show_bug.cgi?id=885698
+ # For SLE12 by default EXCLUDE_RECREATE should contain that components:
+ # fs:/.snapshots fs:/var/tmp fs:/var/spool fs:/var/opt fs:/var/log
+ # fs:/var/lib/pgsql fs:/var/lib/mailman fs:/var/lib/named fs:/usr/local
+ # fs:/tmp fs:/srv fs:/var/crash fs:/boot/grub2/x86_64-efi fs:/opt
+ # fs:/home fs:/boot/grub2/i386-pc
+ # Because that script is run in the rear recovery system the recreated system
+ # and in particular the recreated btrfs subvolumes are under /mnt/local/
+ # But e.g. "btrfs subvolume show /mnt/local/.snapshots" cannot be used
+ # to find out whether or not /mnt/local/.snapshots is a recreated btrfs subvolume
+ # because when e.g. "btrfs subvolume show /mnt/local/.snapshots" is run it results
+ # ERROR: finding real path for '/mnt/local//.snapshots', No such file or directory
+ # because at the time when this script runs in the rear recovery system the
+ # real path '/mnt/local//.snapshots' (the duplicate '//' does not matter)
+ # does really not (yet) exist because this script runs before the partitions
+ # and filesystems and btrfs subvolumes are created by "rear recover".
+ # Instead of checking for btrfs subvolumes a more generic check is done that
+ # matches the special /etc/rear/local.conf for SLE12 with btrfs where
+ # files in btrfs subvolumes are excluded by 'tar --one-file-system'
+ # so that such files must be explictly included to be in the backup via
+ # BACKUP_PROG_INCLUDE that should for SLE12 contain something like such entries:
+ # /var/spool/* /var/opt/* /var/log/* /var/lib/pgsql/* /var/lib/mailman/*
+ # /var/lib/named/* /usr/local/* /srv/* /boot/grub2/x86_64-efi/* /opt/*
+ # /home/* /boot/grub2/i386-pc/*
+ # Accordingly the more generic check is to skip filesystem components
+ # in EXCLUDE_RECREATE that have a matching entry in BACKUP_PROG_INCLUDE
+ # from being automatically added to restore-exclude-list.txt
+ component_directory="${component#*:}"
+ for backup_directory in "${BACKUP_PROG_INCLUDE[@]}"
+ do # For example a component_directory like /var/spool or /var/spool/ should match
+ # a backup_directory like /var/spool or /var/spool/ or /var/spool/*
+ # but it should not get mixed up with /var or /var/ or /var/*
+ backup_directory_without_trailing_asterisk="${backup_directory%\*}"
+ backup_directory_without_trailing_slash="${backup_directory_without_trailing_asterisk%/}"
+ backup_directory_plain="$backup_directory_without_trailing_slash"
+ component_directory_without_trailing_slash="${component_directory%/}"
+ component_directory_plain="$component_directory_without_trailing_slash"
+ if test "$component_directory_plain" = "$backup_directory_plain"
+ then # Continue the outer loop (i.e. contune with the next component in EXCLUDE_RECREATE):
+ continue 2
+ fi
+ done
+ fi
if ! IsInArray "$component" "${EXCLUDE_RESTORE}" ; then
EXCLUDE_RESTORE=( "${EXCLUDE_RESTORE[@]}" "$component" )
fi