diff --git a/fix-machines-subvol-for-rollbacks.sh b/fix-machines-subvol-for-rollbacks.sh new file mode 100644 index 00000000..7bdf5d2c --- /dev/null +++ b/fix-machines-subvol-for-rollbacks.sh @@ -0,0 +1,110 @@ +#! /bin/bash +# +# This is used to initially create /var/lib/machines subvolume in case +# the system we're running on is using BTRFS with the specific layout +# used by snapper to perform snapshots, rollbacks, etc... +# +# Unfortunately some distros (TW) already shipped versions with +# systemd creating a plain subvolume which breaks snapper. +# +# If /var/lib/machines is already populated then it's going to be +# pretty ugly to convert the old subvolume into a new one specially +# since it can be in use. +# +# Hopefully not a lot of users are using machinectl to import +# container/VM images. So in most of the cases this directory should +# be empty and we can then simple delete the subvolume and create a +# new one respecting the snapper layout. +# +# In the rare case where /var/lib/machines is populated, we will warn +# the user and let him fix it manually. +# +# In order to avoid ugly dependencies added in systemd package, this +# script should only be called during package updates when +# mksubvolume(8) is available. During installation, /var/lib/machines +# is supposed to be created by the installer now. +# +# See bsc#992573 +# + +warn() { + echo >&2 "warning: $@" +} + +is_btrfs_subvolume() { + # On btrfs subvolumes always have the inode 256 + test $(stat --format=%i "$1") -eq 256 +} + +# This assumes the directory/subvol is emptied by the caller. +rm_subvolume_or_directory() { + is_btrfs_subvolume "$1" && { + btrfs subvolume delete "$1" + return + } + rmdir "$1" +} + +on_exit() { + # Simply print a common error message in case something went + # wrong. + if test $? -ne 0; then + warn "Please fix /var/lib/machines manually." + # FIXME: point to a documentation explaining how to do + # that. + exit 1 + fi +} + +# +# If something is already mounted don't try to fix anything, the +# subvolume has already been created by either mksubvolume(8) or by +# the admin. In the later case we don't want to screw up his setup. +# +if mountpoint -q /var/lib/machines; then + exit +fi + +# +# Let's try to figure out if the current filesystem uses a Snapper +# BTRFS specific layout. Note that TW uses a different layout than +# SLE... +# +# FIXME: not sure if it's correct, reliable or optimal. +# +case $(findmnt -nr -t btrfs -o FSROOT / 2>/dev/null) in +*.snapshots/*/snapshot*) + ;; +*) + exit 0 +esac + +trap on_exit EXIT + +if test -d /var/lib/machines; then + # + # Ok, we're on a system supporting rollbacks and + # /var/lib/machines is not a subvolume remotely mounted so it + # cannot be suitable for systems supporting rollback. Fix it. + # + echo "Making /var/lib/machines suitable for rollbacks..." + + type mksubvolume >/dev/null 2>&1 || { + warn "mksubvolume(8) is not installed, aborting." + exit 1 + } + test "$(ls -A /var/lib/machines/)" && { + warn "/var/lib/machines is not empty, aborting." + exit 1 + } + + echo "Deleting empty /var/lib/machines directory/subvolume" + rm_subvolume_or_directory /var/lib/machines || { + warn "fail to delete /var/lib/machines" + exit 1 + } +fi + +# At this point /var/lib/machines shouldn't exist. +echo "Creating /var/lib/machines subvolume suitable for rollbacks." +mksubvolume /var/lib/machines diff --git a/systemd-mini.changes b/systemd-mini.changes index 4fc7896d..5d067a28 100644 --- a/systemd-mini.changes +++ b/systemd-mini.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Aug 23 10:12:13 UTC 2016 - fbui@suse.com + +- Add a script to fix /var/lib/machines to make it suitable for + rollbacks (bsc#992573992573) + ------------------------------------------------------------------- Wed Aug 10 11:30:50 UTC 2016 - meissner@suse.com diff --git a/systemd-mini.spec b/systemd-mini.spec index bf7dcf2c..41bcb763 100644 --- a/systemd-mini.spec +++ b/systemd-mini.spec @@ -148,6 +148,7 @@ Source9: nss-myhostname-config Source10: macros.systemd.upstream Source11: after-local.service Source12: systemd-sysv-install +Source13: fix-machines-subvol-for-rollbacks.sh Source1065: systemd-remount-tmpfs @@ -840,8 +841,12 @@ ln -s ../after-local.service %{buildroot}/%{_prefix}/lib/systemd/system/multi-us mkdir -p %{buildroot}%{_localstatedir}/lib/systemd/backlight > %{buildroot}%{_localstatedir}/lib/systemd/random-seed -# machined -mkdir -p %{buildroot}%{_localstatedir}/lib/machines +# On systems supporting rollbacks with btrfs, /var/lib/machines +# subvolume must be created differently. Normally the installer takes +# care of this now but some systems uses a plain subvolume that breaks +# snapshots, rollback ("nearly everything" see bsc#992573). This +# script should help fixing it. +install -m 755 %{S:13} %{buildroot}/%{_prefix}/lib/systemd/ %fdupes -s %{buildroot}%{_mandir} @@ -987,6 +992,13 @@ enabled) ;; *) rm -f %{_prefix}/lib/systemd/system/tmp.mount esac +# Convert /var/lib/machines subvolume to make it suitable for +# rollbacks, if needed. See bsc#992573. The installer has been fixed +# to create it at installation time. +if [ $1 -gt 1 ]; then + %{_prefix}/lib/systemd/fix-machines-subvol-for-rollbacks.sh +fi + %postun /sbin/ldconfig if [ $1 -ge 1 ]; then @@ -1229,6 +1241,7 @@ exit 0 %endif %{_prefix}/lib/systemd/systemd-* %{_prefix}/lib/systemd/systemd +%{_prefix}/lib/systemd/fix-machines-subvol-for-rollbacks.sh %dir %{_prefix}/lib/systemd/catalog %{_prefix}/lib/systemd/catalog/systemd.catalog %{_prefix}/lib/systemd/catalog/systemd.*.catalog @@ -1410,7 +1423,6 @@ exit 0 %{_datadir}/zsh/site-functions/* %ghost %{_localstatedir}/lib/systemd/backlight %ghost %{_localstatedir}/lib/systemd/random-seed -%dir %{_localstatedir}/lib/machines %if %{with resolved} %{_sysconfdir}/dbus-1/system.d/org.freedesktop.resolve1.conf %{_sysconfdir}/systemd/resolved.conf diff --git a/systemd.changes b/systemd.changes index 4fc7896d..5d067a28 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Aug 23 10:12:13 UTC 2016 - fbui@suse.com + +- Add a script to fix /var/lib/machines to make it suitable for + rollbacks (bsc#992573992573) + ------------------------------------------------------------------- Wed Aug 10 11:30:50 UTC 2016 - meissner@suse.com diff --git a/systemd.spec b/systemd.spec index ce853c2f..90da8619 100644 --- a/systemd.spec +++ b/systemd.spec @@ -143,6 +143,7 @@ Source9: nss-myhostname-config Source10: macros.systemd.upstream Source11: after-local.service Source12: systemd-sysv-install +Source13: fix-machines-subvol-for-rollbacks.sh Source1065: systemd-remount-tmpfs @@ -835,8 +836,12 @@ ln -s ../after-local.service %{buildroot}/%{_prefix}/lib/systemd/system/multi-us mkdir -p %{buildroot}%{_localstatedir}/lib/systemd/backlight > %{buildroot}%{_localstatedir}/lib/systemd/random-seed -# machined -mkdir -p %{buildroot}%{_localstatedir}/lib/machines +# On systems supporting rollbacks with btrfs, /var/lib/machines +# subvolume must be created differently. Normally the installer takes +# care of this now but some systems uses a plain subvolume that breaks +# snapshots, rollback ("nearly everything" see bsc#992573). This +# script should help fixing it. +install -m 755 %{S:13} %{buildroot}/%{_prefix}/lib/systemd/ %fdupes -s %{buildroot}%{_mandir} @@ -982,6 +987,13 @@ enabled) ;; *) rm -f %{_prefix}/lib/systemd/system/tmp.mount esac +# Convert /var/lib/machines subvolume to make it suitable for +# rollbacks, if needed. See bsc#992573. The installer has been fixed +# to create it at installation time. +if [ $1 -gt 1 ]; then + %{_prefix}/lib/systemd/fix-machines-subvol-for-rollbacks.sh || : +fi + %postun /sbin/ldconfig if [ $1 -ge 1 ]; then @@ -1224,6 +1236,7 @@ exit 0 %endif %{_prefix}/lib/systemd/systemd-* %{_prefix}/lib/systemd/systemd +%{_prefix}/lib/systemd/fix-machines-subvol-for-rollbacks.sh %dir %{_prefix}/lib/systemd/catalog %{_prefix}/lib/systemd/catalog/systemd.catalog %{_prefix}/lib/systemd/catalog/systemd.*.catalog @@ -1405,7 +1418,6 @@ exit 0 %{_datadir}/zsh/site-functions/* %ghost %{_localstatedir}/lib/systemd/backlight %ghost %{_localstatedir}/lib/systemd/random-seed -%dir %{_localstatedir}/lib/machines %if %{with resolved} %{_sysconfdir}/dbus-1/system.d/org.freedesktop.resolve1.conf %{_sysconfdir}/systemd/resolved.conf