From 3b5eeb2f233a4ead65df4abea3d2c161e0ca1bfd Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 9 May 2023 05:25:17 +0000 Subject: [PATCH] import rear-2.6-17.el9 --- SOURCES/rear-bz2091163.patch | 46 ++ SOURCES/rear-bz2130945.patch | 20 + SOURCES/rear-bz2131946.patch | 129 +++++ SOURCES/s390-no-clobber-disks.patch | 751 ++++++++++++++++++++++++++++ SPECS/rear.spec | 20 +- 5 files changed, 965 insertions(+), 1 deletion(-) create mode 100644 SOURCES/rear-bz2091163.patch create mode 100644 SOURCES/rear-bz2130945.patch create mode 100644 SOURCES/rear-bz2131946.patch create mode 100644 SOURCES/s390-no-clobber-disks.patch diff --git a/SOURCES/rear-bz2091163.patch b/SOURCES/rear-bz2091163.patch new file mode 100644 index 0000000..3a68a34 --- /dev/null +++ b/SOURCES/rear-bz2091163.patch @@ -0,0 +1,46 @@ +diff --git a/usr/share/rear/layout/save/GNU/Linux/220_lvm_layout.sh b/usr/share/rear/layout/save/GNU/Linux/220_lvm_layout.sh +index d3c9ae86..f21845df 100644 +--- a/usr/share/rear/layout/save/GNU/Linux/220_lvm_layout.sh ++++ b/usr/share/rear/layout/save/GNU/Linux/220_lvm_layout.sh +@@ -70,14 +70,20 @@ local lvs_exit_code + # Get physical_device configuration. + # Format: lvmdev [] [] + header_printed="no" +- # Example output of "lvm pvdisplay -c": +- # /dev/sda1:system:41940992:-1:8:8:-1:4096:5119:2:5117:7wwpcO-KmNN-qsTE-7sp7-JBJS-vBdC-Zyt1W7 ++ # Set pvdisplay separator to '|' to prevent issues with a colon in the path under /dev/disk/by-path ++ # that contains a ':' in the SCSI slot name. ++ # Example output of "lvm pvdisplay -C --separator '|' --noheadings --nosuffix --units=b -o pv_name,vg_name,pv_size,pv_uuid" ++ # on a system where LVM is configured to show the /dev/disk/by-path device names instead of the usual ++ # /dev/sda etc. (by using a setting like ++ # filter = [ "r|/dev/disk/by-path/.*-usb-|", "a|/dev/disk/by-path/pci-.*-nvme-|", "a|/dev/disk/by-path/pci-.*-scsi-|", "a|/dev/disk/by-path/pci-.*-ata-|", "a|/dev/disk/by-path/pci-.*-sas-|", "a|loop|", "r|.*|" ] ++ # in /etc/lvm/lvm.conf): ++ # /dev/disk/by-path/pci-0000:03:00.0-scsi-0:0:1:0-part1|system|107340627968|7wwpcO-KmNN-qsTE-7sp7-JBJS-vBdC-Zyt1W7 + # There are two leading blanks in the output (at least on SLES12-SP4 with LVM 2.02.180). +- lvm pvdisplay -c | while read line ; do ++ lvm pvdisplay -C --separator '|' --noheadings --nosuffix --units=b -o pv_name,vg_name,pv_size,pv_uuid | while read line ; do + +- # With the above example pdev=/dev/sda1 ++ # With the above example pdev=/dev/disk/by-path/pci-0000:03:00.0-scsi-0:0:1:0-part1 + # (the "echo $line" makes the leading blanks disappear) +- pdev=$( echo $line | cut -d ":" -f "1" ) ++ pdev=$( echo $line | cut -d "|" -f "1" ) + + # Skip lines that are not describing physical devices + # i.e. lines where pdev does not start with a leading / character: +@@ -91,11 +97,11 @@ local lvs_exit_code + fi + + # With the above example vgrp=system +- vgrp=$( echo $line | cut -d ":" -f "2" ) +- # With the above example size=41940992 +- size=$( echo $line | cut -d ":" -f "3" ) ++ vgrp=$( echo $line | cut -d "|" -f "2" ) ++ # With the above example size=107340627968 ++ size=$( echo $line | cut -d "|" -f "3" ) + # With the above example uuid=7wwpcO-KmNN-qsTE-7sp7-JBJS-vBdC-Zyt1W7 +- uuid=$( echo $line | cut -d ":" -f "12" ) ++ uuid=$( echo $line | cut -d "|" -f "4" ) + + # Translate pdev through diskbyid_mappings file: + pdev=$( get_device_mapping $pdev ) diff --git a/SOURCES/rear-bz2130945.patch b/SOURCES/rear-bz2130945.patch new file mode 100644 index 0000000..5291d13 --- /dev/null +++ b/SOURCES/rear-bz2130945.patch @@ -0,0 +1,20 @@ +diff --git a/usr/share/rear/finalize/Fedora/i386/550_rebuild_initramfs.sh b/usr/share/rear/finalize/Fedora/550_rebuild_initramfs.sh +similarity index 100% +rename from usr/share/rear/finalize/Fedora/i386/550_rebuild_initramfs.sh +rename to usr/share/rear/finalize/Fedora/550_rebuild_initramfs.sh +diff --git a/usr/share/rear/finalize/Fedora/ppc64/550_rebuild_initramfs.sh b/usr/share/rear/finalize/Fedora/ppc64/550_rebuild_initramfs.sh +deleted file mode 120000 +index 22eede59..00000000 +--- a/usr/share/rear/finalize/Fedora/ppc64/550_rebuild_initramfs.sh ++++ /dev/null +@@ -1 +0,0 @@ +-../i386/550_rebuild_initramfs.sh +\ No newline at end of file +diff --git a/usr/share/rear/finalize/Fedora/ppc64le/550_rebuild_initramfs.sh b/usr/share/rear/finalize/Fedora/ppc64le/550_rebuild_initramfs.sh +deleted file mode 120000 +index 22eede59..00000000 +--- a/usr/share/rear/finalize/Fedora/ppc64le/550_rebuild_initramfs.sh ++++ /dev/null +@@ -1 +0,0 @@ +-../i386/550_rebuild_initramfs.sh +\ No newline at end of file diff --git a/SOURCES/rear-bz2131946.patch b/SOURCES/rear-bz2131946.patch new file mode 100644 index 0000000..1ee90ba --- /dev/null +++ b/SOURCES/rear-bz2131946.patch @@ -0,0 +1,129 @@ +diff --git a/usr/share/rear/layout/prepare/GNU/Linux/131_include_filesystem_code.sh b/usr/share/rear/layout/prepare/GNU/Linux/131_include_filesystem_code.sh +index 172ac032..9cff63a0 100644 +--- a/usr/share/rear/layout/prepare/GNU/Linux/131_include_filesystem_code.sh ++++ b/usr/share/rear/layout/prepare/GNU/Linux/131_include_filesystem_code.sh +@@ -143,9 +143,9 @@ function create_fs () { + # unless the user has explicitly specified XFS filesystem options: + local xfs_opts + local xfs_device_basename="$( basename $device )" +- local xfs_info_filename="$LAYOUT_XFS_OPT_DIR/$xfs_device_basename.xfs" ++ local xfs_info_filename="$LAYOUT_XFS_OPT_DIR_RESTORE/$xfs_device_basename.xfs" + # Only uppercase letters and digits are used to ensure mkfs_xfs_options_variable_name is a valid bash variable name +- # even in case of complicated device nodes e.g. things like /dev/mapper/SIBM_2810XIV_78033E7012F-part3 ++ # even in case of complicated device nodes e.g. things like /dev/mapper/SIBM_2810XIV_78033E7012F-part3 + # cf. current_orig_device_basename_alnum_uppercase in layout/prepare/default/300_map_disks.sh + local xfs_device_basename_alnum_uppercase="$( echo $xfs_device_basename | tr -d -c '[:alnum:]' | tr '[:lower:]' '[:upper:]' )" + # cf. predefined_input_variable_name in the function UserInput in lib/_input-output-functions.sh +diff --git a/usr/share/rear/layout/prepare/default/010_prepare_files.sh b/usr/share/rear/layout/prepare/default/010_prepare_files.sh +index 85964712..7a980e63 100644 +--- a/usr/share/rear/layout/prepare/default/010_prepare_files.sh ++++ b/usr/share/rear/layout/prepare/default/010_prepare_files.sh +@@ -5,6 +5,7 @@ LAYOUT_DEPS="$VAR_DIR/layout/diskdeps.conf" + LAYOUT_TODO="$VAR_DIR/layout/disktodo.conf" + LAYOUT_CODE="$VAR_DIR/layout/diskrestore.sh" + LAYOUT_XFS_OPT_DIR="$VAR_DIR/layout/xfs" ++LAYOUT_XFS_OPT_DIR_RESTORE="$LAYOUT_XFS_OPT_DIR/restore" + + FS_UUID_MAP="$VAR_DIR/layout/fs_uuid_mapping" + LUN_WWID_MAP="$VAR_DIR/layout/lun_wwid_mapping" +diff --git a/usr/share/rear/layout/prepare/default/319_rename_xfs_configs.sh b/usr/share/rear/layout/prepare/default/319_rename_xfs_configs.sh +new file mode 100644 +index 00000000..406afa61 +--- /dev/null ++++ b/usr/share/rear/layout/prepare/default/319_rename_xfs_configs.sh +@@ -0,0 +1,83 @@ ++# Cleanup directory which hold XFS configuration file for `rear recover'. ++# This will avoid possible mess in LAYOUT_XFS_OPT_DIR_RESTORE if `rear recover' ++# would be launched multiple times, where user will choose different disk ++# mapping each time. ++# Removing and creating LAYOUT_XFS_OPT_DIR_RESTORE will ensure that ReaR will ++# have only current files available during current session. ++rm -rf "$LAYOUT_XFS_OPT_DIR_RESTORE" ++mkdir -p "$LAYOUT_XFS_OPT_DIR_RESTORE" ++ ++local excluded_configs=() ++ ++# Read $MAPPING_FILE (disk_mappings) to discover final disk mapping. ++# Once mapping is known, configuration files can be renamed. ++# (e.g. sds2.xfs to sdb2.xfs, ...) ++while read source target junk ; do ++ # Disks in MAPPING_FILE are listed with full device path. Since XFS config ++ # files are created in format e.g. sda2.xfs strip prefixed path to have ++ # only short device name available. ++ base_source=$(basename "$source") ++ base_target=$(basename "$target") ++ ++ # Check if XFS configuration file for whole device (unpartitioned) ++ # is available (sda, sdb, ...). If so, rename and copy it to ++ # LAYOUT_XFS_OPT_DIR_RESTORE. ++ if [ -e "$LAYOUT_XFS_OPT_DIR/$base_source.xfs" ]; then ++ Log "Migrating XFS configuration file $base_source.xfs to $base_target.xfs" ++ cp "$v" "$LAYOUT_XFS_OPT_DIR/$base_source.xfs" \ ++ "$LAYOUT_XFS_OPT_DIR_RESTORE/$base_target.xfs" ++ ++ # Replace old device name in meta-data= option in XFS ++ # configuration file as well. ++ sed -i s#"meta-data=${source}\(\s\)"#"meta-data=${target}\1"# \ ++ "$LAYOUT_XFS_OPT_DIR_RESTORE/$base_target.xfs" ++ ++ # Mark XFS config file as processed to avoid copying it again later. ++ # More details on why are configs excluded can be found near the ++ # end of this script (near `tar' command). ++ excluded_configs+=("--exclude=$base_source.xfs") ++ fi ++ ++ # Find corresponding partitions to source disk in LAYOUT_FILE ++ # and migrate/rename them too if necessary. ++ while read _ layout_device _ _ _ _ layout_partition; do ++ if [[ "$source" = "$layout_device" ]]; then ++ base_src_layout_partition=$(basename "$layout_partition") ++ base_dst_layout_partition=${base_src_layout_partition//$base_source/$base_target} ++ dst_layout_partition=${layout_partition//$base_source/$base_target} ++ ++ if [ -e "$LAYOUT_XFS_OPT_DIR/$base_src_layout_partition.xfs" ]; then ++ Log "Migrating XFS configuration $base_src_layout_partition.xfs to $base_dst_layout_partition.xfs" ++ cp "$v" "$LAYOUT_XFS_OPT_DIR/$base_src_layout_partition.xfs" \ ++ "$LAYOUT_XFS_OPT_DIR_RESTORE/$base_dst_layout_partition.xfs" ++ ++ # Replace old device name in meta-data= option in XFS ++ # configuration file as well. ++ sed -i s#"meta-data=${layout_partition}\(\s\)"#"meta-data=${dst_layout_partition}\1"# \ ++ "$LAYOUT_XFS_OPT_DIR_RESTORE/$base_dst_layout_partition.xfs" ++ ++ # Mark XFS config file as processed to avoid copying it again later. ++ # More details on why are configs excluded can be found near the ++ # end of this script (near `tar' command). ++ excluded_configs+=("--exclude=$base_src_layout_partition.xfs") ++ fi ++ fi ++ done < <( grep -E "^part " "$LAYOUT_FILE" ) ++done < <( grep -v '^#' "$MAPPING_FILE" ) ++ ++pushd "$LAYOUT_XFS_OPT_DIR" >/dev/null ++# Copy remaining files ++# We need to copy remaining files into LAYOUT_XFS_OPT_DIR_RESTORE which will ++# serve as base dictionary where ReaR will look for XFS config files. ++# It is necessary to copy only files that were not previously processed, ++# because in LAYOUT_XFS_OPT_DIR they are still listed with ++# original name and copy to LAYOUT_XFS_OPT_DIR_RESTORE could overwrite ++# XFS configs already migrated. ++# e.g. with following disk mapping situation: ++# /dev/sda2 => /dev/sdb2 ++# /dev/sdb2 => /dev/sda2 ++# Files in LAYOUT_XFS_OPT_DIR_RESTORE would be overwritten by XFS configs with ++# wrong names. ++# tar is used to take advantage of its exclude feature. ++tar cf - --exclude=restore "${excluded_configs[@]}" . | tar xfp - -C "$LAYOUT_XFS_OPT_DIR_RESTORE" ++popd >/dev/null +diff --git a/usr/share/rear/layout/save/GNU/Linux/100_create_layout_file.sh b/usr/share/rear/layout/save/GNU/Linux/100_create_layout_file.sh +index 7895e4ee..fc0fa8fc 100644 +--- a/usr/share/rear/layout/save/GNU/Linux/100_create_layout_file.sh ++++ b/usr/share/rear/layout/save/GNU/Linux/100_create_layout_file.sh +@@ -10,6 +10,7 @@ mkdir -p $v $VAR_DIR/layout/config + # We need directory for XFS options only if XFS is in use: + if test "$( mount -t xfs )" ; then + LAYOUT_XFS_OPT_DIR="$VAR_DIR/layout/xfs" ++ rm -rf $LAYOUT_XFS_OPT_DIR + mkdir -p $v $LAYOUT_XFS_OPT_DIR + fi + diff --git a/SOURCES/s390-no-clobber-disks.patch b/SOURCES/s390-no-clobber-disks.patch new file mode 100644 index 0000000..8d2f81a --- /dev/null +++ b/SOURCES/s390-no-clobber-disks.patch @@ -0,0 +1,751 @@ +diff --git a/usr/share/rear/conf/default.conf b/usr/share/rear/conf/default.conf +index 23a83b71..0d13b487 100644 +--- a/usr/share/rear/conf/default.conf ++++ b/usr/share/rear/conf/default.conf +@@ -416,6 +416,18 @@ test "$RECOVERY_UPDATE_URL" || RECOVERY_UPDATE_URL="" + # export MIGRATION_MODE='true' + # directly before he calls "rear recover": + test "$MIGRATION_MODE" || MIGRATION_MODE='' ++#### ++ ++#### ++# Formatting DASDs (S/390 specific) ++# DASD (Direct Access Storage Device) denotes a disk drive on the S/390 architecture. ++# DASDs need to be formatted before use (even before creating a partition table on them). ++# By default ReaR will format the DASDs that are going to be used to recreate the system ++# (are referenced in disklayout.conf) before recreating the disk layout. ++# This can be suppressed by setting FORMAT_DASDS="false". It can be useful when one intends ++# to use already formatted DASDs as recovery target. ++FORMAT_DASDS="" ++#### + + ## + # Resizing partitions in MIGRATION_MODE during "rear recover" +diff --git a/usr/share/rear/layout/prep-for-mount/Linux-s390/205_s390_enable_disk.sh b/usr/share/rear/layout/prep-for-mount/Linux-s390/205_s390_enable_disk.sh +new file mode 120000 +index 00000000..5f7a2ac0 +--- /dev/null ++++ b/usr/share/rear/layout/prep-for-mount/Linux-s390/205_s390_enable_disk.sh +@@ -0,0 +1 @@ ++../../prepare/Linux-s390/205_s390_enable_disk.sh +\ No newline at end of file +diff --git a/usr/share/rear/layout/prepare/GNU/Linux/100_include_partition_code.sh b/usr/share/rear/layout/prepare/GNU/Linux/100_include_partition_code.sh +index 13c69ce8..2a2bc33f 100644 +--- a/usr/share/rear/layout/prepare/GNU/Linux/100_include_partition_code.sh ++++ b/usr/share/rear/layout/prepare/GNU/Linux/100_include_partition_code.sh +@@ -24,6 +24,7 @@ fi + ### Prepare a disk for partitioning/general usage. + create_disk() { + local component disk size label junk ++ local blocksize layout dasdtype dasdcyls junk2 + read component disk size label junk < <(grep "^disk $1 " "$LAYOUT_FILE") + + ### Disks should be block devices. +@@ -67,7 +68,8 @@ sync + + EOF + +- create_partitions "$disk" "$label" ++ # $junk can contain useful DASD-specific fields ++ create_partitions "$disk" "$label" "$junk" + + cat >> "$LAYOUT_CODE" <> "$LAYOUT_CODE" <"$DASD_FORMAT_CODE" ++ ++# Show the current output of lsdasd, it can be useful for identifying disks ++# (in particular it shows the Linux device name <-> virtual device number mapping, ++# formatted / unformatted status and the number/size of blocks when formatted ) ++echo "# Current output of 'lsdasd':" >>"$DASD_FORMAT_CODE" ++lsdasd | sed -e 's/^/# /' >>"$DASD_FORMAT_CODE" ++ ++cat <>"$DASD_FORMAT_CODE" ++ ++LogPrint "Start DASD format restoration." ++ ++set -e ++set -x ++ ++EOF ++ ++while read component disk size label junk; do ++ if [ "$label" == dasd ]; then ++ # Ignore excluded components. ++ # Normally they are removed in 520_exclude_components.sh, ++ # but we run before it, so we must skip them here as well. ++ if IsInArray "$disk" "${EXCLUDE_RECREATE[@]}" ; then ++ Log "Excluding $disk from DASD reformatting." ++ continue ++ fi ++ # dasd has more fields - junk is not junk anymore ++ read blocksize layout dasdtype dasdcyls junk2 <<<$junk ++ dasd_format_code "$disk" "$size" "$blocksize" "$layout" "$dasdtype" "$dasdcyls" >> "$DASD_FORMAT_CODE" || \ ++ LogPrintError "Error producing DASD format code for $disk" ++ fi ++done < <(grep "^disk " "$LAYOUT_FILE") ++ ++cat <>"$DASD_FORMAT_CODE" ++ ++set +x ++set +e ++ ++LogPrint "DASD(s) formatted." ++ ++EOF +diff --git a/usr/share/rear/layout/prepare/Linux-s390/370_confirm_dasd_format_code.sh b/usr/share/rear/layout/prepare/Linux-s390/370_confirm_dasd_format_code.sh +new file mode 100644 +index 00000000..5ba4edd5 +--- /dev/null ++++ b/usr/share/rear/layout/prepare/Linux-s390/370_confirm_dasd_format_code.sh +@@ -0,0 +1,69 @@ ++# adapted from 100_confirm_layout_code.sh ++# ++# Let the user confirm the ++# DASD format code (dasdformat.sh) script. ++# ++ ++is_false "$FORMAT_DASDS" && return 0 ++ ++# Show the user confirmation dialog in any case but when not in migration mode ++# automatically proceed with less timeout USER_INPUT_INTERRUPT_TIMEOUT (by default 10 seconds) ++# to avoid longer delays (USER_INPUT_TIMEOUT is by default 300 seconds) in case of unattended recovery: ++# (taken from 120_confirm_wipedisk_disks.sh) ++local timeout="$USER_INPUT_TIMEOUT" ++is_true "$MIGRATION_MODE" || timeout="$USER_INPUT_INTERRUPT_TIMEOUT" ++ ++rear_workflow="rear $WORKFLOW" ++original_disk_space_usage_file="$VAR_DIR/layout/config/df.txt" ++rear_shell_history="$( echo -e "cd $VAR_DIR/layout/\nvi $DASD_FORMAT_CODE\nless $DASD_FORMAT_CODE" )" ++unset choices ++choices[0]="Confirm DASD format script and continue '$rear_workflow'" ++choices[1]="Edit DASD format script ($DASD_FORMAT_CODE)" ++choices[2]="View DASD format script ($DASD_FORMAT_CODE)" ++choices[3]="View original disk space usage ($original_disk_space_usage_file)" ++choices[4]="Confirm what is currently on the DASDs, skip formatting them and continue '$rear_workflow'" ++choices[5]="Use Relax-and-Recover shell and return back to here" ++choices[6]="Abort '$rear_workflow'" ++prompt="Confirm or edit the DASD format script" ++choice="" ++wilful_input="" ++# When USER_INPUT_DASD_FORMAT_CODE_CONFIRMATION has any 'true' value be liberal in what you accept and ++# assume choices[0] 'Confirm DASD format' was actually meant: ++is_true "$USER_INPUT_DASD_FORMAT_CODE_CONFIRMATION" && USER_INPUT_DASD_FORMAT_CODE_CONFIRMATION="${choices[0]}" ++while true ; do ++ choice="$( UserInput -I DASD_FORMAT_CODE_CONFIRMATION -t "$timeout" -p "$prompt" -D "${choices[0]}" "${choices[@]}" )" && wilful_input="yes" || wilful_input="no" ++ case "$choice" in ++ (${choices[0]}) ++ # Confirm DASD format file and continue: ++ is_true "$wilful_input" && LogPrint "User confirmed DASD format script" || LogPrint "Continuing '$rear_workflow' by default" ++ break ++ ;; ++ (${choices[1]}) ++ # Run 'vi' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ vi $DASD_FORMAT_CODE 0<&6 1>&7 2>&8 ++ ;; ++ (${choices[2]}) ++ # Run 'less' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ less $DASD_FORMAT_CODE 0<&6 1>&7 2>&8 ++ ;; ++ (${choices[3]}) ++ # Run 'less' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ less $original_disk_space_usage_file 0<&6 1>&7 2>&8 ++ ;; ++ (${choices[4]}) ++ # Confirm what is on the disks and continue without formatting ++ FORMAT_DASDS="false" ++ ;; ++ (${choices[5]}) ++ # rear_shell runs 'bash' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ rear_shell "" "$rear_shell_history" ++ ;; ++ (${choices[6]}) ++ abort_dasd_format ++ Error "User chose to abort '$rear_workflow' in ${BASH_SOURCE[0]}" ++ ;; ++ esac ++done ++ ++chmod +x $DASD_FORMAT_CODE ++ +diff --git a/usr/share/rear/layout/prepare/Linux-s390/400_run_dasd_format_code.sh b/usr/share/rear/layout/prepare/Linux-s390/400_run_dasd_format_code.sh +new file mode 100644 +index 00000000..16451af6 +--- /dev/null ++++ b/usr/share/rear/layout/prepare/Linux-s390/400_run_dasd_format_code.sh +@@ -0,0 +1,185 @@ ++# adapted from 200_run_layout_code.sh ++# ++# Run the DASD format code (dasdformat.sh) ++# again and again until it succeeds or the user aborts. ++# ++ ++# Skip DASD formatting when the user has explicitly specified to not format them ++# or when the user selected "Confirm what is currently on the DASDs, skip formatting them" ++# in 370_confirm_dasd_format_code.sh ++ ++is_false "$FORMAT_DASDS" && return 0 ++ ++function lsdasd_output () { ++ lsdasd 1>> >( tee -a "$RUNTIME_LOGFILE" 1>&7 ) ++} ++ ++rear_workflow="rear $WORKFLOW" ++original_disk_space_usage_file="$VAR_DIR/layout/config/df.txt" ++rear_shell_history="$( echo -e "cd $VAR_DIR/layout/\nvi $DASD_FORMAT_CODE\nless $RUNTIME_LOGFILE" )" ++wilful_input="" ++ ++unset choices ++choices[0]="Rerun DASD format script ($DASD_FORMAT_CODE)" ++choices[1]="View '$rear_workflow' log file ($RUNTIME_LOGFILE)" ++choices[2]="Edit DASD format script ($DASD_FORMAT_CODE)" ++choices[3]="Show what is currently on the disks ('lsdasd' device list)" ++choices[4]="View original disk space usage ($original_disk_space_usage_file)" ++choices[5]="Use Relax-and-Recover shell and return back to here" ++choices[6]="Confirm what is currently on the disks and continue '$rear_workflow'" ++choices[7]="Abort '$rear_workflow'" ++prompt="DASD format choices" ++ ++choice="" ++# When USER_INPUT_DASD_FORMAT_CODE_RUN has any 'true' value be liberal in what you accept and ++# assume choices[0] 'Rerun DASD format script' was actually meant ++# regardless that this likely lets 'rear recover' run an endless loop ++# of failed DASD format attempts but ReaR must obey what the user specified ++# (perhaps it is intended to let 'rear recover' loop here until an admin intervenes): ++is_true "$USER_INPUT_DASD_FORMAT_CODE_RUN" && USER_INPUT_DASD_FORMAT_CODE_RUN="${choices[0]}" ++ ++unset confirm_choices ++confirm_choices[0]="Confirm recreated DASD format and continue '$rear_workflow'" ++confirm_choices[1]="Go back one step to redo DASD format" ++confirm_choices[2]="Use Relax-and-Recover shell and return back to here" ++confirm_choices[3]="Abort '$rear_workflow'" ++confirm_prompt="Confirm the recreated DASD format or go back one step" ++confirm_choice="" ++# When USER_INPUT_DASD_FORMAT_MIGRATED_CONFIRMATION has any 'true' value be liberal in what you accept and ++# assume confirm_choices[0] 'Confirm recreated DASD format and continue' was actually meant: ++is_true "$USER_INPUT_DASD_FORMAT_MIGRATED_CONFIRMATION" && USER_INPUT_DASD_FORMAT_MIGRATED_CONFIRMATION="${confirm_choices[0]}" ++ ++# Run the DASD format code (dasdformat.sh) ++# again and again until it succeeds or the user aborts ++# or the user confirms to continue with what is currently on the disks ++# (the user may have setup manually what he needs via the Relax-and-Recover shell): ++while true ; do ++ prompt="The DASD format had failed" ++ # After switching to recreating with DASD format script ++ # change choices[0] from "Run ..." to "Rerun ...": ++ choices[0]="Rerun DASD format script ($DASD_FORMAT_CODE)" ++ # Run DASD_FORMAT_CODE in a sub-shell because it sets 'set -e' ++ # so that it exits the running shell in case of an error ++ # but that exit must not exit this running bash here: ++ ( source $DASD_FORMAT_CODE ) ++ # One must explicitly test whether or not $? is zero in a separated bash command ++ # because with bash 3.x and bash 4.x code like ++ # # ( set -e ; cat qqq ; echo "hello" ) && echo ok || echo failed ++ # cat: qqq: No such file or directory ++ # hello ++ # ok ++ # does not work as one may expect (cf. what "man bash" describes for 'set -e'). ++ # There is a subtle behavioural difference between bash 3.x and bash 4.x ++ # when a script that has 'set -e' set gets sourced: ++ # With bash 3.x the 'set -e' inside the sourced script is effective: ++ # # echo 'set -e ; cat qqq ; echo hello' >script.sh ++ # # ( source script.sh ) && echo ok || echo failed ++ # cat: qqq: No such file or directory ++ # failed ++ # With bash 4.x the 'set -e' inside the sourced script gets noneffective: ++ # # echo 'set -e ; cat qqq ; echo hello' >script.sh ++ # # ( source script.sh ) && echo ok || echo failed ++ # cat: qqq: No such file or directory ++ # hello ++ # ok ++ # With bash 3.x and bash 4.x testing $? in a separated bash command ++ # keeps the 'set -e' inside the sourced script effective: ++ # # echo 'set -e ; cat qqq ; echo hello' >script.sh ++ # # ( source script.sh ) ; (( $? == 0 )) && echo ok || echo failed ++ # cat: qqq: No such file or directory ++ # failed ++ # See also https://github.com/rear/rear/pull/1573#issuecomment-344303590 ++ if (( $? == 0 )) ; then ++ prompt="DASD format had been successful" ++ # When DASD_FORMAT_CODE succeeded and when not in migration mode ++ # break the outer while loop and continue the "rear recover" workflow ++ # which means continue with restoring the backup: ++ is_true "$MIGRATION_MODE" || break ++ # When DASD_FORMAT_CODE succeeded in migration mode ++ # let the user explicitly confirm the recreated (and usually migrated) format ++ # before continuing the "rear recover" workflow with restoring the backup. ++ # Show the recreated DASD format to the user on his terminal (and also in the log file): ++ LogPrint "Recreated DASD format:" ++ lsdasd_output ++ # Run an inner while loop with a user dialog so that the user can inspect the recreated DASD format ++ # and perhaps even manually fix the recreated DASD format if it is not what the user wants ++ # (e.g. by using the Relax-and-Recover shell and returning back to this user dialog): ++ while true ; do ++ confirm_choice="$( UserInput -I DASD_FORMAT_MIGRATED_CONFIRMATION -p "$confirm_prompt" -D "${confirm_choices[0]}" "${confirm_choices[@]}" )" && wilful_input="yes" || wilful_input="no" ++ case "$confirm_choice" in ++ (${confirm_choices[0]}) ++ # Confirm recreated DASD format and continue: ++ is_true "$wilful_input" && LogPrint "User confirmed recreated DASD format" || LogPrint "Continuing with recreated DASD format by default" ++ # Break the outer while loop and continue with restoring the backup: ++ break 2 ++ ;; ++ (${confirm_choices[1]}) ++ # Go back one step to redo DASD format: ++ # Only break the inner while loop (i.e. this user dialog loop) ++ # and continue with the next user dialog below: ++ break ++ ;; ++ (${confirm_choices[2]}) ++ # rear_shell runs 'bash' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ rear_shell "" "$rear_shell_history" ++ ;; ++ (${confirm_choices[3]}) ++ abort_dasd_format ++ Error "User did not confirm the recreated DASD format but aborted '$rear_workflow' in ${BASH_SOURCE[0]}" ++ ;; ++ esac ++ done ++ fi ++ # Run an inner while loop with a user dialog so that the user can fix things ++ # when DASD_FORMAT_CODE failed. ++ # Such a fix does not necessarily mean the user must change ++ # the dasdformat.sh script when DASD_FORMAT_CODE failed. ++ # The user might also fix things by only using the Relax-and-Recover shell and ++ # then confirm what is on the disks and continue with restoring the backup ++ # or abort this "rear recover" run to re-try from scratch. ++ while true ; do ++ choice="$( UserInput -I DASD_FORMAT_CODE_RUN -p "$prompt" -D "${choices[0]}" "${choices[@]}" )" && wilful_input="yes" || wilful_input="no" ++ case "$choice" in ++ (${choices[0]}) ++ # Rerun or run (after switching to recreating with DASD format script) DASD format script: ++ is_true "$wilful_input" && LogPrint "User runs DASD format script" || LogPrint "Running DASD format script by default" ++ # Only break the inner while loop (i.e. the user dialog loop): ++ break ++ ;; ++ (${choices[1]}) ++ # Run 'less' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ less $RUNTIME_LOGFILE 0<&6 1>&7 2>&8 ++ ;; ++ (${choices[2]}) ++ # Run 'vi' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ vi $DASD_FORMAT_CODE 0<&6 1>&7 2>&8 ++ ;; ++ (${choices[3]}) ++ LogPrint "This is the current list of DASDs:" ++ lsdasd_output ++ ;; ++ (${choices[4]}) ++ # Run 'less' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ less $original_disk_space_usage_file 0<&6 1>&7 2>&8 ++ ;; ++ (${choices[5]}) ++ # rear_shell runs 'bash' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user: ++ rear_shell "" "$rear_shell_history" ++ ;; ++ (${choices[6]}) ++ # Confirm what is on the disks and continue: ++ # Break the outer while loop and continue with restoring the backup: ++ break 2 ++ ;; ++ (${choices[7]}) ++ abort_dasd_format ++ Error "User chose to abort '$rear_workflow' in ${BASH_SOURCE[0]}" ++ ;; ++ esac ++ done ++# End of the outer while loop: ++done ++ ++# Local functions must be 'unset' because bash does not support 'local function ...' ++# cf. https://unix.stackexchange.com/questions/104755/how-can-i-create-a-local-function-in-my-bashrc ++unset -f lsdasd_output +diff --git a/usr/share/rear/layout/prepare/default/010_prepare_files.sh b/usr/share/rear/layout/prepare/default/010_prepare_files.sh +index 7a980e63..4191be33 100644 +--- a/usr/share/rear/layout/prepare/default/010_prepare_files.sh ++++ b/usr/share/rear/layout/prepare/default/010_prepare_files.sh +@@ -7,6 +7,8 @@ LAYOUT_CODE="$VAR_DIR/layout/diskrestore.sh" + LAYOUT_XFS_OPT_DIR="$VAR_DIR/layout/xfs" + LAYOUT_XFS_OPT_DIR_RESTORE="$LAYOUT_XFS_OPT_DIR/restore" + ++DASD_FORMAT_CODE="$VAR_DIR/layout/dasdformat.sh" ++ + FS_UUID_MAP="$VAR_DIR/layout/fs_uuid_mapping" + LUN_WWID_MAP="$VAR_DIR/layout/lun_wwid_mapping" + +diff --git a/usr/share/rear/layout/prepare/default/250_compare_disks.sh b/usr/share/rear/layout/prepare/default/250_compare_disks.sh +index c459b928..751433ba 100644 +--- a/usr/share/rear/layout/prepare/default/250_compare_disks.sh ++++ b/usr/share/rear/layout/prepare/default/250_compare_disks.sh +@@ -54,7 +54,9 @@ local more_than_one_same_orig_size='' + # Cf. the "Compare disks one by one" code below: + while read disk dev size junk ; do + if IsInArray "$size" "${original_system_used_disk_sizes[@]}" ; then +- more_than_one_same_orig_size='true' ++ if ! has_mapping_hint "$dev" ; then ++ more_than_one_same_orig_size='true' ++ fi + else + original_system_used_disk_sizes+=( "$size" ) + fi +@@ -109,14 +111,17 @@ fi + # No further disk comparisons are needed when MIGRATION_MODE is already set true above: + if ! is_true "$MIGRATION_MODE" ; then + # Compare original disks and their possible target disk one by one: +- while read disk dev size junk ; do +- dev=$( get_sysfs_name $dev ) ++ while read disk devnode size junk ; do ++ dev=$( get_sysfs_name $devnode ) + Log "Comparing $dev" + if test -e "/sys/block/$dev" ; then + Log "Device /sys/block/$dev exists" + newsize=$( get_disk_size $dev ) + if test "$newsize" -eq "$size" ; then + LogPrint "Device $dev has expected (same) size $size bytes (will be used for '$WORKFLOW')" ++ elif test "$( get_mapping_hint $devnode )" == "$devnode" ; then ++ Debug "Found identical mapping hint ${devnode} -> ${devnode}" ++ LogPrint "Device $dev found according to mapping hints (will be used for '$WORKFLOW')" + else + LogPrint "Device $dev has size $newsize bytes but $size bytes is expected (needs manual configuration)" + MIGRATION_MODE='true' +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 2e90768c..468aa35c 100644 +--- a/usr/share/rear/layout/prepare/default/300_map_disks.sh ++++ b/usr/share/rear/layout/prepare/default/300_map_disks.sh +@@ -112,7 +112,14 @@ 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 + # First, try to find if there is a current disk with same name and same size as the original: +- sysfs_device_name="$( get_sysfs_name "$orig_device" )" ++ # (possibly influenced by mapping hints if known) ++ if has_mapping_hint "$orig_device" ; then ++ candidate_target_device_name="$( get_mapping_hint "$orig_device" )" ++ Debug "Using mapping hint ${candidate_target_device_name} as candidate for $orig_device mapping" ++ else ++ candidate_target_device_name="$orig_device" ++ fi ++ sysfs_device_name="$( get_sysfs_name "$candidate_target_device_name" )" + current_device="/sys/block/$sysfs_device_name" + if test -e $current_device ; then + current_size=$( get_disk_size $sysfs_device_name ) +@@ -122,11 +129,16 @@ while read keyword orig_device orig_size junk ; do + # Continue with next one if the current one is already used as target in the mapping file: + is_mapping_target "$preferred_target_device_name" && continue + # Use the current one if it is of same size as the old one: +- if test "$orig_size" -eq "$current_size" ; then ++ if has_mapping_hint "$orig_device" || test "$orig_size" -eq "$current_size" ; then + # Ensure the determined target device is really a block device: + if test -b "$preferred_target_device_name" ; then ++ if has_mapping_hint "$orig_device" ; then ++ mapping_reason="determined by mapping hint" ++ else ++ mapping_reason="same name and same size $current_size" ++ fi + add_mapping "$orig_device" "$preferred_target_device_name" +- LogPrint "Using $preferred_target_device_name (same name and same size) for recreating $orig_device" ++ LogPrint "Using $preferred_target_device_name ($mapping_reason) for recreating $orig_device" + # Continue with next original device in the LAYOUT_FILE: + continue + fi +diff --git a/usr/share/rear/layout/save/GNU/Linux/200_partition_layout.sh b/usr/share/rear/layout/save/GNU/Linux/200_partition_layout.sh +index 3ab7357d..da6ce64c 100644 +--- a/usr/share/rear/layout/save/GNU/Linux/200_partition_layout.sh ++++ b/usr/share/rear/layout/save/GNU/Linux/200_partition_layout.sh +@@ -362,18 +362,27 @@ Log "Saving disk partitions." + + if [[ $blockd == dasd* && "$ARCH" == "Linux-s390" ]] ; then + devname=$(get_device_name $disk) ++ dasdnum=$( lsdasd | awk "\$3 == \"$blockd\" { print \$1}" ) ++ dasdstatus=$( lsdasd | awk "\$3 == \"$blockd\" { print \$2}" ) ++ # ECKD or FBA ++ dasdtype=$( lsdasd | awk "\$3 == \"$blockd\" { print \$5}" ) ++ if [ "$dasdtype" != ECKD ] && [ "$dasdtype" != FBA ]; then ++ LogPrint "Type $dasdtype of DASD $blockd unexpected: neither ECKD nor FBA" ++ fi + +- echo "# active dasd bus and channel" +- echo "# bus-id type" +- echo "dasd_channel $( lsdasd|grep $blockd|awk '{ print $1 " " $2 " " $3 " " $4}' )" +- +- echo "# dasdfmt - disk layout is either cdl for the compatible disk layout (default) or ldl" +- echo "# example usage: dasdfmt -b 4096 -d cdl -y /dev/dasda" +- layout=$(dasdview -x /dev/$blockd|grep "^format"|awk '{print $7}') +- blocksize=$( dasdview -i /dev/$blockd|grep blocksize|awk '{print $6}' ) +- echo "# dasdfmt $devname" +- echo "# dasdfmt -b -d -y " +- echo "dasdfmt -b $blocksize -d $layout -y $devname" ++ echo "# every DASD bus and channel" ++ echo "# Format: dasd_channel " ++ echo "dasd_channel $dasdnum $blockd" ++ ++ # We need to print the dasd_channel line even for ignored devices, ++ # otherwise we could have naming gaps and naming would change when ++ # recreating layout. ++ # E.g. if dasda is ignored, and dasdb is not, we would create only dasdb ++ # during recreation, but it would be named dasda. ++ if [ "$dasdstatus" != active ]; then ++ Log "Ignoring $blockd: it is not active (Status is $dasdstatus)" ++ continue ++ fi + fi + + #FIXME: exclude *rpmb (Replay Protected Memory Block) for nvme*, mmcblk* and uas +@@ -387,11 +396,38 @@ Log "Saving disk partitions." + devname=$(get_device_name $disk) + devsize=$(get_disk_size ${disk#/sys/block/}) + disktype=$(parted -s $devname print | grep -E "Partition Table|Disk label" | cut -d ":" -f "2" | tr -d " ") +- +- echo "# Disk $devname" +- echo "# Format: disk " +- echo "disk $devname $devsize $disktype" +- ++ if [ "$disktype" != "dasd" ]; then ++ echo "# Disk $devname" ++ echo "# Format: disk " ++ echo "disk $devname $devsize $disktype" ++ elif [[ $blockd == dasd* && "$ARCH" == "Linux-s390" ]] ; then ++ layout=$(dasdview -x $devname |grep "^format"|awk '{print $7}') ++ case "$layout" in ++ (NOT) ++ # NOT -> dasdview has printed "NOT formatted" ++ LogPrintError "Ignoring $blockd: it is not formatted" ++ continue ++ ;; ++ (LDL|CDL) ++ ;; ++ (*) ++ BugError "Invalid 'disk $devname' entry (unknown DASD layout $layout)" ++ ;; ++ esac ++ test $disktype || Error "No partition label type for DASD entry 'disk $devname'" ++ blocksize=$( get_block_size "$blockd" ) ++ if ! test $blocksize ; then ++ # fallback - ugly method ++ blocksize=$( dasdview -i $devname |grep blocksize|awk '{print $6}' ) ++ test $blocksize || Error "Unknown block size of DASD $devname" ++ fi ++ dasdcyls=$( get_dasd_cylinders "$blockd" ) ++ echo "# Disk $devname" ++ echo "# Format: disk " ++ echo "disk $devname $devsize $disktype $blocksize $layout $dasdtype $dasdcyls" ++ else ++ Error "Invalid 'disk $devname' entry (DASD partition label on non-s390 arch $ARCH)" ++ fi + echo "# Partitions on $devname" + echo "# Format: part /dev/" + extract_partitions "$devname" +diff --git a/usr/share/rear/lib/layout-functions.sh b/usr/share/rear/lib/layout-functions.sh +index 91c5ff73..4f5b8f6f 100644 +--- a/usr/share/rear/lib/layout-functions.sh ++++ b/usr/share/rear/lib/layout-functions.sh +@@ -93,6 +93,12 @@ abort_recreate() { + restore_original_file "$LAYOUT_FILE" + } + ++abort_dasd_format() { ++ Log "Error detected during DASD formatting." ++ Log "Restoring saved original $DASD_FORMAT_FILE" ++ restore_original_file "$DASD_FORMAT_FILE" ++} ++ + # Test and log if a component $1 (type $2) needs to be recreated. + create_component() { + local device="$1" +@@ -722,6 +728,46 @@ get_block_size() { + fi + } + ++# Get the number of cylinders of a DASD. ++# The number of cylinders has the advantage of being fixed - size depends on formatting ++# and number of cylinders is valid even for unformatted DASDs, size is not. ++get_dasd_cylinders() { ++ local disk_name="${1##*/}" # /some/path/dasda -> dasda ++ local dasd_cyls ++ ++ dasd_cyls=$(dasdview -i /dev/$disk_name | grep cylinders | cut -d ':' -f2 | awk '{print $4}') ++ ### Make sure we always return a number ++ echo $(( dasd_cyls )) ++} ++ ++# Sometimes we know what the new device for the original device should be in a more reliable way ++# than by looking at disk sizes. THis information is called "mapping hints". Let's pass them ++# to the mapping code using the DISK_MAPPING_HINTS array. Each element of the array has the form ++# "/dev/source /dev/target" (space-separated). ++ ++# Output the mapping hint for the original device. ++function get_mapping_hint () { ++ local device="$1" ++ local hint mapping_hint_source mapping_hint_target ++ ++ for hint in "${DISK_MAPPING_HINTS[@]}"; do ++ mapping_hint_source=${hint%% *} ++ mapping_hint_target=${hint##* } ++ if [ "${device}" == "${mapping_hint_source}" ] ; then ++ echo "$mapping_hint_target" ++ return 0 ++ fi ++ done ++ return 1 ++} ++ ++# Determine if there is a mapping hint for the original device. ++function has_mapping_hint () { ++ local device="$1" ++ ++ get_mapping_hint "$device" > /dev/null ++} ++ + # Get the UUID of a device. + # Device is something like /dev/sda1. + blkid_uuid_of_device() { diff --git a/SPECS/rear.spec b/SPECS/rear.spec index 9e83a48..9da1a06 100644 --- a/SPECS/rear.spec +++ b/SPECS/rear.spec @@ -3,7 +3,7 @@ Name: rear Version: 2.6 -Release: 15%{?dist} +Release: 17%{?dist} Summary: Relax-and-Recover is a Linux disaster recovery and system migration tool URL: http://relax-and-recover.org/ License: GPLv3 @@ -40,6 +40,10 @@ Patch49: rsync-output.patch Patch50: rear-bz2119501.patch Patch51: rear-bz2120736.patch Patch52: rear-bz2117937.patch +Patch53: rear-bz2091163.patch +Patch54: rear-bz2130945.patch +Patch55: rear-bz2131946.patch +Patch56: s390-no-clobber-disks.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. @@ -62,6 +66,11 @@ Requires: /usr/sbin/ofpathname # Needed to make PowerVM LPARs bootable Requires: /usr/sbin/bootlist %endif +%ifarch s390x +# Contain many utilities for working with DASDs +Requires: s390utils-base +Requires: s390utils-core +%endif # In the end this should tell the user that rear is known to work only on ix86 x86_64 ppc ppc64 ppc64le ia64 # and on ix86 x86_64 syslinux is explicitly required to make the bootable ISO image # (in addition to the default installed bootloader grub2) while on ppc ppc64 the @@ -160,6 +169,15 @@ install -m 0644 %{SOURCE3} %{buildroot}%{_docdir}/%{name}/ #-- CHANGELOG -----------------------------------------------------------------# %changelog +* Wed Feb 22 2023 Pavel Cahyna - 2.6-17 +- Backport PR2943 to fix s390x dasd formatting +- Require s390utils-{core,base} on s390x + +* Sun Jan 15 2023 Pavel Cahyna - 2.6-16 +- Apply PR2903 to protect against colons in pvdisplay output +- Apply PR2873 to fix initrd regeneration on s390x +- Apply PR2431 to migrate XFS configuration files + * Thu Aug 25 2022 Pavel Cahyna - 2.6-15 - Exclude /etc/lvm/devices from the rescue system to work around a segfault in lvm pvcreate