import lvm2-2.03.17-7.el9

i9c-beta changed/i9c-beta/lvm2-2.03.17-7.el9
MSVSphere Packaging Team 2 years ago
commit 1bd9c0e6ff

1
.gitignore vendored

@ -0,0 +1 @@
SOURCES/LVM2.2.03.17.tgz

@ -0,0 +1 @@
8a0043a552c17be61234989c02ef501eda971fd1 SOURCES/LVM2.2.03.17.tgz

@ -0,0 +1,133 @@
From b01433cdc841133500a0ed4041b9b35838d45e87 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 2 Dec 2022 11:59:09 -0600
Subject: [PATCH] device_id: fix segfault verifying serial for non-pv
The recent change that verifies sys_serial system.devices entries
using the PVID did not exclude non-PV devices from being checked.
The verification code would attempt to use du->pvid which was null
for the non-PVs causing a segfault.
(cherry picked from commit 6613a61d3b5ce4d12a6fef79195eac34f30ef4da)
---
lib/device/device_id.c | 6 ++-
test/shell/devicesfile-serial.sh | 79 ++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+), 2 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index aae875776..96726a448 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -2237,8 +2237,8 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
* number is correct, since serial numbers may not be unique.
* Search for the PVID on other devs in device_ids_check_serial.
*/
- if ((du->idtype == DEV_ID_TYPE_SYS_SERIAL) &&
- (!du->pvid || memcmp(dev->pvid, du->pvid, ID_LEN))) {
+ if ((du->idtype == DEV_ID_TYPE_SYS_SERIAL) && du->pvid &&
+ memcmp(dev->pvid, du->pvid, ID_LEN)) {
log_debug("suspect device id serial %s for %s", du->idname, dev_name(dev));
str_list_add(cmd->mem, &cmd->device_ids_check_serial, dm_pool_strdup(cmd->mem, du->idname));
*device_ids_invalid = 1;
@@ -2570,6 +2570,8 @@ void device_ids_check_serial(struct cmd_context *cmd, struct dm_list *scan_devs,
dm_list_iterate_items(dul, &dus_check) {
if (!dul->du->dev)
continue;
+ if (!dul->du->pvid)
+ continue;
/* save previously matched devs so they can be dropped from
lvmcache at the end if they are no longer used */
if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil))))
diff --git a/test/shell/devicesfile-serial.sh b/test/shell/devicesfile-serial.sh
index b7bfce29e..a88c1906a 100644
--- a/test/shell/devicesfile-serial.sh
+++ b/test/shell/devicesfile-serial.sh
@@ -772,6 +772,85 @@ grep $SERIAL1 out2
grep $dev3 out3
grep $SERIAL3 out3
+# non-PV devices
+
+aux wipefs_a $dev1
+aux wipefs_a $dev2
+aux wipefs_a $dev3
+aux wipefs_a $dev4
+
+echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
+echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
+echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
+echo $SERIAL4 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
+
+rm $DF
+touch $DF
+vgcreate $vg4 $dev4
+lvmdevices --adddev "$dev1"
+lvmdevices --adddev "$dev2"
+lvmdevices --adddev "$dev3"
+cat $DF
+
+grep $dev1 $DF |tee out1
+grep $dev2 $DF |tee out2
+grep $dev3 $DF |tee out3
+grep $dev4 $DF |tee out4
+
+grep $SERIAL1 out1
+grep $SERIAL2 out2
+grep $SERIAL2 out3
+grep $SERIAL4 out4
+
+pvs |tee out
+grep $dev4 out
+not grep $dev1 out
+not grep $dev2 out
+not grep $dev3 out
+
+pvcreate $dev1
+pvs |tee out
+grep $dev1 out
+grep $dev4 out
+not grep $dev2 out
+not grep $dev3 out
+
+pvcreate $dev2
+pvs |tee out
+grep $dev1 out
+grep $dev4 out
+grep $dev2 out
+not grep $dev3 out
+
+pvcreate $dev3
+pvs |tee out
+grep $dev1 out
+grep $dev4 out
+grep $dev2 out
+grep $dev3 out
+
+PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
+PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
+PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
+PVID4=`pvs "$dev4" --noheading -o uuid | tr -d - | awk '{print $1}'`
+OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
+OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
+OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
+OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
+
+grep $dev1 $DF |tee out1
+grep $dev2 $DF |tee out2
+grep $dev3 $DF |tee out3
+grep $dev4 $DF |tee out4
+
+grep $PVID1 out1
+grep $PVID2 out2
+grep $PVID3 out3
+grep $PVID4 out4
+
+vgcreate $vg2 $dev2 $dev3
+vgs | grep $vg2
+
remove_base
rmmod brd
--
2.38.1

