From 1319ecc1841854723514caad2d05ab3600e3bdcf Mon Sep 17 00:00:00 2001 From: eabdullin Date: Thu, 4 Dec 2025 13:30:59 +0000 Subject: [PATCH] Import from AlmaLinux stable repository --- ...r-detect-prep-boot-on-gpt-RHEL-82098.patch | 69 + .../rear-error-output-s390x-RHEL-99362.patch | 15 + SOURCES/rear-fix-ipv6.patch | 1537 +++++++++++++++++ SOURCES/rear-fix-libsystemd-ldd-warning.patch | 74 + SOURCES/rear-improve-layout-guide.patch | 301 ++++ SOURCES/rear-multipath-bios-grub.patch | 25 + SOURCES/rear-no-fat-16.patch | 84 + ...t-disk-mapping-with-sizes-RHEL-83241.patch | 51 + ...e-ed25519-hostkey-support-RHEL-83479.patch | 27 + .../rear-skip-longhorn-iscsi-RHEL-83551.patch | 107 ++ ...rear-support-aarch64-uefi-RHEL-56045.patch | 682 ++++++++ ...upport-multi-keyslot-luks-RHEL-83776.patch | 167 ++ SPECS/rear.spec | 85 +- 13 files changed, 3220 insertions(+), 4 deletions(-) create mode 100644 SOURCES/rear-detect-prep-boot-on-gpt-RHEL-82098.patch create mode 100644 SOURCES/rear-error-output-s390x-RHEL-99362.patch create mode 100644 SOURCES/rear-fix-ipv6.patch create mode 100644 SOURCES/rear-fix-libsystemd-ldd-warning.patch create mode 100644 SOURCES/rear-improve-layout-guide.patch create mode 100644 SOURCES/rear-multipath-bios-grub.patch create mode 100644 SOURCES/rear-no-fat-16.patch create mode 100644 SOURCES/rear-print-disk-mapping-with-sizes-RHEL-83241.patch create mode 100644 SOURCES/rear-rescue-ed25519-hostkey-support-RHEL-83479.patch create mode 100644 SOURCES/rear-skip-longhorn-iscsi-RHEL-83551.patch create mode 100644 SOURCES/rear-support-aarch64-uefi-RHEL-56045.patch create mode 100644 SOURCES/rear-support-multi-keyslot-luks-RHEL-83776.patch diff --git a/SOURCES/rear-detect-prep-boot-on-gpt-RHEL-82098.patch b/SOURCES/rear-detect-prep-boot-on-gpt-RHEL-82098.patch new file mode 100644 index 0000000..bcee82c --- /dev/null +++ b/SOURCES/rear-detect-prep-boot-on-gpt-RHEL-82098.patch @@ -0,0 +1,69 @@ +From 1ca518c2a0e675ace956ef71bc79d67e4990562b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= +Date: Fri, 7 Mar 2025 13:03:14 +0100 +Subject: [PATCH] 445_guess_bootloader: fix PReP Boot detection on GPT layouts + (#3420) + +In layout/save/default/445_guess_bootloader.sh +fix PPC PReP Boot detection on GPT formatted disks +by checking for a "part ... prep ..." entry in disklayout.conf +as in finalize/Linux-ppc64/680_install_PPC_bootlist.sh +The before used 'file $disk_device' output is not stable. +In particular 'grep' for "ID=0x41" (PPC PReP Boot) +in the 'file' output does not work on GPT formatted disks. +Apparently 'file' detects the GPT protective MBR ("ID=0xee"). +For example on PPC64le with PowerNV like +# file -s /dev/sdb +/dev/sdb: DOS/MBR boot sector; partition 1 : ID=0xee, ... +# parted -s /dev/sdb print +Partition Table: gpt +Disk Flags: pmbr_boot +Number ... Flags +1 ... prep +And also on x86_64 with a EFI system partition (ID=0xEF) like +# file -s /dev/nvme0n1 +/dev/nvme0n1: DOS/MBR boot sector; partition 1 : ID=0xee, ... +# parted -s /dev/nvme0n1 print +Partition Table: gpt +Number ... Flags +1 ... boot, esp + +(cherry picked from commit 1ca518c2a0e675ace956ef71bc79d67e4990562b) +--- + .../layout/save/default/445_guess_bootloader.sh | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/usr/share/rear/layout/save/default/445_guess_bootloader.sh b/usr/share/rear/layout/save/default/445_guess_bootloader.sh +index 1beffc9a9..f10a3834c 100644 +--- a/usr/share/rear/layout/save/default/445_guess_bootloader.sh ++++ b/usr/share/rear/layout/save/default/445_guess_bootloader.sh +@@ -47,6 +47,15 @@ if [ "$ARCH" = "Linux-arm" ] ; then + return + fi + ++# Check if any disk contains a PPC PReP boot partition. ++# Detection taken from usr/share/rear/finalize/Linux-ppc64/680_install_PPC_bootlist.sh ++disk_device="$( awk -F ' ' '/^part / {if ($6 ~ /prep/) {print $2}}' $LAYOUT_FILE )" ++if test "$disk_device" ; then ++ LogPrint "Using guessed bootloader 'PPC' for 'rear recover' (found PPC PReP boot partition on $disk_device)" ++ echo "PPC" >$bootloader_file ++ return ++fi ++ + # Finally guess the used bootloader by inspecting the first bytes on all disks + # and use the first one that matches a known bootloader string: + for block_device in /sys/block/* ; do +@@ -54,12 +63,6 @@ for block_device in /sys/block/* ; do + # Continue with the next block device when the current block device is not a disk that can be used for booting: + [[ $blockd = hd* || $blockd = sd* || $blockd = cciss* || $blockd = vd* || $blockd = xvd* || $blockd = nvme* || $blockd = mmcblk* || $blockd = dasd* ]] || continue + disk_device=$( get_device_name $block_device ) +- # Check if the disk contains a PPC PreP boot partition (ID=0x41): +- if file -s $disk_device | grep -q "ID=0x41" ; then +- LogPrint "Using guessed bootloader 'PPC' (found PPC PreP boot partition 'ID=0x41' on $disk_device)" +- echo "PPC" >$bootloader_file +- return +- fi + # Get all strings in the first 512*4=2048 bytes on the disk: + bootloader_area_strings_file="$TMP_DIR/bootloader_area_strings" + block_size=$( get_block_size ${disk_device##*/} ) + diff --git a/SOURCES/rear-error-output-s390x-RHEL-99362.patch b/SOURCES/rear-error-output-s390x-RHEL-99362.patch new file mode 100644 index 0000000..c900355 --- /dev/null +++ b/SOURCES/rear-error-output-s390x-RHEL-99362.patch @@ -0,0 +1,15 @@ +commit 1e9e7b3c07912b3960d077e05473dfb61d3a0796 +Author: Pavel Cahyna +Date: Wed Aug 13 16:30:46 2025 +0200 + + Error out if any unsupported OUTPUT used on s390 + +diff --git a/usr/share/rear/prep/Linux-s390/034_check_config.sh b/usr/share/rear/prep/Linux-s390/034_check_config.sh +new file mode 100644 +index 000000000..6c3eab289 +--- /dev/null ++++ b/usr/share/rear/prep/Linux-s390/034_check_config.sh +@@ -0,0 +1,3 @@ ++if [ "$OUTPUT" != "RAMDISK" ] && [ "$OUTPUT" != "IPL" ] ; then ++ Error "Currently, only OUTPUT=RAMDISK and OUTPUT=IPL are supported on s390/s390x" ++fi diff --git a/SOURCES/rear-fix-ipv6.patch b/SOURCES/rear-fix-ipv6.patch new file mode 100644 index 0000000..c886d2b --- /dev/null +++ b/SOURCES/rear-fix-ipv6.patch @@ -0,0 +1,1537 @@ +diff --git a/usr/share/rear/backup/BLOCKCLONE/default/400_copy_disk_struct_files.sh b/usr/share/rear/backup/BLOCKCLONE/default/400_copy_disk_struct_files.sh +index a5257278c..dea780742 100644 +--- a/usr/share/rear/backup/BLOCKCLONE/default/400_copy_disk_struct_files.sh ++++ b/usr/share/rear/backup/BLOCKCLONE/default/400_copy_disk_struct_files.sh +@@ -7,17 +7,17 @@ if [ -z "$BLOCKCLONE_SAVE_MBR_DEV" ]; then + return + fi + +-local backup_path=$( url_path $BACKUP_URL ) +-local opath=$(backup_path $scheme $path) ++local backup_path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + LogPrint "Copying $VAR_DIR/layout/$BLOCKCLONE_PARTITIONS_CONF_FILE to $opath" + +-cp $v $VAR_DIR/layout/$BLOCKCLONE_PARTITIONS_CONF_FILE $opath ++cp $v "$VAR_DIR/layout/$BLOCKCLONE_PARTITIONS_CONF_FILE" "$opath" + StopIfError "Failed to copy \ + $VAR_DIR/layout/$BLOCKCLONE_PARTITIONS_CONF_FILE to $opath" + + LogPrint "Copying $VAR_DIR/layout/$BLOCKCLONE_MBR_FILE to $opath" + +-cp $v $VAR_DIR/layout/$BLOCKCLONE_MBR_FILE $opath ++cp $v "$VAR_DIR/layout/$BLOCKCLONE_MBR_FILE" "$opath" + + StopIfError "Failed to copy $VAR_DIR/layout/$BLOCKCLONE_MBR_FILE to $opath" +diff --git a/usr/share/rear/backup/DUPLICITY/default/100_mount_duplicity_path.sh b/usr/share/rear/backup/DUPLICITY/default/100_mount_duplicity_path.sh +index 6ba7d543f..991cde863 100644 +--- a/usr/share/rear/backup/DUPLICITY/default/100_mount_duplicity_path.sh ++++ b/usr/share/rear/backup/DUPLICITY/default/100_mount_duplicity_path.sh +@@ -3,7 +3,7 @@ if [ -n "$BACKUP_DUPLICITY_NETFS_URL" -o -n "$BACKUP_DUPLICITY_NETFS_MOUNTCMD" ] + BACKUP_DUPLICITY_NETFS_URL="var://BACKUP_DUPLICITY_NETFS_MOUNTCMD" + fi + +- mount_url $BACKUP_DUPLICITY_NETFS_URL $BUILD_DIR/outputfs $BACKUP_DUPLICITY_NETFS_OPTIONS ++ mount_url "$BACKUP_DUPLICITY_NETFS_URL" "$BUILD_DIR/outputfs" $BACKUP_DUPLICITY_NETFS_OPTIONS + + BACKUP_DUPLICITY_URL="file://$BUILD_DIR/outputfs" + fi +diff --git a/usr/share/rear/backup/DUPLICITY/default/980_unmount_duplicity_path.sh b/usr/share/rear/backup/DUPLICITY/default/980_unmount_duplicity_path.sh +index 8525ab1de..1331c36e8 100644 +--- a/usr/share/rear/backup/DUPLICITY/default/980_unmount_duplicity_path.sh ++++ b/usr/share/rear/backup/DUPLICITY/default/980_unmount_duplicity_path.sh +@@ -5,5 +5,5 @@ if [ -n "$BACKUP_DUPLICITY_NETFS_URL" -o -n "$BACKUP_DUPLICITY_NETFS_UMOUNTCMD" + BACKUP_DUPLICITY_NETFS_URL="var://BACKUP_DUPLICITY_NETFS_UMOUNTCMD" + fi + +- umount_url $BACKUP_DUPLICITY_NETFS_URL $BUILD_DIR/outputfs ++ umount_url "$BACKUP_DUPLICITY_NETFS_URL" "$BUILD_DIR/outputfs" + fi +diff --git a/usr/share/rear/backup/NETFS/GNU/Linux/600_start_selinux.sh b/usr/share/rear/backup/NETFS/GNU/Linux/600_start_selinux.sh +index 59e497d74..4ed6f4f09 100644 +--- a/usr/share/rear/backup/NETFS/GNU/Linux/600_start_selinux.sh ++++ b/usr/share/rear/backup/NETFS/GNU/Linux/600_start_selinux.sh +@@ -1,8 +1,8 @@ + # Start SELinux if it was stopped - check presence of $TMP_DIR/selinux.mode + [[ -f $TMP_DIR/selinux.mode ]] && { +- local scheme=$(url_scheme $BACKUP_URL) +- local path=$(url_path $BACKUP_URL) +- local opath=$(backup_path $scheme $path) ++ local scheme="$( url_scheme "$BACKUP_URL" )" ++ local path="$( url_path "$BACKUP_URL" )" ++ local opath="$( backup_path "$scheme" "$path" )" + cat $TMP_DIR/selinux.mode > $SELINUX_ENFORCE + Log "Restored original SELinux mode" + touch "${opath}/selinux.autorelabel" +diff --git a/usr/share/rear/backup/NETFS/default/100_mount_NETFS_path.sh b/usr/share/rear/backup/NETFS/default/100_mount_NETFS_path.sh +index b6a955db4..8287582f9 100644 +--- a/usr/share/rear/backup/NETFS/default/100_mount_NETFS_path.sh ++++ b/usr/share/rear/backup/NETFS/default/100_mount_NETFS_path.sh +@@ -2,4 +2,4 @@ if [[ "$BACKUP_MOUNTCMD" ]] ; then + BACKUP_URL="var://BACKUP_MOUNTCMD" + fi + +-mount_url $BACKUP_URL $BUILD_DIR/outputfs $BACKUP_OPTIONS ++mount_url "$BACKUP_URL" "$BUILD_DIR/outputfs" $BACKUP_OPTIONS +diff --git a/usr/share/rear/backup/NETFS/default/150_save_copy_of_prefix_dir.sh b/usr/share/rear/backup/NETFS/default/150_save_copy_of_prefix_dir.sh +index 9bf8f76ae..20740a268 100644 +--- a/usr/share/rear/backup/NETFS/default/150_save_copy_of_prefix_dir.sh ++++ b/usr/share/rear/backup/NETFS/default/150_save_copy_of_prefix_dir.sh +@@ -3,9 +3,9 @@ + [ -z "${NETFS_KEEP_OLD_BACKUP_COPY}" ] && return + + # do not do this for tapes and special attention for file:///path +-local scheme=$( url_scheme $BACKUP_URL ) +-local path=$( url_path $BACKUP_URL ) +-local opath=$( backup_path $scheme $path ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + # if $opath is empty return silently (e.g. scheme tape) + [ -z "$opath" ] && return 0 +diff --git a/usr/share/rear/backup/NETFS/default/200_make_prefix_dir.sh b/usr/share/rear/backup/NETFS/default/200_make_prefix_dir.sh +index 43f5b651f..ccdf65158 100644 +--- a/usr/share/rear/backup/NETFS/default/200_make_prefix_dir.sh ++++ b/usr/share/rear/backup/NETFS/default/200_make_prefix_dir.sh +@@ -2,9 +2,9 @@ + # to $HOSTNAME + + # do not do this for tapes and special attention for file:///path +-local scheme=$( url_scheme $BACKUP_URL ) +-local path=$( url_path $BACKUP_URL ) +-local opath=$( backup_path $scheme $path ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + # if $opath is empty return silently (e.g. scheme tape) + [ -z "$opath" ] && return 0 +diff --git a/usr/share/rear/backup/NETFS/default/250_create_lock.sh b/usr/share/rear/backup/NETFS/default/250_create_lock.sh +index 36d547ec1..5526018c9 100644 +--- a/usr/share/rear/backup/NETFS/default/250_create_lock.sh ++++ b/usr/share/rear/backup/NETFS/default/250_create_lock.sh +@@ -2,9 +2,9 @@ + # made by a previous mkbackup run when the variable NETFS_KEEP_OLD_BACKUP_COPY has been set + + # do not do this for tapes and special attention for file:///path +-local scheme=$( url_scheme $BACKUP_URL ) +-local path=$( url_path $BACKUP_URL ) +-local opath=$( backup_path $scheme $path ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + # if $opath is empty return silently (e.g. scheme tape) + [ -z "$opath" ] && return 0 +diff --git a/usr/share/rear/backup/NETFS/default/500_make_backup.sh b/usr/share/rear/backup/NETFS/default/500_make_backup.sh +index 60c80b5f9..af2b9045f 100644 +--- a/usr/share/rear/backup/NETFS/default/500_make_backup.sh ++++ b/usr/share/rear/backup/NETFS/default/500_make_backup.sh +@@ -8,7 +8,7 @@ function set_tar_features () { + # Test for features in tar + # true if at supports the --warning option (v1.23+) + FEATURE_TAR_WARNINGS= +- local tar_version=$( get_version tar --version ) ++ local tar_version="$( get_version tar --version )" + if version_newer "$tar_version" 1.23 ; then + FEATURE_TAR_WARNINGS="y" + TAR_OPTIONS="$TAR_OPTIONS --warning=no-xdev" +@@ -18,9 +18,9 @@ function set_tar_features () { + + local backup_prog_rc + +-local scheme=$( url_scheme $BACKUP_URL ) +-local path=$( url_path $BACKUP_URL ) +-local opath=$( backup_path $scheme $path ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + test "$opath" && mkdir $v -p "$opath" + + # In any case show an initial basic info what is currently done +@@ -215,12 +215,12 @@ case "$(basename ${BACKUP_PROG})" in + Log "Using unsupported backup program '$BACKUP_PROG'" + Log $BACKUP_PROG "${BACKUP_PROG_COMPRESS_OPTIONS[@]}" \ + $BACKUP_PROG_OPTIONS_CREATE_ARCHIVE $TMP_DIR/backup-exclude.txt \ +- "${BACKUP_PROG_OPTIONS[@]}" $backuparchive \ +- $(cat $TMP_DIR/backup-include.txt) $RUNTIME_LOGFILE > $backuparchive ++ "${BACKUP_PROG_OPTIONS[@]}" "$backuparchive" \ ++ $(cat $TMP_DIR/backup-include.txt) $RUNTIME_LOGFILE > "$backuparchive" + $BACKUP_PROG "${BACKUP_PROG_COMPRESS_OPTIONS[@]}" \ + $BACKUP_PROG_OPTIONS_CREATE_ARCHIVE $TMP_DIR/backup-exclude.txt \ +- "${BACKUP_PROG_OPTIONS[@]}" $backuparchive \ +- $(cat $TMP_DIR/backup-include.txt) $RUNTIME_LOGFILE > $backuparchive ++ "${BACKUP_PROG_OPTIONS[@]}" "$backuparchive" \ ++ $(cat $TMP_DIR/backup-include.txt) $RUNTIME_LOGFILE > "$backuparchive" + ;; + esac 2> "${TMP_DIR}/${BACKUP_PROG_ARCHIVE}.log" + # important trick: the backup prog is the last in each case entry and the case .. esac is the last command +@@ -281,7 +281,7 @@ wait $BackupPID + backup_prog_rc=$? + + if [[ $BACKUP_INTEGRITY_CHECK =~ ^[yY1] && "$(basename ${BACKUP_PROG})" = "tar" ]] ; then +- (cd $(dirname $backuparchive) && md5sum $(basename $backuparchive) > ${backuparchive}.md5 || md5sum $(basename $backuparchive).?? > ${backuparchive}.md5) ++ (cd $(dirname "$backuparchive") && md5sum $(basename "$backuparchive") > "${backuparchive}".md5 || md5sum $(basename "$backuparchive").?? > "${backuparchive}".md5) + fi + + sleep 1 +diff --git a/usr/share/rear/backup/NETFS/default/970_remove_lock.sh b/usr/share/rear/backup/NETFS/default/970_remove_lock.sh +index 7038f5b9a..90c00758d 100644 +--- a/usr/share/rear/backup/NETFS/default/970_remove_lock.sh ++++ b/usr/share/rear/backup/NETFS/default/970_remove_lock.sh +@@ -1,7 +1,7 @@ + # remove the lockfile +-local scheme=$( url_scheme $BACKUP_URL ) +-local path=$( url_path $BACKUP_URL ) +-local opath=$( backup_path $scheme $path ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + # if $opath is empty return silently (e.g. scheme tape) + [ -z "$opath" ] && return 0 +diff --git a/usr/share/rear/backup/NETFS/default/980_umount_NETFS_dir.sh b/usr/share/rear/backup/NETFS/default/980_umount_NETFS_dir.sh +index e1954dc58..f15e39511 100644 +--- a/usr/share/rear/backup/NETFS/default/980_umount_NETFS_dir.sh ++++ b/usr/share/rear/backup/NETFS/default/980_umount_NETFS_dir.sh +@@ -4,4 +4,4 @@ if [[ "$BACKUP_UMOUNTCMD" ]] ; then + BACKUP_URL="var://BACKUP_UMOUNTCMD" + fi + +-umount_url $BACKUP_URL $BUILD_DIR/outputfs ++umount_url "$BACKUP_URL" "$BUILD_DIR/outputfs" +diff --git a/usr/share/rear/backup/RSYNC/GNU/Linux/620_force_autorelabel.sh b/usr/share/rear/backup/RSYNC/GNU/Linux/620_force_autorelabel.sh +index de57d5717..f1b598c99 100644 +--- a/usr/share/rear/backup/RSYNC/GNU/Linux/620_force_autorelabel.sh ++++ b/usr/share/rear/backup/RSYNC/GNU/Linux/620_force_autorelabel.sh +@@ -31,9 +31,9 @@ local backup_prog_rc + ;; + + (*) +- local scheme=$(url_scheme $BACKUP_URL) +- local path=$(url_path $BACKUP_URL) +- local opath=$(backup_path $scheme $path) ++ local scheme="$(url_scheme "$BACKUP_URL")" ++ local path="$(url_path "$BACKUP_URL")" ++ local opath="$(backup_path "$scheme" "$path")" + # probably using the BACKUP=NETFS workflow instead + if [ -d "${opath}" ]; then + if [ ! -f "${opath}/selinux.autorelabel" ]; then +diff --git a/usr/share/rear/layout/save/FDRUPSTREAM/Linux-s390/990_copy_disklayout_file.sh b/usr/share/rear/layout/save/FDRUPSTREAM/Linux-s390/990_copy_disklayout_file.sh +index 8b85d9ab0..60302091d 100644 +--- a/usr/share/rear/layout/save/FDRUPSTREAM/Linux-s390/990_copy_disklayout_file.sh ++++ b/usr/share/rear/layout/save/FDRUPSTREAM/Linux-s390/990_copy_disklayout_file.sh +@@ -15,10 +15,10 @@ + # It was only requested to make this file available for FDRUPSTREAM + # cf. https://github.com/rear/rear/pull/2142#discussion_r356696670 + +-scheme=$( url_scheme $OUTPUT_URL ) +-host=$( url_host $OUTPUT_URL ) +-path=$( url_path $OUTPUT_URL ) +-opath=$( output_path $scheme $path ) ++scheme="$( url_scheme "$OUTPUT_URL" )" ++host="$( url_host "$OUTPUT_URL" )" ++path="$( url_path $OUTPUT_URL )" ++opath="$( output_path "$scheme" "$path" )" + + + if [[ "$ZVM_NAMING" == "Y" && "$ARCH" == "Linux-s390" ]] ; then +@@ -32,7 +32,7 @@ if [[ "$ZVM_NAMING" == "Y" && "$ARCH" == "Linux-s390" ]] ; then + fi + + LogPrint "s390 disklayout.conf will be saved as $opath/$VM_UID.disklayout.conf" +- mkdir -pv $opath ++ mkdir -pv "$opath" + cp $v $DISKLAYOUT_FILE $opath/$VM_UID.disklayout.conf || Error "Failed to copy disklayout.conf ($DISKLAYOUT_FILE) to opath/$VM_UID.disklayout.conf" + fi + +diff --git a/usr/share/rear/layout/save/default/310_autoexclude_usb.sh b/usr/share/rear/layout/save/default/310_autoexclude_usb.sh +index f40c4efd5..115817007 100644 +--- a/usr/share/rear/layout/save/default/310_autoexclude_usb.sh ++++ b/usr/share/rear/layout/save/default/310_autoexclude_usb.sh +@@ -6,9 +6,9 @@ + + for URL in "$OUTPUT_URL" "$BACKUP_URL" ; do + if [[ ! -z "$URL" ]] ; then +- local host=$(url_host $URL) +- local scheme=$(url_scheme $URL) +- local path=$(url_path $URL) ++ local host="$(url_host "$URL")" ++ local scheme="$(url_scheme "$URL")" ++ local path="$(url_path "$URL")" + + case $scheme in + (usb) +@@ -35,9 +35,9 @@ for URL in "$OUTPUT_URL" "$BACKUP_URL" ; do + + grep -q "^$REAL_USB_DEVICE " /proc/mounts + if [[ $? -eq 0 ]] ; then +- local usb_mntpt=$( grep "^$REAL_USB_DEVICE " /proc/mounts | cut -d" " -f2 | tail -1 ) ++ local usb_mntpt="$( grep "^$REAL_USB_DEVICE " /proc/mounts | cut -d" " -f2 | tail -1 )" + if ! IsInArray "$usb_mntpt" "${AUTOEXCLUDE_USB_PATH[@]}" ; then +- AUTOEXCLUDE_USB_PATH+=( $usb_mntpt ) ++ AUTOEXCLUDE_USB_PATH+=( "$usb_mntpt" ) + Log "Auto-excluding USB path $usb_mntpt [device $REAL_USB_DEVICE]" + fi + fi +diff --git a/usr/share/rear/lib/framework-functions.sh b/usr/share/rear/lib/framework-functions.sh +index 5b12d008d..bfe1ecbe1 100644 +--- a/usr/share/rear/lib/framework-functions.sh ++++ b/usr/share/rear/lib/framework-functions.sh +@@ -133,7 +133,7 @@ function cleanup_build_area_and_end_program () { + if mountpoint -q "$BUILD_DIR/outputfs" ; then + # still mounted it seems + sleep 2 +- umount_mountpoint_lazy $BUILD_DIR/outputfs ++ umount_mountpoint_lazy "$BUILD_DIR/outputfs" + fi + remove_temporary_mountpoint "$BUILD_DIR/outputfs" || BugError "Directory $BUILD_DIR/outputfs not empty, can not remove" + rmdir $v $BUILD_DIR >&2 +diff --git a/usr/share/rear/lib/global-functions.sh b/usr/share/rear/lib/global-functions.sh +index 2edb64a61..967c6427a 100644 +--- a/usr/share/rear/lib/global-functions.sh ++++ b/usr/share/rear/lib/global-functions.sh +@@ -255,17 +255,17 @@ function percent_decode() { + # cf. http://bugzilla.opensuse.org/show_bug.cgi?id=561626#c7 + + function url_scheme() { +- local url=$1 ++ local url="$1" + # the scheme is the leading part up to '://' +- local scheme=${url%%://*} ++ local scheme="${url%%://*}" + # rsync scheme does not have to start with rsync:// it can also be scp style + # see the comments in usr/share/rear/lib/rsync-functions.sh +- echo $scheme | grep -q ":" && echo rsync || echo $scheme ++ echo "$scheme" | grep -q ":" && echo rsync || echo "$scheme" + } + + function url_host() { +- local url=$1 +- local url_without_scheme=${url#*//} ++ local url="$1" ++ local url_without_scheme="${url#*//}" + # the authority part is the part after the scheme (e.g. 'host' or 'user@host') + # i.e. after 'scheme://' all up to but excluding the next '/' + # which means it breaks if there is a username that contains a '/' +@@ -273,73 +273,73 @@ function url_host() { + # should have only characters from the portable filename character set + # which is ASCII letters, digits, dot, hyphen, and underscore + # (a hostname must not contain a '/' see RFC 952 and RFC 1123) +- local authority_part=${url_without_scheme%%/*} ++ local authority_part="${url_without_scheme%%/*}" + # for backward compatibility the url_host function returns the whole authority part + # see https://github.com/rear/rear/issues/856 + # to get only hostname or username use the url_hostname and url_username functions +- echo $authority_part ++ echo "$authority_part" + } + + function url_hostname() { +- local url=$1 +- local url_without_scheme=${url#*//} +- local authority_part=${url_without_scheme%%/*} ++ local url="$1" ++ local url_without_scheme="${url#*//}" ++ local authority_part="${url_without_scheme%%/*}" + # if authority_part contains a '@' we assume the 'user@host' format and + # then we remove the 'user@' part (i.e. all up to and including the last '@') + # so that it also works when the username contains a '@' + # like 'john@doe' in BACKUP_URL=sshfs://john@doe@host/G/rear/ + # (a hostname must not contain a '@' see RFC 952 and RFC 1123) +- local host_and_port=${authority_part##*@} ++ local host_and_port="${authority_part##*@}" + # if host_and_port contains a ':' we assume the 'host:port' format and + # then we remove the ':port' part (i.e. all from and including the last ':') + # so that it even works when the hostname contains a ':' (in spite of RFC 952 and RFC 1123) +- echo ${host_and_port%:*} ++ echo "${host_and_port%:*}" + } + + function url_username() { +- local url=$1 +- local url_without_scheme=${url#*//} +- local authority_part=${url_without_scheme%%/*} ++ local url="$1" ++ local url_without_scheme="${url#*//}" ++ local authority_part="${url_without_scheme%%/*}" + # authority_part must contain a '@' when a username is specified +- echo $authority_part | grep -q '@' || return 0 ++ echo "$authority_part" | grep -q '@' || return 0 + # we remove the '@host' part (i.e. all from and including the last '@') + # so that it also works when the username contains a '@' + # like 'john@doe' in BACKUP_URL=sshfs://john@doe@host/G/rear/ + # (a hostname must not contain a '@' see RFC 952 and RFC 1123) +- local user_and_password=${authority_part%@*} ++ local user_and_password="${authority_part%@*}" + # if user_and_password contains a ':' we assume the 'user:password' format and + # then we remove the ':password' part (i.e. all from and including the first ':') + # so that it works when the password contains a ':' + # (a POSIX-compliant username should not contain a ':') +- echo $user_and_password | grep -q ':' && echo ${user_and_password%%:*} || echo $user_and_password ++ echo "$user_and_password" | grep -q ':' && echo "${user_and_password%%:*}" || echo "$user_and_password" + } + + function url_password() { +- local url=$1 +- local url_without_scheme=${url#*//} +- local authority_part=${url_without_scheme%%/*} ++ local url="$1" ++ local url_without_scheme="${url#*//}" ++ local authority_part="${url_without_scheme%%/*}" + # authority_part must contain a '@' when a username is specified +- echo $authority_part | grep -q '@' || return 0 ++ echo "$authority_part" | grep -q '@' || return 0 + # we remove the '@host' part (i.e. all from and including the last '@') + # so that it also works when the username contains a '@' + # like 'john@doe' in BACKUP_URL=sshfs://john@doe@host/G/rear/ + # (a hostname must not contain a '@' see RFC 952 and RFC 1123) +- local user_and_password=${authority_part%@*} ++ local user_and_password="${authority_part%@*}" + # user_and_password must contain a ':' when a password is specified +- echo $user_and_password | grep -q ':' || return 0 ++ echo "$user_and_password" | grep -q ':' || return 0 + # we remove the 'user:' part (i.e. all up to and including the first ':') + # so that it works when the password contains a ':' + # (a POSIX-compliant username should not contain a ':') +- echo ${user_and_password#*:} ++ echo "${user_and_password#*:}" + } + + function url_path() { +- local url=$1 +- local url_without_scheme=${url#*//} ++ local url="$1" ++ local url_without_scheme="${url#*//}" + # the path is all from and including the first '/' in url_without_scheme + # i.e. the whole rest after the authority part so that + # it may contain an optional trailing '?query' and '#fragment' +- echo /${url_without_scheme#*/} ++ echo "/${url_without_scheme#*/}" + } + + ### Returns true if one can upload files to the URL +@@ -351,14 +351,14 @@ function scheme_accepts_files() { + # (then it would still exit with "bash: $1: cannot assign in this way") + # but using a default value is practicable here because $1 is used only once + # cf. https://github.com/rear/rear/pull/2675#discussion_r705018956 +- local scheme=${1:-} ++ local scheme="${1:-}" + # Return false if scheme is empty or blank (e.g. when OUTPUT_URL is unset or empty or blank) + # cf. https://github.com/rear/rear/issues/2676 + # and https://github.com/rear/rear/issues/2667#issuecomment-914447326 + # also return false if scheme is more than one word (so no quoted "$scheme" here) + # cf. https://github.com/rear/rear/pull/2675#discussion_r704401462 +- test $scheme || return 1 +- case $scheme in ++ test "$scheme" || return 1 ++ case "$scheme" in + (null|tape|obdr) + # tapes do not support uploading arbitrary files, one has to handle them + # as special case (usually passing the tape device as argument to tar) +@@ -382,10 +382,10 @@ function scheme_accepts_files() { + ### only that it can be mounted (use mount_url() first) + function scheme_supports_filesystem() { + # Be safe against 'set -eu' exit if scheme_supports_filesystem is called without argument +- local scheme=${1:-} ++ local scheme="${1:-}" + # Return false if scheme is empty or blank or more than one word, cf. scheme_accepts_files() above +- test $scheme || return 1 +- case $scheme in ++ test "$scheme" || return 1 ++ case "$scheme" in + (null|tape|obdr|rsync|fish|ftp|ftps|hftp|http|https|sftp) + return 1 + ;; +@@ -396,9 +396,9 @@ function scheme_supports_filesystem() { + } + + function backup_path() { +- local scheme=$1 +- local path=$2 +- case $scheme in ++ local scheme="$1" ++ local path="$2" ++ case "$scheme" in + (tape) # no path for tape required + path="" + ;; +@@ -422,8 +422,8 @@ function backup_path() { + } + + function output_path() { +- local scheme=$1 +- local path=$2 ++ local scheme="$1" ++ local path="$2" + + # Abort for unmountable schemes ("tape-like" or "ftp-like" schemes). + # Returning an empty string for them is not satisfactory: it could lead to caller putting its files +@@ -433,9 +433,9 @@ function output_path() { + # but if the directory is not a mountpoint, they would get silently lost. + # The caller needs to check the URL/scheme using scheme_supports_filesystem() + # before calling this function. +- scheme_supports_filesystem $scheme || BugError "output_path() called with scheme $scheme that does not support filesystem access" ++ scheme_supports_filesystem "$scheme" || BugError "output_path() called with scheme $scheme that does not support filesystem access" + +- case $scheme in ++ case "$scheme" in + (file) # type file needs a local path (must be mounted by user) + path="$path/${OUTPUT_PREFIX}" + ;; +@@ -449,19 +449,19 @@ function output_path() { + + ### Mount URL $1 at mountpoint $2[, with options $3] + function mount_url() { +- local url=$1 +- local mountpoint=$2 ++ local url="$1" ++ local mountpoint="$2" + local defaultoptions="rw,noatime" +- local options=${3:-"$defaultoptions"} ++ local options="${3:-"$defaultoptions"}" + local scheme + +- scheme=$( url_scheme $url ) ++ scheme="$( url_scheme "$url" )" + + # The cases where we return 0 are those that do not need umount and also do not need ExitTask handling. + # They thus need to be kept in sync with umount_url() so that RemoveExitTasks is used + # iff AddExitTask was used in mount_url(). + +- if ! scheme_supports_filesystem $scheme ; then ++ if ! scheme_supports_filesystem "$scheme" ; then + ### Stuff like null|tape|rsync|fish|ftp|ftps|hftp|http|https|sftp + ### Don't need to umount anything for these. + ### file: supports filesystem access, but is not mounted and unmounted, +@@ -472,7 +472,7 @@ function mount_url() { + + ### Generate a mount command + local mount_cmd +- case $scheme in ++ case "$scheme" in + (file) + ### Don't need to mount anything for file:, it is already mounted by user + return 0 +@@ -582,39 +582,39 @@ function mount_url() { + ;; + (var) + ### The mount command is given by variable in the url host +- local var=$(url_host $url) ++ local var="$(url_host "$url")" + mount_cmd="${!var} $mountpoint" + ;; + (cifs) + if [ x"$options" = x"$defaultoptions" ];then + # defaultoptions contains noatime which is not valid for cifs (issue #752) +- mount_cmd="mount $v -o rw,guest //$(url_host $url)$(url_path $url) $mountpoint" ++ mount_cmd="mount $v -o rw,guest //$(url_host "$url")$(url_path "$url") $mountpoint" + else +- mount_cmd="mount $v -o $options //$(url_host $url)$(url_path $url) $mountpoint" ++ mount_cmd="mount $v -o $options //$(url_host "$url")$(url_path "$url") $mountpoint" + fi + ;; + (usb) +- mount_cmd="mount $v -o $options $(url_path $url) $mountpoint" ++ mount_cmd="mount $v -o $options $(url_path "$url") $mountpoint" + ;; + (sshfs) +- local authority=$( url_host $url ) ++ local authority="$( url_host "$url" )" + test "$authority" || Error "Cannot run 'sshfs' because no authority '[user@]host' found in URL '$url'." +- local path=$( url_path $url ) ++ local path="$( url_path "$url" )" + test "$path" || Error "Cannot run 'sshfs' because no path found in URL '$url'." + # ensure the fuse kernel module is loaded because sshfs is based on FUSE + lsmod | grep -q '^fuse' || modprobe $verbose fuse || Error "Cannot run 'sshfs' because 'fuse' kernel module is not loadable." +- mount_cmd="sshfs $authority:$path $mountpoint -o $options" ++ mount_cmd="sshfs \"$authority\":\"$path\" $mountpoint -o $options" + ;; + (ftpfs) +- local hostname=$( url_hostname $url ) ++ local hostname="$( url_hostname "$url" )" + test "$hostname" || Error "Cannot run 'curlftpfs' because no hostname found in URL '$url'." +- local path=$( url_path $url ) ++ local path="$( url_path "$url" )" + test "$path" || Error "Cannot run 'curlftpfs' because no path found in URL '$url'." +- local username=$( url_username $url ) ++ local username="$( url_username "$url" )" + # ensure the fuse kernel module is loaded because ftpfs (via CurlFtpFS) is based on FUSE + lsmod | grep -q '^fuse' || modprobe $verbose fuse || Error "Cannot run 'curlftpfs' because 'fuse' kernel module is not loadable." + if test "$username" ; then +- local password=$( url_password $url ) ++ local password="$( url_password "$url" )" + if test "$password" ; then + # single quoting is a must for the password + mount_cmd="curlftpfs $verbose -o user='$username:$password' ftp://$hostname$path $mountpoint" +@@ -628,10 +628,10 @@ function mount_url() { + fi + ;; + (davfs) +- mount_cmd="mount $v -t davfs http://$(url_host $url)$(url_path $url) $mountpoint" ++ mount_cmd="mount $v -t davfs http://$(url_host "$url")$(url_path "$url") $mountpoint" + ;; + (*) +- mount_cmd="mount $v -t $(url_scheme $url) -o $options $(url_host $url):$(url_path $url) $mountpoint" ++ mount_cmd="mount $v -t $(url_scheme "$url") -o $options \"$(url_host "$url")\":\"$(url_path "$url")\" $mountpoint" + ;; + esac + +@@ -641,7 +641,7 @@ function mount_url() { + + Log "Mounting with '$mount_cmd'" + # eval is required when mount_cmd contains single quoted stuff (e.g. see the above mount_cmd for curlftpfs) +- eval $mount_cmd || Error "Mount command '$mount_cmd' failed." ++ eval "$mount_cmd" || Error "Mount command '$mount_cmd' failed." + + AddExitTask "perform_umount_url '$url' '$mountpoint' lazy" + return 0 +@@ -655,17 +655,17 @@ function remove_temporary_mountpoint() { + + ### Unmount url $1 at mountpoint $2, perform mountpoint cleanup and exit task + error handling + function umount_url() { +- local url=$1 +- local mountpoint=$2 ++ local url="$1" ++ local mountpoint="$2" + local scheme + +- scheme=$( url_scheme $url ) ++ scheme="$( url_scheme "$url" )" + + # The cases where we return 0 are those that do not need umount and also do not need ExitTask handling. + # They thus need to be kept in sync with mount_url() so that RemoveExitTasks is used + # iff AddExitTask was used in mount_url(). + +- if ! scheme_supports_filesystem $scheme ; then ++ if ! scheme_supports_filesystem "$scheme" ; then + ### Stuff like null|tape|rsync|fish|ftp|ftps|hftp|http|https|sftp + ### Don't need to umount anything for these. + ### file: supports filesystem access, but is not mounted and unmounted, +@@ -674,7 +674,7 @@ function umount_url() { + return 0 + fi + +- case $scheme in ++ case "$scheme" in + (file) + return 0 + ;; +@@ -694,7 +694,7 @@ function umount_url() { + # Therefore it also determines if exit task and mountpoint handling is required and returns early if not. + # The actual umount job is performed inside perform_umount_url(). + # We do not request lazy umount here because we want umount errors to be reliably reported. +- perform_umount_url $url $mountpoint || Error "Unmounting '$mountpoint' failed." ++ perform_umount_url "$url" "$mountpoint" || Error "Unmounting '$mountpoint' failed." + + RemoveExitTask "perform_umount_url '$url' '$mountpoint' lazy" + +@@ -704,9 +704,9 @@ function umount_url() { + + ### Unmount url $1 at mountpoint $2 [ lazily if $3 is set to 'lazy' and normal unmount fails ] + function perform_umount_url() { +- local url=$1 +- local mountpoint=$2 +- local lazy=${3:-} ++ local url="$1" ++ local mountpoint="$2" ++ local lazy="${3:-}" + + if test $lazy ; then + if test $lazy != "lazy" ; then +@@ -714,24 +714,24 @@ function perform_umount_url() { + fi + fi + +- case $(url_scheme $url) in ++ case "$(url_scheme "$url")" in + (sshfs) + # does ftpfs need this special case as well? +- fusermount -u ${lazy:+'-z'} $mountpoint ++ fusermount -u ${lazy:+'-z'} "$mountpoint" + ;; + (davfs) +- umount_davfs $mountpoint $lazy ++ umount_davfs "$mountpoint" $lazy + ;; + (var) + local var +- var=$(url_host $url) ++ var="$(url_host "$url")" + Log "Unmounting with '${!var} $mountpoint'" + # lazy unmount not supported with custom umount command +- ${!var} $mountpoint ++ ${!var} "$mountpoint" + ;; + (*) + # usual umount command +- umount_mountpoint $mountpoint $lazy ++ umount_mountpoint "$mountpoint" $lazy + esac + # The switch above must be the last statement in this function and the umount commands must be + # the last commands (or part of) in each branch. This ensures proper exit code propagation +@@ -741,7 +741,7 @@ function perform_umount_url() { + ### Helper which unmounts davfs mountpoint $1 and cleans up the cache, + ### performing lazy unmount if $2 = 'lazy' and normal unmount fails. + function umount_davfs() { +- local mountpoint=$1 ++ local mountpoint="$1" + local lazy="${2:-}" + + if test $lazy ; then +@@ -750,7 +750,7 @@ function umount_davfs() { + fi + fi + +- if umount_mountpoint $mountpoint ; then ++ if umount_mountpoint "$mountpoint" ; then + # Wait for 3 sek. then remove the cache-dir /var/cache/davfs + sleep 30 + # TODO: put in here the cache-dir from /etc/davfs2/davfs.conf +@@ -763,7 +763,7 @@ function umount_davfs() { + if test $lazy ; then + # try again to unmount lazily and this time do not delete the cache, it is still in use. + LogPrintError "davfs cache /var/cache/davfs2/*outputfs* needs to be cleaned up manually after the lazy unmount finishes" +- umount_mountpoint_lazy $mountpoint ++ umount_mountpoint_lazy "$mountpoint" + else + # propagate errors from umount + return $retval +@@ -775,8 +775,8 @@ function umount_davfs() { + ### Default implementation for filesystems that don't need anything fancy + ### For special umount commands use perform_umount_url() + function umount_mountpoint() { +- local mountpoint=$1 +- local lazy=${2:-} ++ local mountpoint="$1" ++ local lazy="${2:-}" + + if test $lazy ; then + if test $lazy != "lazy" ; then +@@ -786,7 +786,7 @@ function umount_mountpoint() { + + ### First, try a normal unmount, + Log "Unmounting '$mountpoint'" +- umount $v $mountpoint >&2 ++ umount $v "$mountpoint" >&2 + if [[ $? -eq 0 ]] ; then + return 0 + fi +@@ -796,7 +796,7 @@ function umount_mountpoint() { + + ### If that still fails, force unmount. + Log "Forced unmount of '$mountpoint'" +- umount $v -f $mountpoint >&2 ++ umount $v -f "$mountpoint" >&2 + if [[ $? -eq 0 ]] ; then + return 0 + fi +@@ -804,7 +804,7 @@ function umount_mountpoint() { + Log "Unmounting '$mountpoint' failed." + + if test $lazy ; then +- umount_mountpoint_lazy $mountpoint ++ umount_mountpoint_lazy "$mountpoint" + else + return 1 + fi +@@ -813,10 +813,10 @@ function umount_mountpoint() { + ### Unmount mountpoint $1 lazily + ### Preferably use "umount_mountpoint $mountpoint lazy", which attempts non-lazy unmount first. + function umount_mountpoint_lazy() { +- local mountpoint=$1 ++ local mountpoint="$1" + + LogPrint "Directory $mountpoint still mounted - trying lazy umount" +- umount $v -f -l $mountpoint >&2 ++ umount $v -f -l "$mountpoint" >&2 + } + + # Change $1 to user input or leave default value on empty input +@@ -840,9 +840,9 @@ function is_device_mounted() + local disk=$1 + [ -z "$disk" ] && echo 0 && return + +- local m=$(lsblk -n -o MOUNTPOINT $disk 2> /dev/null) ++ local m="$(lsblk -n -o MOUNTPOINT $disk 2> /dev/null)" + +- if [ -z $m ]; then ++ if [ -z "$m" ]; then + echo 0 + else + echo 1 +@@ -856,7 +856,7 @@ function get_mountpoint() + local disk=$1 + [ -z "$disk" ] && return 1 + +- local mp=$(lsblk -n -o MOUNTPOINT $disk 2> /dev/null) ++ local mp="$(lsblk -n -o MOUNTPOINT $disk 2> /dev/null)" + + echo $mp + } +@@ -865,12 +865,12 @@ function get_mountpoint() + # to re-mount the given mountpoint + function build_remount_cmd() + { +- local mp=$1 ++ local mp="$1" + [ -z "$mp" ] && return 1 + + local -a allopts=() + # Get: device, mountpoint, FS type, mount options as string +- local opt_string=$(mount | grep " $mp " | awk '{ print $1 " " $3 " " $5 " " $6 }') ++ local opt_string="$(mount | grep " $mp " | awk '{ print $1 " " $3 " " $5 " " $6 }')" + [ -z "$opt_string" ] && return 1 + + # Split string, store in array +diff --git a/usr/share/rear/lib/mkbackup-workflow.sh b/usr/share/rear/lib/mkbackup-workflow.sh +index ea8498a2b..ae0ad7e3c 100644 +--- a/usr/share/rear/lib/mkbackup-workflow.sh ++++ b/usr/share/rear/lib/mkbackup-workflow.sh +@@ -4,7 +4,7 @@ + WORKFLOW_mkbackup_DESCRIPTION="create rescue media and backup system" + WORKFLOWS+=( mkbackup ) + WORKFLOW_mkbackup () { +- local scheme=$(url_scheme $BACKUP_URL) ++ local scheme="$( url_scheme "$BACKUP_URL" )" + + SourceStage "prep" + +diff --git a/usr/share/rear/lib/rsync-functions.sh b/usr/share/rear/lib/rsync-functions.sh +index 443a9625a..27f4381aa 100644 +--- a/usr/share/rear/lib/rsync-functions.sh ++++ b/usr/share/rear/lib/rsync-functions.sh +@@ -39,7 +39,7 @@ function rsync_user () { + local url="$1" + local host + +- host=$(url_host "$url") ++ host="$(url_host "$url")" + + if grep -q '@' <<< $host ; then + echo "${host%%@*}" # grab user name +@@ -53,8 +53,8 @@ function rsync_host () { + local host + local path + +- host=$(url_host "$url") +- path=$(url_path "$url") ++ host="$(url_host "$url")" ++ path="$(url_path "$url")" + # remove USER@ if present + local tmp2="${host#*@}" + +@@ -77,8 +77,8 @@ function rsync_path () { + local url_without_scheme + local url_without_scheme_user + +- host=$(url_host "$url") +- path=$(url_path "$url") ++ host="$(url_host "$url")" ++ path="$(url_path "$url")" + local tmp2="${host#*@}" + + url_without_scheme="${url#*//}" +diff --git a/usr/share/rear/output/ISO/Linux-i386/810_prepare_multiple_iso.sh b/usr/share/rear/output/ISO/Linux-i386/810_prepare_multiple_iso.sh +index 1c2ec47ca..6ff8be05e 100644 +--- a/usr/share/rear/output/ISO/Linux-i386/810_prepare_multiple_iso.sh ++++ b/usr/share/rear/output/ISO/Linux-i386/810_prepare_multiple_iso.sh +@@ -25,13 +25,13 @@ test "$ISO_MAX_SIZE" || return 0 + # a "rear mkrescue" would overwrite an existing ISO that contains a backup. + test "mkrescue" = "$WORKFLOW" && Error "The mkrescue workflow is forbidden when ISO_MAX_SIZE is set" + +-local backup_path=$( url_path $BACKUP_URL ) ++local backup_path="$( url_path "$BACKUP_URL" )" + + # The backuparchive variable value is set in prep/NETFS/default/070_set_backup_archive.sh + # which is skipped in case of the mkrescue workflow but the mkrescue workflow is forbidden + # when ISO_MAX_SIZE is set and this script is skipped when ISO_MAX_SIZE is not set + # see https://github.com/rear/rear/pull/2063#issuecomment-469222487 +-local isofs_path=$( dirname $backuparchive ) ++local isofs_path="$( dirname "$backuparchive" )" + + # Because usr/sbin/rear sets 'shopt -s nullglob' the 'echo -n' command + # outputs nothing if nothing matches the bash globbing pattern '$backuparchive.??' +diff --git a/usr/share/rear/output/PXE/default/800_copy_to_tftp.sh b/usr/share/rear/output/PXE/default/800_copy_to_tftp.sh +index 3e7512ee5..6b140b4e3 100644 +--- a/usr/share/rear/output/PXE/default/800_copy_to_tftp.sh ++++ b/usr/share/rear/output/PXE/default/800_copy_to_tftp.sh +@@ -7,16 +7,16 @@ + + if [[ ! -z "$PXE_TFTP_URL" ]] ; then + # E.g. PXE_TFTP_URL=nfs://server/export/nfs/tftpboot +- local scheme=$( url_scheme $PXE_TFTP_URL ) ++ local scheme="$( url_scheme "$PXE_TFTP_URL" )" + + # We need filesystem access to the destination (schemes like ftp:// are not supported) + if ! scheme_supports_filesystem $scheme ; then + Error "Scheme $scheme for PXE output not supported, use a scheme that supports mounting (like nfs: )" + fi + +- mount_url $PXE_TFTP_URL $BUILD_DIR/tftpbootfs $BACKUP_OPTIONS ++ mount_url "$PXE_TFTP_URL" "$BUILD_DIR/tftpbootfs" $BACKUP_OPTIONS + # However, we copy under $OUTPUT_PREFIX_PXE directory (usually HOSTNAME) to have different clients on one pxe server +- PXE_TFTP_LOCAL_PATH=$BUILD_DIR/tftpbootfs ++ PXE_TFTP_LOCAL_PATH="$BUILD_DIR/tftpbootfs" + # mode must readable for others for pxe and we copy under the client HOSTNAME (=OUTPUT_PREFIX_PXE) + mkdir -m 755 -p $v "$BUILD_DIR/tftpbootfs/$OUTPUT_PREFIX_PXE" >&2 + StopIfError "Could not mkdir '$BUILD_DIR/tftpbootfs/$OUTPUT_PREFIX_PXE'" +@@ -46,27 +46,27 @@ if [[ ! -z "$PXE_TFTP_URL" ]] && [[ "$PXE_RECOVER_MODE" = "unattended" ]] ; then + # required pxe modules (and we assume that the PXE server run the same OS) + # copy pxelinux.0 and friends + # RHEL/SLES and friends +- PXELINUX_BIN=$( find_syslinux_file pxelinux.0 ) ++ PXELINUX_BIN="$( find_syslinux_file pxelinux.0 )" + if [[ -z "$PXELINUX_BIN" ]] ; then + # perhaps Debian/Ubuntu and friends + [[ -f /usr/lib/PXELINUX/pxelinux.0 ]] && PXELINUX_BIN=/usr/lib/PXELINUX/pxelinux.0 + fi + if [[ ! -z "$PXELINUX_BIN" ]] ; then +- cp $v "$PXELINUX_BIN" $BUILD_DIR/tftpbootfs >&2 ++ cp $v "$PXELINUX_BIN" "$BUILD_DIR/tftpbootfs" >&2 + fi +- syslinux_modules_dir=$( find_syslinux_modules_dir menu.c32 ) +- [[ -z "$syslinux_modules_dir" ]] && syslinux_modules_dir=$(dirname $PXELINUX_BIN) +- cp $v $syslinux_modules_dir/ldlinux.c32 $BUILD_DIR/tftpbootfs >&2 +- cp $v $syslinux_modules_dir/libcom32.c32 $BUILD_DIR/tftpbootfs >&2 +- cp $v $syslinux_modules_dir/libutil.c32 $BUILD_DIR/tftpbootfs >&2 +- cp $v $syslinux_modules_dir/menu.c32 $BUILD_DIR/tftpbootfs >&2 +- cp $v $syslinux_modules_dir/chain.c32 $BUILD_DIR/tftpbootfs >&2 +- cp $v $syslinux_modules_dir/hdt.c32 $BUILD_DIR/tftpbootfs >&2 +- cp $v $syslinux_modules_dir/reboot.c32 $BUILD_DIR/tftpbootfs >&2 ++ syslinux_modules_dir="$( find_syslinux_modules_dir menu.c32 )" ++ [[ -z "$syslinux_modules_dir" ]] && syslinux_modules_dir="$(dirname $PXELINUX_BIN)" ++ cp $v $syslinux_modules_dir/ldlinux.c32 "$BUILD_DIR/tftpbootfs" >&2 ++ cp $v $syslinux_modules_dir/libcom32.c32 "$BUILD_DIR/tftpbootfs" >&2 ++ cp $v $syslinux_modules_dir/libutil.c32 "$BUILD_DIR/tftpbootfs" >&2 ++ cp $v $syslinux_modules_dir/menu.c32 "$BUILD_DIR/tftpbootfs" >&2 ++ cp $v $syslinux_modules_dir/chain.c32 "$BUILD_DIR/tftpbootfs" >&2 ++ cp $v $syslinux_modules_dir/hdt.c32 "$BUILD_DIR/tftpbootfs" >&2 ++ cp $v $syslinux_modules_dir/reboot.c32 "$BUILD_DIR/tftpbootfs" >&2 + if [[ -r "$syslinux_modules_dir/poweroff.com" ]] ; then +- cp $v $syslinux_modules_dir/poweroff.com $BUILD_DIR/tftpbootfs >&2 ++ cp $v $syslinux_modules_dir/poweroff.com "$BUILD_DIR/tftpbootfs" >&2 + elif [[ -r "$syslinux_modules_dir/poweroff.c32" ]] ; then +- cp $v $syslinux_modules_dir/poweroff.c32 $BUILD_DIR/tftpbootfs >&2 ++ cp $v $syslinux_modules_dir/poweroff.c32 "$BUILD_DIR/tftpbootfs" >&2 + fi + chmod 644 $BUILD_DIR/tftpbootfs/*.c32 + chmod 644 $BUILD_DIR/tftpbootfs/*.0 +@@ -75,7 +75,7 @@ fi + + if [[ ! -z "$PXE_TFTP_URL" ]] ; then + LogPrint "Copied kernel+initrd $( du -shc $KERNEL_FILE "$TMP_DIR/$REAR_INITRD_FILENAME" | tail -n 1 | tr -s "\t " " " | cut -d " " -f 1 ) to $PXE_TFTP_URL/$OUTPUT_PREFIX_PXE" +- umount_url $PXE_TFTP_URL $BUILD_DIR/tftpbootfs ++ umount_url "$PXE_TFTP_URL" "$BUILD_DIR/tftpbootfs" + else + # legacy way PXE_TFTP_PATH + LogPrint "Copied kernel+initrd $( du -shc $KERNEL_FILE "$TMP_DIR/$REAR_INITRD_FILENAME" | tail -n 1 | tr -s "\t " " " | cut -d " " -f 1 ) to $PXE_TFTP_PATH" +diff --git a/usr/share/rear/output/PXE/default/810_create_pxelinux_cfg.sh b/usr/share/rear/output/PXE/default/810_create_pxelinux_cfg.sh +index 5041a3bc6..e980439df 100644 +--- a/usr/share/rear/output/PXE/default/810_create_pxelinux_cfg.sh ++++ b/usr/share/rear/output/PXE/default/810_create_pxelinux_cfg.sh +@@ -10,18 +10,18 @@ + if [[ ! -z "$PXE_CONFIG_URL" ]] ; then + # E.g. PXE_CONFIG_URL=nfs://server/export/nfs/tftpboot/pxelinux.cfg + # Better be sure that on 'server' the directory /export/nfs/tftpboot/pxelinux.cfg exists +- local scheme=$( url_scheme $PXE_CONFIG_URL ) ++ local scheme="$( url_scheme "$PXE_CONFIG_URL" )" + + # We need filesystem access to the destination (schemes like ftp:// are not supported) + if ! scheme_supports_filesystem $scheme ; then + Error "Scheme $scheme for PXE output not supported, use a scheme that supports mounting (like nfs: )" + fi + +- mount_url $PXE_CONFIG_URL $BUILD_DIR/tftpbootfs $BACKUP_OPTIONS +- PXE_LOCAL_PATH=$BUILD_DIR/tftpbootfs ++ mount_url "$PXE_CONFIG_URL" "$BUILD_DIR/tftpbootfs" $BACKUP_OPTIONS ++ PXE_LOCAL_PATH="$BUILD_DIR/tftpbootfs" + else + # legacy way using PXE_LOCAL_PATH default +- PXE_LOCAL_PATH=$PXE_CONFIG_PATH ++ PXE_LOCAL_PATH="$PXE_CONFIG_PATH" + fi + + # PXE_CONFIG_PREFIX is a "string" (by default rear-) - is the name of PXE boot configuration of $HOSTNAME +@@ -36,7 +36,7 @@ if [[ ! -z "$PXE_CONFIG_URL" ]] ; then + else + # legacy way using PXE_LOCAL_PATH default + cat >"$PXE_LOCAL_PATH/$PXE_CONFIG_FILE" </dev/null + + if [[ ! -z "$PXE_CONFIG_URL" ]] ; then + LogPrint "Created pxelinux config '${PXE_CONFIG_PREFIX}$HOSTNAME' and symlinks for $PXE_CREATE_LINKS adresses in $PXE_CONFIG_URL" +- umount_url $PXE_TFTP_URL $BUILD_DIR/tftpbootfs ++ umount_url "$PXE_TFTP_URL" "$BUILD_DIR/tftpbootfs" + else + LogPrint "Created pxelinux config '${PXE_CONFIG_PREFIX}$HOSTNAME' and symlinks for $PXE_CREATE_LINKS adresses in $PXE_CONFIG_PATH" + # Add to result files +diff --git a/usr/share/rear/output/default/100_mount_output_path.sh b/usr/share/rear/output/default/100_mount_output_path.sh +index 34ea8e5ef..765e47f7c 100644 +--- a/usr/share/rear/output/default/100_mount_output_path.sh ++++ b/usr/share/rear/output/default/100_mount_output_path.sh +@@ -6,4 +6,4 @@ if [[ -z "$OUTPUT_URL" ]] ; then + return + fi + +-mount_url $OUTPUT_URL $BUILD_DIR/outputfs $OUTPUT_OPTIONS ++mount_url "$OUTPUT_URL" "$BUILD_DIR/outputfs" $OUTPUT_OPTIONS +diff --git a/usr/share/rear/output/default/150_save_copy_of_prefix_dir.sh b/usr/share/rear/output/default/150_save_copy_of_prefix_dir.sh +index 063261147..5d34f93d4 100644 +--- a/usr/share/rear/output/default/150_save_copy_of_prefix_dir.sh ++++ b/usr/share/rear/output/default/150_save_copy_of_prefix_dir.sh +@@ -3,16 +3,16 @@ + [ -z "${KEEP_OLD_OUTPUT_COPY}" ] && return + + # do not do this for tapes and special attention for file:///path +-local scheme=$( url_scheme $OUTPUT_URL ) +-local path=$( url_path $OUTPUT_URL ) ++local scheme="$( url_scheme "$OUTPUT_URL" )" ++local path="$( url_path "$OUTPUT_URL" )" + + # if filesystem access to url is unsupported return silently (e.g. scheme tape) + scheme_supports_filesystem $scheme || return 0 + +-local opath=$( output_path $scheme $path ) ++local opath="$( output_path "$scheme" "$path" )" + + # an old lockfile from a previous run not cleaned up by output is possible +-[[ -f ${opath}/.lockfile ]] && rm -f ${opath}/.lockfile >&2 ++[[ -f "${opath}/.lockfile" ]] && rm -f "${opath}/.lockfile" >&2 + + if test -d "${opath}" ; then + rm -rf $v "${opath}.old" || Error "Could not remove '${opath}.old'" +diff --git a/usr/share/rear/output/default/200_make_prefix_dir.sh b/usr/share/rear/output/default/200_make_prefix_dir.sh +index 606e1c867..16cf8395e 100644 +--- a/usr/share/rear/output/default/200_make_prefix_dir.sh ++++ b/usr/share/rear/output/default/200_make_prefix_dir.sh +@@ -7,13 +7,13 @@ + # but it is also happens for local stuff like OUTPUT_URL=usb:///dev/disk/by-label/REAR-000 + # + # Do not do this for tapes and special attention for file:///path +-local scheme=$( url_scheme $OUTPUT_URL ) +-local path=$( url_path $OUTPUT_URL ) ++local scheme="$( url_scheme "$OUTPUT_URL" )" ++local path="$( url_path "$OUTPUT_URL" )" + + # If filesystem access to url is unsupported return silently (e.g. scheme tape) + scheme_supports_filesystem $scheme || return 0 + +-local opath=$( output_path $scheme $path ) ++local opath="$( output_path "$scheme" "$path" )" + + # Create $OUTPUT_PREFIX sub-directory: + mkdir -p $v -m0750 "$opath" && return +diff --git a/usr/share/rear/output/default/250_create_lock.sh b/usr/share/rear/output/default/250_create_lock.sh +index d792b036a..5e17a48e3 100644 +--- a/usr/share/rear/output/default/250_create_lock.sh ++++ b/usr/share/rear/output/default/250_create_lock.sh +@@ -2,13 +2,13 @@ + # made by a previous mkrescue run when the variable KEEP_OLD_OUTPUT_COPY has been set + + # do not do this for tapes and special attention for file:///path +-local scheme=$( url_scheme $OUTPUT_URL ) +-local path=$( url_path $OUTPUT_URL ) ++local scheme="$( url_scheme "$OUTPUT_URL" )" ++local path="$( url_path "$OUTPUT_URL" )" + + # if filesystem access to url is unsupported return silently (e.g. scheme tape) + scheme_supports_filesystem $scheme || return 0 + +-local opath=$( output_path $scheme $path ) ++local opath="$( output_path "$scheme" "$path" )" + + if test -d "${opath}" ; then + > "${opath}/.lockfile" || Error "Could not create '${opath}/.lockfile'" +diff --git a/usr/share/rear/output/default/950_copy_result_files.sh b/usr/share/rear/output/default/950_copy_result_files.sh +index 77f54d51e..1a7179f2d 100644 +--- a/usr/share/rear/output/default/950_copy_result_files.sh ++++ b/usr/share/rear/output/default/950_copy_result_files.sh +@@ -7,11 +7,11 @@ + # that would need to be copied here to the output location: + test "${RESULT_FILES[*]:-}" || return 0 + +-local scheme=$( url_scheme $OUTPUT_URL ) +-local host=$( url_host $OUTPUT_URL ) +-local path=$( url_path $OUTPUT_URL ) ++local scheme="$( url_scheme "$OUTPUT_URL" )" ++local host="$( url_host "$OUTPUT_URL" )" ++local path="$( url_path "$OUTPUT_URL" )" + +-if [ -z "$OUTPUT_URL" ] || ! scheme_accepts_files $scheme ; then ++if [ -z "$OUTPUT_URL" ] || ! scheme_accepts_files "$scheme" ; then + if [ "$scheme" == "null" -o -z "$OUTPUT_URL" ] ; then + # There are result files to copy, but OUTPUT_URL=null indicates that we are not interested in them + # TODO: empty OUTPUT_URL seems to be equivalent to null, should we continue to allow that, +diff --git a/usr/share/rear/output/default/970_remove_lock.sh b/usr/share/rear/output/default/970_remove_lock.sh +index 3b1b97cc3..255afeda7 100644 +--- a/usr/share/rear/output/default/970_remove_lock.sh ++++ b/usr/share/rear/output/default/970_remove_lock.sh +@@ -1,11 +1,11 @@ + # remove the lockfile +-local scheme=$(url_scheme $OUTPUT_URL) +-local path=$(url_path $OUTPUT_URL) ++local scheme="$( url_scheme "$OUTPUT_URL" )" ++local path="$( url_path "$OUTPUT_URL" )" + + # if filesystem access to url is unsupported return silently (e.g. scheme tape) +-scheme_supports_filesystem $scheme || return 0 ++scheme_supports_filesystem "$scheme" || return 0 + +-local opath=$( output_path $scheme $path ) ++local opath="$( output_path "$scheme" "$path" )" + + # when OUTPUT_URL=BACKUP_URL we keep the lockfile to avoid double moves of the directory + [[ "$OUTPUT_URL" != "$BACKUP_URL" ]] && rm -f $v "${opath}/.lockfile" >&2 +diff --git a/usr/share/rear/output/default/980_umount_output_dir.sh b/usr/share/rear/output/default/980_umount_output_dir.sh +index abf0cd538..1ea42dbed 100644 +--- a/usr/share/rear/output/default/980_umount_output_dir.sh ++++ b/usr/share/rear/output/default/980_umount_output_dir.sh +@@ -8,4 +8,4 @@ if [[ -z "$OUTPUT_URL" ]] ; then + return + fi + +-umount_url $OUTPUT_URL $BUILD_DIR/outputfs ++umount_url "$OUTPUT_URL" "$BUILD_DIR/outputfs" +diff --git a/usr/share/rear/prep/DUPLICITY/default/200_find_duply_profile.sh b/usr/share/rear/prep/DUPLICITY/default/200_find_duply_profile.sh +index 0461d6436..f5e6f4bd4 100644 +--- a/usr/share/rear/prep/DUPLICITY/default/200_find_duply_profile.sh ++++ b/usr/share/rear/prep/DUPLICITY/default/200_find_duply_profile.sh +@@ -27,7 +27,7 @@ if [ "$BACKUP_PROG" = "duplicity" ] && has_binary duply; then + # still here? + if [[ "$SOURCE" = "/" ]]; then + DUPLY_PROFILE_FILE=$CONF +- DUPLY_PROFILE=$( dirname $CONF ) # /root/.duply/mycloud/conf -> /root/.duply/mycloud ++ DUPLY_PROFILE="$( dirname "$CONF" )" # /root/.duply/mycloud/conf -> /root/.duply/mycloud + DUPLY_PROFILE=${DUPLY_PROFILE##*/} # /root/.duply/mycloud -> mycloud + break # the loop + else +@@ -40,7 +40,7 @@ if [ "$BACKUP_PROG" = "duplicity" ] && has_binary duply; then + # we found the duply program; check if we can find a profile defined in ReaR config file + if [[ -z "$DUPLY_PROFILE" ]]; then + # no profile pre-set in local.conf; let's try to find one +- DUPLY_PROFILE=$( find /etc/duply $ROOT_HOME_DIR/.duply -name conf 2>&1) ++ DUPLY_PROFILE="$( find /etc/duply $ROOT_HOME_DIR/.duply -name conf 2>&1)" + # above result could contain more than one profile + [[ -z "$DUPLY_PROFILE" ]] && return + find_duply_profile "$DUPLY_PROFILE" +@@ -50,7 +50,7 @@ if [ "$BACKUP_PROG" = "duplicity" ] && has_binary duply; then + [[ -z "$DUPLY_PROFILE" ]] && return + + # retrieve the real path of DUPLY_PROFILE in case DUPLY_PROFILE was defined local.conf +- DUPLY_PROFILE_FILE=$( ls /etc/duply/$DUPLY_PROFILE/conf $ROOT_HOME_DIR/.duply/$DUPLY_PROFILE/conf 2>/dev/null ) ++ DUPLY_PROFILE_FILE="$( ls /etc/duply/$DUPLY_PROFILE/conf $ROOT_HOME_DIR/.duply/$DUPLY_PROFILE/conf 2>/dev/null )" + # Assuming we have a duply configuration we must have a path, right? + [[ -z "$DUPLY_PROFILE_FILE" ]] && return + find_duply_profile "$DUPLY_PROFILE_FILE" +@@ -71,10 +71,10 @@ if [ "$BACKUP_PROG" = "duplicity" ] && has_binary duply; then + # check the scheme of the TARGET variable in DUPLY_PROFILE ($CONF has full path) to be + # sure we have all executables we need in the rescue image + source $DUPLY_PROFILE_FILE +- local scheme=$( url_scheme $TARGET ) +- case $scheme in ++ local scheme="$( url_scheme "$TARGET" )" ++ case "$scheme" in + (sftp|rsync|scp) +- PROGS+=( $scheme ) ++ PROGS+=( "$scheme" ) + esac + fi + +diff --git a/usr/share/rear/prep/DUPLICITY/default/210_check_NETFS_URL_requirements.sh b/usr/share/rear/prep/DUPLICITY/default/210_check_NETFS_URL_requirements.sh +index 3b4dc7b7c..1a4856fd1 100644 +--- a/usr/share/rear/prep/DUPLICITY/default/210_check_NETFS_URL_requirements.sh ++++ b/usr/share/rear/prep/DUPLICITY/default/210_check_NETFS_URL_requirements.sh +@@ -19,9 +19,9 @@ + StopIfError "You must specify either BACKUP_DUPLICITY_URL or BACKUP_DUPLICITY_NETFS_URL or BACKUP_DUPLICITY_NETFS_MOUNTCMD and BACKUP_DUPLICITY_NETFS_UMOUNTCMD !" + + if [[ "$BACKUP_DUPLICITY_NETFS_URL" ]] ; then +- local scheme=$( url_scheme $BACKUP_DUPLICITY_NETFS_URL ) +- local hostname=$( url_hostname $BACKUP_DUPLICITY_NETFS_URL ) +- local path=$( url_path $BACKUP_DUPLICITY_NETFS_URL ) ++ local scheme="$( url_scheme "$BACKUP_DUPLICITY_NETFS_URL" )" ++ local hostname="$( url_hostname "$BACKUP_DUPLICITY_NETFS_URL" )" ++ local path="$( url_path "$BACKUP_DUPLICITY_NETFS_URL" )" + + ### check for vaild BACKUP_DUPLICITY_NETFS_URL schemes + ### see https://github.com/rear/rear/issues/842 +diff --git a/usr/share/rear/prep/GNU/Linux/300_check_backup_and_output_url.sh b/usr/share/rear/prep/GNU/Linux/300_check_backup_and_output_url.sh +index ebf8315bf..4819292dd 100644 +--- a/usr/share/rear/prep/GNU/Linux/300_check_backup_and_output_url.sh ++++ b/usr/share/rear/prep/GNU/Linux/300_check_backup_and_output_url.sh +@@ -16,9 +16,9 @@ + local url="" + for url in "$BACKUP_URL" "$OUTPUT_URL" ; do + test "$url" || continue +- local scheme=$( url_scheme $url ) +- local authority=$( url_host $url ) +- local path=$( url_path $url ) ++ local scheme="$( url_scheme "$url" )" ++ local authority="$( url_host "$url" )" ++ local path="$( url_path "$url" )" + case "$scheme" in + (file|tape|usb) + # file:// tape:// usb:// URLs must not have an authority part (scheme://authority/path) +diff --git a/usr/share/rear/prep/ISO/GNU/Linux/340_add_isofs_module.sh b/usr/share/rear/prep/ISO/GNU/Linux/340_add_isofs_module.sh +index 3e705e348..0187a62e5 100644 +--- a/usr/share/rear/prep/ISO/GNU/Linux/340_add_isofs_module.sh ++++ b/usr/share/rear/prep/ISO/GNU/Linux/340_add_isofs_module.sh +@@ -2,7 +2,7 @@ + # loopback mount the ISO containing the backup + # BACKUP_URL=iso://backup + +-local scheme=$(url_scheme $BACKUP_URL) ++local scheme="$( url_scheme "$BACKUP_URL" )" + + case "$scheme" in + (iso) +diff --git a/usr/share/rear/prep/NETFS/default/050_check_NETFS_requirements.sh b/usr/share/rear/prep/NETFS/default/050_check_NETFS_requirements.sh +index bcee8e968..65ea96098 100644 +--- a/usr/share/rear/prep/NETFS/default/050_check_NETFS_requirements.sh ++++ b/usr/share/rear/prep/NETFS/default/050_check_NETFS_requirements.sh +@@ -16,16 +16,16 @@ + StopIfError "You must specify either BACKUP_URL or BACKUP_MOUNTCMD and BACKUP_UMOUNTCMD !" + + # url_scheme results the empty string when $BACKUP_URL is empty: +-local scheme=$( url_scheme $BACKUP_URL ) ++local scheme="$( url_scheme "$BACKUP_URL" )" + + if [[ "$BACKUP_URL" ]] ; then + +- local hostname=$( url_hostname $BACKUP_URL ) +- local path=$( url_path $BACKUP_URL ) ++ local hostname="$( url_hostname "$BACKUP_URL" )" ++ local path="$( url_path "$BACKUP_URL" )" + + ### check for vaild BACKUP_URL schemes + ### see https://github.com/rear/rear/issues/842 +- case $scheme in ++ case "$scheme" in + (nfs|cifs|usb|tape|file|iso|sshfs|ftpfs) + # do nothing for vaild BACKUP_URL schemes + : +diff --git a/usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh b/usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh +index 4961bcee6..26ab1981b 100644 +--- a/usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh ++++ b/usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh +@@ -22,12 +22,12 @@ fi + local backup_file_suffix="$BACKUP_PROG_SUFFIX$BACKUP_PROG_COMPRESS_SUFFIX" + local backup_file_name="$BACKUP_PROG_ARCHIVE$backup_file_suffix" + +-local scheme=$( url_scheme $BACKUP_URL ) +-local path=$( url_path $BACKUP_URL ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" + case "$scheme" in + (file|iso) + # Define the output path according to the scheme +- local outputpath=$( backup_path $scheme $path ) ++ local outputpath="$( backup_path "$scheme" "$path" )" + backuparchive="$outputpath/$backup_file_name" + LogPrint "Using backup archive '$backuparchive'" + return +@@ -35,7 +35,7 @@ case "$scheme" in + (tape) + # TODO: Check if that case is really needed. + # Perhaps prep/default/030_translate_tape.sh does already all what is needed. +- backuparchive=$path ++ backuparchive="$path" + LogPrint "Using backup archive '$backuparchive'" + return + ;; +diff --git a/usr/share/rear/prep/NETFS/default/400_automatic_exclude_recreate.sh b/usr/share/rear/prep/NETFS/default/400_automatic_exclude_recreate.sh +index 3c719c446..c8b53e9dd 100644 +--- a/usr/share/rear/prep/NETFS/default/400_automatic_exclude_recreate.sh ++++ b/usr/share/rear/prep/NETFS/default/400_automatic_exclude_recreate.sh +@@ -5,8 +5,8 @@ + # Verify a local backup directory in BACKUP_URL=file:///path and + # add its mountpoint to the EXCLUDE_RECREATE array (if necessary). + +-local scheme=$( url_scheme $BACKUP_URL ) +-local backup_directory=$( url_path $BACKUP_URL ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local backup_directory="$( url_path "$BACKUP_URL" )" + local backup_directory_mountpoint="" + + case $scheme in +@@ -28,7 +28,7 @@ case $scheme in + mkdir $v -p "$backup_directory" >&2 || Error "Could not create backup directory '$backup_directory' (from URL '$BACKUP_URL')." + fi + test -d "$backup_directory" || Error "URL '$BACKUP_URL' specifies '$backup_directory' which is not a directory." +- backup_directory_mountpoint=$( df -P "$backup_directory" | tail -1 | awk '{print $6}' ) ++ backup_directory_mountpoint="$( df -P "$backup_directory" | tail -1 | awk '{print $6}' )" + test "/" = "$backup_directory_mountpoint" && Error "URL '$BACKUP_URL' has the backup directory '$backup_directory' in the '/' filesystem which is forbidden." + # When the mountpoint of the backup directory is not yet excluded add its mountpoint to the EXCLUDE_RECREATE array: + if ! grep -q "$backup_directory_mountpoint" <<< "${EXCLUDE_RECREATE[*]}" ; then +diff --git a/usr/share/rear/prep/RBME/default/050_include_rbme_requirements.sh b/usr/share/rear/prep/RBME/default/050_include_rbme_requirements.sh +index 556d2e5f6..06c419875 100644 +--- a/usr/share/rear/prep/RBME/default/050_include_rbme_requirements.sh ++++ b/usr/share/rear/prep/RBME/default/050_include_rbme_requirements.sh +@@ -1,11 +1,11 @@ + +-scheme=$(url_scheme "$BACKUP_URL") ++scheme="$(url_scheme "$BACKUP_URL")" + case $scheme in + (nfs) + PROGS+=( + showmount +- mount.$(url_scheme $BACKUP_URL) +- umount.$(url_scheme $BACKUP_URL) ++ mount.$(url_scheme "$BACKUP_URL") ++ umount.$(url_scheme "$BACKUP_URL") + ) + ;; + (*) +diff --git a/usr/share/rear/prep/RSYNC/default/100_check_rsync.sh b/usr/share/rear/prep/RSYNC/default/100_check_rsync.sh +index 448a1b1a4..64d18800e 100644 +--- a/usr/share/rear/prep/RSYNC/default/100_check_rsync.sh ++++ b/usr/share/rear/prep/RSYNC/default/100_check_rsync.sh +@@ -7,7 +7,7 @@ if test -z "$BACKUP_URL" ; then + Error "Missing BACKUP_URL=rsync://[USER@]HOST[:PORT][::]/PATH !" + fi + +-local scheme=$(url_scheme $BACKUP_URL) # url_scheme still recognizes old style ++local scheme="$(url_scheme "$BACKUP_URL")" # url_scheme still recognizes old style + + if [[ "$scheme" != "rsync" ]]; then + Error "Missing BACKUP_URL=rsync://[USER@]HOST[:PORT][::]/PATH !" +diff --git a/usr/share/rear/prep/USB/default/060_set_usb_device.sh b/usr/share/rear/prep/USB/default/060_set_usb_device.sh +index aac579e1d..9fdbdcfb2 100644 +--- a/usr/share/rear/prep/USB/default/060_set_usb_device.sh ++++ b/usr/share/rear/prep/USB/default/060_set_usb_device.sh +@@ -1,8 +1,8 @@ + ### set USB device from OUTPUT_URL + if [[ -z "$USB_DEVICE" ]] && [[ "$OUTPUT_URL" ]]; then +- local scheme=$(url_scheme $OUTPUT_URL) +- local path=$(url_path $OUTPUT_URL) +- case $scheme in ++ local scheme="$( url_scheme "$OUTPUT_URL" )" ++ local path="$( url_path "$OUTPUT_URL" )" ++ case "$scheme" in + (usb) + USB_DEVICE="$path" + ;; +@@ -30,8 +30,8 @@ test "$USB_PREFIX" || USB_PREFIX="rear/$HOSTNAME/$(date +%Y%m%d.%H%M)" + + ### Change NETFS_PREFIX to USB_PREFIX if our backup URL is on USB + if [[ "$BACKUP_URL" ]] ; then +- local scheme=$(url_scheme $BACKUP_URL) +- case $scheme in ++ local scheme="$( url_scheme "$BACKUP_URL" )" ++ case "$scheme" in + (usb) + NETFS_PREFIX="$USB_PREFIX" + ;; +diff --git a/usr/share/rear/prep/default/030_translate_tape.sh b/usr/share/rear/prep/default/030_translate_tape.sh +index 7efb6603a..b992683a9 100644 +--- a/usr/share/rear/prep/default/030_translate_tape.sh ++++ b/usr/share/rear/prep/default/030_translate_tape.sh +@@ -1,9 +1,9 @@ + # Provide the necessary variables to use tape/obdr information + + if [[ "$BACKUP_URL" ]] ; then +- backup_scheme=$(url_scheme "$BACKUP_URL") ++ backup_scheme="$(url_scheme "$BACKUP_URL")" + if [[ "$backup_scheme" == tape || "$backup_scheme" == obdr ]] ; then +- testdevice=$(url_path "$BACKUP_URL") ++ testdevice="$(url_path "$BACKUP_URL")" + ### Complain when both are specified, but don't match + if [[ "$TAPE_DEVICE" && "$TAPE_DEVICE" != "$testdevice" ]]; then + Error "Tape device in BACKUP_URL '$BACKUP_URL' and TAPE_DEVICE '$TAPE_DEVICE' is not the same" +diff --git a/usr/share/rear/prep/default/040_check_backup_and_output_scheme.sh b/usr/share/rear/prep/default/040_check_backup_and_output_scheme.sh +index 4ca6c94ff..a15c901c9 100644 +--- a/usr/share/rear/prep/default/040_check_backup_and_output_scheme.sh ++++ b/usr/share/rear/prep/default/040_check_backup_and_output_scheme.sh +@@ -4,8 +4,8 @@ + # + + if test "$BACKUP_URL" ; then +- local backup_scheme=$( url_scheme "$BACKUP_URL" ) +- case $backup_scheme in ++ local backup_scheme="$( url_scheme "$BACKUP_URL" )" ++ case "$backup_scheme" in + (iso) + case $WORKFLOW in + (mkrescue|mkbackuponly) +@@ -52,8 +52,8 @@ else + fi + + if test "$OUTPUT_URL" ; then +- local output_scheme=$( url_scheme "$OUTPUT_URL" ) +- case $output_scheme in ++ local output_scheme="$( url_scheme "$OUTPUT_URL" )" ++ case "$output_scheme" in + (fish|ftp|ftps|hftp|http|https|sftp) + local required_prog='lftp' + has_binary $required_prog || Error "The OUTPUT_URL scheme '$output_scheme' requires the '$required_prog' command which is missing" +diff --git a/usr/share/rear/restore/BLOCKCLONE/default/390_create_partitions.sh b/usr/share/rear/restore/BLOCKCLONE/default/390_create_partitions.sh +index eb1cbdce4..35993506e 100644 +--- a/usr/share/rear/restore/BLOCKCLONE/default/390_create_partitions.sh ++++ b/usr/share/rear/restore/BLOCKCLONE/default/390_create_partitions.sh +@@ -9,8 +9,8 @@ if [ -z "$BLOCKCLONE_SAVE_MBR_DEV" ]; then + return + fi + +-local backup_path=$( url_path $BACKUP_URL ) +-local opath=$( backup_path $scheme $path ) ++local backup_path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + # Destination partition is not present, try to recreate. + if [ ! -b "$BLOCKCLONE_SOURCE_DEV" ]; then +diff --git a/usr/share/rear/restore/NETFS/default/380_prepare_multiple_isos.sh b/usr/share/rear/restore/NETFS/default/380_prepare_multiple_isos.sh +index 458e9728e..d8de8d37e 100644 +--- a/usr/share/rear/restore/NETFS/default/380_prepare_multiple_isos.sh ++++ b/usr/share/rear/restore/NETFS/default/380_prepare_multiple_isos.sh +@@ -1,9 +1,9 @@ + # 380_prepare_multiple_isos + # + +-local scheme=$(url_scheme $BACKUP_URL) +-local path=$(url_path $BACKUP_URL) +-local opath=$(backup_path $scheme $path) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + [[ -f "${opath}/backup.splitted" ]] || return 0 + +diff --git a/usr/share/rear/restore/NETFS/default/400_restore_backup.sh b/usr/share/rear/restore/NETFS/default/400_restore_backup.sh +index 31083c380..eba9ddd55 100644 +--- a/usr/share/rear/restore/NETFS/default/400_restore_backup.sh ++++ b/usr/share/rear/restore/NETFS/default/400_restore_backup.sh +@@ -2,9 +2,9 @@ + # 400_restore_backup.sh + # + +-local scheme=$( url_scheme $BACKUP_URL ) +-local path=$( url_path $BACKUP_URL ) +-local opath=$( backup_path $scheme $path ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + # Create backup restore log file name: + local backup_restore_log_dir="$VAR_DIR/restore" +@@ -54,7 +54,7 @@ if test -f $TMP_DIR/backup.splitted ; then + touch $waiting_for_medium_flag_file + while ! test -f "$backup_file_path" ; do + umount "$BUILD_DIR/outputfs" +- cdrom_drive_names=$( cat /proc/sys/dev/cdrom/info | grep -i "drive name:" | awk '{print $3 " " $4}' ) ++ cdrom_drive_names="$( cat /proc/sys/dev/cdrom/info | grep -i "drive name:" | awk '{print $3 " " $4}' )" + ProgressInfo "Insert medium labelled $vol_name (containing $backup_file_name) in a CD-ROM drive ($cdrom_drive_names) ..." + sleep 3 + for cdrom_dev in $cdrom_drive_names ; do +@@ -105,7 +105,7 @@ fi + for restore_input in "${RESTORE_ARCHIVES[@]}" ; do + # Create backup restore log file name (a different one for each restore_input). + # Each restore_input is a path like '/tmp/rear.XXXX/outputfs/f121/backup.tar.gz': +- restore_input_basename=$( basename $restore_input ) ++ restore_input_basename="$( basename "$restore_input" )" + backup_restore_log_file=$backup_restore_log_dir/$backup_restore_log_prefix.$restore_input_basename.$MASTER_PID.$backup_restore_log_suffix + cat /dev/null >$backup_restore_log_file + LogPrint "Restoring from '$restore_input' (restore log in $backup_restore_log_file) ..." +diff --git a/usr/share/rear/restore/NETFS/default/500_selinux_autorelabel.sh b/usr/share/rear/restore/NETFS/default/500_selinux_autorelabel.sh +index e212b6816..0dabc9ef2 100644 +--- a/usr/share/rear/restore/NETFS/default/500_selinux_autorelabel.sh ++++ b/usr/share/rear/restore/NETFS/default/500_selinux_autorelabel.sh +@@ -8,9 +8,9 @@ + # answer is yes force auto relabeling the files after the reboot to have a correct SELinux labeled system. + + # If selinux was turned off for the backup we have to label the +-local scheme=$( url_scheme $BACKUP_URL ) +-local path=$( url_path $BACKUP_URL ) +-local opath=$( backup_path $scheme $path ) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + if test -f "$opath/selinux.autorelabel" ; then + touch $TARGET_FS_ROOT/.autorelabel +diff --git a/usr/share/rear/restore/RBME/default/400_restore_backup.sh b/usr/share/rear/restore/RBME/default/400_restore_backup.sh +index 3e97e16b4..210d84b2b 100644 +--- a/usr/share/rear/restore/RBME/default/400_restore_backup.sh ++++ b/usr/share/rear/restore/RBME/default/400_restore_backup.sh +@@ -4,7 +4,7 @@ fi + + local backup_prog_rc + +-scheme=$(url_scheme "$BACKUP_URL") ++scheme="$( url_scheme "$BACKUP_URL" )" + + LogPrint "Restoring from backup $RBME_BACKUP." + ProgressStart "Preparing restore operation" +diff --git a/usr/share/rear/restore/YUM/default/410_restore_backup.sh b/usr/share/rear/restore/YUM/default/410_restore_backup.sh +index 4cc5a2af4..e37d3d936 100644 +--- a/usr/share/rear/restore/YUM/default/410_restore_backup.sh ++++ b/usr/share/rear/restore/YUM/default/410_restore_backup.sh +@@ -12,9 +12,9 @@ LogPrint "Restoring system files (YUM_BACKUP_FILES=$YUM_BACKUP_FILES)" + # see https://github.com/rear/rear/wiki/Coding-Style + set -e -u -o pipefail + +-local scheme=$(url_scheme $BACKUP_URL) +-local path=$(url_path $BACKUP_URL) +-local opath=$(backup_path $scheme $path) ++local scheme="$( url_scheme "$BACKUP_URL" )" ++local path="$( url_path "$BACKUP_URL" )" ++local opath="$( backup_path "$scheme" "$path" )" + + # The RESTORE_ARCHIVES array contains the restore input files. + # If it is not set, RESTORE_ARCHIVES is only one element which is the backup archive: +diff --git a/usr/share/rear/verify/NETFS/default/050_start_required_nfs_daemons.sh b/usr/share/rear/verify/NETFS/default/050_start_required_nfs_daemons.sh +index 491065a23..d4bb56c4d 100644 +--- a/usr/share/rear/verify/NETFS/default/050_start_required_nfs_daemons.sh ++++ b/usr/share/rear/verify/NETFS/default/050_start_required_nfs_daemons.sh +@@ -31,7 +31,7 @@ + # and predefining all used variables + # see https://github.com/rear/rear/wiki/Coding-Style + # +-local backup_url_scheme=$( url_scheme "$BACKUP_URL" ) ++local backup_url_scheme="$( url_scheme "$BACKUP_URL" )" + # nothing to do when backup_url_scheme is not "nfs" + test "nfs" = "$backup_url_scheme" || return 0 + # predefine all used variables +diff --git a/usr/share/rear/verify/RBME/default/150_check_nobody_uid_nfs.sh b/usr/share/rear/verify/RBME/default/150_check_nobody_uid_nfs.sh +index edf151548..7a24da1da 100644 +--- a/usr/share/rear/verify/RBME/default/150_check_nobody_uid_nfs.sh ++++ b/usr/share/rear/verify/RBME/default/150_check_nobody_uid_nfs.sh +@@ -1,5 +1,5 @@ + # check if NFS user is nobody - for rsync restore this is a NOGO +-nfs_uid=$(ls -l $BUILD_DIR/outputfs | tail -1 | awk '{print $3}') ++nfs_uid=$(ls -l "$BUILD_DIR/outputfs" | tail -1 | awk '{print $3}') + case "$nfs_uid" in + "nobody"|"-1"|"-2"|"4294967294") + Error "RBME rsync restore will result in a broken system (owner=$nfs_uid). +diff --git a/usr/share/rear/verify/RBME/default/540_choose_backup.sh b/usr/share/rear/verify/RBME/default/540_choose_backup.sh +index a67f1df3f..ee81f271e 100644 +--- a/usr/share/rear/verify/RBME/default/540_choose_backup.sh ++++ b/usr/share/rear/verify/RBME/default/540_choose_backup.sh +@@ -1,6 +1,6 @@ + +-scheme=$(url_scheme "$BACKUP_URL") +-case $scheme in ++scheme="$( url_scheme "$BACKUP_URL" )" ++case "$scheme" in + (local|nfs) + : + ;; +diff --git a/usr/share/rear/verify/USB/NETFS/default/540_choose_backup_archive.sh b/usr/share/rear/verify/USB/NETFS/default/540_choose_backup_archive.sh +index 4cbc782c7..a90dfd6e7 100644 +--- a/usr/share/rear/verify/USB/NETFS/default/540_choose_backup_archive.sh ++++ b/usr/share/rear/verify/USB/NETFS/default/540_choose_backup_archive.sh +@@ -3,7 +3,7 @@ + # This script is only run during a backup restore workflow (recover/restoreoly) + # so that RESTORE_ARCHIVES is set in this script. + +-scheme=$( url_scheme "$BACKUP_URL" ) ++scheme="$( url_scheme "$BACKUP_URL" )" + # Skip if not backup on USB: + test "usb" = "$scheme" || return 0 + diff --git a/SOURCES/rear-fix-libsystemd-ldd-warning.patch b/SOURCES/rear-fix-libsystemd-ldd-warning.patch new file mode 100644 index 0000000..fc5507a --- /dev/null +++ b/SOURCES/rear-fix-libsystemd-ldd-warning.patch @@ -0,0 +1,74 @@ +diff --git a/usr/share/rear/build/default/990_verify_rootfs.sh b/usr/share/rear/build/default/990_verify_rootfs.sh +index 76a4f1f4b..1b76d8019 100644 +--- a/usr/share/rear/build/default/990_verify_rootfs.sh ++++ b/usr/share/rear/build/default/990_verify_rootfs.sh +@@ -69,6 +69,11 @@ fi + Log "Testing each binary (except links) with ldd and look for 'not found' libraries within the recovery system" + local binary="" + local broken_binaries="" ++local not_found_output="" ++local not_found_library="" ++local junk="" ++local actually_found_library="" ++local actually_missing_libraries="no" + # Third-party backup tools may use LD_LIBRARY_PATH to find their libraries + # so that for testing such third-party backup tools we must also use + # their special LD_LIBRARY_PATH here: +@@ -151,7 +156,6 @@ test $old_LD_LIBRARY_PATH && export LD_LIBRARY_PATH=$old_LD_LIBRARY_PATH || unse + # Report binaries with 'not found' shared object dependencies: + local fatal_missing_library="" + if contains_visible_char "$broken_binaries" ; then +- LogPrintError "There are binaries or libraries in the ReaR recovery system that need additional libraries" + local ldd_output="" + for binary in $broken_binaries ; do + # Only for programs (i.e. files in a .../bin/... or .../sbin/... directory) treat a missing library as fatal +@@ -161,26 +165,43 @@ if contains_visible_char "$broken_binaries" ; then + if test "$NON_FATAL_BINARIES_WITH_MISSING_LIBRARY" ; then + # A program with missing library is treated as fatal when it does not match the pattern: + if grep -E -q "$NON_FATAL_BINARIES_WITH_MISSING_LIBRARY" <<<"$binary" ; then +- LogPrintError "$binary requires additional libraries (specified as non-fatal)" ++ LogPrint "$binary requires libraries where 'ldd' shows 'not found' (specified as non-fatal)" + else +- LogPrintError "$binary requires additional libraries (fatal error)" ++ LogPrint "$binary requires libraries where 'ldd' shows 'not found' (fatal error)" + fatal_missing_library="yes" + fi + else +- LogPrintError "$binary requires additional libraries (fatal error)" ++ LogPrint "$binary requires libraries where 'ldd' shows 'not found' (fatal by default)" + fatal_missing_library="yes" + fi + else +- LogPrintError "$binary requires additional libraries" ++ LogPrint "$binary requires libraries where 'ldd' shows 'not found'" + fi + # Run the same ldd call as above but now keep its whole output: + ldd_output="$( chroot $ROOTFS_DIR /bin/ldd $binary )" + # Have the whole ldd output only in the log: + Log "$ldd_output" ++ # For each 'not found' shared object (i.e. a shared object that was 'not found' by 'ldd') ++ # check whether or not the shared object may exist nevertheless in the ReaR recovery system ++ # and if yes, we may sufficiently safely assume things are OK in the ReaR recovery system ++ # so we do not report it as missing to the user (for debugging we have all in the log) ++ # cf. https://github.com/rear/rear/issues/3021#issuecomment-2165453757 ++ not_found_output="$( grep 'not found' <<<"$ldd_output" )" ++ # not_found_output is a string of multiple lines (separated by \n) that look e.g. like ++ # libsystemd-shared-255.4-1.fc40.so => not found ++ # /path/to/library => not found ++ while read not_found_library junk ; do ++ # We prefer a simple 'grep -q' pipe over dealing with find -name versus -path options: ++ if actually_found_library="$( find $ROOTFS_DIR -xdev | grep "$not_found_library" )" ; then ++ LogPrint "$binary requires $not_found_library which was not found by 'ldd' but exists as $actually_found_library" ++ else ++ actually_missing_libraries="yes" + # Show only the missing libraries to the user to not flood his screen with tons of other ldd output lines: +- PrintError "$( grep 'not found' <<<"$ldd_output" )" ++ LogPrintError "$binary requires $not_found_library which could not be found in the ReaR recovery system" ++ fi ++ done <<<"$not_found_output" + done +- LogPrintError "ReaR recovery system in '$ROOTFS_DIR' needs additional libraries, check $RUNTIME_LOGFILE for details" ++ is_true $actually_missing_libraries && LogPrintError "ReaR recovery system in '$ROOTFS_DIR' needs additional libraries, check $RUNTIME_LOGFILE for details" + is_true "$fatal_missing_library" && keep_build_dir + fi + diff --git a/SOURCES/rear-improve-layout-guide.patch b/SOURCES/rear-improve-layout-guide.patch new file mode 100644 index 0000000..d829839 --- /dev/null +++ b/SOURCES/rear-improve-layout-guide.patch @@ -0,0 +1,301 @@ +diff --git a/doc/user-guide/06-layout-configuration.adoc b/doc/user-guide/06-layout-configuration.adoc +index 88ba0420f..680d69640 100644 +--- a/doc/user-guide/06-layout-configuration.adoc ++++ b/doc/user-guide/06-layout-configuration.adoc +@@ -35,22 +35,22 @@ Layout information is stored in +/var/lib/rear/layout/disklayout.conf+. The term + Consider the information from the following system as an example: + ---------------------------------- + disk /dev/sda 160041885696 msdos +-# disk /dev/sdb 320072933376 msdos +-# disk /dev/sdc 1999696297984 msdos ++#disk /dev/sdb 320072933376 msdos ++#disk /dev/sdc 1999696297984 msdos + part /dev/sda 209682432 32768 primary boot /dev/sda1 + part /dev/sda 128639303680 209719296 primary lvm /dev/sda2 + part /dev/sda 31192862720 128849022976 primary none /dev/sda3 +-# part /dev/sdb 162144912384 32256 primary none /dev/sdb1 +-# part /dev/sdb 152556666880 162144944640 primary none /dev/sdb2 +-# part /dev/sdb 5371321856 314701611520 primary boot /dev/sdb3 +-# part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 +-# part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 +-# lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 ++#part /dev/sdb 162144912384 32256 primary none /dev/sdb1 ++#part /dev/sdb 152556666880 162144944640 primary none /dev/sdb2 ++#part /dev/sdb 5371321856 314701611520 primary boot /dev/sdb3 ++#part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 ++#part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 ++#lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 + lvmdev /dev/system /dev/mapper/disk N4Hpdc-DkBP-Hdm6-Z6FH-VixZ-7tTb-LiRt0w 251244544 +-# lvmgrp /dev/backup 4096 220764 904249344 ++#lvmgrp /dev/backup 4096 220764 904249344 + lvmgrp /dev/system 4096 30669 125620224 +-# lvmvol /dev/backup backup 12800 104857600 +-# lvmvol /dev/backup externaltemp 38400 314572800 ++#lvmvol /dev/backup backup 12800 104857600 ++#lvmvol /dev/backup externaltemp 38400 314572800 + lvmvol /dev/system root 2560 20971520 + lvmvol /dev/system home 5120 41943040 + lvmvol /dev/system var 2560 20971520 +@@ -81,45 +81,7 @@ It's easy to see that there are 3 disks attached to the system. +/dev/sda+ is th + Relax-and-Recover has reasonable defaults when creating the recovery + information. It has commented out the two external disks and any + component that's part of it. The reason is that no mounted filesystem +-uses these two disks. After all, you don't want to recreate your +-backup disk when you're recovering your system. +- +-If we mount the filesystem on +/dev/mapper/backup-backup+ on +/media/backup+, +-Relax-and-Recover will think that it's necessary to recreate the filesystem: +----------------------------------- +-disk /dev/sda 160041885696 msdos +-# disk /dev/sdb 320072933376 msdos +-disk /dev/sdc 1999696297984 msdos +-part /dev/sda 209682432 32768 primary boot /dev/sda1 +-part /dev/sda 128639303680 209719296 primary lvm /dev/sda2 +-part /dev/sda 31192862720 128849022976 primary none /dev/sda3 +-# part /dev/sdb 162144912384 32256 primary none /dev/sdb1 +-# part /dev/sdb 152556666880 162144944640 primary none /dev/sdb2 +-# part /dev/sdb 5371321856 314701611520 primary boot /dev/sdb3 +-part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 +-part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 +-lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 +-lvmdev /dev/system /dev/mapper/disk N4Hpdc-DkBP-Hdm6-Z6FH-VixZ-7tTb-LiRt0w 251244544 +-lvmgrp /dev/backup 4096 220764 904249344 +-lvmgrp /dev/system 4096 30669 125620224 +-lvmvol /dev/backup backup 12800 104857600 +-lvmvol /dev/backup externaltemp 38400 314572800 +-lvmvol /dev/system root 2560 20971520 +-lvmvol /dev/system home 5120 41943040 +-lvmvol /dev/system var 2560 20971520 +-lvmvol /dev/system swap 512 4194304 +-lvmvol /dev/system vmxfs 7680 62914560 +-lvmvol /dev/system kvm 5000 40960000 +-fs /dev/mapper/system-root / ext4 uuid=dbb0c0d4-7b9a-40e2-be83-daafa14eff6b label= blocksize=4096 reserved_blocks=131072 max_mounts=21 check_interval=180d options=rw,commit=0 +-fs /dev/mapper/system-home /home ext4 uuid=e9310015-6043-48cd-a37d-78dbfdba1e3b label= blocksize=4096 reserved_blocks=262144 max_mounts=38 check_interval=180d options=rw,commit=0 +-fs /dev/mapper/system-var /var ext4 uuid=a12bb95f-99f2-42c6-854f-1cb3f144d662 label= blocksize=4096 reserved_blocks=131072 max_mounts=23 check_interval=180d options=rw,commit=0 +-fs /dev/mapper/system-vmxfs /vmware xfs uuid=7457d2ab-8252-4f41-bab6-607316259975 label= options=rw,noatime +-fs /dev/mapper/system-kvm /kvm ext4 uuid=173ab1f7-8450-4176-8cf7-c09b47f5e3cc label= blocksize=4096 reserved_blocks=256000 max_mounts=21 check_interval=180d options=rw,noatime,commit=0 +-fs /dev/sda1 /boot ext3 uuid=f6b08566-ea5e-46f9-8f73-5e8ffdaa7be6 label= blocksize=1024 reserved_blocks=10238 max_mounts=35 check_interval=180d options=rw,commit=0 +-fs /dev/mapper/backup-backup /media/backup ext4 uuid=da20354a-dc4c-4bef-817c-1c92894bb002 label= blocksize=4096 reserved_blocks=655360 max_mounts=24 check_interval=180d options=rw +-swap /dev/mapper/system-swap uuid=9f347fc7-1605-4788-98fd-fca828beedf1 label= +-crypt /dev/mapper/disk /dev/sda2 cipher=aes-xts-plain hash=sha1 uuid=beafe67c-d9a4-4992-80f1-e87791a543bb +----------------------------------- ++uses these two disks. + + This behavior is controlled by the +AUTOEXCLUDE_DISKS=y+ parameter in + +default.conf+. If we unset it in the local configuration, Relax-and-Recover +@@ -131,61 +93,81 @@ multipath disks. Typically, they are part of the SAN disaster recovery + strategy. However, there can be cases where you want to recover them. The + information is retained in +disklayout.conf+. + +-=== Manual excludes +-It seems prudent to prevent the external drives from ever being backed-up or overwritten. The default configuration contains these lines: ++Some filesystems are excluded from the layout file by default if their ++mountpoints are located under certain directories. This behavior is ++controlled by the +AUTOEXCLUDE_PATH+ variable. It is an array of ++paths. If a mountpoint of a filesystem is under one of the paths, the ++filesystem is excluded. The default value includes +/media+, +/mnt+ ++and +/tmp+. See +default.conf+ for the full list. Note that if one of ++the paths is itself a mountpoint, the filesystem is not excluded. So, ++if +/media+ is a mounted filesystem, it will not be excluded, but if ++we mount the +/dev/mapper/backup-backup+ filesystem on +++/media/backup+, it will get excluded, as the mountpoint is under +++/media+. ++ ++If we mount the filesystem on +/dev/mapper/backup-backup+ on +/backup+, ++Relax-and-Recover will think that it's necessary to recreate the filesystem: + ---------------------------------- +-# Exclude components from being backed up, recreation information is active +-EXCLUDE_BACKUP=() +- +-# Exclude components during component recreation +-# will be added to EXCLUDE_BACKUP (it is not backed up) +-# recreation information gathered, but commented out +-EXCLUDE_RECREATE=() +- +-# Exclude components during the backup restore phase +-# only used to exclude files from the restore. +-EXCLUDE_RESTORE=() ++disk /dev/sdc 1999696297984 msdos ++... ++part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 ++part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 ++lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 ++... ++lvmgrp /dev/backup 4096 220764 904249344 ++... ++lvmvol /dev/backup backup 12800 104857600 ++lvmvol /dev/backup externaltemp 38400 314572800 ++... ++fs /dev/mapper/backup-backup /backup ext4 uuid=da20354a-dc4c-4bef-817c-1c92894bb002 label= blocksize=4096 reserved_blocks=655360 max_mounts=24 check_interval=180d options=rw + ---------------------------------- + +-To prevent an inadvertently mounted backup filesystem being added to the restore list, the easiest way is to add the filesystem to the +EXCLUDE_RECREATE+ array. +----------------------------------- +-EXCLUDE_RECREATE+=( "fs:/media/backup" ) ++=== Manual excludes ++In this example, the external drive +/dev/sdc+ contains a volume group ++used for backups outside Relax-and-Recover. It is assumed that one ++does not want to overwrite and recreate the content of the backup disk ++when recovering the system, but one expects the backup disk to survive ++the recovery unchanged, and that one also does not want ++Relax-and-Recover to make a backup of its content. (Note that ++excluding a filesystem from the layout file also excludes the files in ++the filesystem from the backup when using a supported backup method, ++which is what we want in this case.) One thus needs to ++exclude the components on the disk from the layout file. ++A generic mechanism for doing this is the +EXCLUDE_RECREATE+ ++variable. It can contain a list of storage components that will be ++excluded from the layout (will be present in the layout file, but ++commented out) recursively together with their descendants (components ++that depend on the excluded component, like a filesystem on the ++underlying logical volume). Each component in the list corresponds to ++a component in the layout file, but the syntax is different. To ++specify a mounted filesystem, use the +fs:+ prefix: +++fs:+. To specify swap, use the +swap:+ prefix. The syntax ++to specify a volume group to exclude (together with all its logical ++volumes and filesystems on them) is +/dev/+. Consult ++the +/var/lib/rear/layout/disktodo.conf+ file created together with ++the layout file for the full list of components in a compatible ++syntax. ++ ++To prevent the mounted backup filesystem from being added to ++the layout file and recreated, one may add the filesystem to the +EXCLUDE_RECREATE+ array. ++---------------------------------- ++EXCLUDE_RECREATE+=( "fs:/backup" ) + ---------------------------------- + + The layout file is as expected: + ---------------------------------- +-disk /dev/sda 160041885696 msdos +-# disk /dev/sdb 320072933376 msdos +-# disk /dev/sdc 1999696297984 msdos +-part /dev/sda 209682432 32768 primary boot /dev/sda1 +-part /dev/sda 128639303680 209719296 primary lvm /dev/sda2 +-part /dev/sda 31192862720 128849022976 primary none /dev/sda3 +-# part /dev/sdb 162144912384 32256 primary none /dev/sdb1 +-# part /dev/sdb 152556666880 162144944640 primary none /dev/sdb2 +-# part /dev/sdb 5371321856 314701611520 primary boot /dev/sdb3 +-# part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 +-# part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 +-# lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 +-lvmdev /dev/system /dev/mapper/disk N4Hpdc-DkBP-Hdm6-Z6FH-VixZ-7tTb-LiRt0w 251244544 +-# lvmgrp /dev/backup 4096 220764 904249344 +-lvmgrp /dev/system 4096 30669 125620224 +-# lvmvol /dev/backup backup 12800 104857600 +-# lvmvol /dev/backup externaltemp 38400 314572800 +-lvmvol /dev/system root 2560 20971520 +-lvmvol /dev/system home 5120 41943040 +-lvmvol /dev/system var 2560 20971520 +-lvmvol /dev/system swap 512 4194304 +-lvmvol /dev/system vmxfs 7680 62914560 +-lvmvol /dev/system kvm 5000 40960000 +-fs /dev/mapper/system-root / ext4 uuid=dbb0c0d4-7b9a-40e2-be83-daafa14eff6b label= blocksize=4096 reserved_blocks=131072 max_mounts=21 check_interval=180d options=rw,commit=0 +-fs /dev/mapper/system-home /home ext4 uuid=e9310015-6043-48cd-a37d-78dbfdba1e3b label= blocksize=4096 reserved_blocks=262144 max_mounts=38 check_interval=180d options=rw,commit=0 +-fs /dev/mapper/system-var /var ext4 uuid=a12bb95f-99f2-42c6-854f-1cb3f144d662 label= blocksize=4096 reserved_blocks=131072 max_mounts=23 check_interval=180d options=rw,commit=0 +-fs /dev/mapper/system-vmxfs /vmware xfs uuid=7457d2ab-8252-4f41-bab6-607316259975 label= options=rw,noatime +-fs /dev/mapper/system-kvm /kvm ext4 uuid=173ab1f7-8450-4176-8cf7-c09b47f5e3cc label= blocksize=4096 reserved_blocks=256000 max_mounts=21 check_interval=180d options=rw,noatime,commit=0 +-fs /dev/sda1 /boot ext3 uuid=f6b08566-ea5e-46f9-8f73-5e8ffdaa7be6 label= blocksize=1024 reserved_blocks=10238 max_mounts=35 check_interval=180d options=rw,commit=0 +-# fs /dev/mapper/backup-backup /media/backup ext4 uuid=da20354a-dc4c-4bef-817c-1c92894bb002 label= blocksize=4096 reserved_blocks=655360 max_mounts=24 check_interval=180d options=rw +-swap /dev/mapper/system-swap uuid=9f347fc7-1605-4788-98fd-fca828beedf1 label= +-crypt /dev/mapper/disk /dev/sda2 cipher=aes-xts-plain hash=sha1 uuid=beafe67c-d9a4-4992-80f1-e87791a543bb ++#disk /dev/sdc 1999696297984 msdos ++... ++#part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 ++#part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 ++#lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 ++... ++#lvmgrp /dev/backup 4096 220764 904249344 ++... ++#lvmvol /dev/backup backup 12800 104857600 ++#lvmvol /dev/backup externaltemp 38400 314572800 ++... ++#fs /dev/mapper/backup-backup /backup ext4 uuid=da20354a-dc4c-4bef-817c-1c92894bb002 label= blocksize=4096 reserved_blocks=655360 max_mounts=24 check_interval=180d options=rw + ---------------------------------- + + Another approach would be to exclude the backup volume group. This is achieved by adding this line to the local configuration: +@@ -295,22 +277,22 @@ checking the disklayout file, we'd better do that. + ---------------------------------- + #? 1 + disk /dev/sdb 160041885696 msdos +-# disk _REAR1_ 320072933376 msdos +-# disk /dev/sdc 1999696297984 msdos ++#disk _REAR1_ 320072933376 msdos ++#disk /dev/sdc 1999696297984 msdos + part /dev/sdb 209682432 32768 primary boot /dev/sdb1 + part /dev/sdb -20916822016 209719296 primary lvm /dev/sdb2 + part /dev/sdb 31192862720 128849022976 primary none /dev/sdb3 +-# part _REAR1_ 162144912384 32256 primary none _REAR1_1 +-# part _REAR1_ 152556666880 162144944640 primary none _REAR1_2 +-# part _REAR1_ 5371321856 314701611520 primary boot _REAR1_3 +-# part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 +-# part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 +-# lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 ++#part _REAR1_ 162144912384 32256 primary none _REAR1_1 ++#part _REAR1_ 152556666880 162144944640 primary none _REAR1_2 ++#part _REAR1_ 5371321856 314701611520 primary boot _REAR1_3 ++#part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 ++#part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 ++#lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 + lvmdev /dev/system /dev/mapper/disk N4Hpdc-DkBP-Hdm6-Z6FH-VixZ-7tTb-LiRt0w 251244544 +-# lvmgrp /dev/backup 4096 220764 904249344 ++#lvmgrp /dev/backup 4096 220764 904249344 + lvmgrp /dev/system 4096 30669 125620224 +-# lvmvol /dev/backup backup 12800 104857600 +-# lvmvol /dev/backup externaltemp 38400 314572800 ++#lvmvol /dev/backup backup 12800 104857600 ++#lvmvol /dev/backup externaltemp 38400 314572800 + lvmvol /dev/system root 2560 20971520 + lvmvol /dev/system home 5120 41943040 + lvmvol /dev/system var 2560 20971520 +@@ -323,7 +305,7 @@ fs /dev/mapper/system-var /var ext4 uuid=a12bb95f-99f2-42c6-854f-1cb3f144d662 la + fs /dev/mapper/system-vmxfs /vmware xfs uuid=7457d2ab-8252-4f41-bab6-607316259975 label= options=rw,noatime + fs /dev/mapper/system-kvm /kvm ext4 uuid=173ab1f7-8450-4176-8cf7-c09b47f5e3cc label= blocksize=4096 reserved_blocks=256000 max_mounts=21 check_interval=180d options=rw,noatime,commit=0 + fs /dev/sdb1 /boot ext3 uuid=f6b08566-ea5e-46f9-8f73-5e8ffdaa7be6 label= blocksize=1024 reserved_blocks=10238 max_mounts=35 check_interval=180d options=rw,commit=0 +-# fs /dev/mapper/backup-backup /media/backup ext4 uuid=da20354a-dc4c-4bef-817c-1c92894bb002 label= blocksize=4096 reserved_blocks=655360 max_mounts=24 check_interval=180d options=rw ++#fs /dev/mapper/backup-backup /backup ext4 uuid=da20354a-dc4c-4bef-817c-1c92894bb002 label= blocksize=4096 reserved_blocks=655360 max_mounts=24 check_interval=180d options=rw + swap /dev/mapper/system-swap uuid=9f347fc7-1605-4788-98fd-fca828beedf1 label= + crypt /dev/mapper/disk /dev/sdb2 cipher=aes-xts-plain hash=sha1 uuid=beafe67c-d9a4-4992-80f1-e87791a543bb + +@@ -344,22 +326,22 @@ The /kvm and /vmware filesystems are quite big. We don't care about them, so jus + The resulting layout file looks like this: + ---------------------------------- + disk /dev/sdb 160041885696 msdos +-# disk _REAR1_ 320072933376 msdos +-# disk /dev/sdc 1999696297984 msdos ++#disk _REAR1_ 320072933376 msdos ++#disk /dev/sdc 1999696297984 msdos + part /dev/sdb 209682432 32768 primary boot /dev/sdb1 + part /dev/sdb -20916822016 209719296 primary lvm /dev/sdb2 + part /dev/sdb 31192862720 128849022976 primary none /dev/sdb3 +-# part _REAR1_ 162144912384 32256 primary none _REAR1_1 +-# part _REAR1_ 152556666880 162144944640 primary none _REAR1_2 +-# part _REAR1_ 5371321856 314701611520 primary boot _REAR1_3 +-# part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 +-# part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 +-# lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 ++#part _REAR1_ 162144912384 32256 primary none _REAR1_1 ++#part _REAR1_ 152556666880 162144944640 primary none _REAR1_2 ++#part _REAR1_ 5371321856 314701611520 primary boot _REAR1_3 ++#part /dev/sdc 1073741824000 1048576 primary boot /dev/sdc1 ++#part /dev/sdc 925953425408 1073742872576 primary lvm /dev/sdc2 ++#lvmdev /dev/backup /dev/sdc2 cJp4Mt-Vkgv-hVlr-wTMb-0qeA-FX7j-3C60p5 1808502784 + lvmdev /dev/system /dev/mapper/disk N4Hpdc-DkBP-Hdm6-Z6FH-VixZ-7tTb-LiRt0w 251244544 +-# lvmgrp /dev/backup 4096 220764 904249344 ++#lvmgrp /dev/backup 4096 220764 904249344 + lvmgrp /dev/system 4096 30669 125620224 +-# lvmvol /dev/backup backup 12800 104857600 +-# lvmvol /dev/backup externaltemp 38400 314572800 ++#lvmvol /dev/backup backup 12800 104857600 ++#lvmvol /dev/backup externaltemp 38400 314572800 + lvmvol /dev/system root 2560 20971520 + lvmvol /dev/system home 5120 41943040 + lvmvol /dev/system var 2560 20971520 +@@ -372,7 +354,7 @@ fs /dev/mapper/system-var /var ext4 uuid=a12bb95f-99f2-42c6-854f-1cb3f144d662 la + #fs /dev/mapper/system-vmxfs /vmware xfs uuid=7457d2ab-8252-4f41-bab6-607316259975 label= options=rw,noatime + #fs /dev/mapper/system-kvm /kvm ext4 uuid=173ab1f7-8450-4176-8cf7-c09b47f5e3cc label= blocksize=4096 reserved_blocks=256000 max_mounts=21 check_interval=180d options=rw,noatime,commit=0 + fs /dev/sdb1 /boot ext3 uuid=f6b08566-ea5e-46f9-8f73-5e8ffdaa7be6 label= blocksize=1024 reserved_blocks=10238 max_mounts=35 check_interval=180d options=rw,commit=0 +-# fs /dev/mapper/backup-backup /media/backup ext4 uuid=da20354a-dc4c-4bef-817c-1c92894bb002 label= blocksize=4096 reserved_blocks=655360 max_mounts=24 check_interval=180d options=rw ++#fs /dev/mapper/backup-backup /backup ext4 uuid=da20354a-dc4c-4bef-817c-1c92894bb002 label= blocksize=4096 reserved_blocks=655360 max_mounts=24 check_interval=180d options=rw + swap /dev/mapper/system-swap uuid=9f347fc7-1605-4788-98fd-fca828beedf1 label= + crypt /dev/mapper/disk /dev/sdb2 cipher=aes-xts-plain hash=sha1 uuid=beafe67c-d9a4-4992-80f1-e87791a543bb + ---------------------------------- diff --git a/SOURCES/rear-multipath-bios-grub.patch b/SOURCES/rear-multipath-bios-grub.patch new file mode 100644 index 0000000..97d0368 --- /dev/null +++ b/SOURCES/rear-multipath-bios-grub.patch @@ -0,0 +1,25 @@ +commit 6289aae51d60d0ce326913f3fc30f5325abb483d +Author: Renaud Métrich <1163635+rmetrich@users.noreply.github.com> +Date: Fri Oct 25 09:14:50 2024 +0200 + + Make get_disklabel_type() also work for 'multipath' devices (#3334) + + Without this fix, get_disklabel_type() used to find a disk to install GRUB on + was returning nothing when the disk was a multipath device. + The reason is that then the line in disklayout.conf starts with 'multipath' + but ReaR had searched for 'disk' only. Now it also searches for 'multipath'. + See https://github.com/rear/rear/pull/3334 + +diff --git a/usr/share/rear/lib/layout-functions.sh b/usr/share/rear/lib/layout-functions.sh +index 90b16cb20..0763963de 100644 +--- a/usr/share/rear/lib/layout-functions.sh ++++ b/usr/share/rear/lib/layout-functions.sh +@@ -529,7 +529,7 @@ function get_disklabel_type () { + + disk='' + +- read component disk size label junk < <(grep "^disk $1 " "$LAYOUT_FILE") ++ read component disk size label junk < <(grep -E "^(disk|multipath) $1 " "$LAYOUT_FILE") + test $disk || return 1 + + echo $label diff --git a/SOURCES/rear-no-fat-16.patch b/SOURCES/rear-no-fat-16.patch new file mode 100644 index 0000000..f41bcb5 --- /dev/null +++ b/SOURCES/rear-no-fat-16.patch @@ -0,0 +1,84 @@ +diff --git a/usr/share/rear/format/USB/default/300_format_usb_disk.sh b/usr/share/rear/format/USB/default/300_format_usb_disk.sh +index 0e0a2e080..fa6496b23 100644 +--- a/usr/share/rear/format/USB/default/300_format_usb_disk.sh ++++ b/usr/share/rear/format/USB/default/300_format_usb_disk.sh +@@ -94,7 +94,13 @@ sleep 5 + + if is_true "$EFI" ; then + LogPrint "Creating vfat filesystem on EFI system partition on '${RAW_USB_DEVICE}1'" +- if ! mkfs.vfat $v -F 16 -n REAR-EFI ${RAW_USB_DEVICE}1 >&2 ; then ++ # Make a FAT filesystem on the EFI system partition ++ # cf. https://github.com/rear/rear/issues/2575 ++ # and output/ISO/Linux-i386/700_create_efibootimg.sh ++ # and output/RAWDISK/Linux-i386/280_create_bootable_disk_image.sh ++ # Let mkfs.vfat automatically select the FAT type based on the size. ++ # I.e. do not use a '-F 16' or '-F 32' option and hope for the best: ++ if ! mkfs.vfat $v -n REAR-EFI ${RAW_USB_DEVICE}1 >&2 ; then + Error "Failed to create vfat filesystem on '${RAW_USB_DEVICE}1'" + fi + # create link for EFI partition in /dev/disk/by-label +diff --git a/usr/share/rear/output/ISO/Linux-i386/700_create_efibootimg.sh b/usr/share/rear/output/ISO/Linux-i386/700_create_efibootimg.sh +index 0eb5350f8..39bbebad8 100644 +--- a/usr/share/rear/output/ISO/Linux-i386/700_create_efibootimg.sh ++++ b/usr/share/rear/output/ISO/Linux-i386/700_create_efibootimg.sh +@@ -13,13 +13,33 @@ StopIfError "Failed to determine disk usage of EFI virtual image content directo + + # prepare EFI virtual image aligned to 32MiB blocks: + dd if=/dev/zero of=$TMP_DIR/efiboot.img count=$efi_img_sz bs=32M +-mkfs.vfat $v -F 16 $TMP_DIR/efiboot.img >&2 +-mkdir -p $v $TMP_DIR/efi_virt >&2 +-mount $v -o loop -t vfat -o fat=16 $TMP_DIR/efiboot.img $TMP_DIR/efi_virt >&2 + +-# copy files from staging directory ++# Make a FAT filesystem on the efiboot.img file and loop mount it ++# cf. https://github.com/rear/rear/issues/2575 ++# See output/RAWDISK/Linux-i386/280_create_bootable_disk_image.sh ++# Having a small EFI System Partition (ESP) might introduce problems: ++# - The UEFI spec seems to require a FAT32 EFI System Partition (ESP). ++# - syslinux/Legacy BIOS fails to install on small FAT32 partitions with "syslinux: zero FAT sectors (FAT12/16)". ++# - Some firmwares fail to boot from small FAT32 partitions. ++# - Some firmwares fail to boot from FAT16 partitions. ++# See: ++# - http://www.rodsbooks.com/efi-bootloaders/principles.html ++# - http://lists.openembedded.org/pipermail/openembedded-core/2012-January/055999.html ++# Let mkfs.vfat automatically select the FAT type based on the size. ++# See what "man mkfs.vfat" reads for the '-F' option: ++# "If nothing is specified, mkfs.fat will automatically select ++# between 12, 16 and 32 bit, whatever fits better for the filesystem size" ++# I.e. do not use a '-F 16' or '-F 32' option and hope for the best: ++mkfs.vfat $v $TMP_DIR/efiboot.img ++mkdir -p $v $TMP_DIR/efi_virt ++# Do not specify '-o fat=16' or '-o fat=32' when loop mounting the efiboot.img FAT file ++# but rely on the automatic FAT type detection (see what "man 8 mount" reads for 'fat=...'): ++mount $v -o loop -t vfat $TMP_DIR/efiboot.img $TMP_DIR/efi_virt || Error "Failed to loop mount efiboot.img" ++ ++# Copy files from staging directory into efiboot.img + cp $v -r $TMP_DIR/mnt/. $TMP_DIR/efi_virt + +-umount $v $TMP_DIR/efiboot.img >&2 +-mv $v -f $TMP_DIR/efiboot.img $TMP_DIR/isofs/boot/efiboot.img >&2 +-StopIfError "Could not move efiboot.img file" ++umount $v $TMP_DIR/efiboot.img ++ ++# Move efiboot.img into ISO directory: ++mv $v -f $TMP_DIR/efiboot.img $TMP_DIR/isofs/boot/efiboot.img || Error "Failed to move efiboot.img to isofs/boot/efiboot.img" +diff --git a/usr/share/rear/output/ISO/Linux-ia64/200_mount_bootimg.sh b/usr/share/rear/output/ISO/Linux-ia64/200_mount_bootimg.sh +index b5f603ec5..716d7d383 100644 +--- a/usr/share/rear/output/ISO/Linux-ia64/200_mount_bootimg.sh ++++ b/usr/share/rear/output/ISO/Linux-ia64/200_mount_bootimg.sh +@@ -1,6 +1,11 @@ + # 200_mount_bootimg.sh + dd if=/dev/zero of=$TMP_DIR/boot.img count=64000 bs=1024 +-# make sure we select FAT16 instead of FAT12 as size >30MB +-mkfs.vfat $v -F 16 $TMP_DIR/boot.img >&2 +-mkdir -p $v $TMP_DIR/mnt >&2 +-mount $v -o loop -t vfat -o fat=16 $TMP_DIR/boot.img $TMP_DIR/mnt >&2 ++# Make a FAT filesystem on the boot.img file and loop mount it ++# cf. https://github.com/rear/rear/issues/2575 ++# and output/ISO/Linux-i386/700_create_efibootimg.sh ++# and output/RAWDISK/Linux-i386/280_create_bootable_disk_image.sh ++# Let mkfs.vfat automatically select the FAT type based on the size. ++# I.e. do not use a '-F 16' or '-F 32' option and hope for the best: ++mkfs.vfat $v $TMP_DIR/boot.img ++mkdir -p $v $TMP_DIR/mnt ++mount $v -o loop -t vfat $TMP_DIR/boot.img $TMP_DIR/mnt || Error "Failed to loop mount boot.img" diff --git a/SOURCES/rear-print-disk-mapping-with-sizes-RHEL-83241.patch b/SOURCES/rear-print-disk-mapping-with-sizes-RHEL-83241.patch new file mode 100644 index 0000000..7a79c67 --- /dev/null +++ b/SOURCES/rear-print-disk-mapping-with-sizes-RHEL-83241.patch @@ -0,0 +1,51 @@ +diff --git a/usr/share/rear/layout/prepare/default/300_map_disks.sh b/usr/share/rear/layout/prepare/default/300_map_disks.sh +index 468aa35cf..40ba876c7 100644 +--- a/usr/share/rear/layout/prepare/default/300_map_disks.sh ++++ b/usr/share/rear/layout/prepare/default/300_map_disks.sh +@@ -110,7 +110,10 @@ done + # to current block devices in the currently running recovery system: + while read keyword orig_device orig_size junk ; do + # Continue with next original device when it is already used as source in the mapping file: +- is_mapping_source "$orig_device" && continue ++ if is_mapping_source "$orig_device" ; then ++ DebugPrint "Skip automapping $orig_device with size $orig_size (already exists as source in $MAPPING_FILE)" ++ continue ++ fi + # First, try to find if there is a current disk with same name and same size as the original: + # (possibly influenced by mapping hints if known) + if has_mapping_hint "$orig_device" ; then +@@ -162,7 +165,7 @@ while read keyword orig_device orig_size junk ; do + # Ensure the determined target device is really a block device: + if test -b "$preferred_target_device_name" ; then + add_mapping "$orig_device" "$preferred_target_device_name" +- LogPrint "Using $preferred_target_device_name (same size) for recreating $orig_device" ++ LogPrint "Using $preferred_target_device_name (same size $current_size) for recreating $orig_device" + # Break looping over all current block devices to find one + # and continue with next original device in the LAYOUT_FILE: + break +@@ -213,6 +216,7 @@ while read keyword orig_device orig_size junk ; do + Log "$preferred_target_device_name excluded from device mapping choices (is already used as mapping target)" + continue + fi ++ LogPrint "The size of $preferred_target_device_name is $(blockdev --getsize64 $current_device_path)" + # Add the current device as possible choice for the user: + possible_targets+=( "$preferred_target_device_name" ) + done +@@ -225,7 +229,7 @@ while read keyword orig_device orig_size junk ; do + # At the end the mapping file is shown and the user can edit it if he does not like an automated mapping: + if test "1" -eq "${#possible_targets[@]}" ; then + add_mapping "$orig_device" "$possible_targets" +- LogPrint "Using $possible_targets (the only appropriate) for recreating $orig_device" ++ LogPrint "Using $possible_targets (the only available of the disks) for recreating $orig_device with size $orig_size" + # Continue with next original device in the LAYOUT_FILE: + continue + fi +@@ -233,7 +237,7 @@ while read keyword orig_device orig_size junk ; do + skip_choice="Do not map $preferred_orig_device_name" + regular_choices=( "${possible_targets[@]}" "$skip_choice" ) + rear_shell_choice="Use Relax-and-Recover shell and return back to here" +- prompt="Choose an appropriate replacement for $preferred_orig_device_name" ++ prompt="Choose an appropriate replacement for $preferred_orig_device_name with size $orig_size" + choice="" + wilful_input="" + # Generate a runtime-specific user_input_ID so that for each unmapped original device diff --git a/SOURCES/rear-rescue-ed25519-hostkey-support-RHEL-83479.patch b/SOURCES/rear-rescue-ed25519-hostkey-support-RHEL-83479.patch new file mode 100644 index 0000000..5a0d3fb --- /dev/null +++ b/SOURCES/rear-rescue-ed25519-hostkey-support-RHEL-83479.patch @@ -0,0 +1,27 @@ +From ed10cb3c612c49a6442e679052b755c52248ab3d Mon Sep 17 00:00:00 2001 +From: "D'Haese, Gratien [GTSBE - Non JJ]" +Date: Fri, 28 Feb 2025 17:05:21 +0100 +Subject: [PATCH] On EL9 sshd will not start anymore #3413 + +--- + usr/share/rear/skel/default/etc/scripts/run-sshd | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/usr/share/rear/skel/default/etc/scripts/run-sshd b/usr/share/rear/skel/default/etc/scripts/run-sshd +index 23b8233eed..3a422fe7cd 100755 +--- a/usr/share/rear/skel/default/etc/scripts/run-sshd ++++ b/usr/share/rear/skel/default/etc/scripts/run-sshd +@@ -13,6 +13,12 @@ if grep -q '^ssh:' /etc/inittab ; then + ssh-keygen -q -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key + echo -e "\nSSH fingerprint: $( ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub )\n" >> /etc/issue + fi ++ if ! test -s /etc/ssh/ssh_host_ed25519_key ; then ++ # Generate the ed25519 SSH host key required on EL9 ++ ssh-keygen -q -t ed25519 -N '' -f /etc/ssh/ssh_host_ed25519_key ++ echo -e "\nSSH fingerprint: $( ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub )\n" >> /etc/issue ++ fi ++ mkdir -p /usr/share/empty.sshd # required on EL9 + mkdir -p /run/sshd + # Avoid "Could not load host key: /etc/ssh/ssh_host_..._key" messages + # that look confusing on the recovery system login screen + diff --git a/SOURCES/rear-skip-longhorn-iscsi-RHEL-83551.patch b/SOURCES/rear-skip-longhorn-iscsi-RHEL-83551.patch new file mode 100644 index 0000000..58a0b94 --- /dev/null +++ b/SOURCES/rear-skip-longhorn-iscsi-RHEL-83551.patch @@ -0,0 +1,107 @@ +From 71e854e28db3b02497cd48637cc22bda843ccab0 Mon Sep 17 00:00:00 2001 +From: gdha +Date: Thu, 13 Feb 2025 15:59:31 +0100 +Subject: [PATCH 1/2] #3401 discard longhorn devices + +Signed-off-by: gdha +--- + .../save/GNU/Linux/230_filesystem_layout.sh | 59 ++++++++++--------- + 1 file changed, 30 insertions(+), 29 deletions(-) + +diff --git a/usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh b/usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh +index 15e104403..6ac35c8db 100644 +--- a/usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh ++++ b/usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh +@@ -117,37 +117,38 @@ fi + Log "Filesystem $fstype on $device mounted at $mountpoint is below Docker Root Dir $docker_root_dir, skipping." + continue + fi +- # In case Longhorn is rebuilding a replica device it will show up as a pseudo-device and when that is the +- # case then you would find traces of it in the /var/lib/rear/layout/disklayout.conf file, which would +- # break the recovery as Longhorn Engine replica's are under control of Rancher Longhorn software and these are +- # rebuild automatically via kubernetes longhorn-engine pods. +- # Issue where we discovered this behavior was #2365 +- # In normal situations you will find traces of longhorn in the log saying skipping non-block devices. +- # For example an output of the 'df' command: +- # /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 82045336 4500292 77528660 6% /var/lib/kubelet/pods/7f47aa55-30e2-4e7b-8fec-ec9a1e761352/volumes/kubernetes.io~csi/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792/mount +- # lsscsi shows it as: +- # [34:0:0:0] storage IET Controller 0001 - +- # [34:0:0:1] disk IET VIRTUAL-DISK 0001 /dev/sdf +- # ls -l /dev/sdf /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 +- # brw-rw---- 1 root disk 8, 80 Apr 17 12:02 /dev/sdf +- # brw-rw---- 1 root root 8, 64 Apr 17 10:36 /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 +- # and parted says: +- # parted /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 print +- # Model: IET VIRTUAL-DISK (scsi) +- # Disk /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792: 85.9GB +- # Sector size (logical/physical): 512B/512B +- # Partition Table: loop +- # Disk Flags: +- # Number Start End Size File system Flags +- # 1 0.00B 85.9GB 85.9GB ext4 +- # => as result (without the next if clausule) we would end up with an entry in the disklayout.conf file: +- # fs /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 /var/lib/kubelet/pods/61ed399a-d51b-40b8-8fe8-a78e84a1dd0b/volumes/kubernetes.io~csi/pvc-c65df331-f1c5-466a-9731-b2aa5e6da714/mount ext4 uuid=4fafdd40-a9ae-4b62-8bfb-f29036dbe3b9 label= blocksize=4096 reserved_blocks=0% max_mounts=-1 check_interval=0d bytes_per_inode=16384 default_mount_options=user_xattr,acl options=rw,relatime,data=ordered +- if echo "$device" | grep -q "^/dev/longhorn/pvc-" ; then +- Log "Longhorn Engine replica $device, skipping." +- continue +- fi + fi + fi ++ # In case Longhorn is rebuilding a replica device it will show up as a pseudo-device and when that is the ++ # case then you would find traces of it in the /var/lib/rear/layout/disklayout.conf file, which would ++ # break the recovery as Longhorn Engine replica's are under control of Rancher Longhorn software and these are ++ # rebuild automatically via kubernetes longhorn-engine pods. ++ # Issue where we discovered this behavior was #2365 ++ # In normal situations you will find traces of longhorn in the log saying skipping non-block devices. ++ # For example an output of the 'df' command: ++ # /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 82045336 4500292 77528660 6% /var/lib/kubelet/pods/7f47aa55-30e2-4e7b-8fec-ec9a1e761352/volumes/kubernetes.io~csi/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792/mount ++ # lsscsi shows it as: ++ # [34:0:0:0] storage IET Controller 0001 - ++ # [34:0:0:1] disk IET VIRTUAL-DISK 0001 /dev/sdf ++ # ls -l /dev/sdf /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 ++ # brw-rw---- 1 root disk 8, 80 Apr 17 12:02 /dev/sdf ++ # brw-rw---- 1 root root 8, 64 Apr 17 10:36 /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 ++ # and parted says: ++ # parted /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 print ++ # Model: IET VIRTUAL-DISK (scsi) ++ # Disk /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792: 85.9GB ++ # Sector size (logical/physical): 512B/512B ++ # Partition Table: loop ++ # Disk Flags: ++ # Number Start End Size File system Flags ++ # 1 0.00B 85.9GB 85.9GB ext4 ++ # => as result (without the next if clausule) we would end up with an entry in the disklayout.conf file: ++ # fs /dev/longhorn/pvc-ed09c0f2-c086-41c8-a38a-76ee8c289792 /var/lib/kubelet/pods/61ed399a-d51b-40b8-8fe8-a78e84a1dd0b/volumes/kubernetes.io~csi/pvc-c65df331-f1c5-466a-9731-b2aa5e6da714/mount ext4 uuid=4fafdd40-a9ae-4b62-8bfb-f29036dbe3b9 label= blocksize=4096 reserved_blocks=0% max_mounts=-1 check_interval=0d bytes_per_inode=16384 default_mount_options=user_xattr,acl options=rw,relatime,data=ordered ++ if echo "$device" | grep -q "^/dev/longhorn/pvc-" ; then ++ Log "Longhorn Engine replica $device, skipping." ++ continue ++ fi ++ + # Replace a symbolic link /dev/disk/by-uuid/a1b2c3 -> ../../sdXn + # by the fully canonicalized target of the link e.g. /dev/sdXn + if [[ $device == /dev/disk/by-uuid* ]]; then + +From 7805e8e440c9a2a2e7a890e8e70e5c7c285aee08 Mon Sep 17 00:00:00 2001 +From: gdha +Date: Fri, 14 Feb 2025 08:22:26 +0100 +Subject: [PATCH 2/2] replacing tab with spaces in comment + +Signed-off-by: gdha +--- + usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh b/usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh +index 6ac35c8db..b3dd4bbc0 100644 +--- a/usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh ++++ b/usr/share/rear/layout/save/GNU/Linux/230_filesystem_layout.sh +@@ -119,7 +119,7 @@ fi + fi + fi + fi +- # In case Longhorn is rebuilding a replica device it will show up as a pseudo-device and when that is the ++ # In case Longhorn is rebuilding a replica device it will show up as a pseudo-device and when that is the + # case then you would find traces of it in the /var/lib/rear/layout/disklayout.conf file, which would + # break the recovery as Longhorn Engine replica's are under control of Rancher Longhorn software and these are + # rebuild automatically via kubernetes longhorn-engine pods. + diff --git a/SOURCES/rear-support-aarch64-uefi-RHEL-56045.patch b/SOURCES/rear-support-aarch64-uefi-RHEL-56045.patch new file mode 100644 index 0000000..6d3ee9a --- /dev/null +++ b/SOURCES/rear-support-aarch64-uefi-RHEL-56045.patch @@ -0,0 +1,682 @@ +diff --git a/packaging/rpm/rear.spec b/packaging/rpm/rear.spec +index afb31e1e4..910c9f89a 100644 +--- a/packaging/rpm/rear.spec ++++ b/packaging/rpm/rear.spec +@@ -29,8 +29,8 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) + # Of course the rear bash scripts can be installed on any architecture just as any binaries can be installed on any architecture. + # But the meaning of architecture dependent packages should be on what architectures they will work. + # Therefore only those architectures that are actually supported are explicitly listed. +-# This avoids that rear can be "just installed" on architectures that are actually not supported (e.g. ARM or IBM z Systems): +-ExclusiveArch: %ix86 x86_64 ppc ppc64 ppc64le ia64 ++# This avoids that rear can be "just installed" on architectures that are actually not supported: ++ExclusiveArch: %ix86 x86_64 ppc ppc64 ppc64le ia64 s390x %arm aarch64 + # Furthermore for some architectures it requires architecture dependent packages (like syslinux for x86 and x86_64) + # so that rear must be architecture dependent because ifarch conditions never match in case of "BuildArch: noarch" + # see the GitHub issue https://github.com/rear/rear/issues/629 +diff --git a/usr/share/rear/conf/default.conf b/usr/share/rear/conf/default.conf +index 826f1ee59..17bf1a110 100644 +--- a/usr/share/rear/conf/default.conf ++++ b/usr/share/rear/conf/default.conf +@@ -784,9 +784,9 @@ ISO_RECOVER_MODE="" + ## + # + # OUTPUT=USB is only supported on PC-compatible (Linux-i386/x86/x86_64) architecture +-# see https://github.com/rear/rear/issues/2348 ++# see https://github.com/rear/rear/issues/2348 and arm/aarch64 using EFI. + # Accordingly in case of false usage of OUTPUT=USB on non-PC-compatible architectures +-# (i.e. the POWER architectures ppc64/ppc64le, IBM Z s390/s390x, and ARM) ++# (i.e. the POWER architectures ppc64/ppc64le, IBM Z s390/s390x) + # "rear mkrescue/mkbackup" errors out because on those architectures the USB medium cannot be booted + # because for non-PC-compatible architectures there are no scripts that install a USB bootloader. + # On non-PC-compatible architectures a possible alternative could be OUTPUT=RAMDISK (see above) +diff --git a/usr/share/rear/finalize/Linux-arm/610_EFISTUB_run_efibootmgr.sh b/usr/share/rear/finalize/Linux-arm/610_EFISTUB_run_efibootmgr.sh +new file mode 120000 +index 000000000..92f571a6b +--- /dev/null ++++ b/usr/share/rear/finalize/Linux-arm/610_EFISTUB_run_efibootmgr.sh +@@ -0,0 +1 @@ ++../Linux-i386/610_EFISTUB_run_efibootmgr.sh +\ No newline at end of file +diff --git a/usr/share/rear/finalize/Linux-arm/670_run_efibootmgr.sh b/usr/share/rear/finalize/Linux-arm/670_run_efibootmgr.sh +new file mode 120000 +index 000000000..5b967460e +--- /dev/null ++++ b/usr/share/rear/finalize/Linux-arm/670_run_efibootmgr.sh +@@ -0,0 +1 @@ ++../Linux-i386/670_run_efibootmgr.sh +\ No newline at end of file +diff --git a/usr/share/rear/layout/save/default/445_guess_bootloader.sh b/usr/share/rear/layout/save/default/445_guess_bootloader.sh +index 3576c387c..0211a4d6c 100644 +--- a/usr/share/rear/layout/save/default/445_guess_bootloader.sh ++++ b/usr/share/rear/layout/save/default/445_guess_bootloader.sh +@@ -30,15 +30,6 @@ if test -f /etc/sysconfig/bootloader ; then + fi + fi + +-# On ARM, guess the dummy bootloader: +-if [ "$ARCH" = "Linux-arm" ] ; then +- BOOTLOADER=ARM +- # Inform the user that we do nothing: +- LogPrint "Using guessed bootloader 'ARM'. Skipping bootloader backup, see default.conf" +- echo "$BOOTLOADER" >$bootloader_file +- return +-fi +- + # Check if any disk contains a PPC PReP boot partition. + # Detection taken from usr/share/rear/finalize/Linux-ppc64/680_install_PPC_bootlist.sh + disk_device="$( awk -F ' ' '/^part / {if ($6 ~ /prep/) {print $2}}' $LAYOUT_FILE )" +@@ -127,6 +118,15 @@ if is_true $USING_UEFI_BOOTLOADER ; then + return 0 + fi + ++# On ARM, guess the dummy bootloader: ++if [ "$ARCH" = "Linux-arm" ] ; then ++ BOOTLOADER=ARM ++ # Inform the user that we do nothing: ++ LogPrint "Using guessed bootloader 'ARM'. Skipping bootloader backup, see default.conf about 'BOOTLOADER'" ++ echo "$BOOTLOADER" >$bootloader_file ++ return ++fi ++ + # Error out when no bootloader was specified or could be autodetected: + Error "Cannot autodetect what is used as bootloader, see default.conf about 'BOOTLOADER'" + +diff --git a/usr/share/rear/lib/uefi-functions.sh b/usr/share/rear/lib/uefi-functions.sh +index 47f3c4fc3..bb79035e5 100644 +--- a/usr/share/rear/lib/uefi-functions.sh ++++ b/usr/share/rear/lib/uefi-functions.sh +@@ -36,7 +36,7 @@ function trim { + echo -n "$var" + } + +-function build_bootx86_efi { ++function build_boot_efi { + local outfile="$1" + local embedded_config="" + local gmkstandalone="" +@@ -62,9 +62,10 @@ function build_bootx86_efi { + # At least SUSE systems use 'grub2' prefixed names for GRUB2 programs: + gmkstandalone=grub2-mkstandalone + else +- # This build_bootx86_efi function is only called in output/ISO/Linux-i386/250_populate_efibootimg.sh +- # which runs only if UEFI is used so that we simply error out here if we cannot make a bootable EFI image of GRUB2 +- # (normally a function should not exit out but return to its caller with a non-zero return code): ++ # This build_boot_efi function is only called in 250_populate_efibootimg.sh ++ # and 100_create_efiboot.sh and 940_grub2_rescue.sh ++ # only if UEFI is used so that we simply error out here if we cannot make a bootable EFI image of GRUB2 ++ # (normally a function should not exit but return to its caller with a non-zero return code): + Error "Cannot make bootable EFI image of GRUB2 (neither grub-mkstandalone nor grub2-mkstandalone found)" + fi + +@@ -80,9 +81,9 @@ function build_bootx86_efi { + LogPrint "Neither grub-probe nor grub2-probe found" + # Since openSUSE Leap 15.1 things were moved from /usr/lib/grub2/ to /usr/share/grub2/ + # cf. https://github.com/rear/rear/issues/2338#issuecomment-594432946 +- if test /usr/*/grub*/x86_64-efi/partmap.lst ; then ++ if test /usr/*/grub*/"$GRUB2_IMAGE_FORMAT"/partmap.lst ; then + LogPrint "including all partition modules" +- modules=( $( cat /usr/*/grub*/x86_64-efi/partmap.lst ) ) ++ modules=( $( cat /usr/*/grub*/"$GRUB2_IMAGE_FORMAT"/partmap.lst ) ) + else + Error "Can not determine partition modules, ${dirs[*]} would be likely inaccessible in GRUB2" + fi +@@ -98,25 +99,25 @@ function build_bootx86_efi { + fi + fi + +- # grub-mkstandalone needs a .../grub*/x86_64-efi/moddep.lst file (cf. https://github.com/rear/rear/issues/1193) ++ # grub-mkstandalone needs a .../grub*/$GRUB2_IMAGE_FORMAT/moddep.lst file (cf. https://github.com/rear/rear/issues/1193) + # At least on SUSE systems that is in different 'grub2' directories (cf. https://github.com/rear/rear/issues/2338) + # e.g. on openSUSE Leap 15.0 it is in /usr/lib/grub2/x86_64-efi/moddep.lst + # but on openSUSE Leap 15.1 that was moved to /usr/share/grub2/x86_64-efi/moddep.lst + # and the one in /boot/grub2/x86_64-efi/moddep.lst is a copy of the one in /usr/*/grub2/x86_64-efi/moddep.lst + # so we do not error out if we do not find a /x86_64-efi/moddep.lst file because it could be "anywhere else" in the future + # but we inform the user here in advance about possible problems when there is no /x86_64-efi/moddep.lst file. +- # Careful: usr/sbin/rear sets nullglob so that /usr/*/grub*/x86_64-efi/moddep.lst gets empty if nothing matches +- # and 'test -f' succeeds with empty argument so that we cannot use 'test -f /usr/*/grub*/x86_64-efi/moddep.lst' ++ # Careful: usr/sbin/rear sets nullglob so that /usr/*/grub*/$GRUB2_IMAGE_FORMAT/moddep.lst gets empty if nothing matches ++ # and 'test -f' succeeds with empty argument so that we cannot use 'test -f /usr/*/grub*/$GRUB2_IMAGE_FORMAT/moddep.lst' + # also 'test -n' succeeds with empty argument but (fortunately/intentionally?) plain 'test' fails with empty argument. +- # Another implicit condition that this 'test' works is that '/usr/*/grub*/x86_64-efi/moddep.lst' matches at most one file +- # because otherwise e.g. "test /usr/*/grub*/x86_64-efi/mod*" where two files moddep.lst and modinfo.sh match ++ # Another implicit condition that this 'test' works is that '/usr/*/grub*/$GRUB2_IMAGE_FORMAT/moddep.lst' matches at most one file ++ # because otherwise e.g. "test /usr/*/grub*/$GRUB2_IMAGE_FORMAT/mod*" where two files moddep.lst and modinfo.sh match + # would falsely fail with "bash: test: ... unary operator expected": +- test /usr/*/grub*/x86_64-efi/moddep.lst || LogPrintError "$gmkstandalone may fail to make a bootable EFI image of GRUB2 (no /usr/*/grub*/x86_64-efi/moddep.lst file)" ++ test /usr/*/grub*/"$GRUB2_IMAGE_FORMAT"/moddep.lst || LogPrintError "$gmkstandalone may fail to make a bootable EFI image of GRUB2 (no /usr/*/grub*/$GRUB2_IMAGE_FORMAT/moddep.lst file)" + + (( ${#GRUB2_MODULES_UEFI[@]} )) && LogPrint "Installing only ${GRUB2_MODULES_UEFI[*]} modules into $outfile memdisk" + (( ${#modules[@]} )) && LogPrint "GRUB2 modules to load: ${modules[*]}" + +- if ! $gmkstandalone $v ${GRUB2_MODULES_UEFI:+"--install-modules=${GRUB2_MODULES_UEFI[*]}"} ${modules:+"--modules=${modules[*]}"} -O x86_64-efi -o $outfile $embedded_config ; then ++ if ! $gmkstandalone $v ${GRUB2_MODULES_UEFI:+"--install-modules=${GRUB2_MODULES_UEFI[*]}"} ${modules:+"--modules=${modules[*]}"} -O "$GRUB2_IMAGE_FORMAT" -o $outfile $embedded_config ; then + Error "Failed to make bootable EFI image of GRUB2 (error during $gmkstandalone of $outfile)" + fi + } +diff --git a/usr/share/rear/output/ISO/Linux-arm/250_populate_efibootimg.sh b/usr/share/rear/output/ISO/Linux-arm/250_populate_efibootimg.sh +new file mode 120000 +index 000000000..847e8f465 +--- /dev/null ++++ b/usr/share/rear/output/ISO/Linux-arm/250_populate_efibootimg.sh +@@ -0,0 +1 @@ ++../Linux-i386/250_populate_efibootimg.sh +\ No newline at end of file +diff --git a/usr/share/rear/output/ISO/Linux-arm/260_EFISTUB_populate.sh b/usr/share/rear/output/ISO/Linux-arm/260_EFISTUB_populate.sh +new file mode 120000 +index 000000000..93113f663 +--- /dev/null ++++ b/usr/share/rear/output/ISO/Linux-arm/260_EFISTUB_populate.sh +@@ -0,0 +1 @@ ++../Linux-i386/260_EFISTUB_populate.sh +\ No newline at end of file +diff --git a/usr/share/rear/output/ISO/Linux-arm/700_create_efibootimg.sh b/usr/share/rear/output/ISO/Linux-arm/700_create_efibootimg.sh +new file mode 120000 +index 000000000..8aa6a84a3 +--- /dev/null ++++ b/usr/share/rear/output/ISO/Linux-arm/700_create_efibootimg.sh +@@ -0,0 +1 @@ ++../Linux-i386/700_create_efibootimg.sh +\ No newline at end of file +diff --git a/usr/share/rear/output/ISO/Linux-arm/800_create_isofs.sh b/usr/share/rear/output/ISO/Linux-arm/800_create_isofs.sh +new file mode 100644 +index 000000000..0108dac05 +--- /dev/null ++++ b/usr/share/rear/output/ISO/Linux-arm/800_create_isofs.sh +@@ -0,0 +1,36 @@ ++# 800_create_isofs.sh ++# ++# create initramfs for Relax-and-Recover ++# ++# This file is part of Relax-and-Recover, licensed under the GNU General ++# Public License. Refer to the included COPYING for full text of license. ++ ++# Based on output/ISO/Linux-i386/800_create_isofs.sh with the creation of the ++# $TMP_DIR/isofs/isolinux directory added. This allows us to share scripts ++# used on x86_64 EFI machines. ++ ++# check that we have mkisofs ++test -x "$ISO_MKISOFS_BIN" || Error "No executable ISO_MKISOFS_BIN '$ISO_MKISOFS_BIN'" ++ ++# create some sub-dirs under $TMP_DIR for booting ++# The isolinux directory is used so that the x86_64 EFI scripts can be symlinked directly. ++[[ ! -d $TMP_DIR/isofs/isolinux ]] && mkdir $v -m 755 $TMP_DIR/isofs/isolinux >&2 ++ ++# kernel and initrd are already included in virtual image of ISO if ebiso is used ++if [[ $(basename $ISO_MKISOFS_BIN) = "ebiso" && $(basename ${UEFI_BOOTLOADER}) = "elilo.efi" ]]; then ++ Log "ebiso is used where kernel and initrd are already included in virtual image of ISO, skipping copying kernel and initrd" ++else ++ Log "Copying kernel and initrd" ++ cp -pL $v $KERNEL_FILE $TMP_DIR/isofs/isolinux/kernel || Error "Failed to copy KERNEL_FILE '$KERNEL_FILE'" ++ cp $v $TMP_DIR/$REAR_INITRD_FILENAME $TMP_DIR/isofs/isolinux/$REAR_INITRD_FILENAME || Error "Failed to copy initrd '$REAR_INITRD_FILENAME'" ++fi ++ ++#ISO_FILES+=( $TMP_DIR/kernel $TMP_DIR/$REAR_INITRD_FILENAME ) ++# in case the user populates this array manually we must not forget to copy ++# these files to our temporary isofs ++if test "${#ISO_FILES[@]}" -gt 0 ; then ++ cp -pL $v "${ISO_FILES[@]}" $TMP_DIR/isofs/isolinux/ || Error "Failed to copy ISO_FILES ${ISO_FILES[*]}" ++fi ++ ++mkdir -p $v "$ISO_DIR" || Error "Failed to create ISO_DIR '$ISO_DIR'" ++ +diff --git a/usr/share/rear/output/ISO/Linux-arm/810_prepare_multiple_iso.sh b/usr/share/rear/output/ISO/Linux-arm/810_prepare_multiple_iso.sh +new file mode 120000 +index 000000000..04f8a4955 +--- /dev/null ++++ b/usr/share/rear/output/ISO/Linux-arm/810_prepare_multiple_iso.sh +@@ -0,0 +1 @@ ++../Linux-i386/810_prepare_multiple_iso.sh +\ No newline at end of file +diff --git a/usr/share/rear/output/ISO/Linux-arm/820_create_iso_image.sh b/usr/share/rear/output/ISO/Linux-arm/820_create_iso_image.sh +new file mode 100644 +index 000000000..37842e018 +--- /dev/null ++++ b/usr/share/rear/output/ISO/Linux-arm/820_create_iso_image.sh +@@ -0,0 +1,40 @@ ++# Based on output/ISO/Linux-i386/820_create_iso_image.sh with the support ++# for non-EFI machines removed. ++ ++is_true $EFI_STUB && return 0 ++ ++Log "Starting '$ISO_MKISOFS_BIN'" ++LogPrint "Making ISO image" ++ ++is_true $USING_UEFI_BOOTLOADER || Error "OUTPUT=ISO on Linux-arm works only with UEFI" ++if [ -f /etc/slackware-version ] ; then ++ # slackware mkisofs uses different command line options ++ EFIBOOT="-eltorito-alt-boot -no-emul-boot -eltorito-platform efi -eltorito-boot boot/efiboot.img" ++else ++ EFIBOOT="-eltorito-alt-boot -e boot/efiboot.img -no-emul-boot" ++fi ++ ++pushd $TMP_DIR/isofs >/dev/null ++ ++# Error out when files greater or equal ISO_FILE_SIZE_LIMIT should be included in the ISO (cf. default.conf). ++# Consider all regular files and follow symbolic links to also get regular files where symlinks point to: ++assert_ISO_FILE_SIZE_LIMIT $( find -L . -type f ) ++ ++# ebiso uses different command line options and parameters: ++if test "ebiso" = $( basename $ISO_MKISOFS_BIN ) ; then ++ $ISO_MKISOFS_BIN $ISO_MKISOFS_OPTS -R -o $ISO_DIR/$ISO_PREFIX.iso -e boot/efiboot.img . ++else ++ $ISO_MKISOFS_BIN $v $ISO_MKISOFS_OPTS -o "$ISO_DIR/$ISO_PREFIX.iso" -no-emul-boot \ ++ -R -J -volid "$ISO_VOLID" $EFIBOOT -v -iso-level 3 . >/dev/null ++ ##-R -J -volid "$ISO_VOLID" $EFIBOOT "${ISO_FILES[@]}" >/dev/null ++fi ++StopIfError "Could not create ISO image (with $ISO_MKISOFS_BIN)" ++popd >/dev/null ++ ++iso_image_size=( $(du -h "$ISO_DIR/$ISO_PREFIX.iso") ) ++LogPrint "Wrote ISO image: $ISO_DIR/$ISO_PREFIX.iso ($iso_image_size)" ++ ++# Add ISO image to result files ++RESULT_FILES+=( "$ISO_DIR/$ISO_PREFIX.iso" ) ++ ++# vim: set et ts=4 sw=4: +diff --git a/usr/share/rear/output/ISO/Linux-arm/830_create_iso_image_EFISTUB.sh b/usr/share/rear/output/ISO/Linux-arm/830_create_iso_image_EFISTUB.sh +new file mode 100644 +index 000000000..83c2d1eeb +--- /dev/null ++++ b/usr/share/rear/output/ISO/Linux-arm/830_create_iso_image_EFISTUB.sh +@@ -0,0 +1,25 @@ ++# Based on output/ISO/Linux-i386/830_create_iso_image_EFISTUB.sh with the ++# support for non-EFI machines removed. ++ ++is_true $EFI_STUB || return 0 ++ ++Log "EFI_STUB: Starting '$ISO_MKISOFS_BIN'" ++LogPrint "EFI_STUB: Making ISO image" ++ ++pushd $TMP_DIR/isofs >/dev/null ++ ++# Error out when files greater or equal ISO_FILE_SIZE_LIMIT should be included in the ISO (cf. default.conf). ++# Consider all regular files and follow symbolic links to also get regular files where symlinks point to: ++assert_ISO_FILE_SIZE_LIMIT $( find -L . -type f ) ++ ++$ISO_MKISOFS_BIN $v $ISO_MKISOFS_OPTS -o "$ISO_DIR/$ISO_PREFIX.iso" -no-emul-boot \ ++ -R -J -volid "$ISO_VOLID" -v -iso-level 3 . >/dev/null ++ ++StopIfError "EFI_STUB: Could not create ISO image (with $ISO_MKISOFS_BIN)" ++popd >/dev/null ++ ++iso_image_size=( $(du -h "$ISO_DIR/$ISO_PREFIX.iso") ) ++LogPrint "EFI_STUB: Wrote ISO image: $ISO_DIR/$ISO_PREFIX.iso ($iso_image_size)" ++ ++# Add ISO image to result files ++RESULT_FILES+=( "$ISO_DIR/$ISO_PREFIX.iso" ) +diff --git a/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh b/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh +index 74ed1df3a..141cfbeae 100644 +--- a/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh ++++ b/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh +@@ -15,7 +15,7 @@ mkdir $v -p $efi_boot_tmp_dir/locale || Error "Could not create $efi_boot_tmp_di + + # Copy the grub*.efi executable to EFI/BOOT/BOOTX64.efi + # Intentionally an empty UEFI_BOOTLOADER results an invalid "cp -v /tmp/.../mnt/EFI/BOOT/BOOTX64.efi" command that fails: +-cp $v "$UEFI_BOOTLOADER" $efi_boot_tmp_dir/BOOTX64.efi || Error "Could not find UEFI_BOOTLOADER '$UEFI_BOOTLOADER'" ++cp $v "$UEFI_BOOTLOADER" $efi_boot_tmp_dir/BOOT$EFI_ARCH_UPPER.efi || Error "Could not find UEFI_BOOTLOADER '$UEFI_BOOTLOADER'" + local uefi_bootloader_dirname="$( dirname $UEFI_BOOTLOADER )" + if test -f "$SECURE_BOOT_BOOTLOADER" ; then + # FIXME: Explain why it tests that a SECURE_BOOT_BOOTLOADER file exists +@@ -52,7 +52,7 @@ if test "ebiso" = "$( basename $ISO_MKISOFS_BIN )" ; then + fi + + if [[ -n "$(type -p grub)" ]]; then +- cat > $efi_boot_tmp_dir/BOOTX64.conf << EOF ++ cat > $efi_boot_tmp_dir/BOOT$EFI_ARCH_UPPER.conf << EOF + default=0 + timeout 5 + splashimage=/EFI/BOOT/splash.xpm.gz +@@ -70,9 +70,9 @@ fi + # We are not able to create signed boot loader + # so we need to reuse existing one. + # See issue #1374 +-# build_bootx86_efi () can be safely used for other scenarios. ++# build_boot_efi () can be safely used for other scenarios. + if ! test -f "$SECURE_BOOT_BOOTLOADER" ; then +- build_bootx86_efi $TMP_DIR/mnt/EFI/BOOT/BOOTX64.efi $efi_boot_tmp_dir/grub.cfg "$boot_dir" "$UEFI_BOOTLOADER" ++ build_boot_efi $TMP_DIR/mnt/EFI/BOOT/BOOT$EFI_ARCH_UPPER.efi $efi_boot_tmp_dir/grub.cfg "$boot_dir" "$UEFI_BOOTLOADER" + fi + + # We will be using grub-efi or grub2 (with efi capabilities) to boot from ISO. +@@ -111,7 +111,7 @@ cp $v -r $TMP_DIR/mnt/EFI $TMP_DIR/isofs/ || Error "Could not create the isofs/E + # Make /boot/grub/grub.cfg available on isofs/ + mkdir $v -p -m 755 $TMP_DIR/isofs/boot/grub + if test "$( type -p grub )" ; then +- cp $v $TMP_DIR/isofs/EFI/BOOT/BOOTX64.conf $TMP_DIR/isofs/boot/grub/ || Error "Could not copy EFI/BOOT/BOOTX64.conf to isofs/boot/grub" ++ cp $v $TMP_DIR/isofs/EFI/BOOT/BOOT$EFI_ARCH_UPPER.conf $TMP_DIR/isofs/boot/grub/ || Error "Could not copy EFI/BOOT/BOOT${EFI_ARCH_UPPER}.conf to isofs/boot/grub" + else + cp $v $TMP_DIR/isofs/EFI/BOOT/grub.cfg $TMP_DIR/isofs/boot/grub/ || Error "Could not copy EFI/BOOT/grub.cfg to isofs/boot/grub" + fi +diff --git a/usr/share/rear/output/ISO/Linux-i386/260_EFISTUB_populate.sh b/usr/share/rear/output/ISO/Linux-i386/260_EFISTUB_populate.sh +index a91264494..3c2380d8b 100644 +--- a/usr/share/rear/output/ISO/Linux-i386/260_EFISTUB_populate.sh ++++ b/usr/share/rear/output/ISO/Linux-i386/260_EFISTUB_populate.sh +@@ -33,7 +33,7 @@ else + Error "EFI_STUB: EFI executable $OUTPUT_EFISTUB_SYSTEMD_BOOTLOADER not found" + fi + +-cp $v "$OUTPUT_EFISTUB_SYSTEMD_BOOTLOADER" $efi_boot_tmp_dir/BOOTX64.efi ++cp $v "$OUTPUT_EFISTUB_SYSTEMD_BOOTLOADER" $efi_boot_tmp_dir/BOOT${EFI_ARCH_UPPER}.efi + + + # Create boot menu entries for systemd-bootx64.efi. +diff --git a/usr/share/rear/output/RAWDISK/Linux-i386/260_create_syslinux_efi_bootloader.sh b/usr/share/rear/output/RAWDISK/Linux-i386/260_create_syslinux_efi_bootloader.sh +index cca8caf6b..155f433c9 100644 +--- a/usr/share/rear/output/RAWDISK/Linux-i386/260_create_syslinux_efi_bootloader.sh ++++ b/usr/share/rear/output/RAWDISK/Linux-i386/260_create_syslinux_efi_bootloader.sh +@@ -33,7 +33,7 @@ local efi_boot_directory="$RAWDISK_BOOT_EFI_STAGING_ROOT/BOOT" + + mkdir $v -p "$efi_boot_directory" || Error "Could not create $efi_boot_directory" + +-cp $v "$syslinux_efi" "$efi_boot_directory/BOOTX64.EFI" >&2 ++cp $v "$syslinux_efi" "$efi_boot_directory/BOOT${EFI_ARCH_UPPER}.EFI" >&2 + cp $v "$ldlinux_e64" "$efi_boot_directory" >&2 + + +diff --git a/usr/share/rear/output/RAWDISK/Linux-i386/270_create_grub2_efi_bootloader.sh b/usr/share/rear/output/RAWDISK/Linux-i386/270_create_grub2_efi_bootloader.sh +index 8b543d8c8..0dbf17547 100644 +--- a/usr/share/rear/output/RAWDISK/Linux-i386/270_create_grub2_efi_bootloader.sh ++++ b/usr/share/rear/output/RAWDISK/Linux-i386/270_create_grub2_efi_bootloader.sh +@@ -21,7 +21,7 @@ fi + # cf. https://github.com/rear/rear/issues/2338#issuecomment-594432946 + local efi_modules_directory + local dir +-for dir in /usr/lib/grub/x86_64-efi /usr/lib/grub2/x86_64-efi /usr/share/grub2/x86_64-efi; do ++for dir in "/usr/lib/grub/$GRUB2_IMAGE_FORMAT" "/usr/lib/grub2/$GRUB2_IMAGE_FORMAT" "/usr/share/grub2/$GRUB2_IMAGE_FORMAT"; do + if [[ -d "$dir" ]]; then + efi_modules_directory="$dir" + break +@@ -71,10 +71,10 @@ if [[ -n "$SECURE_BOOT_BOOTLOADER" ]]; then + # If /boot/$grub2_name exists, it contains additional Grub modules, which are not compiled into the grub core image. + # Pick required ones from there, too. + local additional_grub_directory="/boot/$grub2_name" +- local grub_modules_directory="x86_64-efi" ++ local grub_modules_directory="$GRUB2_IMAGE_FORMAT" + local additional_grub_modules=( all_video.mod ) + if [[ -d "$additional_grub_directory/$grub_modules_directory" ]]; then +- local grub_target_directory="$(dirname "$(find "$RAWDISK_BOOT_EFI_STAGING_ROOT" -iname grubx64.efi -print)")" ++ local grub_target_directory="$(dirname "$(find "$RAWDISK_BOOT_EFI_STAGING_ROOT" -iname grub${EFI_ARCH}.efi -print)")" + [[ "$grub_target_directory" == "." ]] && Error "Could not find Grub executable" # dirname "" returns "." + + mkdir "$grub_target_directory/$grub_modules_directory" || Error "Could not create Grub modules directory" +@@ -102,9 +102,9 @@ else + + # Create a Grub 2 EFI core image and install it as boot loader. (NOTE: This version will not be signed.) + # Use the UEFI default boot loader name, so that firmware will find it without an existing boot entry. +- local boot_loader="$efi_boot_directory/BOOTX64.EFI" ++ local boot_loader="$efi_boot_directory/BOOT${EFI_ARCH_UPPER}.EFI" + local grub_modules=( part_gpt fat normal configfile linux video all_video ) + [[ -f "$efi_modules_directory/linuxefi.mod" ]] && grub_modules+=("$efi_modules_directory/linuxefi.mod") +- $grub2_name-mkimage -O x86_64-efi -o "$boot_loader" -p "/EFI/BOOT" "${grub_modules[@]}" ++ $grub2_name-mkimage -O "$GRUB2_IMAGE_FORMAT" -o "$boot_loader" -p "/EFI/BOOT" "${grub_modules[@]}" + StopIfError "Error occurred during $grub2_name-mkimage of $boot_loader" + fi +diff --git a/usr/share/rear/output/USB/Linux-arm/100_create_efiboot.sh b/usr/share/rear/output/USB/Linux-arm/100_create_efiboot.sh +new file mode 120000 +index 000000000..3846131fb +--- /dev/null ++++ b/usr/share/rear/output/USB/Linux-arm/100_create_efiboot.sh +@@ -0,0 +1 @@ ++../Linux-i386/100_create_efiboot.sh +\ No newline at end of file +diff --git a/usr/share/rear/output/USB/Linux-i386/100_create_efiboot.sh b/usr/share/rear/output/USB/Linux-i386/100_create_efiboot.sh +index fd631c444..cfcd001d7 100644 +--- a/usr/share/rear/output/USB/Linux-i386/100_create_efiboot.sh ++++ b/usr/share/rear/output/USB/Linux-i386/100_create_efiboot.sh +@@ -51,8 +51,8 @@ if test -f "$SECURE_BOOT_BOOTLOADER" ; then + # (cf. rescue/default/850_save_sysfs_uefi_vars.sh) + # then Shim (usually shim.efi) must be copied as EFI/BOOT/BOOTX64.efi + # and Shim's second stage bootloader must be also copied where Shim already is. +- DebugPrint "Using '$SECURE_BOOT_BOOTLOADER' as first stage Secure Boot bootloader BOOTX64.efi" +- cp -L $v "$SECURE_BOOT_BOOTLOADER" "$EFI_DST/BOOTX64.efi" || Error "Failed to copy SECURE_BOOT_BOOTLOADER '$SECURE_BOOT_BOOTLOADER' to $EFI_DST/BOOTX64.efi" ++ DebugPrint "Using '$SECURE_BOOT_BOOTLOADER' as first stage Secure Boot bootloader BOOT${EFI_ARCH_UPPER}.efi" ++ cp -L $v "$SECURE_BOOT_BOOTLOADER" "$EFI_DST/BOOT${EFI_ARCH_UPPER}.efi" || Error "Failed to copy SECURE_BOOT_BOOTLOADER '$SECURE_BOOT_BOOTLOADER' to $EFI_DST/BOOT${EFI_ARCH_UPPER}.efi" + # When Shim is used, its second stage bootloader can be actually anything + # named grub*.efi (second stage bootloader is Shim compile time option), see + # http://www.rodsbooks.com/efi-bootloaders/secureboot.html#initial_shim +@@ -65,9 +65,8 @@ if test -f "$SECURE_BOOT_BOOTLOADER" ; then + DebugPrint "Using second stage Secure Boot bootloader files: $second_stage_UEFI_bootloader_files" + cp -L $v $second_stage_UEFI_bootloader_files $EFI_DST/ || Error "Failed to copy second stage Secure Boot bootloader files" + else +- cp -L $v "$UEFI_BOOTLOADER" "$EFI_DST/BOOTX64.efi" || Error "Failed to copy UEFI_BOOTLOADER '$UEFI_BOOTLOADER' to $EFI_DST/BOOTX64.efi" ++ cp -L $v "$UEFI_BOOTLOADER" "$EFI_DST/BOOT${EFI_ARCH_UPPER}.efi" || Error "Failed to copy UEFI_BOOTLOADER '$UEFI_BOOTLOADER' to $EFI_DST/BOOT${EFI_ARCH_UPPER}.efi" + fi +-cp $v $UEFI_BOOTLOADER "$EFI_DST/BOOTX64.efi" || Error "Failed to copy UEFI_BOOTLOADER '$UEFI_BOOTLOADER' to $EFI_DST/BOOTX64.efi" + + # Copy kernel + cp -pL $v "$KERNEL_FILE" "$EFI_DST/kernel" || Error "Failed to copy KERNEL_FILE '$KERNEL_FILE' to $EFI_DST/kernel" +@@ -109,7 +108,7 @@ else + Log "Configuring grub 0.97 for EFI boot" + + # Create config for grub 0.97 +- cat > ${EFI_DST}/BOOTX64.conf << EOF ++ cat > ${EFI_DST}/BOOT${EFI_ARCH_UPPER}.conf << EOF + default=0 + timeout=5 + +@@ -117,7 +116,7 @@ title Relax-and-Recover (no Secure Boot) + kernel ${EFI_DIR}/kernel $KERNEL_CMDLINE + initrd ${EFI_DIR}/$REAR_INITRD_FILENAME + EOF +- ;; ++ ;; + 2) + Log "Configuring grub 2.0 for EFI boot" + # We need to explicitly set $root variable to $EFI_LABEL +@@ -128,22 +127,22 @@ EOF + grub2_set_usb_root="search --no-floppy --set=root --label ${EFI_LABEL}" + + # Create config for grub 2.0 +- create_grub2_cfg ${EFI_DIR}/kernel ${EFI_DIR}/$REAR_INITRD_FILENAME > ${EFI_DST}/grub.cfg ++ create_grub2_cfg ${EFI_DIR}/kernel ${EFI_DIR}/$REAR_INITRD_FILENAME > ${EFI_DST}/grub.cfg + + # Create bootloader, this overwrite BOOTX64.efi copied in previous step ... +- # Create BOOTX86.efi but only if we are NOT secure booting. +- # We are not able to create signed boot loader +- # so we need to reuse existing one. +- # See issue #1374 +- # build_bootx86_efi () can be safely used for other scenarios. +- if ! test -f "$SECURE_BOOT_BOOTLOADER" ; then +- build_bootx86_efi ${EFI_DST}/BOOTX64.efi ${EFI_DST}/grub.cfg "/boot" "$UEFI_BOOTLOADER" +- fi +- ;; ++ # Create BOOTX86.efi but only if we are NOT secure booting. ++ # We are not able to create signed boot loader ++ # so we need to reuse existing one. ++ # See issue #1374 ++ # build_boot_efi () can be safely used for other scenarios. ++ if ! test -f "$SECURE_BOOT_BOOTLOADER" ; then ++ build_boot_efi $EFI_DST/BOOT$EFI_ARCH_UPPER.efi $EFI_DST/grub.cfg "/boot" "$UEFI_BOOTLOADER" ++ fi ++ ;; + *) + BugError "Neither grub 0.97 nor 2.0" +- ;; +- esac ++ ;; ++ esac + else + BugIfError "Unknown EFI bootloader" + fi +diff --git a/usr/share/rear/output/USB/Linux-i386/300_create_extlinux.sh b/usr/share/rear/output/USB/Linux-i386/300_create_extlinux.sh +index 47c7dc80c..3bbb66e2b 100644 +--- a/usr/share/rear/output/USB/Linux-i386/300_create_extlinux.sh ++++ b/usr/share/rear/output/USB/Linux-i386/300_create_extlinux.sh +@@ -95,12 +95,6 @@ case "$WORKFLOW" in + (*) BugError "Workflow $WORKFLOW should not run this script." + esac + +-USB_REAR_DIR="$BUILD_DIR/outputfs/$USB_PREFIX" +-if [ ! -d "$USB_REAR_DIR" ]; then +- mkdir -p $v "$USB_REAR_DIR" >/dev/null +- StopIfError "Could not create USB ReaR dir [$USB_REAR_DIR] !" +-fi +- + # We generate a single syslinux.cfg for the current system + Log "Creating $USB_PREFIX/syslinux.cfg" + # FIXME: # type -a time +diff --git a/usr/share/rear/output/USB/default/200_make_usb_prefix_dir.sh b/usr/share/rear/output/USB/default/200_make_usb_prefix_dir.sh +new file mode 100644 +index 000000000..3c8ff6e6c +--- /dev/null ++++ b/usr/share/rear/output/USB/default/200_make_usb_prefix_dir.sh +@@ -0,0 +1,8 @@ ++# The $BUILD_DIR/outputfs/$USB_PREFIX directory is needed by subsequent scripts ++# like output/USB/default/830_copy_kernel_initrd.sh to store kernel and initrd ++# and for parts of the syslinux config in 'syslinux.cfg' if syslinux/extlinux is used ++ ++USB_REAR_DIR="$BUILD_DIR/outputfs/$USB_PREFIX" ++if [ ! -d "$USB_REAR_DIR" ] ; then ++ mkdir -p $v "$USB_REAR_DIR" || Error "Failed to create USB ReaR dir '$usb_rear_dir'" ++fi +diff --git a/usr/share/rear/output/USB/Linux-i386/830_copy_kernel_initrd.sh b/usr/share/rear/output/USB/default/830_copy_kernel_initrd.sh +similarity index 100% +rename from usr/share/rear/output/USB/Linux-i386/830_copy_kernel_initrd.sh +rename to usr/share/rear/output/USB/default/830_copy_kernel_initrd.sh +diff --git a/usr/share/rear/output/default/940_grub2_rescue.sh b/usr/share/rear/output/default/940_grub2_rescue.sh +index 38e816389..af09ca381 100644 +--- a/usr/share/rear/output/default/940_grub2_rescue.sh ++++ b/usr/share/rear/output/default/940_grub2_rescue.sh +@@ -173,7 +173,8 @@ if is_true $USING_UEFI_BOOTLOADER ; then + ) > $grub_config_dir/rear.cfg + + # Create rear.efi at UEFI default boot directory location. +- build_bootx86_efi $boot_dir/efi/EFI/BOOT/rear.efi $grub_config_dir/rear.cfg "$boot_dir" "$UEFI_BOOTLOADER" ++ # The build_boot_efi errors out if it cannot make a bootable EFI image of GRUB2: ++ build_boot_efi $boot_dir/efi/EFI/BOOT/rear.efi $grub_config_dir/rear.cfg "$boot_dir" "$UEFI_BOOTLOADER" + + # If UEFI boot entry for "Relax-and-Recover" does not exist, create it. + # This will also add "Relax-and-Recover" to boot order because if UEFI entry is not listed in BootOrder, +diff --git a/usr/share/rear/prep/Linux-arm/060_check_config.sh b/usr/share/rear/prep/Linux-arm/060_check_config.sh +deleted file mode 100644 +index ca0978a12..000000000 +--- a/usr/share/rear/prep/Linux-arm/060_check_config.sh ++++ /dev/null +@@ -1,3 +0,0 @@ +-if [ "$OUTPUT" != "PXE" ] ; then +- Error "Currently only OUTPUT=PXE is supported on ARM" +-fi +diff --git a/usr/share/rear/prep/Linux-arm/330_set_efi_arch.sh b/usr/share/rear/prep/Linux-arm/330_set_efi_arch.sh +new file mode 100644 +index 000000000..2dfd82d24 +--- /dev/null ++++ b/usr/share/rear/prep/Linux-arm/330_set_efi_arch.sh +@@ -0,0 +1,21 @@ ++ ++# Set EFI architecture, used as suffix for various files in the ESP ++# See https://github.com/rhboot/shim/blob/main/Make.defaults ++ ++# Set the variables even if USING_UEFI_BOOTLOADER empty or no explicit 'true' value ++# cf. prep/Linux-i386/330_set_efi_arch.sh ++ ++case "$REAL_MACHINE" in ++ (arm64|aarch64) ++ EFI_ARCH=aa64 ++ GRUB2_IMAGE_FORMAT=arm64-efi ++ ;; ++ (arm*) ++ EFI_ARCH=arm ++ GRUB2_IMAGE_FORMAT=arm-efi ++ ;; ++ (*) ++ BugError "Unknown architecture $REAL_MACHINE" ++esac ++ ++EFI_ARCH_UPPER="${EFI_ARCH^^}" +diff --git a/usr/share/rear/prep/Linux-i386/330_set_efi_arch.sh b/usr/share/rear/prep/Linux-i386/330_set_efi_arch.sh +new file mode 100644 +index 000000000..51a320767 +--- /dev/null ++++ b/usr/share/rear/prep/Linux-i386/330_set_efi_arch.sh +@@ -0,0 +1,32 @@ ++ ++# Set EFI architecture, used as suffix for various files in the ESP ++# See https://github.com/rhboot/shim/blob/main/Make.defaults ++ ++# Set the variables even if USING_UEFI_BOOTLOADER empty or no explicit 'true' value ++# which sets GRUB2_IMAGE_FORMAT (used as argument for 'grub-mkstandalone -O ...') ++# to a value for EFI systems ('x86_64-efi' or 'i386-efi') also on BIOS systems ++# but that does not matter for now because currently GRUB2_IMAGE_FORMAT ++# is only used in case of EFI in the scripts lib/uefi-functions.sh ++# and output/RAWDISK/Linux-i386/270_create_grub2_efi_bootloader.sh ++# see https://github.com/rear/rear/pull/3157 ++# and https://github.com/rear/rear/issues/3191 ++# and https://github.com/rear/rear/issues/3195 ++ ++case "$REAL_MACHINE" in ++ # cf. the seting of REAL_MACHINE ('uname -m') and MACHINE in default.conf ++ (i686|i586|i386) ++ # all these behave exactly like i386. ++ # ia32 is another name for i386, used by EFI ++ # (but ia64 is not x86_64 aka amd64, it is the architecture of Itanium) ++ EFI_ARCH=ia32 ++ GRUB2_IMAGE_FORMAT=i386-efi ++ ;; ++ (x86_64) ++ EFI_ARCH=x64 ++ GRUB2_IMAGE_FORMAT=x86_64-efi ++ ;; ++ (*) ++ BugError "Unknown architecture $REAL_MACHINE" ++esac ++ ++EFI_ARCH_UPPER="${EFI_ARCH^^}" +diff --git a/usr/share/rear/prep/Linux-ia64/330_set_efi_arch.sh b/usr/share/rear/prep/Linux-ia64/330_set_efi_arch.sh +new file mode 100644 +index 000000000..668a3262e +--- /dev/null ++++ b/usr/share/rear/prep/Linux-ia64/330_set_efi_arch.sh +@@ -0,0 +1,12 @@ ++ ++# Set EFI architecture, used as suffix for various files in the ESP ++# See https://github.com/rhboot/shim/blob/main/Make.defaults ++ ++# Set the variables even if USING_UEFI_BOOTLOADER empty or no explicit 'true' value ++# cf. prep/Linux-i386/330_set_efi_arch.sh ++ ++EFI_ARCH=ia64 ++# argument for grub2-mkstandalone -O ... ++GRUB2_IMAGE_FORMAT=ia64-efi ++ ++EFI_ARCH_UPPER="${EFI_ARCH^^}" +diff --git a/usr/share/rear/prep/USB/Linux-arm/350_safeguard_error_out.sh b/usr/share/rear/prep/USB/Linux-arm/350_safeguard_error_out.sh +deleted file mode 120000 +index 49a162aeb..000000000 +--- a/usr/share/rear/prep/USB/Linux-arm/350_safeguard_error_out.sh ++++ /dev/null +@@ -1 +0,0 @@ +-../Linux-ppc64/350_safeguard_error_out.sh +\ No newline at end of file +diff --git a/usr/share/rear/prep/USB/Linux-ppc64/350_safeguard_error_out.sh b/usr/share/rear/prep/USB/Linux-ppc64/350_safeguard_error_out.sh +index 412014ea3..6b56a5dee 100644 +--- a/usr/share/rear/prep/USB/Linux-ppc64/350_safeguard_error_out.sh ++++ b/usr/share/rear/prep/USB/Linux-ppc64/350_safeguard_error_out.sh +@@ -27,10 +27,6 @@ + # OUTPUT=USB on IBM Z (s390/s390x) architecture: + # The symbolic link prep/USB/Linux-s390/350_safeguard_error_out.sh + # and its link target prep/USB/Linux-ppc64/350_safeguard_error_out.sh +-# +-# OUTPUT=USB on ARM architecture: +-# The symbolic link prep/USB/Linux-arm/350_safeguard_error_out.sh +-# and its link target prep/USB/Linux-ppc64/350_safeguard_error_out.sh + + Error "OUTPUT=USB not supported on $ARCH (no support to install a bootloader)" + +diff --git a/usr/share/rear/rescue/default/850_save_sysfs_uefi_vars.sh b/usr/share/rear/rescue/default/850_save_sysfs_uefi_vars.sh +index 678b9c598..8e4f902d3 100644 +--- a/usr/share/rear/rescue/default/850_save_sysfs_uefi_vars.sh ++++ b/usr/share/rear/rescue/default/850_save_sysfs_uefi_vars.sh +@@ -55,11 +55,11 @@ for dummy in "once" ; do + UEFI_BOOTLOADER=$( find /boot/efi -name 'elilo.efi' | tail -1 ) + test -f "$UEFI_BOOTLOADER" && continue + # In case we have a 64-bit systemd bootloader we might be lucky with next statement: +- UEFI_BOOTLOADER=$( find /boot/EFI -name 'BOOTX64.EFI' | tail -1 ) ++ UEFI_BOOTLOADER=$( find /boot/EFI -name "BOOT${EFI_ARCH_UPPER}.EFI" | tail -1 ) + test -f "$UEFI_BOOTLOADER" && continue + # Try more generic finds in whole /boot with case insensitive filename matching. + # On older systems where 'find' does not support '-iname' this does not make it really worse because there 'find' just fails. +- for find_name_pattern in 'grub*.efi' 'elilo.efi' 'BOOTX64.EFI' ; do ++ for find_name_pattern in 'grub*.efi' 'elilo.efi' "BOOT${EFI_ARCH_UPPER}.EFI" ; do + # No need to test if find_name_pattern is empty because 'find' does not find anything with empty '-iname': + UEFI_BOOTLOADER=$( find /boot -iname "$find_name_pattern" | tail -1 ) + # Continue with the code after the outer 'for' loop: diff --git a/SOURCES/rear-support-multi-keyslot-luks-RHEL-83776.patch b/SOURCES/rear-support-multi-keyslot-luks-RHEL-83776.patch new file mode 100644 index 0000000..973e75a --- /dev/null +++ b/SOURCES/rear-support-multi-keyslot-luks-RHEL-83776.patch @@ -0,0 +1,167 @@ +From b448f6c71e96d01909ec8d877f78201e9f9efa45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= + <1163635+rmetrich@users.noreply.github.com> +Date: Fri, 27 Jun 2025 14:39:01 +0200 +Subject: [PATCH] LUKS2: try to handle multiple key slots (#3430) + +LUKS2: try to handle multiple key slots: +The current code doesn't deal properly with multiple key slots nor +extracts the Hash that was used at LUKS creation properly. +With current code, when multiple key slots are found or PBKDF algorithm +is "pbkdf2" (instead of default "argon2id"), the disk layout file +contains 2 lines for 'crypt' parameters, causing havoc during recovery. +This new code tries to do better: +It searches for the Hash in Keyslots section only +(and falls back to Digests section if not found). +It warns the admin if multiple keyslots are in use +(e.g. because of multiple passphrases or Clevis binding). +It handles the PBKDF algorithm. +It makes sure that the 'crypt' parameters are always on one line. +--- + doc/user-guide/06-layout-configuration.adoc | 2 +- + .../GNU/Linux/160_include_luks_code.sh | 3 + + .../layout/save/GNU/Linux/260_crypt_layout.sh | 69 ++++++++++++++++--- + 3 files changed, 62 insertions(+), 12 deletions(-) + +diff --git a/doc/user-guide/06-layout-configuration.adoc b/doc/user-guide/06-layout-configuration.adoc +index 680d69640..8a56cb77a 100644 +--- a/doc/user-guide/06-layout-configuration.adoc ++++ b/doc/user-guide/06-layout-configuration.adoc +@@ -612,7 +612,7 @@ lvmvol [key:value ...] + + === LUKS Devices === + ---------------------------------- +-crypt /dev/mapper/ [type=] [cipher=] [key_size=] [hash=] [uuid=] [keyfile=] [password=] ++crypt /dev/mapper/ [type=] [cipher=] [key_size=] [hash=] [uuid=] [pbkdf= ] [keyfile=] [password=] + ---------------------------------- + + === DRBD === +diff --git a/usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh b/usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh +index 0c662f677..3b0b34cd1 100644 +--- a/usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh ++++ b/usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh +@@ -62,6 +62,9 @@ create_crypt() { + (uuid) + test $value && cryptsetup_options+=" --uuid $value" + ;; ++ (pbkdf) ++ test $value && cryptsetup_options+=" --pbkdf $value" ++ ;; + (keyfile) + test $value && keyfile=$value + ;; +diff --git a/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh b/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh +index afeabf6a7..c13cdb94a 100644 +--- a/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh ++++ b/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh +@@ -53,31 +53,73 @@ while read target_name junk ; do + fi + luks_type=luks$version + ++ luksDump_cmd="cryptsetup luksDump $source_device" ++ + # Gather crypt information: +- if ! cryptsetup luksDump $source_device >$TMP_DIR/cryptsetup.luksDump ; then +- LogPrintError "Error: Cannot get LUKS$version values for $target_name ('cryptsetup luksDump $source_device' failed)" ++ if ! $luksDump_cmd >$TMP_DIR/cryptsetup.luksDump ; then ++ LogPrintError "Error: Cannot get LUKS$version values for $target_name ('$luksDump_cmd' failed)" + continue + fi ++ + uuid=$( grep "UUID" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' ) + keyfile_option=$( [ -f /etc/crypttab ] && awk '$1 == "'"$target_name"'" && $3 != "none" && $3 != "-" && $3 != "" { print "keyfile=" $3; }' /etc/crypttab ) ++ pbkdf_option="" ++ + if test $luks_type = "luks1" ; then ++ + cipher_name=$( grep "Cipher name" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' ) + cipher_mode=$( grep "Cipher mode" $TMP_DIR/cryptsetup.luksDump | cut -d: -f2- | awk '{printf("%s",$1)};' ) + cipher=$cipher_name-$cipher_mode + key_size=$( grep "MK bits" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' ) + hash=$( grep "Hash spec" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' ) ++ + elif test $luks_type = "luks2" ; then +- cipher=$( grep "cipher:" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' ) +- # More than one keyslot may be defined - use key_size from the first slot. ++ ++ keyslots_section=$( awk '/^Keyslots:/ {include=1;next} /^[[:upper:]]/ && include {exit} include' $TMP_DIR/cryptsetup.luksDump ) ++ if [ -z "$keyslots_section" ]; then ++ LogPrintError "Error: No Keyslots section found in '$luksDump_cmd' output" ++ continue ++ fi ++ if [ $( grep -c -P '^\s+\d+: luks2' <<< "$keyslots_section" ) -gt 1 ]; then ++ LogPrintError "Warning: More than one luks2 keyslot found in '$luksDump_cmd' output, will only consider the first keyslot during recovery" ++ fi ++ luks2_section=$( awk '/^[[:blank:]]+[[:digit:]]+:/ && include {exit} /^[[:blank:]]+[[:digit:]]+: luks2/{include=1} include' <<< "$keyslots_section") ++ ++ cipher=$( grep "Cipher:" <<< "$luks2_section" | sed -r 's/^.+:\s*(.+)$/\1/' ) ++ pbkdf=$( grep "PBKDF:" <<< "$luks2_section" | sed -r 's/^.+:\s*(.+)$/\1/' ) ++ if [ -z "$pbkdf" ]; then ++ LogPrintError "Warning: no PBKDF found in luks2 keyslot of '$luksDump_cmd' output, will use defaults during recovery" ++ else ++ pbkdf_option="pbkdf=$pbkdf" ++ fi ++ + # Depending on the version the "cryptsetup luksDump" command outputs the key_size value + # as a line like + # Key: 512 bits + # and/or as a line like + # Cipher key: 512 bits + # cf. https://github.com/rear/rear/pull/2504#issuecomment-718729198 and subsequent comments +- # so we grep for both lines but use only the first match from the first slot: +- key_size=$( egrep -m 1 "Key:|Cipher key:" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+) bits$/\1/' ) +- hash=$( grep "Hash" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' ) ++ key_size=$( grep -E "Key:|Cipher key:" <<< "$luks2_section" | sed -r 's/^.+:\s*(.+) bits$/\1/' | sort -u ) ++ if [ -z "$key_size" ]; then ++ LogPrintError "Error: No key size found in luks2 keyslot of '$luksDump_cmd' output" ++ elif [ $( wc -w <<< "$key_size" ) -gt 1 ]; then ++ LogPrintError "Error: Too many key sizes found in luks2 keyslot of '$luksDump_cmd' output" ++ key_size="" ++ fi ++ ++ hash=$( grep "AF hash:" <<< "$luks2_section" | sed -r 's/^.+:\s*(.+)$/\1/' ) ++ if [ -z "$hash" ]; then ++ # Fallback to using Hash field found in Digests section ++ digests_section=$( awk '/^Digests:/ {include=1;next} /^[[:upper:]]/ && include {exit} include' $TMP_DIR/cryptsetup.luksDump ) ++ hash=$( grep "Hash:" <<< "$digests_section" | sed -r 's/^.+:\s*(.+)$/\1/' | sort -u ) ++ if [ -z "$hash" ]; then ++ LogPrintError "Warning: No Hash found in Digests section of '$luksDump_cmd' output, will use default type during recovery" ++ elif [ $( wc -w <<< "$hash" ) -gt 1 ]; then ++ hash=$( head -1 <<< "$hash" ) ++ LogPrintError "Warning: Too many Hash found in Digests section of '$luksDump_cmd' output, will use '$hash' during recovery" ++ fi ++ fi ++ + fi + + # Basic checks that the cipher key_size hash uuid values exist +@@ -87,9 +129,9 @@ while read target_name junk ; do + # and it seems cryptsetup fails when options with empty values are specified + # cf. https://github.com/rear/rear/pull/2504#issuecomment-719479724 + # For example a LUKS1 crypt entry in disklayout.conf looks like +- # crypt /dev/mapper/luks1test /dev/sda7 type=luks1 cipher=aes-xts-plain64 key_size=256 hash=sha256 uuid=1b4198c9-d9b0-4c57-b9a3-3433e391e706 +- # and a LUKS1 crypt entry in disklayout.conf looks like +- # crypt /dev/mapper/luks2test /dev/sda8 type=luks2 cipher=aes-xts-plain64 key_size=256 hash=sha256 uuid=3e874a28-7415-4f8c-9757-b3f28a96c4d2 ++ # crypt /dev/mapper/luks1test /dev/sda7 type=luks1 cipher=aes-xts-plain64 key_size=256 hash=sha256 uuid=1b4198c9-d9b0-4c57-b9a3-3433e391e706 ++ # and a LUKS2 crypt entry in disklayout.conf looks like ++ # crypt /dev/mapper/luks2test /dev/sda8 type=luks2 cipher=aes-xts-plain64 key_size=256 hash=sha256 uuid=3e874a28-7415-4f8c-9757-b3f28a96c4d2 pbkdf=argon2id + # Only the keyfile_option value is optional and the luks_type value is already tested above. + # Using plain test to ensure a value is a single non empty and non blank word + # without quoting because test " " would return zero exit code +@@ -119,7 +161,12 @@ while read target_name junk ; do + LogPrintError "Error: No 'uuid' value for LUKS$version volume $target_name in $source_device (mounting it or booting the recreated system may fail)" + fi + +- echo "crypt /dev/mapper/$target_name $source_device type=$luks_type cipher=$cipher key_size=$key_size hash=$hash uuid=$uuid $keyfile_option" >> $DISKLAYOUT_FILE ++ { ++ echo -n "crypt /dev/mapper/$target_name $source_device type=$luks_type cipher=$cipher key_size=$key_size hash=$hash uuid=$uuid" ++ [ -n "$keyfile_option" ] && echo -n " $keyfile_option" ++ [ -n "$pbkdf_option" ] && echo -n " $pbkdf_option" ++ echo ++ } >> $DISKLAYOUT_FILE + + done < <( dmsetup ls --target crypt ) + +-- +2.39.5 + diff --git a/SPECS/rear.spec b/SPECS/rear.spec index 2b3794e..102a8cf 100644 --- a/SPECS/rear.spec +++ b/SPECS/rear.spec @@ -3,7 +3,7 @@ Name: rear Version: 2.6 -Release: 24%{?dist} +Release: 27%{?dist} Summary: Relax-and-Recover is a Linux disaster recovery and system migration tool URL: http://relax-and-recover.org/ License: GPLv3 @@ -70,6 +70,51 @@ Patch114: rear-resolve-libraries-for-symlinks-in-COPY_AS_IS-RHEL-15108.patch # https://github.com/rear/rear/commit/808b15a677191aac62faadd1bc71885484091316 Patch115: rear-skip-invalid-drives-RHEL-22863.patch +# Fix useless warning that libsystemd-core requires additional libraries +# and ReaR recovery system needs additional libraries +# https://github.com/rear/rear/pull/3250 +Patch116: rear-fix-libsystemd-ldd-warning.patch + +# Fix IPv6 addresses in nfs:// and sshfs:// BACKUP/OUTPUT_URL +# https://github.com/rear/rear/pull/3242 +Patch117: rear-fix-ipv6.patch + +# Remove obsolete FAT16 options to avoid kernel warning +# https://github.com/rear/rear/pull/2576 +Patch118: rear-no-fat-16.patch + +# Install GRUB on multipath disks +# https://github.com/rear/rear/pull/3334 +Patch119: rear-multipath-bios-grub.patch + +# Improve docs of layout configuration in user guide +# https://github.com/rear/rear/pull/3125 +Patch121: rear-improve-layout-guide.patch + +# skip longhorn iscsi devices in disklayout.conf +# https://github.com/rear/rear/commit/d765abff976a8346ce6afa432c9a09d67ed63482 +Patch122: rear-skip-longhorn-iscsi-RHEL-83551.patch + +# fix PPC PReP Boot detection on GPT layouts +# https://github.com/rear/rear/commit/1ca518c2a0e675ace956ef71bc79d67e4990562b +Patch123: rear-detect-prep-boot-on-gpt-RHEL-82098.patch + +# fix recovery of LUKS encrypted systems with multiple keyslots +# https://github.com/rear/rear/commit/e9ce93f096e505968cc728a7eb5a06e25dc8d88b +Patch124: rear-support-multi-keyslot-luks-RHEL-83776.patch + +# support generation of ed25519 SSH host keys in the rescue image +# https://github.com/rear/rear/commit/62d9a744ff710de34035ce15bd1b1bf810b6934a +Patch125: rear-rescue-ed25519-hostkey-support-RHEL-83479.patch + +# enhance the 300_map_disks.sh script to also print the disk sizes +# https://github.com/rear/rear/commit/43d62fdfcac50b35be4f99d45bac3b5340525a7a +Patch126: rear-print-disk-mapping-with-sizes-RHEL-83241.patch + +# add initial support for arm/aarch64 machines with UEFI +# https://github.com/rear/rear/commit/9b28f14fad26ff00a6f90b13c3e4906d85f3ae3c +Patch127: rear-support-aarch64-uefi-RHEL-56045.patch + ###################### # downstream patches # ###################### @@ -80,20 +125,29 @@ Patch206: rear-nbu-RHEL-17390-RHEL-17393.patch # support "export TMPDIR" again, temporarily, with a warning. Patch207: rear-support-export-TMPDIR.patch +# error out if any unsupported OUTPUT used on s390 +Patch208: rear-error-output-s390x-RHEL-99362.patch + # rear contains only bash scripts plus documentation so that on first glance it could be "BuildArch: noarch" # but actually it is not "noarch" because it only works on those architectures that are explicitly supported. # Of course the rear bash scripts can be installed on any architecture just as any binaries can be installed on any architecture. # But the meaning of architecture dependent packages should be on what architectures they will work. # Therefore only those architectures that are actually supported are explicitly listed. -# This avoids that rear can be "just installed" on architectures that are actually not supported (e.g. ARM): -ExclusiveArch: %ix86 x86_64 ppc ppc64 ppc64le ia64 s390x +# This avoids that rear can be "just installed" on architectures that are actually not supported: +ExclusiveArch: %ix86 x86_64 ppc ppc64 ppc64le ia64 s390x %arm aarch64 # Furthermore for some architectures it requires architecture dependent packages (like syslinux for x86 and x86_64) # so that rear must be architecture dependent because ifarch conditions never match in case of "BuildArch: noarch" # see the GitHub issue https://github.com/rear/rear/issues/629 %ifarch %ix86 x86_64 -Requires: syslinux +Requires: syslinux-extlinux +%endif +# See https://github.com/rhboot/efi-rpm-macros/blob/main/README +%ifarch %{efi} # We need mkfs.vfat for recreating EFI System Partition Recommends: dosfstools +# Needed for ISO image creation +Recommends: grub2-efi-%{efi_arch}-modules +Recommends: grub2-tools-extra %endif %ifarch ppc ppc64 ppc64le # Called by grub2-install (except on PowerNV) @@ -111,6 +165,7 @@ Requires: s390utils-core # (in addition to the default installed bootloader grub2) while on ppc ppc64 the # default installed bootloader yaboot is also useed to make the bootable ISO image. +BuildRequires: efi-srpm-macros # Required for HTML user guide BuildRequires: make BuildRequires: asciidoctor @@ -204,6 +259,28 @@ install -m 0644 %{SOURCE3} %{buildroot}%{_docdir}/%{name}/ #-- CHANGELOG -----------------------------------------------------------------# %changelog +* Thu Aug 14 2025 Pavel Cahyna - 2.6-27 +- add dependency on grub2-tools-extra and GRUB EFI modules on EFI machines +- add dependency on syslinux-extlinux on x86 +- add initial support for aarch64 machines with UEFI +- enhance the 300_map_disks.sh script to also print the disk sizes +- support generation of ed25519 SSH host keys in the rescue image +- create sshd home directory in the rescue image on systems upgraded from EL8 +- fix recovery of LUKS encrypted systems with multiple keyslots +- fix PPC PReP Boot detection on GPT layouts +- skip longhorn iscsi devices in disklayout.conf +- error out if any unsupported OUTPUT used on s390x + +* Tue Feb 11 2025 Pavel Cahyna - 2.6-26 +- Install GRUB on multipath disks, PR 3334 +- Improve docs of layout configuration in user guide, PR 3125 + +* Sat Jul 20 2024 Pavel Cahyna - 2.6-25 +- Backport PR 3250 to fix useless warning that libsystemd-core requires + additional libraries and ReaR recovery system needs additional libraries +- Backport PR 3242 to fix IPv6 address in nfs:// and sshfs:// BACKUP/OUTPUT_URL +- Backport PR 2576 to remove obsolete FAT16 options to avoid kernel warning + * Sat Feb 24 2024 Pavel Cahyna - 2.6-24 - Support "export TMPDIR" in user configuration again, print a warning when this is used - revert commit f464eae2, adapt PR 3163, add commit