diff --git a/0007-tests-lvresize-fs-crypt-using-helper-only-for-crypt-.patch b/0007-tests-lvresize-fs-crypt-using-helper-only-for-crypt-.patch new file mode 100644 index 0000000..2a97a50 --- /dev/null +++ b/0007-tests-lvresize-fs-crypt-using-helper-only-for-crypt-.patch @@ -0,0 +1,49 @@ +From 380e3855fbc661eed490665cf1e3d05e985da189 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 3 Jan 2023 14:35:26 -0600 +Subject: [PATCH 1/4] tests: lvresize-fs-crypt using helper only for crypt dev + +(cherry picked from commit 2580f007f0aaa3bf22c43295caa2c60c6142494f) +--- + test/shell/lvresize-fs-crypt.sh | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/test/shell/lvresize-fs-crypt.sh b/test/shell/lvresize-fs-crypt.sh +index e7b8b9426..61a6de022 100644 +--- a/test/shell/lvresize-fs-crypt.sh ++++ b/test/shell/lvresize-fs-crypt.sh +@@ -135,6 +135,31 @@ cryptsetup close $cr + lvchange -an $vg/$lv + lvremove $vg/$lv + ++# lvresize uses helper only for crypt dev resize ++# because the fs was resized separately beforehand ++lvcreate -n $lv -L 456M $vg ++echo 93R4P4pIqAH8 | cryptsetup luksFormat -i1 --type luks1 "$DM_DEV_DIR/$vg/$lv" ++echo 93R4P4pIqAH8 | cryptsetup luksOpen "$DM_DEV_DIR/$vg/$lv" $cr ++mkfs.ext4 /dev/mapper/$cr ++mount /dev/mapper/$cr "$mount_dir" ++dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=100 conv=fdatasync ++df --output=size "$mount_dir" |tee df1 ++# resize only the fs (to 256M), not the crypt dev or LV ++umount "$mount_dir" ++resize2fs /dev/mapper/$cr 262144k ++mount /dev/mapper/$cr "$mount_dir" ++# this lvresize will not resize the fs (which is already reduced ++# to smaller than the requested LV size), but lvresize will use ++# the helper to resize the crypt dev before resizing the LV. ++lvresize -L-100M $vg/$lv ++check lv_field $vg/$lv lv_size "356.00m" ++df --output=size "$mount_dir" |tee df2 ++not diff df1 df2 ++umount "$mount_dir" ++cryptsetup close $cr ++lvchange -an $vg/$lv ++lvremove $vg/$lv ++ + # test with LUKS2? + + vgremove -ff $vg +-- +2.39.1 + diff --git a/0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch b/0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch new file mode 100644 index 0000000..36f9669 --- /dev/null +++ b/0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch @@ -0,0 +1,114 @@ +From 7e0c2e1581225a916269edc8f04fb10e4ef5e952 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 19 Jan 2023 11:36:51 -0600 +Subject: [PATCH 2/4] lvresize: only resize crypt when fs resize is enabled + +There were a couple of cases where lvresize, without --fs resize, +was resizing the crypt layer above the LV. Resizing the crypt +layer should only be done when fs resizing is enabled (even if the +fs is already small enough due to being independently reduced.) + +Also, check the size of the crypt device to see if it's already +been reduced independently, and skip the cryptsetup resize if +it's not needed. + +(cherry picked from commit 3bb55765286dc8e4f0000957d85a6b8ee2752852) +--- + lib/device/filesystem.c | 12 ++++++++++++ + lib/device/filesystem.h | 1 + + lib/metadata/lv_manip.c | 18 +++++++++++++++++- + test/shell/lvresize-fs-crypt.sh | 7 ++++++- + 4 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c +index bdc230175..b4c43a626 100644 +--- a/lib/device/filesystem.c ++++ b/lib/device/filesystem.c +@@ -106,6 +106,7 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv, + struct fs_info info; + FILE *fme = NULL; + struct mntent *me; ++ int fd; + int ret; + + if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", lv->vg->cmd->dev_dir, +@@ -151,6 +152,17 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv, + log_print("File system found on crypt device %s on LV %s.", + crypt_path, display_lvname(lv)); + ++ if ((fd = open(crypt_path, O_RDONLY)) < 0) { ++ log_error("Failed to open crypt path %s", crypt_path); ++ return 0; ++ } ++ if (ioctl(fd, BLKGETSIZE64, &info.crypt_dev_size_bytes) < 0) { ++ log_error("Failed to get crypt device size %s", crypt_path); ++ close(fd); ++ return 0; ++ } ++ close(fd); ++ + if (!fs_get_blkid(crypt_path, &info)) { + log_error("No file system info from blkid for dm-crypt device %s on LV %s.", + crypt_path, display_lvname(lv)); +diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h +index 7a34d2ae0..fd1af0416 100644 +--- a/lib/device/filesystem.h ++++ b/lib/device/filesystem.h +@@ -25,6 +25,7 @@ struct fs_info { + uint64_t fs_last_byte; /* last byte on the device used by the fs */ + uint32_t crypt_offset_bytes; /* offset in bytes of crypt data on LV */ + dev_t crypt_devt; /* dm-crypt device between the LV and FS */ ++ uint64_t crypt_dev_size_bytes; + + unsigned nofs:1; + unsigned unmounted:1; +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index f8eae0447..a2e9db2c9 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -6397,7 +6397,23 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv, + * but the crypt dev over the LV should be shrunk to correspond with + * the LV size, so that the FS does not see an incorrect device size. + */ +- if (!fsinfo.needs_reduce && fsinfo.needs_crypt && !test_mode()) { ++ if (!fsinfo.needs_reduce && fsinfo.needs_crypt) { ++ /* Check if the crypt device is already sufficiently reduced. */ ++ if (fsinfo.crypt_dev_size_bytes <= newsize_bytes_fs) { ++ log_print("crypt device is already reduced to %llu bytes.", ++ (unsigned long long)fsinfo.crypt_dev_size_bytes); ++ ret = 1; ++ goto out; ++ } ++ if (!strcmp(lp->fsopt, "checksize")) { ++ log_error("crypt reduce is required (see --resizefs or cryptsetup resize.)"); ++ ret = 0; ++ goto out; ++ } ++ if (test_mode()) { ++ ret = 1; ++ goto_out; ++ } + ret = crypt_resize_script(cmd, lv, &fsinfo, newsize_bytes_fs); + goto out; + } +diff --git a/test/shell/lvresize-fs-crypt.sh b/test/shell/lvresize-fs-crypt.sh +index 61a6de022..4bef771dc 100644 +--- a/test/shell/lvresize-fs-crypt.sh ++++ b/test/shell/lvresize-fs-crypt.sh +@@ -151,7 +151,12 @@ mount /dev/mapper/$cr "$mount_dir" + # this lvresize will not resize the fs (which is already reduced + # to smaller than the requested LV size), but lvresize will use + # the helper to resize the crypt dev before resizing the LV. +-lvresize -L-100M $vg/$lv ++# Using --fs resize is required to allow lvresize to look above ++# the lv at crypt&fs layers for potential resizing. Without ++# --fs resize, lvresize fails because it sees that crypt resize ++# is needed and --fs resize is needed to enable that. ++not lvresize -L-100 $vg/$lv ++lvresize -L-100M --fs resize $vg/$lv + check lv_field $vg/$lv lv_size "356.00m" + df --output=size "$mount_dir" |tee df2 + not diff df1 df2 +-- +2.39.1 + diff --git a/0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch b/0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch new file mode 100644 index 0000000..3a87788 --- /dev/null +++ b/0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch @@ -0,0 +1,188 @@ +From fba3614c3ed596b99d8adf2fe6c60886db10b2c0 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 26 Jan 2023 14:00:00 -0600 +Subject: [PATCH 3/4] lvresize: fail early if mounted LV was renamed + +If a mounted LV is renamed, then fs resizing utilities will fail, +so detect this condition and fail the command before any changes +are made. + +(cherry picked from commit 5374a44c57127cdd832a675545c1d2bbf0b3751a) +--- + lib/device/filesystem.c | 110 ++++++++++++++++++++++++++++++++++++++ + lib/device/filesystem.h | 2 + + lib/metadata/lv_manip.c | 3 ++ + test/shell/lvresize-fs.sh | 11 ++++ + 4 files changed, 126 insertions(+) + +diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c +index b4c43a626..db507bdda 100644 +--- a/lib/device/filesystem.c ++++ b/lib/device/filesystem.c +@@ -214,6 +214,116 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv, + return ret; + } + ++int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *lv, char *lv_path, char *fstype) ++{ ++ FILE *fp; ++ char proc_line[PATH_MAX]; ++ char proc_fstype[FSTYPE_MAX]; ++ char proc_devpath[1024]; ++ char proc_mntpath[1024]; ++ char lv_mapper_path[1024]; ++ char mntent_mount_dir[1024]; ++ char *dm_name; ++ struct stat st_lv; ++ struct stat stme; ++ FILE *fme = NULL; ++ struct mntent *me; ++ int renamed = 0; ++ int found_dir = 0; ++ int found_dev = 0; ++ int dev_match, dir_match; ++ ++ if (stat(lv_path, &st_lv) < 0) { ++ log_error("Failed to get LV path %s", lv_path); ++ return 0; ++ } ++ ++ /* ++ * If LVs have been renamed while their file systems were mounted, then ++ * inconsistencies appear in the device path and mount point info ++ * provided by getmntent and /proc/mounts. If there's any ++ * inconsistency or duplication of info for the LV name or the mount ++ * point, then give up and don't try fs resize which is likely to fail ++ * due to kernel problems where mounts reference old device names ++ * causing fs resizing tools to fail. ++ */ ++ ++ if (!(fme = setmntent("/etc/mtab", "r"))) ++ return_0; ++ ++ while ((me = getmntent(fme))) { ++ if (strcmp(me->mnt_type, fstype)) ++ continue; ++ if (me->mnt_dir[0] != '/') ++ continue; ++ if (me->mnt_fsname[0] != '/') ++ continue; ++ if (stat(me->mnt_dir, &stme) < 0) ++ continue; ++ if (stme.st_dev != st_lv.st_rdev) ++ continue; ++ strncpy(mntent_mount_dir, me->mnt_dir, PATH_MAX-1); ++ } ++ endmntent(fme); ++ ++ if (!(dm_name = dm_build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL))) ++ return_0; ++ ++ if ((dm_snprintf(lv_mapper_path, 1024, "%s/%s", dm_dir(), dm_name) < 0)) ++ return_0; ++ ++ if (!(fp = fopen("/proc/mounts", "r"))) ++ return_0; ++ ++ while (fgets(proc_line, sizeof(proc_line), fp)) { ++ if (proc_line[0] != '/') ++ continue; ++ if (sscanf(proc_line, "%s %s %s", proc_devpath, proc_mntpath, proc_fstype) != 3) ++ continue; ++ if (strcmp(fstype, proc_fstype)) ++ continue; ++ ++ dir_match = !strcmp(mntent_mount_dir, proc_mntpath); ++ dev_match = !strcmp(lv_mapper_path, proc_devpath); ++ ++ if (dir_match) ++ found_dir++; ++ if (dev_match) ++ found_dev++; ++ ++ if (dir_match != dev_match) { ++ log_error("LV %s mounted at %s may have been renamed (from %s).", ++ lv_mapper_path, proc_mntpath, proc_devpath); ++ renamed = 1; ++ } ++ } ++ ++ if (fclose(fp)) ++ stack; ++ ++ /* ++ * Don't try resizing if: ++ * - different device names apppear for the mount point ++ * (LVs probably renamed while mounted), or ++ * - the mount point for the LV appears multiple times, or ++ * - the LV device is listed for multiple mounts. ++ */ ++ if (renamed) { ++ log_error("File system resizing not supported: fs utilities do not support renamed devices."); ++ return 1; ++ } ++ /* These two are likely detected as renamed, but include checks in case. */ ++ if (found_dir > 1) { ++ log_error("File system resizing not supported: %s appears more than once in /proc/mounts.", mntent_mount_dir); ++ return 1; ++ } ++ if (found_dev > 1) { ++ log_error("File system resizing not supported: %s appears more than once in /proc/mounts.", lv_mapper_path); ++ return 1; ++ } ++ return 0; ++} ++ + #define FS_CMD_MAX_ARGS 16 + + int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi, +diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h +index fd1af0416..77eac34d0 100644 +--- a/lib/device/filesystem.h ++++ b/lib/device/filesystem.h +@@ -48,4 +48,6 @@ int fs_reduce_script(struct cmd_context *cmd, struct logical_volume *lv, struct + uint64_t newsize_bytes, char *fsmode); + int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi, + uint64_t newsize_bytes_fs); ++ ++int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *lv, char *lv_path, char *fstype); + #endif +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index a2e9db2c9..25e16d41d 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -6928,6 +6928,9 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv, + log_error("File system not found for --resizefs or --fs options."); + goto out; + } ++ /* FS utils will fail if LVs were renamed while mounted. */ ++ if (fs_mount_state_is_misnamed(cmd, lv_top, lv_path, fstype)) ++ goto_out; + } + + /* +diff --git a/test/shell/lvresize-fs.sh b/test/shell/lvresize-fs.sh +index 0be6911a0..f437652d6 100644 +--- a/test/shell/lvresize-fs.sh ++++ b/test/shell/lvresize-fs.sh +@@ -262,6 +262,17 @@ umount "$mount_dir" + lvchange -an $vg/$lv + lvremove $vg/$lv + ++# lvextend|lvreduce, ext4, active, mounted, --fs resize, renamed LV ++lvcreate -n $lv -L 256M $vg ++mkfs.ext4 "$DM_DEV_DIR/$vg/$lv" ++mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir" ++lvrename $vg/$lv $vg/$lv2 ++not lvextend --fs resize -L+32M $vg/$lv2 ++not lvreduce --fs resize -L-32M $vg/$lv2 ++umount "$mount_dir" ++lvchange -an $vg/$lv2 ++lvremove $vg/$lv2 ++ + + # + # lvextend, xfs +-- +2.39.1 + diff --git a/0010-udev-import-previous-results-of-blkid-when-in-suspen.patch b/0010-udev-import-previous-results-of-blkid-when-in-suspen.patch new file mode 100644 index 0000000..78c3f72 --- /dev/null +++ b/0010-udev-import-previous-results-of-blkid-when-in-suspen.patch @@ -0,0 +1,69 @@ +From 285c766877b54b24234f84c313bb5806c0dcfa21 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 2 Feb 2023 00:28:12 +0900 +Subject: [PATCH 4/4] udev: import previous results of blkid when in suspended + state + +Follow-up for e10f67e91728f1e576803df884049ecbd92874d0. + +The commit e10f67e91728f1e576803df884049ecbd92874d0 tries to keep device +node symlinks even if the device is in the suspended state. However, +necessary properties that may previously obtained by the blkid command +were not imported at least in the .rules file. So, unless ID_FS_xyz +properties are imported by another earlier .rules file, the device node +symlinks are still lost when event is processed in the suspended state. + +Let's explicitly import the necessary properties. + +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=2158628 +GHPR: https://github.com/lvmteam/lvm2/pull/105 +(cherry picked from commit 94f77a4d8d9737fca05fb4e451678ec440c68670) +--- + WHATS_NEW_DM | 4 ++++ + udev/13-dm-disk.rules.in | 14 ++++++++++++-- + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index f676ff7e1..c129c7f8a 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,3 +1,7 @@ ++Version 1.02.191 - ++===================================== ++ Import previous ID_FS_* udev records in 13-dm-disk.rules for suspended DM dev. ++ + Version 1.02.187 - 10th November 2022 + ===================================== + Add DM_REPORT_GROUP_JSON_STD for more JSON standard compliant output format. +diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in +index 5cc08121e..dca00bc01 100644 +--- a/udev/13-dm-disk.rules.in ++++ b/udev/13-dm-disk.rules.in +@@ -17,12 +17,22 @@ ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="dm_end" + SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}" + ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}" + +-ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_link" +-ENV{DM_NOSCAN}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_link" ++ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import" ++ENV{DM_NOSCAN}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import" + ENV{DM_SUSPENDED}=="1", GOTO="dm_end" + ENV{DM_NOSCAN}=="1", GOTO="dm_watch" + + (BLKID_RULE) ++GOTO="dm_link" ++ ++LABEL="dm_import" ++IMPORT{db}="ID_FS_USAGE" ++IMPORT{db}="ID_FS_UUID_ENC" ++IMPORT{db}="ID_FS_LABEL_ENC" ++IMPORT{db}="ID_PART_ENTRY_NAME" ++IMPORT{db}="ID_PART_ENTRY_UUID" ++IMPORT{db}="ID_PART_ENTRY_SCHEME" ++IMPORT{db}="ID_PART_GPT_AUTO_ROOT" + + LABEL="dm_link" + ENV{DM_UDEV_LOW_PRIORITY_FLAG}=="1", OPTIONS="link_priority=-100" +-- +2.39.1 + diff --git a/lvm2.spec b/lvm2.spec index 68a28d7..c47409d 100644 --- a/lvm2.spec +++ b/lvm2.spec @@ -63,7 +63,7 @@ Version: 2.03.17 #Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix} Release: 4%{?dist}%{?rel_suffix} %else -Release: 5%{?dist}%{?rel_suffix} +Release: 6%{?dist}%{?rel_suffix} %endif License: GPLv2 URL: http://sourceware.org/lvm2 @@ -83,6 +83,13 @@ Patch4: 0004-vgimportclone-fix-importing-PV-without-metadata.patch # BZ 2164044: Patch5: 0005-lvmdbusd-Move-get_error_msg-to-utils.patch Patch6: 0006-lvmdbusd-Add-command_log_selection-to-command-line.patch +# BZ 2162144: +Patch7: 0007-tests-lvresize-fs-crypt-using-helper-only-for-crypt-.patch +Patch8: 0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch +# BZ 2164226: +Patch9: 0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch +# BZ 2158628: +Patch10: 0010-udev-import-previous-results-of-blkid-when-in-suspen.patch BuildRequires: make BuildRequires: gcc @@ -149,6 +156,10 @@ or more physical volumes and creating one or more logical volumes %patch4 -p1 -b .backup4 %patch5 -p1 -b .backup5 %patch6 -p1 -b .backup6 +%patch7 -p1 -b .backup7 +%patch8 -p1 -b .backup8 +%patch9 -p1 -b .backup9 +%patch10 -p1 -b .backup10 %build %global _default_pid_dir /run @@ -720,6 +731,11 @@ An extensive functional testsuite for LVM2. %endif %changelog +* Thu Feb 09 2023 Marian Csontos - 2.03.17-6 +- Fix lvresize resizing LUKS device only when resizing FS is enabled. +- Improve lvresize handling of renamed volumes. +- Fix random unmount when resizing volume backed by thin pool. + * Fri Jan 27 2023 Marian Csontos - 2.03.17-5 - Fix vgimportclone fail if PV has no metadata. - Fix lvmdbusd missing stderr for commands not returning JSON.