From: Marian Csontos <mcsontos@sourceware.org>
To: lvm-devel@redhat.com
Subject: rhel-9.2.0 - lvresize: fail early if mounted LV was renamed
Date: Thu, 9 Feb 2023 20:40:49 +0000 (GMT) [thread overview]
Message-ID: <20230209204049.0158E3858C5F@sourceware.org> (raw)
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fba3614c3ed596b99d8adf2fe6c60886db10b2c0
Commit: fba3614c3ed596b99d8adf2fe6c60886db10b2c0
Parent: 7e0c2e1581225a916269edc8f04fb10e4ef5e952
Author: David Teigland <teigland@redhat.com>
AuthorDate: Thu Jan 26 14:00:00 2023 -0600
Committer: Marian Csontos <mcsontos@redhat.com>
CommitterDate: Thu Feb 9 16:29:38 2023 +0100
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@%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
reply other threads:[~2023-02-09 20:40 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230209204049.0158E3858C5F@sourceware.org \
--to=mcsontos@sourceware.org \
--cc=lvm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.