From 5a99d6a77e85479ae0e3e09ba633b8194424640c Mon Sep 17 00:00:00 2001 From: Pavel Cahyna Date: Fri, 1 Dec 2023 21:37:29 +0100 Subject: [PATCH] Backport upstream PR #3058 Skip useless xfs mount options when mounting during recovery Resolves: RHEL-10478 --- ...useless-xfs-mount-options-RHEL-10478.patch | 85 +++++++++++++++++++ rear.spec | 1 + 2 files changed, 86 insertions(+) create mode 100644 rear-skip-useless-xfs-mount-options-RHEL-10478.patch diff --git a/rear-skip-useless-xfs-mount-options-RHEL-10478.patch b/rear-skip-useless-xfs-mount-options-RHEL-10478.patch new file mode 100644 index 0000000..2863131 --- /dev/null +++ b/rear-skip-useless-xfs-mount-options-RHEL-10478.patch @@ -0,0 +1,85 @@ +diff --git a/usr/share/rear/layout/prepare/GNU/Linux/133_include_mount_filesystem_code.sh b/usr/share/rear/layout/prepare/GNU/Linux/133_include_mount_filesystem_code.sh +index d57077791..87ab5d691 100644 +--- a/usr/share/rear/layout/prepare/GNU/Linux/133_include_mount_filesystem_code.sh ++++ b/usr/share/rear/layout/prepare/GNU/Linux/133_include_mount_filesystem_code.sh +@@ -29,6 +29,7 @@ mount_fs() { + case $name in + (options) + # Do not mount nodev, as chrooting later on would fail: ++ # FIXME: naive approach, will replace any "nodev" inside longer options/values + value=${value//nodev/dev} + # btrfs mount options like subvolid=259 or subvol=/@/.snapshots/1/snapshot + # from the old system cannot work here for recovery because btrfs subvolumes +@@ -147,6 +148,27 @@ mount_fs() { + echo "mount $mountopts,remount,user_xattr $device $TARGET_FS_ROOT$mountpoint" + ) >> "$LAYOUT_CODE" + ;; ++ (xfs) ++ # remove logbsize=... mount option. It is a purely performance/memory usage optimization option, ++ # which can lead to mount failures, because it must be an integer multiple of the log stripe unit ++ # and the log stripe unit can be different in the recreated filesystem from the original filesystem ++ # (for example when using MKFS_XFS_OPTIONS, or in some exotic situations involving an old filesystem, ++ # see GitHub issue #2777 ). ++ # If logbsize is not an integer multiple of the log stripe unit, mount fails with the warning ++ # "XFS (...): logbuf size must be greater than or equal to log stripe size" ++ # in the kernel log ++ # (and a confusing error message ++ # "mount: ...: wrong fs type, bad option, bad superblock on ..., missing codepage or helper program, or other error." ++ # from the mount command), causing the layout restoration in the recovery process to fail. ++ # Wrong sunit/swidth can cause mount to fail as well, with this in the kernel log: ++ # "kernel: XFS (...): alignment check failed: sunit/swidth vs. agsize", ++ # so remove the sunit=.../swidth=... mount options as well. ++ mountopts="$( remove_mount_options_values "$mountopts" logbsize sunit swidth )" ++ ( ++ echo "mkdir -p $TARGET_FS_ROOT$mountpoint" ++ echo "mount $mountopts $device $TARGET_FS_ROOT$mountpoint" ++ ) >> "$LAYOUT_CODE" ++ ;; + (*) + ( + echo "mkdir -p $TARGET_FS_ROOT$mountpoint" +diff --git a/usr/share/rear/lib/filesystems-functions.sh b/usr/share/rear/lib/filesystems-functions.sh +index afdd3f24c..658d757f4 100644 +--- a/usr/share/rear/lib/filesystems-functions.sh ++++ b/usr/share/rear/lib/filesystems-functions.sh +@@ -239,3 +239,40 @@ function xfs_parse + # Output xfs options for further use + echo "$xfs_opts" + } ++ ++ ++# $1 is a mount command argument (string containing comma-separated ++# mount options). The remaining arguments to the function ($2 ... ) ++# specify the mount options to remove from $1, together with a trailing "=" ++# and any value that follows each option. ++# For example, the call ++# "remove_mount_options_values nodev,uid=1,rw,gid=1 uid gid" ++# returns "nodev,rw". ++# There is no support for removing a mount option without a value and "=", ++# so "remove_mount_options_values nodev,uid=1,rw,gid=1 rw" will not work. ++# The function will return the modified string on stdout. ++ ++function remove_mount_options_values () { ++ local str="$1" ++ ++ shift ++ # First add a comma at the end so that it is easier to remove a mount option at the end: ++ str="${str/%/,}" ++ for i in "$@" ; do ++ # FIXME this also removes trailing strings at the end of longer words ++ # For example if one wants to remove any id=... option, ++ # the function will also replace "uid=1" by "u" by removing ++ # the trailing "id=1", which is not intended. ++ # Not easy to fix because $str can contain prefixes which are not ++ # mount options but arguments to the mount command itself ++ # (in particluar, "-o "). ++ # FIXME this simple approach would fail in case of mount options ++ # containing commas, for example the "context" option values, ++ # see mount(8) ++ ++ # the extglob shell option is enabled in rear ++ str="${str//$i=*([^,]),/}" ++ done ++ # Remove all commas at the end: ++ echo "${str/%,/}" ++} diff --git a/rear.spec b/rear.spec index b2dbf48..8ae5c83 100644 --- a/rear.spec +++ b/rear.spec @@ -52,6 +52,7 @@ Patch61: rear-uefi-usb-secureboot-bz2196445.patch Patch62: rear-vg-command-not-found-bz2121476.patch Patch63: rear-remove-lvmdevices-bz2145014.patch Patch64: rear-save-lvm-poolmetadatasize-RHEL-6984.patch +Patch65: rear-skip-useless-xfs-mount-options-RHEL-10478.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.