commit 3d1bcf1b50ca8201a3805bc7cab6ca69c14951a1 Author: pcahyna Date: Thu May 5 12:11:55 2022 +0200 Merge pull request #2795 from pcahyna/recover-check-sums Verify file hashes at the end of recover after file restore from backup diff --git a/usr/share/rear/conf/default.conf b/usr/share/rear/conf/default.conf index f231bf3d..881a0af0 100644 --- a/usr/share/rear/conf/default.conf +++ b/usr/share/rear/conf/default.conf @@ -313,8 +313,30 @@ CDROM_SIZE=20 # which exits with non-zero exit code when the disk layout or those files changed # (cf. https://github.com/rear/rear/issues/1134) but the checklayout workflow # does not automatically recreate the rescue/recovery system. +# Files matching FILES_TO_PATCH_PATTERNS are added to this list automatically. CHECK_CONFIG_FILES=( '/etc/drbd/' '/etc/drbd.conf' '/etc/lvm/lvm.conf' '/etc/multipath.conf' '/etc/rear/' '/etc/udev/udev.conf' ) +# FILES_TO_PATCH_PATTERNS is a space-separated list of shell glob patterns. +# Files that match are eligible for a final migration of UUIDs and other +# identifiers after recovery (if the layout recreation process has led +# to a change of an UUID or a device name and a corresponding change needs +# to be performed on restored configuration files ). +# See finalize/GNU/Linux/280_migrate_uuid_tags.sh +# The [] around the first letter make sure that shopt -s nullglob removes this file from the list if it does not exist + +FILES_TO_PATCH_PATTERNS="[b]oot/{grub.conf,menu.lst,device.map} [e]tc/grub.* \ + [b]oot/grub/{grub.conf,grub.cfg,menu.lst,device.map} \ + [b]oot/grub2/{grub.conf,grub.cfg,menu.lst,device.map} \ + [e]tc/sysconfig/grub [e]tc/sysconfig/bootloader \ + [e]tc/lilo.conf [e]tc/elilo.conf \ + [e]tc/yaboot.conf \ + [e]tc/mtab [e]tc/fstab \ + [e]tc/mtools.conf \ + [e]tc/smartd.conf [e]tc/sysconfig/smartmontools \ + [e]tc/sysconfig/rawdevices \ + [e]tc/security/pam_mount.conf.xml \ + [b]oot/efi/*/*/grub.cfg" + ## # Relax-and-Recover recovery system update during "rear recover" # diff --git a/usr/share/rear/finalize/GNU/Linux/250_migrate_disk_devices_layout.sh b/usr/share/rear/finalize/GNU/Linux/250_migrate_disk_devices_layout.sh index 1a91a0e3..e869e5e9 100644 --- a/usr/share/rear/finalize/GNU/Linux/250_migrate_disk_devices_layout.sh +++ b/usr/share/rear/finalize/GNU/Linux/250_migrate_disk_devices_layout.sh @@ -29,19 +29,9 @@ LogPrint "The original restored files get saved in $save_original_file_dir (in $ local symlink_target="" local restored_file="" -# the funny [] around the first letter make sure that shopt -s nullglob removes this file from the list if it does not exist -# the files without a [] are mandatory, like fstab FIXME: but below there is [e]tc/fstab not etc/fstab - why? - -for restored_file in [b]oot/{grub.conf,menu.lst,device.map} [e]tc/grub.* [b]oot/grub/{grub.conf,menu.lst,device.map} \ - [b]oot/grub2/{grub.conf,grub.cfg,menu.lst,device.map} \ - [e]tc/sysconfig/grub [e]tc/sysconfig/bootloader \ - [e]tc/lilo.conf \ - [e]tc/yaboot.conf \ - [e]tc/mtab [e]tc/fstab \ - [e]tc/mtools.conf \ - [e]tc/smartd.conf [e]tc/sysconfig/smartmontools \ - [e]tc/sysconfig/rawdevices \ - [e]tc/security/pam_mount.conf.xml [b]oot/efi/*/*/grub.cfg +# The variable expansion is deliberately not quoted in order to perform +# pathname expansion on the variable value. +for restored_file in $FILES_TO_PATCH_PATTERNS do # Silently skip directories and file not found: test -f "$restored_file" || continue diff --git a/usr/share/rear/finalize/GNU/Linux/280_migrate_uuid_tags.sh b/usr/share/rear/finalize/GNU/Linux/280_migrate_uuid_tags.sh index 074689a1..d994ce8e 100644 --- a/usr/share/rear/finalize/GNU/Linux/280_migrate_uuid_tags.sh +++ b/usr/share/rear/finalize/GNU/Linux/280_migrate_uuid_tags.sh @@ -23,18 +23,9 @@ LogPrint "Migrating filesystem UUIDs in certain restored files in $TARGET_FS_ROO local symlink_target="" local restored_file="" -# the funny [] around the first letter make sure that shopt -s nullglob removes this file from the list if it does not exist -# the files without a [] are mandatory, like fstab FIXME: but below there is [e]tc/fstab not etc/fstab - why? -for restored_file in [b]oot/{grub.conf,menu.lst,device.map} [e]tc/grub.* \ - [b]oot/grub/{grub.conf,grub.cfg,menu.lst,device.map} \ - [b]oot/grub2/{grub.conf,grub.cfg,menu.lst,device.map} \ - [e]tc/sysconfig/grub [e]tc/sysconfig/bootloader \ - [e]tc/lilo.conf [e]tc/elilo.conf \ - [e]tc/mtab [e]tc/fstab \ - [e]tc/mtools.conf \ - [e]tc/smartd.conf [e]tc/sysconfig/smartmontools \ - [e]tc/sysconfig/rawdevices \ - [e]tc/security/pam_mount.conf.xml [b]oot/efi/*/*/grub.cfg +# The variable expansion is deliberately not quoted in order to perform +# pathname expansion on the variable value. +for restored_file in $FILES_TO_PATCH_PATTERNS do # Silently skip directories and file not found: test -f "$restored_file" || continue diff --git a/usr/share/rear/finalize/default/060_compare_files.sh b/usr/share/rear/finalize/default/060_compare_files.sh new file mode 100644 index 00000000..6947fda9 --- /dev/null +++ b/usr/share/rear/finalize/default/060_compare_files.sh @@ -0,0 +1,6 @@ +if [ -e $VAR_DIR/layout/config/files.md5sum ] ; then + if ! chroot $TARGET_FS_ROOT md5sum -c --quiet < $VAR_DIR/layout/config/files.md5sum 1>> >( tee -a "$RUNTIME_LOGFILE" 1>&7 ) 2>> >( tee -a "$RUNTIME_LOGFILE" 1>&8 ) ; then + LogPrintError "Error: Restored files do not match the recreated system in $TARGET_FS_ROOT" + return 1 + fi +fi diff --git a/usr/share/rear/layout/save/default/490_check_files_to_patch.sh b/usr/share/rear/layout/save/default/490_check_files_to_patch.sh new file mode 100644 index 00000000..ee717063 --- /dev/null +++ b/usr/share/rear/layout/save/default/490_check_files_to_patch.sh @@ -0,0 +1,43 @@ +# FILES_TO_PATCH_PATTERNS is a space-separated list of shell glob patterns. +# Files that match are eligible for a final migration of UUIDs and other +# identifiers after recovery (if the layout recreation process has led +# to a change of an UUID or a device name and a corresponding change needs +# to be performed on restored configuration files ). +# See finalize/GNU/Linux/280_migrate_uuid_tags.sh +# We should add all such files to CHECK_CONFIG_FILES - if they change, +# we risk inconsistencies between the restored files and recreated layout, +# or failures of UUID migration. + +local file final_file symlink_target + +# The patterns are relative to /, change directory there +# so that the shell finds the files during pathname expansion +pushd / >/dev/null +# The variable expansion is deliberately not quoted in order to perform +# pathname expansion on the variable value. +for file in $FILES_TO_PATCH_PATTERNS ; do + final_file="/$file" + IsInArray "$final_file" "${CHECK_CONFIG_FILES[@]}" && continue + # Symlink handling (partially from 280_migrate_uuid_tags.sh): + # avoid dead symlinks, and symlinks to files on dynamic filesystems + # ( /proc etc.) - they are expected to change and validating + # their checksums has no sense + if test -L "$final_file" ; then + if symlink_target="$( readlink -e "$final_file" )" ; then + # If the symlink target contains /proc/ /sys/ /dev/ or /run/ we skip it because then + # the symlink target is considered to not be a restored file that needs to be patched + # and thus we don't need to generate and check its hash, either + # cf. https://github.com/rear/rear/pull/2047#issuecomment-464846777 + if echo $symlink_target | egrep -q '/proc/|/sys/|/dev/|/run/' ; then + Log "Skip adding symlink $final_file target $symlink_target on /proc/ /sys/ /dev/ or /run/ to CHECK_CONFIG_FILES" + continue + fi + Debug "Adding symlink $final_file with target $symlink_target to CHECK_CONFIG_FILES" + else + LogPrint "Skip adding dead symlink $final_file to CHECK_CONFIG_FILES" + continue + fi + fi + CHECK_CONFIG_FILES+=( "$final_file" ) +done +popd >/dev/null diff --git a/usr/share/rear/layout/save/default/600_snapshot_files.sh b/usr/share/rear/layout/save/default/600_snapshot_files.sh index 0ebf197c..3ac6b07e 100644 --- a/usr/share/rear/layout/save/default/600_snapshot_files.sh +++ b/usr/share/rear/layout/save/default/600_snapshot_files.sh @@ -3,7 +3,8 @@ if [ "$WORKFLOW" = "checklayout" ] ; then return 0 fi -config_files=() +local obj +local config_files=() for obj in "${CHECK_CONFIG_FILES[@]}" ; do if [ -d "$obj" ] ; then config_files+=( $( find "$obj" -type f ) )