import CS rear-2.6-28.el9

This commit is contained in:
AlmaLinux RelEng Bot 2026-03-30 10:58:04 -04:00
parent f4477ae3b1
commit 9caf3f1ade
9 changed files with 1226 additions and 5 deletions

View File

@ -0,0 +1,115 @@
From c4a7729242455cdef69f5ac3982f8d76ccc183c3 Mon Sep 17 00:00:00 2001
From: Johannes Meixner <jsmeix@suse.com>
Date: Fri, 1 Oct 2021 11:29:37 +0200
Subject: [PATCH] Update rear
Error out in sbin/rear when it failed to source or Source mandatory files
cf. https://github.com/rear/rear/issues/2686
(cherry picked from commit c4a7729242455cdef69f5ac3982f8d76ccc183c3)
---
usr/sbin/rear | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/usr/sbin/rear b/usr/sbin/rear
index 0cb9f4059c..5ce1d8c1e4 100755
--- a/usr/sbin/rear
+++ b/usr/sbin/rear
@@ -58,6 +58,9 @@ readonly PROGRAM=${0##*/}
readonly VERSION=2.6
readonly RELEASE_DATE="2020-06-17"
+# Where users should report bugs:
+readonly BUG_REPORT_SITE="https://github.com/rear/rear/issues"
+
# Used in framework-functions.sh to calculate the time spent executing rear:
readonly STARTTIME=$SECONDS
@@ -333,7 +336,10 @@ export LC_CTYPE=C LC_ALL=C LANG=C
# setting the right RUNTIME_LOGFILE value requires values from default.conf
# in particular the default LOGFILE value and the values of the
# LOCKLESS_WORKFLOWS and SIMULTANEOUS_RUNNABLE_WORKFLOWS arrays:
-source $SHARE_DIR/conf/default.conf
+if ! source $SHARE_DIR/conf/default.conf ; then
+ echo -e "ERROR: BUG in $PRODUCT\nFailed to source $SHARE_DIR/conf/default.conf\nPlease report it at $BUG_REPORT_SITE" >&2
+ exit 1
+fi
# Use RUNTIME_LOGFILE for the logfile that is actually used during runtime
# so that the user can specify a different LOGFILE in his local.conf file.
@@ -398,7 +404,10 @@ fi
# so that ReaR functions for actually intended user messages can use fd7 and fd8
# to show messages to the user regardless where to STDOUT and STDERR are redirected
# and fd6 to get input from the user regardless where to STDIN is redirected:
-source $SHARE_DIR/lib/_input-output-functions.sh
+if ! source $SHARE_DIR/lib/_input-output-functions.sh ; then
+ echo -e "ERROR: BUG in $PRODUCT\nFailed to source $SHARE_DIR/lib/_input-output-functions.sh\nPlease report it at $BUG_REPORT_SITE" >&2
+ exit 1
+fi
# Keep old log file:
test -r "$RUNTIME_LOGFILE" && mv -f "$RUNTIME_LOGFILE" "$RUNTIME_LOGFILE".old 2>/dev/null
@@ -478,7 +487,7 @@ fi
# Include functions after RUNTIME_LOGFILE is set and readonly
# so that functions can use a fixed RUNTIME_LOGFILE value:
for script in $SHARE_DIR/lib/[a-z]*.sh ; do
- source $script
+ source $script || BugError "Failed to source $script"
done
# Show initial startup messages:
@@ -510,21 +519,27 @@ fi
Debug "Combining configuration files"
# Use this file to manually override the OS detection:
test -d "$CONFIG_DIR" || Error "Configuration directory $CONFIG_DIR is not a directory"
-test -r "$CONFIG_DIR/os.conf" && Source "$CONFIG_DIR/os.conf" || true
-test -r "$CONFIG_DIR/$WORKFLOW.conf" && Source "$CONFIG_DIR/$WORKFLOW.conf" || true
+if test -r "$CONFIG_DIR/os.conf" ; then
+ Source "$CONFIG_DIR/os.conf" || Error "Failed to Source $CONFIG_DIR/os.conf"
+fi
+if test -r "$CONFIG_DIR/$WORKFLOW.conf" ; then
+ Source "$CONFIG_DIR/$WORKFLOW.conf" || Error "Failed to Source $CONFIG_DIR/$WORKFLOW.conf"
+fi
SetOSVendorAndVersion
# Distribution configuration files:
for config in "$ARCH" "$OS" \
"$OS_MASTER_VENDOR" "$OS_MASTER_VENDOR_ARCH" "$OS_MASTER_VENDOR_VERSION" "$OS_MASTER_VENDOR_VERSION_ARCH" \
"$OS_VENDOR" "$OS_VENDOR_ARCH" "$OS_VENDOR_VERSION" "$OS_VENDOR_VERSION_ARCH" ; do
- test -r "$SHARE_DIR/conf/$config.conf" && Source "$SHARE_DIR/conf/$config.conf" || true
+ if test -r "$SHARE_DIR/conf/$config.conf" ; then
+ Source "$SHARE_DIR/conf/$config.conf" || BugError "Failed to Source $SHARE_DIR/conf/$config.conf"
+ fi
done
# User configuration files, last thing is to overwrite variables if we are in the rescue system:
for config in site local rescue ; do
if test -r "$CONFIG_DIR/$config.conf" ; then
# Delete all characters except '\r' and error out if the resulting string is not empty:
test "$( tr -d -c '\r' < $CONFIG_DIR/$config.conf )" && Error "Carriage return character in $CONFIG_DIR/$config.conf (perhaps DOS or Mac format)"
- Source "$CONFIG_DIR/$config.conf" || true
+ Source "$CONFIG_DIR/$config.conf" || Error "Failed to Source $CONFIG_DIR/$config.conf"
fi
done
# Finally source additional configuration files if specified on the command line:
@@ -567,10 +582,10 @@ if test "$CONFIG_APPEND_FILES" ; then
# try if 'foo.conf' exists and if yes, use that:
if test -r "$config_append_file_path" ; then
LogPrint "Sourcing additional configuration file '$config_append_file_path'"
- Source "$config_append_file_path"
+ Source "$config_append_file_path" || Error "Failed to Source $config_append_file_path"
else if test -r "$config_append_file_path.conf" ; then
LogPrint "Sourcing additional configuration file '$config_append_file_path.conf'"
- Source "$config_append_file_path.conf"
+ Source "$config_append_file_path.conf" || Error "Failed to Source $config_append_file_path.conf"
else
LogPrintError "There is '-C $config_append_file' but neither '$config_append_file_path' nor '$config_append_file_path.conf' can be read."
fi
@@ -583,7 +598,7 @@ readonly SHARE_DIR CONFIG_DIR VAR_DIR LOG_DIR KERNEL_VERSION
# Enable progress subsystem only in verbose mode, set some stuff that others can use:
if test "$VERBOSE" ; then
- source $SHARE_DIR/lib/progresssubsystem.nosh
+ source $SHARE_DIR/lib/progresssubsystem.nosh || BugError "Failed to source $SHARE_DIR/lib/progresssubsystem.nosh"
fi
SourceStage "init"

View File

@ -0,0 +1,129 @@
From 9143e620579a14a3897b9842db5a2546e1e6b437 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= <lzaoral@redhat.com>
Date: Mon, 25 Aug 2025 10:14:29 +0200
Subject: [PATCH 1/3] Copy dbus-broker binaries and configs when present on
host
Resolves: https://github.com/rear/rear/issues/3480
---
usr/share/rear/prep/GNU/Linux/280_include_systemd.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/usr/share/rear/prep/GNU/Linux/280_include_systemd.sh b/usr/share/rear/prep/GNU/Linux/280_include_systemd.sh
index b45597c11c..e78036dfc5 100644
--- a/usr/share/rear/prep/GNU/Linux/280_include_systemd.sh
+++ b/usr/share/rear/prep/GNU/Linux/280_include_systemd.sh
@@ -6,7 +6,7 @@
if ps ax | grep -v grep | grep -q systemd ; then
PROGS+=( systemd agetty systemctl systemd-notify systemd-ask-password
systemd-udevd systemd-journald journalctl
- dbus-uuidgen dbus-daemon dbus-send
+ dbus-uuidgen dbus-daemon dbus-send dbus-broker dbus-broker-launch
upstart-udev-bridge systemd-tmpfiles )
# cgroup stuff - not required for ReaR
#PROGS+=( cg_annotate cgclear cgcreate cgget cgrulesengd cgset cgdelete cgclassify cgexec )
@@ -15,7 +15,7 @@ if ps ax | grep -v grep | grep -q systemd ; then
# 2- Need to add systemd/network subdir in order to preserve rules about network device naming
# (predictable naming or persitant naming / like udev).
# more info here: https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/
- COPY_AS_IS+=( /usr/share/systemd /etc/dbus-1
+ COPY_AS_IS+=( /usr/share/systemd /etc/dbus-1 /usr/share/dbus-1
/usr/lib/systemd/systemd-* /lib/systemd/systemd-*
/usr/lib/systemd/network /lib/systemd/network
/usr/lib/systemd/system-generators/systemd-getty-generator
From 75654caee0424df3911add7fa41bb33df7b59021 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= <lzaoral@redhat.com>
Date: Mon, 25 Aug 2025 10:17:56 +0200
Subject: [PATCH 2/3] Prefer dbus-broker over dbus-daemon in rescue
... if the host has dbus-broker installed.
Resolves: https://github.com/rear/rear/issues/3480
---
.../GNU/Linux/610_verify_and_adjust_udev_systemd.sh | 6 ++++++
.../usr/lib/systemd/system/dbus-broker.service | 11 +++++++++++
.../system/{dbus.service => dbus-daemon.service} | 0
3 files changed, 17 insertions(+)
create mode 100644 usr/share/rear/skel/default/usr/lib/systemd/system/dbus-broker.service
rename usr/share/rear/skel/default/usr/lib/systemd/system/{dbus.service => dbus-daemon.service} (100%)
diff --git a/usr/share/rear/build/GNU/Linux/610_verify_and_adjust_udev_systemd.sh b/usr/share/rear/build/GNU/Linux/610_verify_and_adjust_udev_systemd.sh
index 69b0b6b92d..7d2a7ff417 100644
--- a/usr/share/rear/build/GNU/Linux/610_verify_and_adjust_udev_systemd.sh
+++ b/usr/share/rear/build/GNU/Linux/610_verify_and_adjust_udev_systemd.sh
@@ -30,3 +30,9 @@ for m in "${my_udev_files[@]}" ; do
fi
done
+# prefer dbus-broker over dbus-daemon (the reference implementation)
+if [[ -f /lib/systemd/system/dbus-broker.service ]] || [[ -f /usr/lib/systemd/system/dbus-broker.service ]]; then
+ ln $v -rsf $ROOTFS_DIR/usr/lib/systemd/system/dbus{-broker,}.service >&2
+else
+ ln $v -rsf $ROOTFS_DIR/usr/lib/systemd/system/dbus{-daemon,}.service >&2
+fi
diff --git a/usr/share/rear/skel/default/usr/lib/systemd/system/dbus-broker.service b/usr/share/rear/skel/default/usr/lib/systemd/system/dbus-broker.service
new file mode 100644
index 0000000000..965c1ce984
--- /dev/null
+++ b/usr/share/rear/skel/default/usr/lib/systemd/system/dbus-broker.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=D-Bus System Message Bus
+Documentation=man:dbus-broker-launch(1)
+After=dbus.socket
+Requires=dbus.socket
+
+[Service]
+Type=notify-reload
+Sockets=dbus.socket
+OOMScoreAdjust=-900
+ExecStart=/usr/bin/dbus-broker-launch --scope system
diff --git a/usr/share/rear/skel/default/usr/lib/systemd/system/dbus.service b/usr/share/rear/skel/default/usr/lib/systemd/system/dbus-daemon.service
similarity index 100%
rename from usr/share/rear/skel/default/usr/lib/systemd/system/dbus.service
rename to usr/share/rear/skel/default/usr/lib/systemd/system/dbus-daemon.service
From 05ab7584baf81c1e3ea99513d9a50a09ac3d0687 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= <lzaoral@redhat.com>
Date: Mon, 25 Aug 2025 12:47:42 +0200
Subject: [PATCH 3/3] Modernize dbus.socket unit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
/var/run has been a symlink pointing to /run since Fedora 15 (RHEL 7+) and
modern systemd now issues a warning when some units still use this legacy path:
```
systemd[1]: /usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/,
updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
```
Moreover, the dbus.target.wants directory can be removed because the dbus.target
unit was never committed to this repository.
---
usr/share/rear/skel/default/usr/lib/systemd/system/dbus.socket | 2 +-
.../usr/lib/systemd/system/dbus.target.wants/dbus.service | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
delete mode 120000 usr/share/rear/skel/default/usr/lib/systemd/system/dbus.target.wants/dbus.service
diff --git a/usr/share/rear/skel/default/usr/lib/systemd/system/dbus.socket b/usr/share/rear/skel/default/usr/lib/systemd/system/dbus.socket
index 0303bfbde6..5c373cf450 100644
--- a/usr/share/rear/skel/default/usr/lib/systemd/system/dbus.socket
+++ b/usr/share/rear/skel/default/usr/lib/systemd/system/dbus.socket
@@ -2,4 +2,4 @@
Description=D-Bus System Message Bus Socket
[Socket]
-ListenStream=/var/run/dbus/system_bus_socket
+ListenStream=/run/dbus/system_bus_socket
diff --git a/usr/share/rear/skel/default/usr/lib/systemd/system/dbus.target.wants/dbus.service b/usr/share/rear/skel/default/usr/lib/systemd/system/dbus.target.wants/dbus.service
deleted file mode 120000
index 224df24b70..0000000000
--- a/usr/share/rear/skel/default/usr/lib/systemd/system/dbus.target.wants/dbus.service
+++ /dev/null
@@ -1 +0,0 @@
-../dbus.service
\ No newline at end of file

View File

@ -0,0 +1,686 @@
commit 258e34a72374d512155054e2d6efa84f8f5cd974
Merge: db673c433 62a99159b
Author: Johannes Meixner <jsmeix@suse.com>
Date: Fri Oct 15 12:33:19 2021 +0200
Merge pull request #2693 from rear/jsmeix-automapping-overhauled
In layout/prepare/default/300_map_disks.sh overhauled the
automapping of original 'disk' devices and 'multipath' devices
to current block devices in the currently running recovery system
so that now it automatically finds an existing unique disk size mapping
also when there is a unique mapping between more than two disks,
see https://github.com/rear/rear/issues/2690
(cherry-picked from commit 258e34a72374d512155054e2d6efa84f8f5cd974)
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 2e90768cb..6756ce10e 100644
--- a/usr/share/rear/layout/prepare/default/300_map_disks.sh
+++ b/usr/share/rear/layout/prepare/default/300_map_disks.sh
@@ -110,6 +110,7 @@ done
DebugPrint "Skip automapping $orig_device with size $orig_size (already exists as source in $MAPPING_FILE)"
continue
fi
+ # The original device is not yet mapped (i.e. not used as source in the mapping file) so it needs to be mapped.
# 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
@@ -119,25 +123,31 @@ while read keyword orig_device orig_size junk ; do
# The current_device (e.g. /sys/block/sda) is not a block device so that
# its matching actual block device (e.g. /dev/sda) must be determined:
preferred_target_device_name="$( get_device_name $current_device )"
- # 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 has_mapping_hint "$orig_device" || test "$orig_size" -eq "$current_size" ; then
- # Ensure the determined target device is really a block device:
+ # Ensure the target device is really a block device on the replacement hardware.
+ # Here the target device has same name as the original device which was a block device on the original hardware
+ # but it might perhaps happen that this device name is not a block device on the replacement hardware:
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 ($mapping_reason) for recreating $orig_device"
- # Continue with next original device in the LAYOUT_FILE:
- continue
+ # Do not map if the current one is already used as target in the mapping file:
+ if is_mapping_target "$preferred_target_device_name" ; then
+ DebugPrint "Cannot use $preferred_target_device_name ($mapping_reason) for recreating $orig_device ($preferred_target_device_name already exists as target in $MAPPING_FILE)"
+ else
+ add_mapping "$orig_device" "$preferred_target_device_name"
+ LogPrint "Using $preferred_target_device_name ($mapping_reason) for recreating $orig_device"
+ # Continue with next original device because the current one is now mapped:
+ continue
+ fi
fi
fi
fi
- # Else, loop over all current block devices to find one of the same size as the original:
+ # If there is no current disk with same name and same size as the original
+ # loop over all current block devices to find one of same size as the original:
for current_device_path in /sys/block/* ; do
# Continue with next block device if the current one has no queue directory:
test -d $current_device_path/queue || continue
@@ -143,20 +153,26 @@ while read keyword orig_device orig_size junk ; do
# The current_device_path (e.g. /sys/block/sdb) is not a block device so that
# its matching actual block device (e.g. /dev/sdb) must be determined:
preferred_target_device_name="$( get_device_name $current_device_path )"
- # 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
- # 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 $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
- fi
+ # Ensure the determined target device is really a block device (cf. above):
+ test -b "$preferred_target_device_name" || continue
+ # Continue with next current block device if the current one is not of same size as the original:
+ test "$orig_size" -eq "$current_size" || continue
+ # Continue with next current block device if the current one is already used as target in the mapping file:
+ if is_mapping_target "$preferred_target_device_name" ; then
+ DebugPrint "Cannot use $preferred_target_device_name (same size $current_size) for recreating $orig_device ($preferred_target_device_name already exists as target in $MAPPING_FILE)"
+ continue
fi
+ # The first of all current block devices with same size as the original that is not yet used as target gets used:
+ add_mapping "$orig_device" "$preferred_target_device_name"
+ LogPrint "Using $preferred_target_device_name (same size $current_size) for recreating $orig_device"
+ # Continue the outer while loop with next original device because the current one is now mapped:
+ continue 2
done
+ # The original device could not be automapped because there is
+ # neither a current disk with same name and same size as the original
+ # nor is there a current disk with different name but same size as the original
+ # so the user must maually specify the right mapping target:
+ DebugPrint "Could not automap $orig_device (no disk with same size $orig_size found)"
done < <( grep -E "^disk |^multipath " "$LAYOUT_FILE" )
# For every unmapped original 'disk' device and 'multipath' device in the LAYOUT_FILE
commit 7e5aea79e0fe1badf7c0820e854f8ca3ac32cef0
Merge: 357f9cdf8 a16d8ea19
Author: Johannes Meixner <jsmeix@suse.com>
Date: Tue Oct 26 14:11:35 2021 +0200
Merge pull request #2626 from OliverO2/feature/stop-overwriting-backups
Stop ReaR from overwriting its own disk and backup drives
for OUTPUT=USB and OUTPUT=RAWDISK via new
WRITE_PROTECTED_... config variables (see default.conf)
where UUIDs or filesystem labels can be specified so that
disks that contain such UUIDs or filesystem labels
will be 'write protected' during "rear recover",
see https://github.com/rear/rear/issues/1271
(cherry-picked from commit 7e5aea79e0fe1badf7c0820e854f8ca3ac32cef0)
diff --git a/usr/share/rear/conf/default.conf b/usr/share/rear/conf/default.conf
index ac6e6aa17..cf2b3689b 100644
--- a/usr/share/rear/conf/default.conf
+++ b/usr/share/rear/conf/default.conf
@@ -525,6 +525,22 @@ AUTORESIZE_EXCLUDE_PARTITIONS=( boot swap efi )
AUTOSHRINK_DISK_SIZE_LIMIT_PERCENTAGE=2
AUTOINCREASE_DISK_SIZE_THRESHOLD_PERCENTAGE=10
+##
+# Write-protection during "rear recover"
+#
+# Designate target disk devices or partitions as write-protected
+# to avoid being accidentally overwritten during "rear recover".
+#
+# List of partition table UUIDs, which designate write-protected disk devices.
+# ReaR's own disk device will be automatically added to this list if necessary.
+# Example: WRITE_PROTECTED_PARTITION_TABLE_UUIDS+=("ecacbce4-e05e-4eb9-835c-ade0c3ed0fea")
+WRITE_PROTECTED_PARTITION_TABLE_UUIDS=()
+#
+# List of (shell glob) patterns, which designate matching file system labels as write-protected partitions.
+# Entries may be quoted and contain blanks, but they may not contain single quotes themselves.
+# Example: WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS+=("Backup *")
+WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS=()
+
##
# Creating XFS filesystems during "rear recover"
#
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 c459b9286..49dadb3e5 100644
--- a/usr/share/rear/layout/prepare/default/250_compare_disks.sh
+++ b/usr/share/rear/layout/prepare/default/250_compare_disks.sh
@@ -79,6 +79,8 @@ if ! is_true "$MIGRATION_MODE" ; then
is_multipath_path ${current_device_path#/sys/block/} && continue
# Continue with next block device if the current one has no queue directory:
test -d $current_device_path/queue || continue
+ # Continue with next block device if the current one is designated as write-protected
+ is_write_protected $current_device_path && continue
# Continue with next block device if no size can be read for the current one:
test -r $current_device_path/size || continue
current_disk_name="${current_device_path#/sys/block/}"
@@ -116,7 +118,12 @@ if ! is_true "$MIGRATION_MODE" ; 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')"
+ if is_write_protected "/sys/block/$dev"; then
+ LogPrint "Device $dev is designated as write-protected (needs manual configuration)"
+ MIGRATION_MODE='true'
+ else
+ LogPrint "Device $dev has expected (same) size $size bytes (will be used for '$WORKFLOW')"
+ fi
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')"
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 6756ce10e..7e879470f 100644
--- a/usr/share/rear/layout/prepare/default/300_map_disks.sh
+++ b/usr/share/rear/layout/prepare/default/300_map_disks.sh
@@ -133,10 +133,15 @@ while read keyword orig_device orig_size junk ; do
if is_mapping_target "$preferred_target_device_name" ; then
DebugPrint "Cannot use $preferred_target_device_name ($mapping_reason) for recreating $orig_device ($preferred_target_device_name already exists as target in $MAPPING_FILE)"
else
- add_mapping "$orig_device" "$preferred_target_device_name"
- LogPrint "Using $preferred_target_device_name ($mapping_reason) for recreating $orig_device"
- # Continue with next original device because the current one is now mapped:
- continue
+ # Ensure the determined target device is not write-protected:
+ if is_write_protected "$preferred_target_device_name" ; then
+ DebugPrint "Cannot use $preferred_target_device_name ($mapping_reason) for recreating $orig_device ($preferred_target_device_name is write-protected)"
+ else
+ add_mapping "$orig_device" "$preferred_target_device_name"
+ LogPrint "Using $preferred_target_device_name ($mapping_reason) for recreating $orig_device"
+ # Continue with next original device because the current one is now mapped:
+ continue
+ fi
fi
fi
fi
@@ -162,6 +167,11 @@ while read keyword orig_device orig_size junk ; do
DebugPrint "Cannot use $preferred_target_device_name (same size $current_size) for recreating $orig_device ($preferred_target_device_name already exists as target in $MAPPING_FILE)"
continue
fi
+ # Ensure the determined target device is not write-protected (cf. above):
+ if is_write_protected "$preferred_target_device_name" ; then
+ DebugPrint "Cannot use $preferred_target_device_name (same size $current_size) for recreating $orig_device ($preferred_target_device_name is write-protected)"
+ continue
+ fi
# The first of all current block devices with same size as the original that is not yet used as target gets used:
add_mapping "$orig_device" "$preferred_target_device_name"
LogPrint "Using $preferred_target_device_name (same size $current_size) for recreating $orig_device"
@@ -217,6 +227,14 @@ 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
+ if is_write_protected_by_pt_uuid "$preferred_target_device_name"; then
+ Log "$preferred_target_device_name excluded from device mapping choices (write-protected partition table UUID)"
+ continue
+ fi
+ if is_write_protected_by_fs_label "$preferred_target_device_name"; then
+ Log "$preferred_target_device_name excluded from device mapping choices (write-protected file system label)"
+ 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" )
diff --git a/usr/share/rear/lib/write-protect-functions.sh b/usr/share/rear/lib/write-protect-functions.sh
new file mode 100644
index 000000000..709ebbe41
--- /dev/null
+++ b/usr/share/rear/lib/write-protect-functions.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+#
+# Functions to identify write-protected disks and partitions
+#
+
+function write_protected_candidate_device() {
+ local device="$1"
+ # prints the path of the block device, translating it if given as /sys/block/*.
+
+ if [[ "$device" == /sys/block/* ]]; then
+ device="$(get_device_name "$device")"
+ fi
+ [[ ! -b "$device" ]] && Error "Could not check '$1' ('$device') for write protection not a block device"
+ echo "$device"
+}
+
+function is_write_protected_by_pt_uuid() {
+ local device="$(write_protected_candidate_device "$1")"
+ # returns 0 if the device's partition table UUID is in the list of write-protected UUIDs.
+
+ local partition_table_uuid="$(lsblk --output PTUUID --noheadings --nodeps "$device")"
+
+ if [[ " ${WRITE_PROTECTED_PARTITION_TABLE_UUIDS[*]} " == *" $partition_table_uuid "* ]]; then
+ Log "$device is designated as write-protected by partition table UUID '$partition_table_uuid'"
+ return 0
+ fi
+
+ return 1
+}
+
+function is_write_protected_by_fs_label() {
+ local device="$(write_protected_candidate_device "$1")"
+ # returns 0 if one of the device's file system labels matches a prefix from the list of write-protected
+ # label prefixes.
+
+ # Check all partitions of a device for a matching label
+ local write_protected_pattern
+ while read -r partition_label; do
+ if [[ -n "$partition_label" ]]; then
+ for write_protected_pattern in "${WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS[@]}"; do
+ if [[ "$partition_label" == $write_protected_pattern ]]; then
+ Log "$device is designated as write-protected, its label '$partition_label' matches '$write_protected_pattern'"
+ return 0
+ fi
+ done
+ fi
+ done < <(lsblk --output LABEL --noheadings "$device")
+
+ return 1
+}
+
+function is_write_protected() {
+ local device="$(write_protected_candidate_device "$1")"
+ # returns 0 if the device is designated as write-protected by any of the above means.
+
+ is_write_protected_by_pt_uuid "$device" || is_write_protected_by_fs_label "$device"
+}
diff --git a/usr/share/rear/output/RAWDISK/Linux-i386/280_create_bootable_disk_image.sh b/usr/share/rear/output/RAWDISK/Linux-i386/280_create_bootable_disk_image.sh
index 497ff8979..dcbc4633e 100644
--- a/usr/share/rear/output/RAWDISK/Linux-i386/280_create_bootable_disk_image.sh
+++ b/usr/share/rear/output/RAWDISK/Linux-i386/280_create_bootable_disk_image.sh
@@ -53,7 +53,10 @@ local typecode="8300" # Linux partition for non-EFI booting
local legacy_boot_option=""
is_true $use_syslinux_legacy && legacy_boot_option="--attributes=1:set:2" # mark partition as Legacy BIOS-bootable
-sgdisk --new 1::0 --typecode=1:"$typecode" --change-name=1:"${RAWDISK_GPT_PARTITION_NAME:-Rescue System}" $legacy_boot_option "$disk_image"
+local guid_option=""
+[[ -n "$RAWDISK_PTUUID" ]] && guid_option="--disk-guid=$RAWDISK_PTUUID" # Use a pre-determined partition UUID
+
+sgdisk $guid_option --new 1::0 --typecode=1:"$typecode" --change-name=1:"${RAWDISK_GPT_PARTITION_NAME:-Rescue System}" $legacy_boot_option "$disk_image"
StopIfError "Could not create GPT partition table on $disk_image"
Log "Raw disk image partition table:"
diff --git a/usr/share/rear/prep/RAWDISK/Linux-i386/480_initialize_write_protect_settings.sh b/usr/share/rear/prep/RAWDISK/Linux-i386/480_initialize_write_protect_settings.sh
new file mode 100644
index 000000000..87929e5c5
--- /dev/null
+++ b/usr/share/rear/prep/RAWDISK/Linux-i386/480_initialize_write_protect_settings.sh
@@ -0,0 +1,13 @@
+# RAWDISK output typically resides on a writable disk device, which should be protected against
+# accidental overwriting by rear recover. This code initializes RAWDISK_PTUUID, a partition table UUID
+# designating ReaR's own boot device and registers it as write protected.
+
+if has_binary uuidgen; then
+ # Generate a partition table UUID now and add it to the kernel's command line options.
+ #
+ # Normally, a partition table UUID is generated automatically during partitioning. We cannot wait for this
+ # to happen as the variable will be part of the initrd, which is completed before any partition table is
+ # created.
+ RAWDISK_PTUUID="$(uuidgen)"
+ WRITE_PROTECTED_PARTITION_TABLE_UUIDS+=( $RAWDISK_PTUUID )
+fi
diff --git a/usr/share/rear/prep/USB/default/480_initialize_write_protect_settings.sh b/usr/share/rear/prep/USB/default/480_initialize_write_protect_settings.sh
new file mode 100644
index 000000000..bde1fb26c
--- /dev/null
+++ b/usr/share/rear/prep/USB/default/480_initialize_write_protect_settings.sh
@@ -0,0 +1,4 @@
+# USB output typically resides on a writable disk device, which should be protected against
+# accidental overwriting by rear recover. This code registers it as write protected.
+
+WRITE_PROTECTED_PARTITION_TABLE_UUIDS+=( $(lsblk --output PTUUID --noheadings --nodeps "$USB_DEVICE") )
diff --git a/usr/share/rear/prep/default/490_store_write_protect_settings.sh b/usr/share/rear/prep/default/490_store_write_protect_settings.sh
new file mode 100644
index 000000000..eba36cf28
--- /dev/null
+++ b/usr/share/rear/prep/default/490_store_write_protect_settings.sh
@@ -0,0 +1,15 @@
+# Store settings for write-protected file systems in the rescue configuration.
+
+{
+ echo "# The following lines were added by 490_store_write_protect_settings.sh"
+
+ echo "WRITE_PROTECTED_PARTITION_TABLE_UUIDS=( ${WRITE_PROTECTED_PARTITION_TABLE_UUIDS[*]} )"
+
+ echo -n "WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS=("
+ for prefix in "${WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS[@]}"; do
+ [[ -n "$prefix" ]] && echo -n " '$prefix'"
+ done
+ echo " )"
+
+ echo ""
+} >> "$ROOTFS_DIR/etc/rear/rescue.conf"
commit a5edba7551884e9201a21fc1ea33de7ca7e6cb07
Merge: 039b7b255 46a6e9ad3
Author: Johannes Meixner <jsmeix@suse.com>
Date: Wed Nov 10 13:41:17 2021 +0100
Merge pull request #2703 from rear/jsmeix-write-protect
Enhanced disk write-protection,
see https://github.com/rear/rear/pull/2626
WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS
is shortened to WRITE_PROTECTED_FS_LABEL_PATTERNS.
The specific WRITE_PROTECTED_PARTITION_TABLE_UUIDS
is replaced by WRITE_PROTECTED_IDS with generic functionality,
cf. https://github.com/rear/rear/pull/2626#issuecomment-950953826
together with the new WRITE_PROTECTED_ID_TYPES which
defaults to UUID PTUUID PARTUUID WWN so that the user can
specify different lsblk columns as needed in his particular environment
cf. https://github.com/rear/rear/pull/2703#issuecomment-962418441
(cherry-picked from commit a5edba7551884e9201a21fc1ea33de7ca7e6cb07)
diff --git a/usr/share/rear/conf/default.conf b/usr/share/rear/conf/default.conf
index 17b2310fd..041772d07 100644
--- a/usr/share/rear/conf/default.conf
+++ b/usr/share/rear/conf/default.conf
@@ -527,19 +527,45 @@ AUTOINCREASE_DISK_SIZE_THRESHOLD_PERCENTAGE=10
##
# Write-protection during "rear recover"
-#
-# Designate target disk devices or partitions as write-protected
-# to avoid being accidentally overwritten during "rear recover".
-#
-# List of partition table UUIDs, which designate write-protected disk devices.
-# ReaR's own disk device will be automatically added to this list if necessary.
-# Example: WRITE_PROTECTED_PARTITION_TABLE_UUIDS+=("ecacbce4-e05e-4eb9-835c-ade0c3ed0fea")
-WRITE_PROTECTED_PARTITION_TABLE_UUIDS=()
-#
-# List of (shell glob) patterns, which designate matching file system labels as write-protected partitions.
+# for OUTPUT=USB and OUTPUT=RAWDISK
+#
+# Designate disks via disk specific IDs or file system labels as write-protected
+# to avoid that those disks could get used as target disk during "rear recover"
+# via WRITE_PROTECTED_IDS and WRITE_PROTECTED_FS_LABEL_PATTERNS
+# in etc/rear/rescue.conf in the ReaR rescue/recovery system.
+#
+# WRITE_PROTECTED_ID_TYPES is a string of the 'lsblk' output columns where
+# their values are stored in WRITE_PROTECTED_IDS during "rear mkrescue/mkbackup".
+# During "rear recover" a disk is write-protected when one of the values
+# of this 'lsblk' output columns for the disk also exists in WRITE_PROTECTED_IDS.
+# The default 'lsblk' output columns for write-protection via disk specific IDs are
+# UUID filesystem UUID
+# PTUUID partition table identifier (usually UUID)
+# PARTUUID partition UUID
+# WWN unique storage identifier
+WRITE_PROTECTED_ID_TYPES="UUID PTUUID PARTUUID WWN"
+#
+# For OUTPUT=USB the values of the 'lsblk' output columns in WRITE_PROTECTED_ID_TYPES
+# of the ReaR recovery system disk (i.e. USB_DEVICE) are automatically added
+# to the WRITE_PROTECTED_IDS array during "rear mkrescue/mkbackup".
+# For OUTPUT=RAWDISK a partition table UUID is generated (provided 'uuidgen' is there)
+# that is added to the WRITE_PROTECTED_IDS array.
+# For the IDs in WRITE_PROTECTED_IDS their matching 'lsblk' output columns
+# must exist in WRITE_PROTECTED_ID_TYPES because only this ID types are used
+# to test if a disk is write-protected (see WRITE_PROTECTED_ID_TYPES above).
+# E.g. if you like to use additionally the 'lsblk' output column MODEL as ID
+# in WRITE_PROTECTED_IDS like WRITE_PROTECTED_IDS+=( "ACME_USB_DISK_XL" )
+# you must also append that 'lsblk' output column as separated additional word
+# to the WRITE_PROTECTED_ID_TYPES string like WRITE_PROTECTED_ID_TYPES+=" MODEL"
+WRITE_PROTECTED_IDS=()
+#
+# WRITE_PROTECTED_FS_LABEL_PATTERNS is an array of (shell glob) patterns which designate
+# matching file system labels as write-protected partitions to write-protect their disk.
# Entries may be quoted and contain blanks, but they may not contain single quotes themselves.
-# Example: WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS+=("Backup *")
-WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS=()
+# Example: WRITE_PROTECTED_FS_LABEL_PATTERNS+=( "Backup *" )
+# For OUTPUT=USB the file system label of the ReaR data partition on the ReaR recovery system disk
+# is automatically added to WRITE_PROTECTED_FS_LABEL_PATTERNS during "rear mkrescue/mkbackup".
+WRITE_PROTECTED_FS_LABEL_PATTERNS=()
##
# Creating XFS filesystems during "rear recover"
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 7e879470f..7b127b3ab 100644
--- a/usr/share/rear/layout/prepare/default/300_map_disks.sh
+++ b/usr/share/rear/layout/prepare/default/300_map_disks.sh
@@ -115,6 +115,11 @@ while read keyword orig_device orig_size junk ; do
continue
fi
# The original device is not yet mapped (i.e. not used as source in the mapping file) so it needs to be mapped.
+ # Remember when target devices get known by the "same name and same size" tests
+ # that they cannot be used for recreating the current original device
+ # to avoid that already excluded target devices get needlessly
+ # considered again during the subsequent "same size" tests:
+ excluded_target_device_names=()
# 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
@@ -132,10 +137,12 @@ while read keyword orig_device orig_size junk ; do
# Do not map if the current one is already used as target in the mapping file:
if is_mapping_target "$preferred_target_device_name" ; then
DebugPrint "Cannot use $preferred_target_device_name ($mapping_reason) for recreating $orig_device ($preferred_target_device_name already exists as target in $MAPPING_FILE)"
+ excluded_target_device_names+=( "$preferred_target_device_name" )
else
# Ensure the determined target device is not write-protected:
if is_write_protected "$preferred_target_device_name" ; then
DebugPrint "Cannot use $preferred_target_device_name ($mapping_reason) for recreating $orig_device ($preferred_target_device_name is write-protected)"
+ excluded_target_device_names+=( "$preferred_target_device_name" )
else
add_mapping "$orig_device" "$preferred_target_device_name"
LogPrint "Using $preferred_target_device_name ($mapping_reason) for recreating $orig_device"
@@ -160,9 +167,11 @@ while read keyword orig_device orig_size junk ; do
preferred_target_device_name="$( get_device_name $current_device_path )"
# Ensure the determined target device is really a block device (cf. above):
test -b "$preferred_target_device_name" || continue
- # Continue with next current block device if the current one is not of same size as the original:
+ # Continue with next block device if the current one is not of same size as the original:
test "$orig_size" -eq "$current_size" || continue
- # Continue with next current block device if the current one is already used as target in the mapping file:
+ # Continue with next block device if the current one was already excluded by the "same name and same size" tests above:
+ IsInArray "$preferred_target_device_name" "${excluded_target_device_names[@]}" && continue
+ # Continue with next block device if the current one is already used as target in the mapping file:
if is_mapping_target "$preferred_target_device_name" ; then
DebugPrint "Cannot use $preferred_target_device_name (same size $current_size) for recreating $orig_device ($preferred_target_device_name already exists as target in $MAPPING_FILE)"
continue
@@ -227,12 +236,9 @@ 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
- if is_write_protected_by_pt_uuid "$preferred_target_device_name"; then
- Log "$preferred_target_device_name excluded from device mapping choices (write-protected partition table UUID)"
- continue
- fi
- if is_write_protected_by_fs_label "$preferred_target_device_name"; then
- Log "$preferred_target_device_name excluded from device mapping choices (write-protected file system label)"
+ # Continue with next block device if the current one is designated as write-protected:
+ if is_write_protected "$preferred_target_device_name"; then
+ Log "$preferred_target_device_name excluded from device mapping choices (is designated as write-protected)"
continue
fi
LogPrint "The size of $preferred_target_device_name is $(blockdev --getsize64 $current_device_path)"
diff --git a/usr/share/rear/lib/write-protect-functions.sh b/usr/share/rear/lib/write-protect-functions.sh
index 709ebbe41..cbc9e390b 100644
--- a/usr/share/rear/lib/write-protect-functions.sh
+++ b/usr/share/rear/lib/write-protect-functions.sh
@@ -8,23 +8,73 @@ function write_protected_candidate_device() {
# prints the path of the block device, translating it if given as /sys/block/*.
if [[ "$device" == /sys/block/* ]]; then
- device="$(get_device_name "$device")"
+ device="$( get_device_name "$device" )"
fi
- [[ ! -b "$device" ]] && Error "Could not check '$1' ('$device') for write protection not a block device"
+ test -b "$device" || BugError "write_protected_candidate_device called for '$1' but '$device' is no block device"
echo "$device"
}
-function is_write_protected_by_pt_uuid() {
- local device="$(write_protected_candidate_device "$1")"
- # returns 0 if the device's partition table UUID is in the list of write-protected UUIDs.
+function write_protection_ids() {
+ local device="$( write_protected_candidate_device "$1" )"
+ # Output the IDs for write-protection, each ID on a separated line.
+
+ # At least for OUTPUT=USB $device is of the form /dev/disk/by-label/$USB_DEVICE_FILESYSTEM_LABEL
+ # which is a symlink to the ReaR data partition (e.g. /dev/sdb3 on a USB disk /dev/sdb).
+ # On a USB disk that was formatted with "rear format" there is only one layer of child devices
+ # (i.e. there are only partitions like /dev/sdb1 /dev/sdb2 /dev/sdb3 on a USB disk /dev/sdb).
+ # So we only need to use the direct parent device to get all IDs of the whole disk
+ # because the goal is to write-protect the whole disk by using all its IDs
+ # cf. https://github.com/rear/rear/pull/2703#issuecomment-952888484
+ local parent_device=""
+ # Older Linux distributions do not contain lsblk (e.g. SLES10)
+ # and older lsblk versions do not support the output column PKNAME
+ # e.g. lsblk in util-linux 2.19.1 in SLES11 supports NAME and KNAME but not PKNAME
+ # cf. https://github.com/rear/rear/pull/2626#issuecomment-856700823
+ # We ignore lsblk failures and error messages and we skip empty lines in the output via 'awk NF'
+ # cf. https://unix.stackexchange.com/questions/274708/most-elegant-pipe-to-get-rid-of-empty-lines-you-can-think-of
+ # and https://stackoverflow.com/questions/23544804/how-awk-nf-filename-is-working
+ # (an empty line appears for a whole disk device e.g. /dev/sdb that has no PKNAME)
+ # and we use only the topmost reported PKNAME:
+ parent_device="$( lsblk -inpo PKNAME "$device" 2>/dev/null | awk NF | head -n1 )"
+ # parent_device is empty when lsblk does not support PKNAME.
+ # Without quoting an empty parent_device would result plain "test -b" which would (falsely) succeed:
+ test -b "$parent_device" && device="$parent_device"
+
+ local column
+ # The default WRITE_PROTECTED_ID_TYPES are UUID PTUUID PARTUUID WWN.
+ # Older lsblk versions do not support all output columns UUID PTUUID PARTUUID WWN
+ # e.g. lsblk in util-linux 2.19.1 in SLES11 only supports UUID but neither PTUUID nor PARTUUID nor WWN
+ # cf. https://github.com/rear/rear/pull/2626#issuecomment-856700823
+ # When an unsupported output column is specified lsblk aborts with "unknown column" error message
+ # without output for supported output columns so we run lsblk for each output column separately
+ # and ignore lsblk failures and error messages and we skip empty lines in the output via 'awk NF'
+ # (empty lines appear when a partition does not have a filesystem UUID or for the whole device that has no PARTUUID
+ # or for all columns except UUID when a child device is a /dev/mapper/* device
+ # and some devices do not have any WWN set)
+ # and we remove duplicate reported IDs (in particular PTUUID is reported also for each partition):
+ for column in $WRITE_PROTECTED_ID_TYPES ; do lsblk -ino $column "$device" 2>/dev/null ; done | awk NF | sort -u
+}
- local partition_table_uuid="$(lsblk --output PTUUID --noheadings --nodeps "$device")"
+function is_write_protected_by_id() {
+ local device="$(write_protected_candidate_device "$1")"
+ # returns 0 if one of the device's IDs is in the list of write-protected IDs.
- if [[ " ${WRITE_PROTECTED_PARTITION_TABLE_UUIDS[*]} " == *" $partition_table_uuid "* ]]; then
- Log "$device is designated as write-protected by partition table UUID '$partition_table_uuid'"
+ local ids id
+ ids="$( write_protection_ids "$device" )"
+ # ids is a string of IDs separated by newline characters
+ if ! test "$ids" ; then
+ LogPrintError "Cannot check write protection by ID for $device (no ID found)"
+ # It is safer to assume that the disk is protected (and thus return 0)
+ # instead of assuming that it is not protected and blindly proceed:
return 0
fi
-
+ for id in $ids ; do
+ if IsInArray "$id" "${WRITE_PROTECTED_IDS[@]}" ; then
+ Log "$device is designated as write-protected by ID $id"
+ return 0
+ fi
+ done
+ Log "$device is not write-protected by ID"
return 1
}
@@ -37,7 +87,7 @@ function is_write_protected_by_fs_label() {
local write_protected_pattern
while read -r partition_label; do
if [[ -n "$partition_label" ]]; then
- for write_protected_pattern in "${WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS[@]}"; do
+ for write_protected_pattern in "${WRITE_PROTECTED_FS_LABEL_PATTERNS[@]}"; do
if [[ "$partition_label" == $write_protected_pattern ]]; then
Log "$device is designated as write-protected, its label '$partition_label' matches '$write_protected_pattern'"
return 0
@@ -45,7 +95,7 @@ function is_write_protected_by_fs_label() {
done
fi
done < <(lsblk --output LABEL --noheadings "$device")
-
+ Log "$device is not write-protected by file system label"
return 1
}
@@ -53,5 +103,5 @@ function is_write_protected() {
local device="$(write_protected_candidate_device "$1")"
# returns 0 if the device is designated as write-protected by any of the above means.
- is_write_protected_by_pt_uuid "$device" || is_write_protected_by_fs_label "$device"
+ is_write_protected_by_id "$device" || is_write_protected_by_fs_label "$device"
}
diff --git a/usr/share/rear/prep/RAWDISK/Linux-i386/480_initialize_write_protect_settings.sh b/usr/share/rear/prep/RAWDISK/Linux-i386/480_initialize_write_protect_settings.sh
index 87929e5c5..0199d0059 100644
--- a/usr/share/rear/prep/RAWDISK/Linux-i386/480_initialize_write_protect_settings.sh
+++ b/usr/share/rear/prep/RAWDISK/Linux-i386/480_initialize_write_protect_settings.sh
@@ -8,6 +8,12 @@ if has_binary uuidgen; then
# Normally, a partition table UUID is generated automatically during partitioning. We cannot wait for this
# to happen as the variable will be part of the initrd, which is completed before any partition table is
# created.
- RAWDISK_PTUUID="$(uuidgen)"
- WRITE_PROTECTED_PARTITION_TABLE_UUIDS+=( $RAWDISK_PTUUID )
+ RAWDISK_PTUUID="$( uuidgen )"
+ if test "$RAWDISK_PTUUID"; then
+ WRITE_PROTECTED_IDS+=( $RAWDISK_PTUUID )
+ else
+ LogPrintError "Cannot write protect '${RAWDISK_GPT_PARTITION_NAME:-Rescue System}' disk (no partition table UUID)"
+ fi
+else
+ LogPrintError "Cannot write protect '${RAWDISK_GPT_PARTITION_NAME:-Rescue System}' disk (no 'uuidgen' found)"
fi
diff --git a/usr/share/rear/prep/USB/default/480_initialize_write_protect_settings.sh b/usr/share/rear/prep/USB/default/480_initialize_write_protect_settings.sh
index bde1fb26c..4a9fea047 100644
--- a/usr/share/rear/prep/USB/default/480_initialize_write_protect_settings.sh
+++ b/usr/share/rear/prep/USB/default/480_initialize_write_protect_settings.sh
@@ -1,4 +1,29 @@
-# USB output typically resides on a writable disk device, which should be protected against
-# accidental overwriting by rear recover. This code registers it as write protected.
+# USB output typically resides on a writable disk device
+# which should be protected against overwriting by "rear recover"
+# cf. https://github.com/rear/rear/issues/1271
+# This code registers the USB output device as write protected.
-WRITE_PROTECTED_PARTITION_TABLE_UUIDS+=( $(lsblk --output PTUUID --noheadings --nodeps "$USB_DEVICE") )
+# The values of the 'lsblk' output columns in WRITE_PROTECTED_ID_TYPES
+# of the ReaR recovery system disk (parent of USB_DEVICE) are automatically added
+# to the WRITE_PROTECTED_IDS array during "rear mkrescue/mkbackup".
+# The default WRITE_PROTECTED_ID_TYPES are UUID PTUUID PARTUUID WWN.
+local ids
+ids="$( write_protection_ids "$USB_DEVICE" )"
+# ids is a string of IDs separated by newline characters so quoting for 'test' is required
+# but no quoting to add them to the array to get each ID as a separated array element:
+if test "$ids" ; then
+ WRITE_PROTECTED_IDS+=( $ids )
+ DebugPrint "USB disk IDs of '$USB_DEVICE' added to WRITE_PROTECTED_IDS"
+else
+ LogPrintError "Cannot write protect USB disk of '$USB_DEVICE' via ID (no ID found)"
+fi
+
+# The file system label of the ReaR data partition (i.e. USB_DEVICE) on the ReaR recovery system disk
+# is automatically added to WRITE_PROTECTED_FS_LABEL_PATTERNS during "rear mkrescue/mkbackup".
+# Empty lines in the lsblk output get automatically ignored (i.e. no empty array elements get added)
+# and we do not alert the user via LogPrintError because file system labels are optional:
+if WRITE_PROTECTED_FS_LABEL_PATTERNS+=( $( lsblk -ino LABEL "$USB_DEVICE" ) ) ; then
+ DebugPrint "File system label of '$USB_DEVICE' added to WRITE_PROTECTED_FS_LABEL_PATTERNS"
+else
+ DebugPrint "Cannot write protect USB disk of '$USB_DEVICE' via file system label (none found)"
+fi
diff --git a/usr/share/rear/prep/default/490_store_write_protect_settings.sh b/usr/share/rear/prep/default/490_store_write_protect_settings.sh
index eba36cf28..6309184f4 100644
--- a/usr/share/rear/prep/default/490_store_write_protect_settings.sh
+++ b/usr/share/rear/prep/default/490_store_write_protect_settings.sh
@@ -3,10 +3,10 @@
{
echo "# The following lines were added by 490_store_write_protect_settings.sh"
- echo "WRITE_PROTECTED_PARTITION_TABLE_UUIDS=( ${WRITE_PROTECTED_PARTITION_TABLE_UUIDS[*]} )"
+ echo "WRITE_PROTECTED_IDS=( ${WRITE_PROTECTED_IDS[*]} )"
- echo -n "WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS=("
- for prefix in "${WRITE_PROTECTED_FILE_SYSTEM_LABEL_PATTERNS[@]}"; do
+ echo -n "WRITE_PROTECTED_FS_LABEL_PATTERNS=("
+ for prefix in "${WRITE_PROTECTED_FS_LABEL_PATTERNS[@]}"; do
[[ -n "$prefix" ]] && echo -n " '$prefix'"
done
echo " )"

View File

@ -0,0 +1,26 @@
From 70acf6fa39b3d133c0a632e3496e5a273dc9ef27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Fri, 5 Feb 2021 13:50:42 +0100
Subject: [PATCH] Update 110_include_lvm_code.sh
Make sure we delete the volume group before re-creating it.
The issue happens in Migration mode when ReaR is not trying to use vgcfgrestore.
(cherry picked from commit 70acf6fa39b3d133c0a632e3496e5a273dc9ef27)
---
usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh b/usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh
index 7cfdfcf28c..1d75990849 100644
--- a/usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh
+++ b/usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh
@@ -140,6 +140,7 @@ EOF
cat >> "$LAYOUT_CODE" <<EOF
if IsInArray $vg "\${create_volume_group[@]}" ; then
LogPrint "Creating LVM VG '$vg'; Warning: some properties may not be preserved..."
+ lvm vgremove --force --force --yes $vg >&2 || true
if [ -e "$vgrp" ] ; then
rm -rf "$vgrp"
fi

View File

@ -0,0 +1,103 @@
From bfb6bcd6903d0bff70b4d4e607bb0253bacdd610 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= <lzaoral@redhat.com>
Date: Mon, 24 Feb 2025 14:16:58 +0100
Subject: [PATCH 1/2] add bootloader auto-detection for modern PowerNV systems
Modern PowerNV systems do not necessary have the PPC PReP Boot partitions so
let's fall back on GRUB2 in the case the bootloader was not detected already.
---
.../rear/layout/save/default/445_guess_bootloader.sh | 8 ++++++++
1 file changed, 8 insertions(+)
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 f10a3834c2..7e32957547 100644
--- a/usr/share/rear/layout/save/default/445_guess_bootloader.sh
+++ b/usr/share/rear/layout/save/default/445_guess_bootloader.sh
@@ -114,6 +114,14 @@ for block_device in /sys/block/* ; do
Log "End of strings in the first bytes on $disk_device"
done
+# Default to GRUB2 on ppc64le PowerNV machines if no PPC PReP Boot partitions
+# were found because it is not manadatory to use them in this setup.
+if [ "$ARCH" = "Linux-ppc64le" ] && [ "$(awk '/platform/ {print $NF}' < /proc/cpuinfo)" = "PowerNV" ] ; then
+ LogPrint "Using guessed bootloader 'GRUB2' for 'rear recover' (default for ppc64le PowerNV machines)"
+ echo "GRUB2" >$bootloader_file
+ return
+fi
+
# No bootloader detected, but we are using UEFI - there is probably an EFI bootloader
if is_true $USING_UEFI_BOOTLOADER ; then
if is_grub2_installed ; then
From eda63ba36cc4b73b3cd62a803a233d6590a6dba4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= <lzaoral@redhat.com>
Date: Mon, 10 Mar 2025 13:53:30 +0100
Subject: [PATCH 2/2] Linux-ppc64le/660_install_grub2: fix compatibility with
PowerNV
Modern PowerNV systems with the OPAL firmware do not require the presence of
the PPC PReP boot partition [1,2]. Therefore, the installation of GRUB2
should be made optional on these machines if such partition does not exist.
As long as the GRUB2 configuration is created successfully, Petitboot will be
able to load it and boot the restored system. That was already the case, this
commit just fixes the annoying warning message about a missing bootloader.
[1] https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html-single/automatically_installing_rhel/index#raid_kickstart-commands-for-handling-storage
[2] https://bugzilla.redhat.com/show_bug.cgi?id=1970432#c2
(cherry picked from commit eda63ba36cc4b73b3cd62a803a233d6590a6dba4)
---
.../Linux-ppc64le/660_install_grub2.sh | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/usr/share/rear/finalize/Linux-ppc64le/660_install_grub2.sh b/usr/share/rear/finalize/Linux-ppc64le/660_install_grub2.sh
index ed8f024867..6b43bc3b28 100644
--- a/usr/share/rear/finalize/Linux-ppc64le/660_install_grub2.sh
+++ b/usr/share/rear/finalize/Linux-ppc64le/660_install_grub2.sh
@@ -85,15 +85,22 @@ if ! test -d "$TARGET_FS_ROOT/boot/$grub_name" ; then
done
# Generate GRUB configuration file anew to be on the safe side (this could be even mandatory in MIGRATION_MODE):
+local grub2_config_generated="yes"
if ! chroot $TARGET_FS_ROOT /bin/bash --login -c "$grub_name-mkconfig -o /boot/$grub_name/grub.cfg" ; then
+ grub2_config_generated="no"
+ # TODO: We should make this fatal. Outdated/incomplete/just wrong grub2.cfg may result into an unbootable system.
LogPrintError "Failed to generate boot/$grub_name/grub.cfg in $TARGET_FS_ROOT - trying to install GRUB2 nevertheless"
fi
+# Detect platform, e.g. PowerNV, in advance.
+# An alternative approach, also based on parsing /proc/cpuinfo, can be found in the pseries_platform helper from powerpc-utils.
+grub2_ppc_platform="$(awk '/platform/ {print $NF}' < /proc/cpuinfo)"
+
# Do not update nvram when system is running in PowerNV mode (BareMetal).
# grub2-install will fail if not run with the --no-nvram option on a PowerNV system,
# see https://github.com/rear/rear/pull/1742
grub2_no_nvram_option=""
-if [[ $(awk '/platform/ {print $NF}' < /proc/cpuinfo) == PowerNV ]] ; then
+if [[ "$grub2_ppc_platform" == PowerNV ]] ; then
grub2_no_nvram_option="--no-nvram"
fi
# Also do not update nvram when no character device node /dev/nvram exists.
@@ -173,6 +180,20 @@ LogPrint "Determining where to install GRUB2 (no GRUB2_INSTALL_DEVICES specified
# Find PPC PReP Boot partitions:
part_list=$( awk -F ' ' '/^part / {if ($6 ~ /prep/) {print $7}}' $LAYOUT_FILE )
if ! test "$part_list" ; then
+ # The PReP Boot partitions are not required on PowerNV systems.
+ if [[ "$grub2_ppc_platform" == "PowerNV" ]] ; then
+ if is_false "$grub2_config_generated" ; then
+ LogPrintError "Booting using Petitboot may not work (failed to generate GRUB configuration file anew)"
+ return 1
+ fi
+
+ LogPrint "PPC PReP boot partition not found - GRUB2 installation is not necessary on PowerNV systems"
+ # As long as the GRUB 2 configuration was generated successfully, the
+ # system will be bootable using Petitboot.
+ NOBOOTLOADER=''
+ return 0
+ fi
+
LogPrintError "Cannot install GRUB2 (unable to find a PPC PReP boot partition)"
return 1
fi

View File

@ -0,0 +1,29 @@
From 825478ee27f916553938afaf5164fec22cb32732 Mon Sep 17 00:00:00 2001
From: Johannes Meixner <jsmeix@suse.com>
Date: Tue, 10 May 2022 10:43:39 +0200
Subject: [PATCH] Update 200_partition_layout.sh
In layout/save/GNU/Linux/200_partition_layout.sh
ensure $disk_label is one of the supported partition tables, cf.
https://github.com/rear/rear/issues/2801#issuecomment-1122015129
---
usr/share/rear/layout/save/GNU/Linux/200_partition_layout.sh | 5 +++++
1 file changed, 5 insertions(+)
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 b747d121c6..6e641d280e 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
@@ -115,6 +115,11 @@ extract_partitions() {
parted -s $device print > $TMP_DIR/parted
disk_label=$(grep -E "Partition Table|Disk label" $TMP_DIR/parted | cut -d ":" -f "2" | tr -d " ")
fi
+ # Ensure $disk_label is valid to determine the partition name/type in the next step at 'declare type'
+ # cf. https://github.com/rear/rear/issues/2801#issuecomment-1122015129
+ if ! [[ "$disk_label" = "msdos" || "$disk_label" = "gpt" || "$disk_label" = "gpt_sync_mbr" || "$disk_label" = "dasd" ]] ; then
+ Error "Unsupported partition table '$disk_label' (must be one of 'msdos' 'gpt' 'gpt_sync_mbr' 'dasd')"
+ fi
cp $TMP_DIR/partitions $TMP_DIR/partitions-data

View File

@ -0,0 +1,88 @@
From 8497de2d8a029460b0e47119b0664f0d254c97ac Mon Sep 17 00:00:00 2001
From: Pavel Cahyna <pcahyna@redhat.com>
Date: Thu, 14 Aug 2025 16:11:08 +0200
Subject: [PATCH] Copy a sshd helper to the rescue ramdisk
Without it, sshd in the rescue ramdisk does not start on EL 10
and aborts with
"/usr/libexec/openssh/sshd-session does not exist or is not executable"
The idea is very similar to the sftp-server part of the script, but the
implementation is deliberately different:
- Instead of grepping a fixed known configuration file, the output of
sshd -T is used. sshd -T prints the effective configuration on stdout.
This way one does not need to know the path to the sshd configuration
file, while avoiding possible issues like the one described in
https://github.com/rear/rear/pull/1538#issuecomment-337883867
and one also gets automatic support for more complicated setups
with configuration snippets like on Debian,
see its sshd_config(5) manual page:
"Note that the Debian openssh-server package sets several options as stan-
dard in /etc/ssh/sshd_config which are not the default in sshd(8):
- Include /etc/ssh/sshd_config.d/*.conf
..."
At the same time, the command takes care of removing comments and
assigning default values (one would not get them by grepping the
configuration file).
- awk is used instead of grep, allowing to match the precise value of a
configuration option and not just the prefix, and to not rely on the
shell to parse the output into fields.
- The path to the helper gets added to COPY_AS_IS instead of to PROGS.
The problem with PROGS is that it ignores the path (even if the program
gets specified by its absolute path) and copies the program to
/usr/bin - but sshd need the helper at exactly the same path as on the
original system, as it invokes the helper via its full path (not
$PATH). This behavior of PROGS is arguably something that should be
changed and PROGS should use an absolute path as target if provided. For
now, use COPY_AS_IS as a workaround.
(The sftp-server part would of course benefit from the same changes, as
the arguments above apply to it equally. In particular, the last point
looks fatal, as the sftp-server gets also copied to /usr/bin instead
to its correct path, but sshd refers to it by its full path. Indeed,
sftp to the rescue system does not work, even if ssh does:
$ sftp root@...
Warning: Permanently added ... to the list of known hosts.
Connection closed.
Connection closed
Similar code has been here since the beginning of the git history
(2009), so I wonder whether the sftp part has ever worked... )
(cherry picked from commit 8497de2d8a029460b0e47119b0664f0d254c97ac)
---
usr/share/rear/rescue/default/500_ssh.sh | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/usr/share/rear/rescue/default/500_ssh.sh b/usr/share/rear/rescue/default/500_ssh.sh
index 27e48742a8..60d9fbd5a4 100644
--- a/usr/share/rear/rescue/default/500_ssh.sh
+++ b/usr/share/rear/rescue/default/500_ssh.sh
@@ -44,6 +44,26 @@ contains_visible_char "${copy_as_is_ssh_files[*]}" && COPY_AS_IS+=( "${copy_as_i
# Copy the usual SSH programs into the recovery system:
PROGS+=( ssh sshd scp sftp ssh-agent ssh-keygen )
+# Copy a helper needed at least on EL 10.
+# Without it, sshd aborts with
+# "/usr/libexec/openssh/sshd-session does not exist or is not executable".
+# sshd -T prints the effective configuration on stdout. This way one
+# does not need to know the path to the sshd configuration file, while
+# avoiding possible issues like the one described in
+# https://github.com/rear/rear/pull/1538#issuecomment-337883867
+# and one also gets automatic support for more complicated setups
+# with configuration snippets like on Debian,
+# see its sshd_config(5) manual page:
+# "Note that the Debian openssh-server package sets several options as stan-
+# dard in /etc/ssh/sshd_config which are not the default in sshd(8):
+# - Include /etc/ssh/sshd_config.d/*.conf
+# ..."
+# At the same time, the command takes care of removing comments and assigning
+# default values (one would not get them by grepping the configuration file).
+# The path to the helper is the value of the sshdsessionpath option.
+local sshdsessionpath="$( sshd -T | awk '$1=="sshdsessionpath" { print $2 }' )"
+test "$sshdsessionpath" && COPY_AS_IS+=( "$sshdsessionpath" )
+
# Copy a sftp-server program (e.g. /usr/lib/ssh/sftp-server) into the recovery system (if exists).
# Because only OpenSSH >= 3.1 is supported where /etc/ssh/ is the default directory for configuration files
# only /etc/ssh/sshd_config is inspected to grep for a sftp-server program therein

View File

@ -3,8 +3,8 @@ index d2cb6c070..ea66f0a98 100755
--- a/usr/sbin/rear
+++ b/usr/sbin/rear
@@ -376,6 +376,10 @@ fi
# and fd6 to get input from the user regardless where to STDIN is redirected:
source $SHARE_DIR/lib/_input-output-functions.sh
exit 1
fi
+# Used to determine whether TMPDIR has been changed in user config.
+# Save the current value to detect changes.
@ -15,7 +15,7 @@ index d2cb6c070..ea66f0a98 100755
@@ -446,6 +450,14 @@ for config in site local rescue ; do
test "$( tr -d -c '\r' < $CONFIG_DIR/$config.conf )" && Error "Carriage return character in $CONFIG_DIR/$config.conf (perhaps DOS or Mac format)"
Source "$CONFIG_DIR/$config.conf" || true
Source "$CONFIG_DIR/$config.conf" || Error "Failed to Source $CONFIG_DIR/$config.conf"
fi
+ if [ "$config" == local ] ; then
+ # changing TMPDIR in rescue.conf is expected for now, see

View File

@ -3,7 +3,7 @@
Name: rear
Version: 2.6
Release: 27%{?dist}
Release: 28%{?dist}
Summary: Relax-and-Recover is a Linux disaster recovery and system migration tool
URL: http://relax-and-recover.org/
License: GPLv3
@ -115,6 +115,40 @@ Patch126: rear-print-disk-mapping-with-sizes-RHEL-83241.patch
# https://github.com/rear/rear/commit/9b28f14fad26ff00a6f90b13c3e4906d85f3ae3c
Patch127: rear-support-aarch64-uefi-RHEL-56045.patch
# copy an sshd helper to the rescue ramdisk, necessary on EL9.8
# https://github.com/rear/rear/commit/bcf6669fac64d194d18b2e5360df4181002856e8
Patch128: rear-sshd-RHEL-146037.patch
# fix support for PowerNV machines without PPC PReP partitions
# https://github.com/rear/rear/commit/79a3b50a0effcf4c1a43e9dfe1b8d0427ee0bf02
Patch129: rear-fix-powerNV-support-RHEL-134217.patch
# EL10-only
# Patch130:
# Patch131:
# add support for dbus broker
# https://github.com/rear/rear/commit/61d294b9635b3c71bd58409e810bccb705b1220c
Patch132: rear-dbus-broker-RHEL-31749.patch
# abort when sourcing fails due to a syntax error
# https://github.com/rear/rear/commit/c4a7729242455cdef69f5ac3982f8d76ccc183c3
Patch133: rear-abort-source-on-syntax-error-RHEL-104289.patch
# fix recreation of multi-disk volume groups in migration mode
# https://github.com/rear/rear/commit/acb19846599a5fc411fd8c288776e1af2d79c920
Patch134: rear-fix-VG-recreation-RHEL-23887.patch
# skip unsupported partition tables, e.g. sun
# https://github.com/rear/rear/commit/825478ee27f916553938afaf5164fec22cb32732
Patch135: rear-skip-unsupported-partition-tables-RHEL-78583.patch
# do not attempt to use the disk with backup for recovery
# https://github.com/rear/rear/commit/258e34a72374d512155054e2d6efa84f8f5cd974
# https://github.com/rear/rear/commit/7e5aea79e0fe1badf7c0820e854f8ca3ac32cef0
# https://github.com/rear/rear/commit/a5edba7551884e9201a21fc1ea33de7ca7e6cb07
Patch136: rear-do-not-use-backup-disk-for-recovery-RHEL-111612.patch
######################
# downstream patches #
######################
@ -166,6 +200,7 @@ Requires: s390utils-core
# default installed bootloader yaboot is also useed to make the bootable ISO image.
BuildRequires: efi-srpm-macros
BuildRequires: git-core
# Required for HTML user guide
BuildRequires: make
BuildRequires: asciidoctor
@ -214,7 +249,7 @@ Professional services and support are available.
#-- PREP, BUILD & INSTALL -----------------------------------------------------#
%prep
%autosetup -p1
%autosetup -p1 -S git
### Add a specific os.conf so we do not depend on LSB dependencies
%{?fedora:echo -e "OS_VENDOR=Fedora\nOS_VERSION=%{?fedora}" >etc/rear/os.conf}
@ -259,6 +294,16 @@ install -m 0644 %{SOURCE3} %{buildroot}%{_docdir}/%{name}/
#-- CHANGELOG -----------------------------------------------------------------#
%changelog
* Thu Jan 29 2026 Lukáš Zaoral <lzaoral@redhat.com> - 2.6-28
- use git to apply downstream patches
- copy an sshd helper to the rescue ramdisk (RHEL-146037)
- fix support for PowerNV machines without PPC PReP partitions (RHEL-134217)
- add support for dbus broker (RHEL-31749)
- abort when sourcing fails due to a syntax error (RHEL-104289)
- fix recreation of multi-disk volume groups in migration mode (RHEL-23887)
- skip unsupported partition tables (RHEL-78583)
- do not attempt to use the disk with backup for recovery (RHEL-111612)
* Thu Aug 14 2025 Pavel Cahyna <pcahyna@redhat.com> - 2.6-27
- add dependency on grub2-tools-extra and GRUB EFI modules on EFI machines
- add dependency on syslinux-extlinux on x86