diff --git a/usr/share/rear/conf/default.conf b/usr/share/rear/conf/default.conf index a5152a273a..0ae36b4156 100644 --- a/usr/share/rear/conf/default.conf +++ b/usr/share/rear/conf/default.conf @@ -763,6 +763,57 @@ EXTERNAL_IGNORE_ERRORS=( 23 24 ) # output on STDOUT by rerouting that to FD 8, the progress bar EXTERNAL_CHECK="ssh vms date >&8" +## +# BACKUP_RESTORE_MOVE_AWAY +# +# Move away restored files or directories that should not have been restored: +# +# Do not confuse it with EXCLUDE_RESTORE in the EXCLUDES section below. +# With EXCLUDE_RESTORE items are excluded during backup restore +# where each particular backup method must explicitly implement support +# for the EXCLUDE_RESTORE functionality (most do not support it). +# In contrast BACKUP_RESTORE_MOVE_AWAY works generically +# for any backup restore method. +# +# See https://github.com/rear/rear/issues/779 +# +# After backup restore rear should move away files or directories +# that should not have been restored - maily files or directories +# that are created and maintained by system tools where +# a restore from the backup results wrong/outdated +# content that conflicts with the actual system. +# +# The generic traditional example of such a file was /etc/mtab. +# As long as it was a regular file it must not have been restored +# with outdated content from a backup. Nowadays it is a symbolic link +# to /proc/self/mounts which should probably be restored to ensure +# that link is available. +# +# rear will not remove any file (any user data is sacrosanct). +# Instead rear moves those files away into a rear-specific directory +# so that the admin can inspect that directory to see what rear thinks +# should not have been restored: +readonly BACKUP_RESTORE_MOVE_AWAY_DIRECTORY="$VAR_DIR/moved_away_after_backup_restore/" +# +# There is nothing hardcoded in the scripts. +# Instead BACKUP_RESTORE_MOVE_AWAY_FILES is a documented list +# that explains why each file or directory is moved away. +# The BACKUP_RESTORE_MOVE_AWAY_FILES list is not readonly +# so that it can be modified as needed by the scripts. +# The items in the BACKUP_RESTORE_MOVE_AWAY_FILES list do not need to be only files. +# Also a whole directory tree can be moved away (automatically recursively). +# Already existing stuff in the BACKUP_RESTORE_MOVE_AWAY_DIRECTORY that would be (partially) +# overwritten by the items in the BACKUP_RESTORE_MOVE_AWAY_FILES list is removed before +# (because such stuff is considered as outdated leftover e.g. from a previous recovery) +# but already existing stuff in the BACKUP_RESTORE_MOVE_AWAY_DIRECTORY that is not +# in the curent BACKUP_RESTORE_MOVE_AWAY_FILES list is kept. +# Example: +# Perhaps stuff in the /var/tmp directory is not needed after a system recovery +# and /etc/udev/rules.d/70-persistent-net.rules is created and maintained +# by systemd/udev (see https://github.com/rear/rear/issues/770): +# BACKUP_RESTORE_MOVE_AWAY_FILES=( /var/tmp /etc/udev/rules.d/70-persistent-net.rules ) +BACKUP_RESTORE_MOVE_AWAY_FILES=() + ## # How to exclude something ----- EXCLUDES ------- # diff --git a/usr/share/rear/restore/default/99_move_away_restored_files.sh b/usr/share/rear/restore/default/99_move_away_restored_files.sh new file mode 100644 index 0000000000..9461c670c8 --- /dev/null +++ b/usr/share/rear/restore/default/99_move_away_restored_files.sh @@ -0,0 +1,66 @@ +# +# Move away restored files or directories that should not have been restored: +# +# See https://github.com/rear/rear/issues/779 +# +# After backup restore rear should move away files or directories +# that should not have been restored - maily files or directories +# that are created and maintained by system tools where +# a restore from the backup results wrong/outdated +# content that conflicts with the actual system. +# +# The generic traditional example of such a file was /etc/mtab. +# As long as it was a regular file it must not have been restored +# with outdated content from a backup. Nowadays it is a symbolic link +# to /proc/self/mounts which should probably be restored to ensure +# that link is available. +# +# rear will not remove any file (any user data is sacrosanct). +# Instead rear moves those files away into a rear-specific directory +# (specified by BACKUP_RESTORE_MOVE_AWAY_DIRECTORY in default.conf) +# so that the admin can inspect that directory to see what rear thinks +# should not have been restored. +# +# There is nothing hardcoded in the scripts. +# Instead BACKUP_RESTORE_MOVE_AWAY_FILES is a documented predefined list +# in default.conf what files or directories are moved away by default. + +# Go to the recovery system root directory: +pushd $TARGET_FS_ROOT >&8 +# Artificial 'for' clause that is run only once to be able to 'continue' in case of errors +# (because the 'for' loop is run only once 'continue' is the same as 'break'): +for dummy in "once" ; do + # The following code is only meant to be used for the "recover" workflow: + test "recover" = "$WORKFLOW" || continue + # Nothing to do if the BACKUP_RESTORE_MOVE_AWAY_FILES list is empty + # (that list is considered to be empty when its first element is empty): + test "$BACKUP_RESTORE_MOVE_AWAY_FILES" || continue + # Strip leading '/' from $BACKUP_RESTORE_MOVE_AWAY_DIRECTORY + # to get a relative path that is needed inside the recovery system: + move_away_dir="${BACKUP_RESTORE_MOVE_AWAY_DIRECTORY#/}" + # Do nothing if no real BACKUP_RESTORE_MOVE_AWAY_DIRECTORY is specified + # (it has to be specified in default.conf and must not be only '/'): + test "$move_away_dir" || continue + # Create the move away directory with mode 0700 (rwx------) + # so that only root can access files and subdirectories therein + # because the files therein could contain security relevant information: + mkdir -p -m 0700 $move_away_dir || continue + # Copy each file or directory in BACKUP_RESTORE_MOVE_AWAY_FILES with full path: + for file in ${BACKUP_RESTORE_MOVE_AWAY_FILES[@]} ; do + # Strip leading '/' from $file to get it with relative path that is needed inside the recovery system: + file_relative="${file#/}" + # Skip files or directories listed in BACKUP_RESTORE_MOVE_AWAY_FILES that do not actually exist: + test -e $file_relative || continue + # Clean up already existing stuff in the move away directory + # that would be (partially) overwritten by the current copy + # (such stuff is considered as outdated leftover e.g. from a previous recovery) + # but keep already existing stuff in the move away directory + # that is not in the curent BACKUP_RESTORE_MOVE_AWAY_FILES list: + rm -rf $move_away_dir/$file_relative + # Only if the copy was successful remove the original file or directory: + cp -a --parents $file_relative $move_away_dir && rm -rf $file_relative + done +done +# Go back from the recovery system root directory: +popd >&8 +