@ -0,0 +1,36 @@
From 20c6961e37bf6f5010f9d2035dbc1ce03f9b0223 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 15 Dec 2022 09:57:04 -0600
Subject: [PATCH] lvextend: fix overprovisioning check for thin lvs
18722dfdf4d3 lvresize: restructure code
mistakenly changed the overprovisioning check from applying
to all lv_is_thin_type lvs to only lv_is_thin_pool lvs, so
it no longer applied when extending thin lvs. The result
was missing warning messages when extending thin lvs.
(cherry picked from commit 4baef0f93f608403b6f2db445e7bf1e80f8f3ee6)
---
lib/metadata/lv_manip.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 4cdbc19a0..f8eae0447 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7007,9 +7007,10 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_thin_pool(lv_top)) {
if (!update_thin_pool_lv(lv_top, 1))
goto_out;
- if (is_extend)
- thin_pool_check_overprovisioning(lv_top);
}
+ if (lv_is_thin_type(lv_top) && is_extend)
+ thin_pool_check_overprovisioning(lv_top);
+
if (lv_main && lv_is_cow_covering_origin(lv_main)) {
if (!monitor_dev_for_events(cmd, lv_main, 0, 0))
stack;
--
2.38.1

@ -0,0 +1,32 @@
From db067b9054d87ada6aa133394e65e3af9d75fc08 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 3 Jan 2023 11:38:33 -0600
Subject: [PATCH] lvresize: fix cryptsetup resize in helper
typo used "cryptresize" as command name
this affects cases where the file system is resized
independently, and then the lvresize command is used
which only needs to resize the crypt device and the LV.
(cherry picked from commit 81acde7ffdf9fbe522ada16f89e429d9f729dc0c)
---
scripts/lvresize_fs_helper.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/lvresize_fs_helper.sh b/scripts/lvresize_fs_helper.sh
index 031b8453b..f531dd447 100755
--- a/scripts/lvresize_fs_helper.sh
+++ b/scripts/lvresize_fs_helper.sh
@@ -224,7 +224,7 @@ fsreduce() {
cryptresize() {
NEWSIZESECTORS=$(($NEWSIZEBYTES/512))
logmsg "cryptsetup resize ${NEWSIZESECTORS} sectors ${DEVPATH}"
- cryptresize resize --size "$NEWSIZESECTORS" "$DEVPATH"
+ cryptsetup resize --size "$NEWSIZESECTORS" "$DEVPATH"
if [ $? -eq 0 ]; then
logmsg "cryptsetup done"
else
--
2.39.0

@ -0,0 +1,48 @@
From 8f7b4456ad93c3907a82fd03d0feceb9785e3bfc Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 5 Jan 2023 14:28:31 -0600
Subject: [PATCH 1/3] vgimportclone: fix importing PV without metadata
If one of the PVs in the VG does not hold metadata, then the
command would fail, thinking that PV was from a different VG.
Also add missing free on that error path.
(cherry picked from commit c4b898a53eec39bc28b5451e7fde87945303a644)
---
tools/vgimportclone.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index 60ef20762..93fa3b18d 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -203,7 +203,7 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
struct device *dev;
struct device_list *devl;
struct dm_list other_devs;
- struct volume_group *vg, *error_vg;
+ struct volume_group *vg, *error_vg = NULL;
const char *vgname;
char base_vgname[NAME_LEN] = { 0 };
char tmp_vgname[NAME_LEN] = { 0 };
@@ -322,7 +322,7 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
goto out;
}
- if (!(vgname = lvmcache_vgname_from_info(info))) {
+ if (!(vgname = lvmcache_vgname_from_info(info)) || is_orphan_vg(vgname)) {
/* The PV may not have metadata, this will be resolved in
the process_each_vg/vg_read at the end. */
continue;
@@ -503,6 +503,8 @@ retry_name:
}
ret = ECMD_PROCESSED;
out:
+ if (error_vg)
+ release_vg(error_vg);
unlock_devices_file(cmd);
return ret;
}
--
2.39.1

@ -0,0 +1,89 @@
From 4e34edd6e4e52328dd77b6a55aeadd9b0454c743 Mon Sep 17 00:00:00 2001
From: Tony Asleson <tasleson@redhat.com>
Date: Tue, 29 Nov 2022 10:00:39 -0600
Subject: [PATCH 2/3] lvmdbusd: Move get_error_msg to utils
Moving this so we can re-use outside of lvm_shell_proxy.
(cherry picked from commit 8f60c494515ddccb20e4afb804edb6b9599e65c0)
---
daemons/lvmdbusd/lvm_shell_proxy.py.in | 23 +++--------------------
daemons/lvmdbusd/utils.py | 17 +++++++++++++++++
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
index ac6d51e65..37d73218b 100755
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
@@ -28,7 +28,7 @@ except ImportError:
import lvmdbusd.cfg as cfg
from lvmdbusd.utils import log_debug, log_error, add_no_notify, make_non_block,\
- read_decoded, extract_stack_trace, LvmBug
+ read_decoded, extract_stack_trace, LvmBug, get_error_msg
SHELL_PROMPT = "lvm> "
@@ -191,24 +191,7 @@ class LVMShellProxy(object):
def get_last_log(self):
self._write_cmd('lastlog\n')
report_json = self._read_response()[1]
- return LVMShellProxy.get_error_msg(report_json)
-
- @staticmethod
- def get_error_msg(report_json):
- # Get the error message from the returned JSON
- if 'log' in report_json:
- error_msg = ""
- # Walk the entire log array and build an error string
- for log_entry in report_json['log']:
- if log_entry['log_type'] == "error":
- if error_msg:
- error_msg += ', ' + log_entry['log_message']
- else:
- error_msg = log_entry['log_message']
-
- return error_msg
-
- return None
+ return get_error_msg(report_json)
def call_lvm(self, argv, debug=False):
rc = 1
@@ -245,7 +228,7 @@ class LVMShellProxy(object):
# report json too.
error_msg = self.get_last_log()
if error_msg is None:
- error_msg = LVMShellProxy.get_error_msg(report_json)
+ error_msg = get_error_msg(report_json)
if error_msg is None:
error_msg = 'No error reason provided! (missing "log" section)'
diff --git a/daemons/lvmdbusd/utils.py b/daemons/lvmdbusd/utils.py
index 5aecb1fff..0b81591b2 100644
--- a/daemons/lvmdbusd/utils.py
+++ b/daemons/lvmdbusd/utils.py
@@ -859,3 +859,20 @@ class LvmDebugData:
self._close_fd()
# In case lvm_complete doesn't get called.
self._remove_file()
+
+
+def get_error_msg(report_json):
+ # Get the error message from the returned JSON
+ if 'log' in report_json:
+ error_msg = ""
+ # Walk the entire log array and build an error string
+ for log_entry in report_json['log']:
+ if log_entry['log_type'] == "error":
+ if error_msg:
+ error_msg += ', ' + log_entry['log_message']
+ else:
+ error_msg = log_entry['log_message']
+
+ return error_msg
+
+ return None
--
2.39.1

@ -0,0 +1,79 @@
From 0441d340e752427d0d355a85e5e5e465e911a102 Mon Sep 17 00:00:00 2001
From: Tony Asleson <tasleson@redhat.com>
Date: Tue, 29 Nov 2022 10:04:17 -0600
Subject: [PATCH 3/3] lvmdbusd: Add command_log_selection to command line
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2145114
(cherry picked from commit e63b0c7262f50ab43fcde1c50b6d880acab68407)
---
daemons/lvmdbusd/cmdhandler.py | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 0c7bd8528..9a76db4c9 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -17,7 +17,7 @@ import os
from lvmdbusd import cfg
from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error, add_no_notify,\
- make_non_block, read_decoded, extract_stack_trace, LvmBug, add_config_option
+ make_non_block, read_decoded, extract_stack_trace, LvmBug, add_config_option, get_error_msg
from lvmdbusd.lvm_shell_proxy import LVMShellProxy
try:
@@ -121,6 +121,9 @@ def call_lvm(command, debug=False, line_cb=None,
command.insert(0, cfg.LVM_CMD)
command = add_no_notify(command)
+ # Ensure we get an error message when we fork & exec the lvm command line
+ command = add_config_option(command, "--config", 'log/command_log_selection="log_context!=''"')
+
process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=True,
env=os.environ)
@@ -167,7 +170,17 @@ def call_lvm(command, debug=False, line_cb=None,
if debug or (process.returncode != 0 and (process.returncode != 5 and "fullreport" in command)):
_debug_c(command, process.returncode, (stdout_text, stderr_text))
- return process.returncode, stdout_text, stderr_text
+ try:
+ report_json = json.loads(stdout_text)
+ except json.decoder.JSONDecodeError:
+ # Some lvm commands don't return json even though we are asking for it to do so.
+ return process.returncode, stdout_text, stderr_text
+
+ error_msg = get_error_msg(report_json)
+ if error_msg:
+ stderr_text += error_msg
+
+ return process.returncode, report_json, stderr_text
else:
if cfg.run.value == 0:
raise SystemExit
@@ -619,20 +632,8 @@ def lvm_full_report_json():
rc, out, err = call(cmd)
# When we have an exported vg the exit code of lvs or fullreport will be 5
if rc == 0 or rc == 5:
- # If the 'call' implementation is lvmshell, the out is a dictionary as lvmshell has to
- # parse the output to get the exit value. When doing fork & exec, out is a string
- # representing the JSON. TODO: Make this consistent between implementations.
- if cfg.SHELL_IN_USE:
- assert(type(out) == dict)
- return out
- else:
- try:
- return json.loads(out)
- except json.decoder.JSONDecodeError as joe:
- log_error("JSONDecodeError %s, \n JSON=\n%s\n" %
- (str(joe), out))
- raise LvmBug("'fullreport' returned invalid JSON")
-
+ assert(type(out) == dict)
+ return out
raise LvmBug("'fullreport' exited with code '%d'" % rc)
--
2.39.1

@ -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

@ -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

@ -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

@ -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

@ -0,0 +1,49 @@
From cbcf65c6518652242aab6960eeb983c6bc771bd3 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Sun, 12 Feb 2023 19:23:12 +0100
Subject: [PATCH] filesystem: use PATH_MAX for linux paths
(cherry picked from commit cf0dc9a13cf365859e7dad3bb1ad02040925ae11)
---
lib/device/filesystem.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
index db507bdda..0c902ec14 100644
--- a/lib/device/filesystem.c
+++ b/lib/device/filesystem.c
@@ -219,10 +219,10 @@ int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *l
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 proc_devpath[PATH_MAX];
+ char proc_mntpath[PATH_MAX];
+ char lv_mapper_path[PATH_MAX];
+ char mntent_mount_dir[PATH_MAX];
char *dm_name;
struct stat st_lv;
struct stat stme;
@@ -262,14 +262,14 @@ int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *l
continue;
if (stme.st_dev != st_lv.st_rdev)
continue;
- strncpy(mntent_mount_dir, me->mnt_dir, PATH_MAX-1);
+ dm_strncpy(mntent_mount_dir, me->mnt_dir, sizeof(mntent_mount_dir));
}
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))
+ if ((dm_snprintf(lv_mapper_path, sizeof(lv_mapper_path), "%s/%s", dm_dir(), dm_name) < 0))
return_0;
if (!(fp = fopen("/proc/mounts", "r")))
--
2.39.1

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save