Additional patches for 9.2.0 lvm2

Resolves: #2162144 #2164226 #2158628
This commit is contained in:
Marian Csontos 2023-02-09 17:20:18 +01:00
parent d2b663602b
commit 5e0fa0f972
5 changed files with 437 additions and 1 deletions

View File

@ -0,0 +1,49 @@
From 380e3855fbc661eed490665cf1e3d05e985da189 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
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

View File

@ -0,0 +1,114 @@
From 7e0c2e1581225a916269edc8f04fb10e4ef5e952 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
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

View File

@ -0,0 +1,188 @@
From fba3614c3ed596b99d8adf2fe6c60886db10b2c0 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
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

View File

@ -0,0 +1,69 @@
From 285c766877b54b24234f84c313bb5806c0dcfa21 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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

View File

@ -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 <mcsontos@redhat.com> - 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 <mcsontos@redhat.com> - 2.03.17-5
- Fix vgimportclone fail if PV has no metadata.
- Fix lvmdbusd missing stderr for commands not returning JSON.