From 21958a66ff332c13df9fb63f35ef638bb19f83cf Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 9 May 2023 05:39:35 +0000 Subject: [PATCH] import lvm2-2.03.17-7.el9 --- .gitignore | 2 +- .lvm2.metadata | 2 +- ...segfault-verifying-serial-for-non-pv.patch | 133 ++++ ...e-move-clean-up-after-command-is-run.patch | 49 -- ...l-if-devicesfile-filename-doesn-t-ex.patch | 55 -- ...-overprovisioning-check-for-thin-lvs.patch | 36 + ...handle-other-wwid-types-in-blacklist.patch | 54 -- ...size-fix-cryptsetup-resize-in-helper.patch | 32 + ...-mpath-get-wwids-from-sysfs-vpd_pg83.patch | 743 ------------------ ...ne-fix-importing-PV-without-metadata.patch | 48 ++ ...lvmdbusd-Move-get_error_msg-to-utils.patch | 89 +++ ...vdisplay-restore-reportformat-option.patch | 36 - ...-when-devicesfile-name-doesn-t-exist.patch | 247 ------ ...ommand_log_selection-to-command-line.patch | 79 ++ SOURCES/0007-make-generate.patch | 43 - ...s-crypt-using-helper-only-for-crypt-.patch | 49 ++ ...component_detection-0-to-duplicate-P.patch | 55 -- ...size-crypt-when-fs-resize-is-enabled.patch | 114 +++ ...-conditional-for-lvm-child-process-r.patch | 30 - ...fail-early-if-mounted-LV-was-renamed.patch | 188 +++++ ...-lvmdbusd-Simplify-child-process-env.patch | 30 - ...ious-results-of-blkid-when-in-suspen.patch | 69 ++ ...esystem-use-PATH_MAX-for-linux-paths.patch | 49 ++ ...0011-lvmdbusd-re-work-lvm-shell-main.patch | 73 -- ...ug-output-for-which-lvm-binary-is-us.patch | 26 - ...sd-Change-unit-test-vdo-minimum-size.patch | 73 -- ...Fix-env-variable-LVM_DBUSD_TEST_MODE.patch | 54 -- ...e-the-use-of-sub-shell-for-lvm-shell.patch | 62 -- ...b-prop.-Get-GetAll-exec.-immediately.patch | 42 - ...d-Don-t-require-lvm-prompt-for-shell.patch | 174 ---- SPECS/lvm2.spec | 94 ++- 31 files changed, 946 insertions(+), 1884 deletions(-) create mode 100644 SOURCES/0001-device_id-fix-segfault-verifying-serial-for-non-pv.patch delete mode 100644 SOURCES/0001-devices-file-move-clean-up-after-command-is-run.patch delete mode 100644 SOURCES/0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch create mode 100644 SOURCES/0002-lvextend-fix-overprovisioning-check-for-thin-lvs.patch delete mode 100644 SOURCES/0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch create mode 100644 SOURCES/0003-lvresize-fix-cryptsetup-resize-in-helper.patch delete mode 100644 SOURCES/0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch create mode 100644 SOURCES/0004-vgimportclone-fix-importing-PV-without-metadata.patch create mode 100644 SOURCES/0005-lvmdbusd-Move-get_error_msg-to-utils.patch delete mode 100644 SOURCES/0005-pvdisplay-restore-reportformat-option.patch delete mode 100644 SOURCES/0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch create mode 100644 SOURCES/0006-lvmdbusd-Add-command_log_selection-to-command-line.patch delete mode 100644 SOURCES/0007-make-generate.patch create mode 100644 SOURCES/0007-tests-lvresize-fs-crypt-using-helper-only-for-crypt-.patch delete mode 100644 SOURCES/0008-apply-multipath_component_detection-0-to-duplicate-P.patch create mode 100644 SOURCES/0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch delete mode 100644 SOURCES/0009-lvmdbusd-Correct-conditional-for-lvm-child-process-r.patch create mode 100644 SOURCES/0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch delete mode 100644 SOURCES/0010-lvmdbusd-Simplify-child-process-env.patch create mode 100644 SOURCES/0010-udev-import-previous-results-of-blkid-when-in-suspen.patch create mode 100644 SOURCES/0011-filesystem-use-PATH_MAX-for-linux-paths.patch delete mode 100644 SOURCES/0011-lvmdbusd-re-work-lvm-shell-main.patch delete mode 100644 SOURCES/0012-lvmdbusd-Add-debug-output-for-which-lvm-binary-is-us.patch delete mode 100644 SOURCES/0013-lvmdbusd-Change-unit-test-vdo-minimum-size.patch delete mode 100644 SOURCES/0014-lvmdbusd-Fix-env-variable-LVM_DBUSD_TEST_MODE.patch delete mode 100644 SOURCES/0015-lvmdbusd-Remove-the-use-of-sub-shell-for-lvm-shell.patch delete mode 100644 SOURCES/0016-lvmdbusd-Job-prop.-Get-GetAll-exec.-immediately.patch delete mode 100644 SOURCES/0017-lvmdbusd-Don-t-require-lvm-prompt-for-shell.patch diff --git a/.gitignore b/.gitignore index 8fdb939..35fd4e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/LVM2.2.03.16.tgz +SOURCES/LVM2.2.03.17.tgz diff --git a/.lvm2.metadata b/.lvm2.metadata index 4d2ea90..eda57a2 100644 --- a/.lvm2.metadata +++ b/.lvm2.metadata @@ -1 +1 @@ -a99cfcbcb2cf665824acde03775dccc9ef54a836 SOURCES/LVM2.2.03.16.tgz +8a0043a552c17be61234989c02ef501eda971fd1 SOURCES/LVM2.2.03.17.tgz diff --git a/SOURCES/0001-device_id-fix-segfault-verifying-serial-for-non-pv.patch b/SOURCES/0001-device_id-fix-segfault-verifying-serial-for-non-pv.patch new file mode 100644 index 0000000..5832580 --- /dev/null +++ b/SOURCES/0001-device_id-fix-segfault-verifying-serial-for-non-pv.patch @@ -0,0 +1,133 @@ +From b01433cdc841133500a0ed4041b9b35838d45e87 Mon Sep 17 00:00:00 2001 +From: David Teigland +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 + diff --git a/SOURCES/0001-devices-file-move-clean-up-after-command-is-run.patch b/SOURCES/0001-devices-file-move-clean-up-after-command-is-run.patch deleted file mode 100644 index 5e4a248..0000000 --- a/SOURCES/0001-devices-file-move-clean-up-after-command-is-run.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 28a4df481fa47d0b71996a25ac08546c4bd094f8 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Fri, 27 May 2022 12:38:43 -0500 -Subject: [PATCH 1/7] devices file: move clean up after command is run - -devices_file_exit wasn't being called between lvm_shell -commands, so the file lock wouldn't be released. - -(cherry picked from commit 9dfa6f38793f6b5f7de2a4148ab2f7790e3c39da) ---- - lib/commands/toolcontext.c | 2 -- - tools/lvmcmdline.c | 1 + - 2 files changed, 1 insertion(+), 2 deletions(-) - -diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c -index 4cb81bf94..2666d7b42 100644 ---- a/lib/commands/toolcontext.c -+++ b/lib/commands/toolcontext.c -@@ -1905,7 +1905,6 @@ int refresh_toolcontext(struct cmd_context *cmd) - _destroy_segtypes(&cmd->segtypes); - _destroy_formats(cmd, &cmd->formats); - -- devices_file_exit(cmd); - if (!dev_cache_exit()) - stack; - _destroy_dev_types(cmd); -@@ -2034,7 +2033,6 @@ void destroy_toolcontext(struct cmd_context *cmd) - _destroy_segtypes(&cmd->segtypes); - _destroy_formats(cmd, &cmd->formats); - _destroy_filters(cmd); -- devices_file_exit(cmd); - dev_cache_exit(); - _destroy_dev_types(cmd); - _destroy_tags(cmd); -diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c -index 1e3547ed7..b052d698f 100644 ---- a/tools/lvmcmdline.c -+++ b/tools/lvmcmdline.c -@@ -3305,6 +3305,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv) - hints_exit(cmd); - lvmcache_destroy(cmd, 1, 1); - label_scan_destroy(cmd); -+ devices_file_exit(cmd); - - if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING))) - dm_config_destroy(config_string_cft); --- -2.34.3 - diff --git a/SOURCES/0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch b/SOURCES/0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch deleted file mode 100644 index ed57cf2..0000000 --- a/SOURCES/0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 9a79248fe21554e6cb99dd6ed044e7cbff18f777 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Fri, 27 May 2022 14:27:03 -0500 -Subject: [PATCH 2/7] devices file: fail if --devicesfile filename doesn't - exist - -A typo of the filename after --devicesfile should result in a -command error rather than the command falling back to using no -devices file at all. Exception is vgcreate|pvcreate which -create a new devices file if the file name doesn't exist. - -(cherry picked from commit bfe072e4388b530cbf5369be8a8f1305220198bf) ---- - lib/device/dev-cache.c | 9 +++++++++ - test/shell/devicesfile-basic.sh | 4 ++++ - 2 files changed, 13 insertions(+) - -diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c -index 3aaf6a2e5..ed9c726c9 100644 ---- a/lib/device/dev-cache.c -+++ b/lib/device/dev-cache.c -@@ -1863,6 +1863,15 @@ int setup_devices(struct cmd_context *cmd) - - file_exists = devices_file_exists(cmd); - -+ /* -+ * Fail if user specifies a file name that doesn't exist and -+ * the command is not creating a new devices file. -+ */ -+ if (!file_exists && !cmd->create_edit_devices_file && cmd->devicesfile && strlen(cmd->devicesfile)) { -+ log_error("Devices file not found: %s", cmd->devices_file_path); -+ return 0; -+ } -+ - /* - * Removing the devices file is another way of disabling the use of - * a devices file, unless the command creates the devices file. -diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh -index 9c3455c76..77fe265a0 100644 ---- a/test/shell/devicesfile-basic.sh -+++ b/test/shell/devicesfile-basic.sh -@@ -104,6 +104,10 @@ not ls "$DFDIR/system.devices" - vgs --devicesfile test.devices $vg1 - not vgs --devicesfile test.devices $vg2 - -+# misspelled override name fails -+not vgs --devicesfile doesnotexist $vg1 -+not vgs --devicesfile doesnotexist $vg2 -+ - # devicesfile and devices cannot be used together - not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1 - --- -2.34.3 - diff --git a/SOURCES/0002-lvextend-fix-overprovisioning-check-for-thin-lvs.patch b/SOURCES/0002-lvextend-fix-overprovisioning-check-for-thin-lvs.patch new file mode 100644 index 0000000..1e42978 --- /dev/null +++ b/SOURCES/0002-lvextend-fix-overprovisioning-check-for-thin-lvs.patch @@ -0,0 +1,36 @@ +From 20c6961e37bf6f5010f9d2035dbc1ce03f9b0223 Mon Sep 17 00:00:00 2001 +From: David Teigland +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 + diff --git a/SOURCES/0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch b/SOURCES/0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch deleted file mode 100644 index 7d3ca86..0000000 --- a/SOURCES/0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 1e78ed5a0d9a8296b42578cfc250a3a281a32878 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Mon, 6 Jun 2022 11:39:02 -0500 -Subject: [PATCH 3/7] filter-mpath: handle other wwid types in blacklist - -Fixes commit 494372b4eed0c8f6040e3357939eb7511ac25745 - "filter-mpath: use multipath blacklist" -to handle wwids with initial type digits 1 and 2 used -for t10 and eui ids. Originally recognized type 3 naa. - -(cherry picked from commit c302903dbab1d5fd05b344c654bed83c9ecb69f8) ---- - lib/device/dev-mpath.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c -index 270366ad7..846f6c8ba 100644 ---- a/lib/device/dev-mpath.c -+++ b/lib/device/dev-mpath.c -@@ -54,7 +54,7 @@ static void _read_blacklist_file(const char *path) - int section_black = 0; - int section_exceptions = 0; - int found_quote; -- int found_three; -+ int found_type; - int i, j; - - if (!(fp = fopen(path, "r"))) -@@ -114,7 +114,7 @@ static void _read_blacklist_file(const char *path) - - memset(wwid, 0, sizeof(wwid)); - found_quote = 0; -- found_three = 0; -+ found_type = 0; - j = 0; - - for (; i < MAX_WWID_LINE; i++) { -@@ -132,9 +132,10 @@ static void _read_blacklist_file(const char *path) - /* second quote is end of wwid */ - if ((line[i] == '"') && found_quote) - break; -- /* ignore first "3" in wwid */ -- if ((line[i] == '3') && !found_three) { -- found_three = 1; -+ /* exclude initial 3/2/1 for naa/eui/t10 */ -+ if (!j && !found_type && -+ ((line[i] == '3') || (line[i] == '2') || (line[i] == '1'))) { -+ found_type = 1; - continue; - } - --- -2.34.3 - diff --git a/SOURCES/0003-lvresize-fix-cryptsetup-resize-in-helper.patch b/SOURCES/0003-lvresize-fix-cryptsetup-resize-in-helper.patch new file mode 100644 index 0000000..ec63d69 --- /dev/null +++ b/SOURCES/0003-lvresize-fix-cryptsetup-resize-in-helper.patch @@ -0,0 +1,32 @@ +From db067b9054d87ada6aa133394e65e3af9d75fc08 Mon Sep 17 00:00:00 2001 +From: David Teigland +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 + diff --git a/SOURCES/0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch b/SOURCES/0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch deleted file mode 100644 index d2a09bc..0000000 --- a/SOURCES/0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch +++ /dev/null @@ -1,743 +0,0 @@ -From 2966df2bcbbf553d86d0a608852dcc140df28fc0 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Mon, 6 Jun 2022 14:04:20 -0500 -Subject: [PATCH 4/7] filter-mpath: get wwids from sysfs vpd_pg83 - -to compare with wwids in /etc/multipath/wwids when -excluding multipath components. The wwid printed -from the sysfs wwid file may not be the wwid used -in multipath wwids. Save the wwids found for each -device on dev->wwids to avoid repeating reading -and parsing the sysfs files. - -(cherry picked from commit 3b0f9cec7e999c33f17714358d2b469bda6967d2) ---- - lib/Makefile.in | 1 + - lib/device/dev-cache.c | 18 ++++ - lib/device/dev-cache.h | 1 + - lib/device/dev-mpath.c | 232 ++++++++++++++++++++++++++++++++++------- - lib/device/device.h | 13 +++ - lib/device/device_id.c | 31 +++++- - lib/device/device_id.h | 2 + - lib/device/parse_vpd.c | 199 +++++++++++++++++++++++++++++++++++ - 8 files changed, 454 insertions(+), 43 deletions(-) - create mode 100644 lib/device/parse_vpd.c - -diff --git a/lib/Makefile.in b/lib/Makefile.in -index 22b96134b..3ab5cb2f1 100644 ---- a/lib/Makefile.in -+++ b/lib/Makefile.in -@@ -41,6 +41,7 @@ SOURCES =\ - device/dev-dasd.c \ - device/dev-lvm1-pool.c \ - device/online.c \ -+ device/parse_vpd.c \ - display/display.c \ - error/errseg.c \ - unknown/unknown.c \ -diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c -index ed9c726c9..193eb7585 100644 ---- a/lib/device/dev-cache.c -+++ b/lib/device/dev-cache.c -@@ -80,6 +80,7 @@ static void _dev_init(struct device *dev) - - dm_list_init(&dev->aliases); - dm_list_init(&dev->ids); -+ dm_list_init(&dev->wwids); - } - - void dev_destroy_file(struct device *dev) -@@ -383,6 +384,22 @@ out: - return 1; - } - -+int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen) -+{ -+ int ret; -+ int fd; -+ -+ fd = open(path, O_RDONLY); -+ if (fd < 0) -+ return 0; -+ ret = read(fd, buf, buf_size); -+ close(fd); -+ if (ret <= 0) -+ return 0; -+ *retlen = ret; -+ return 1; -+} -+ - int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value) - { - FILE *fp; -@@ -1336,6 +1353,7 @@ int dev_cache_exit(void) - dm_hash_iterate(n, _cache.names) { - dev = (struct device *) dm_hash_get_data(_cache.names, n); - free_dids(&dev->ids); -+ free_wwids(&dev->wwids); - } - } - -diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h -index 46b1da72c..7ffe01152 100644 ---- a/lib/device/dev-cache.h -+++ b/lib/device/dev-cache.h -@@ -74,6 +74,7 @@ void dev_cache_failed_path(struct device *dev, const char *path); - bool dev_cache_has_md_with_end_superblock(struct dev_types *dt); - - int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value); -+int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen); - int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor); - - int setup_devices_file(struct cmd_context *cmd); -diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c -index 846f6c8ba..27b0f41a6 100644 ---- a/lib/device/dev-mpath.c -+++ b/lib/device/dev-mpath.c -@@ -200,11 +200,12 @@ static void _read_wwid_exclusions(void) - log_debug("multipath config ignored %d wwids", rem_count); - } - --static void _read_wwid_file(const char *config_wwids_file) -+static void _read_wwid_file(const char *config_wwids_file, int *entries) - { - FILE *fp; - char line[MAX_WWID_LINE]; - char *wwid, *p; -+ char typestr[2] = { 0 }; - int count = 0; - - if (config_wwids_file[0] != '/') { -@@ -226,8 +227,17 @@ static void _read_wwid_file(const char *config_wwids_file) - if (line[0] == '/') - wwid++; - -- /* skip the initial '3' */ -- wwid++; -+ -+ /* -+ * the initial character is the id type, -+ * 1 is t10, 2 is eui, 3 is naa, 8 is scsi name. -+ * wwids are stored in the hash table without the type charater. -+ * It seems that sometimes multipath does not include -+ * the type charater (seen with t10 scsi_debug devs). -+ */ -+ typestr[0] = *wwid; -+ if (typestr[0] == '1' || typestr[0] == '2' || typestr[0] == '3') -+ wwid++; - - if ((p = strchr(wwid, '/'))) - *p = '\0'; -@@ -240,6 +250,7 @@ static void _read_wwid_file(const char *config_wwids_file) - stack; - - log_debug("multipath wwids read %d from %s", count, config_wwids_file); -+ *entries = count; - } - - int dev_mpath_init(const char *config_wwids_file) -@@ -247,6 +258,7 @@ int dev_mpath_init(const char *config_wwids_file) - struct dm_pool *mem; - struct dm_hash_table *minor_tab; - struct dm_hash_table *wwid_tab; -+ int entries = 0; - - dm_list_init(&_ignored); - dm_list_init(&_ignored_exceptions); -@@ -283,10 +295,16 @@ int dev_mpath_init(const char *config_wwids_file) - _wwid_hash_tab = wwid_tab; - - if (config_wwids_file) { -- _read_wwid_file(config_wwids_file); -+ _read_wwid_file(config_wwids_file, &entries); - _read_wwid_exclusions(); - } - -+ if (!entries) { -+ /* reading dev wwids is skipped with null wwid_hash_tab */ -+ dm_hash_destroy(_wwid_hash_tab); -+ _wwid_hash_tab = NULL; -+ } -+ - return 1; - } - -@@ -434,10 +452,10 @@ static int _dev_is_mpath_component_udev(struct device *dev) - - /* mpath_devno is major:minor of the dm multipath device currently using the component dev. */ - --static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev, dev_t *mpath_devno) -+static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev, -+ int primary_result, dev_t primary_dev, dev_t *mpath_devno) - { - struct dev_types *dt = cmd->dev_types; -- const char *part_name; - const char *name; /* e.g. "sda" for "/dev/sda" */ - char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */ - char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */ -@@ -451,25 +469,15 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device - int dm_dev_major; - int dm_dev_minor; - struct stat info; -- dev_t primary_dev; - int is_mpath_component = 0; - -- /* multipathing is only known to exist for SCSI or NVME devices */ -- if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev)) -- return 0; -- -- switch (dev_get_primary_dev(dt, dev, &primary_dev)) { -+ switch (primary_result) { - - case 2: /* The dev is partition. */ -- part_name = dev_name(dev); /* name of original dev for log_debug msg */ - - /* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */ - if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path)))) - return_0; -- -- log_debug_devs("%s: Device is a partition, using primary " -- "device %s for mpath component detection", -- part_name, name); - break; - - case 1: /* The dev is already a primary dev. Just continue with the dev. */ -@@ -593,47 +601,189 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device - return is_mpath_component; - } - --static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev) -+static int _read_sys_wwid(struct cmd_context *cmd, struct device *dev, -+ char *idbuf, int idbufsize) - { -- char sysbuf[PATH_MAX] = { 0 }; -- char *wwid; -- long look; -+ char idtmp[DEV_WWID_SIZE]; - -- if (!_wwid_hash_tab) -+ if (!read_sys_block(cmd, dev, "device/wwid", idbuf, idbufsize)) { -+ /* the wwid file is not under device for nvme devs */ -+ if (!read_sys_block(cmd, dev, "wwid", idbuf, idbufsize)) -+ return 0; -+ } -+ if (!idbuf[0]) - return 0; - -- if (!read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf))) -+ /* in t10 id, replace series of spaces with one _ like multipath */ -+ if (!strncmp(idbuf, "t10.", 4) && strchr(idbuf, ' ')) { -+ if (idbufsize < DEV_WWID_SIZE) -+ return 0; -+ memcpy(idtmp, idbuf, DEV_WWID_SIZE); -+ memset(idbuf, 0, idbufsize); -+ format_t10_id((const unsigned char *)idtmp, DEV_WWID_SIZE, (unsigned char *)idbuf, idbufsize); -+ } -+ return 1; -+} -+ -+#define VPD_SIZE 4096 -+ -+static int _read_sys_vpd_wwids(struct cmd_context *cmd, struct device *dev, -+ struct dm_list *ids) -+{ -+ unsigned char vpd_data[VPD_SIZE] = { 0 }; -+ int vpd_datalen = 0; -+ -+ if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen)) -+ return 0; -+ if (!vpd_datalen) - return 0; - -- if (!sysbuf[0]) -+ /* adds dev_wwid entry to dev->wwids for each id in vpd data */ -+ parse_vpd_ids(vpd_data, vpd_datalen, ids); -+ return 1; -+} -+ -+void free_wwids(struct dm_list *ids) -+{ -+ struct dev_wwid *dw, *safe; -+ -+ dm_list_iterate_items_safe(dw, safe, ids) { -+ dm_list_del(&dw->list); -+ free(dw); -+ } -+} -+ -+static int _wwid_type_num(char *id) -+{ -+ if (!strncmp(id, "naa.", 4)) -+ return 3; -+ else if (!strncmp(id, "eui.", 4)) -+ return 2; -+ else if (!strncmp(id, "t10.", 4)) -+ return 1; -+ else -+ return -1; -+} -+ -+/* -+ * TODO: if each of the different wwid types (naa/eui/t10) were -+ * represented by different DEV_ID_TYPE_FOO values, and used -+ * as device_id types, then we could drop struct dev_wwid and -+ * drop dev->wwids, and just use dev->ids for each of the -+ * different wwids found in vpd_pg83. This would also require -+ * the ability to handle both the original method of replacing -+ * every space in the id string with _ and the new/multipath -+ * format_t10_id replacing series of spaces with one _. -+ */ -+struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids) -+{ -+ struct dev_wwid *dw; -+ int len; -+ -+ if (!id_type) { -+ id_type = _wwid_type_num(id); -+ if (id_type == -1) -+ log_debug("unknown wwid type %s", id); -+ } -+ -+ if (!(dw = zalloc(sizeof(struct dev_wwid)))) -+ return NULL; -+ len = strlen(id); -+ if (len >= DEV_WWID_SIZE) -+ len = DEV_WWID_SIZE - 1; -+ memcpy(dw->id, id, len); -+ dw->type = id_type; -+ dm_list_add(ids, &dw->list); -+ return dw; -+} -+ -+/* -+ * we save ids with format: naa., eui., t10.. -+ * multipath wwids file uses format: 3, 2, 1. -+ * The values are saved in wwid_hash_tab without the type prefix. -+ */ -+ -+static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev, -+ int primary_result, dev_t primary_dev) -+{ -+ char idbuf[DEV_WWID_SIZE] = { 0 }; -+ struct dev_wwid *dw; -+ char *wwid; -+ -+ if (!_wwid_hash_tab) - return 0; - - /* -- * sysfs prints wwid as . -- * multipath wwid uses '3' -- * does "." always correspond to "3"? -+ * Check the primary device, not the partition. - */ -- if (!(wwid = strchr(sysbuf, '.'))) -- return 0; -+ if (primary_result == 2) { -+ if (!(dev = dev_cache_get_by_devt(cmd, primary_dev))) { -+ log_debug("dev_is_mpath_component %s no primary dev", dev_name(dev)); -+ return 0; -+ } -+ } - -- /* skip the type and dot, just as '3' was skipped from wwids entry */ -- wwid++; -- -- look = (long) dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid)); -+ /* -+ * This function may be called multiple times for the same device, in -+ * particular if partitioned for each partition. -+ */ -+ if (!dm_list_empty(&dev->wwids)) -+ goto lookup; - -- if (look) { -- log_debug_devs("dev_is_mpath_component %s multipath wwid %s", dev_name(dev), wwid); -- return 1; -+ /* -+ * Get all the ids for the device from vpd_pg83 and check if any of -+ * those are in /etc/multipath/wwids. These ids should include the -+ * value printed from the sysfs wwid file. -+ */ -+ _read_sys_vpd_wwids(cmd, dev, &dev->wwids); -+ if (!dm_list_empty(&dev->wwids)) -+ goto lookup; -+ -+ /* -+ * This will read the sysfs wwid file, nvme devices in particular have -+ * a wwid file but not a vpd_pg83 file. -+ */ -+ if (_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf))) -+ add_wwid(idbuf, 0, &dev->wwids); -+ -+ lookup: -+ dm_list_iterate_items(dw, &dev->wwids) { -+ if (dw->type == 1 || dw->type == 2 || dw->type == 3) -+ wwid = &dw->id[4]; -+ else -+ wwid = dw->id; -+ -+ if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) { -+ log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), dw->id); -+ return 1; -+ } - } -+ - return 0; - } - - int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *holder_devno) - { -- if (_dev_is_mpath_component_sysfs(cmd, dev, holder_devno) == 1) -+ struct dev_types *dt = cmd->dev_types; -+ int primary_result; -+ dev_t primary_dev; -+ -+ /* -+ * multipath only uses SCSI or NVME devices -+ */ -+ if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev)) -+ return 0; -+ -+ /* -+ * primary_result 2: dev is a partition, primary_dev is the whole device -+ * primary_result 1: dev is a whole device -+ */ -+ primary_result = dev_get_primary_dev(dt, dev, &primary_dev); -+ -+ if (_dev_is_mpath_component_sysfs(cmd, dev, primary_result, primary_dev, holder_devno) == 1) - goto found; - -- if (_dev_in_wwid_file(cmd, dev)) -+ if (_dev_in_wwid_file(cmd, dev, primary_result, primary_dev)) - goto found; - - if (external_device_info_source() == DEV_EXT_UDEV) { -@@ -641,6 +791,12 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *h - goto found; - } - -+ /* -+ * TODO: save the result of this function in dev->flags and use those -+ * flags on repeated calls to avoid repeating the work multiple times -+ * for the same device when there are partitions on the device. -+ */ -+ - return 0; - found: - return 1; -diff --git a/lib/device/device.h b/lib/device/device.h -index d0d670ec3..06440f44b 100644 ---- a/lib/device/device.h -+++ b/lib/device/device.h -@@ -59,6 +59,14 @@ struct dev_ext { - void *handle; - }; - -+#define DEV_WWID_SIZE 128 -+ -+struct dev_wwid { -+ struct dm_list list; -+ int type; -+ char id[DEV_WWID_SIZE]; -+}; -+ - #define DEV_ID_TYPE_SYS_WWID 0x0001 - #define DEV_ID_TYPE_SYS_SERIAL 0x0002 - #define DEV_ID_TYPE_MPATH_UUID 0x0003 -@@ -105,6 +113,7 @@ struct dev_use { - */ - struct device { - struct dm_list aliases; /* struct dm_str_list */ -+ struct dm_list wwids; /* struct dev_wwid, used for multipath component detection */ - struct dm_list ids; /* struct dev_id, different entries for different idtypes */ - struct dev_id *id; /* points to the the ids entry being used for this dev */ - dev_t dev; -@@ -206,5 +215,9 @@ void dev_destroy_file(struct device *dev); - - int dev_mpath_init(const char *config_wwids_file); - void dev_mpath_exit(void); -+struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids); -+void free_wwids(struct dm_list *ids); -+int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids); -+int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes); - - #endif -diff --git a/lib/device/device_id.c b/lib/device/device_id.c -index f1928347c..9dec9f884 100644 ---- a/lib/device/device_id.c -+++ b/lib/device/device_id.c -@@ -182,7 +182,9 @@ void free_dids(struct dm_list *ids) - } - } - --int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize) -+static int _read_sys_block(struct cmd_context *cmd, struct device *dev, -+ const char *suffix, char *sysbuf, int sysbufsize, -+ int binary, int *retlen) - { - char path[PATH_MAX]; - dev_t devt = dev->dev; -@@ -196,11 +198,17 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff - return 0; - } - -- get_sysfs_value(path, sysbuf, sysbufsize, 0); -+ if (binary) { -+ ret = get_sysfs_binary(path, sysbuf, sysbufsize, retlen); -+ if (ret && !*retlen) -+ ret = 0; -+ } else { -+ ret = get_sysfs_value(path, sysbuf, sysbufsize, 0); -+ if (ret && !sysbuf[0]) -+ ret = 0; -+ } - -- if (sysbuf[0]) { -- if (prim) -- log_debug("Using primary device_id for partition %s.", dev_name(dev)); -+ if (ret) { - sysbuf[sysbufsize - 1] = '\0'; - return 1; - } -@@ -220,6 +228,19 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff - return 0; - } - -+int read_sys_block(struct cmd_context *cmd, struct device *dev, -+ const char *suffix, char *sysbuf, int sysbufsize) -+{ -+ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 0, NULL); -+} -+ -+int read_sys_block_binary(struct cmd_context *cmd, struct device *dev, -+ const char *suffix, char *sysbuf, int sysbufsize, -+ int *retlen) -+{ -+ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 1, retlen); -+} -+ - static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix) - { - if (!strncmp(sysbuf, prefix, strlen(prefix))) -diff --git a/lib/device/device_id.h b/lib/device/device_id.h -index 94773a65e..9b9c9ce03 100644 ---- a/lib/device/device_id.h -+++ b/lib/device/device_id.h -@@ -58,6 +58,8 @@ void devices_file_exit(struct cmd_context *cmd); - void unlink_searched_devnames(struct cmd_context *cmd); - - int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize); -+int read_sys_block_binary(struct cmd_context *cmd, struct device *dev, -+ const char *suffix, char *sysbuf, int sysbufsize, int *retlen); - - int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out); - -diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c -new file mode 100644 -index 000000000..4bafa7b9e ---- /dev/null -+++ b/lib/device/parse_vpd.c -@@ -0,0 +1,199 @@ -+/* -+ * Copyright (C) 2022 Red Hat, Inc. All rights reserved. -+ * -+ * This file is part of LVM2. -+ * -+ * This copyrighted material is made available to anyone wishing to use, -+ * modify, copy, or redistribute it subject to the terms and conditions -+ * of the GNU Lesser General Public License v.2.1. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "base/memory/zalloc.h" -+#include "lib/misc/lib.h" -+#include "lib/device/device.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * Replace series of spaces with a single _. -+ */ -+int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes) -+{ -+ int in_space = 0; -+ int retlen = 0; -+ int j = 0; -+ int i; -+ -+ for (i = 0; i < in_bytes; i++) { -+ if (!in[i]) -+ break; -+ if (j >= (out_bytes - 2)) -+ break; -+ /* skip leading spaces */ -+ if (!retlen && (in[i] == ' ')) -+ continue; -+ /* replace one or more spaces with _ */ -+ if (in[i] == ' ') { -+ in_space = 1; -+ continue; -+ } -+ /* spaces are finished so insert _ */ -+ if (in_space) { -+ out[j++] = '_'; -+ in_space = 0; -+ retlen++; -+ } -+ out[j++] = in[i]; -+ retlen++; -+ } -+ return retlen; -+} -+ -+static int _to_hex(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes) -+{ -+ int off = 0; -+ int num; -+ int i; -+ -+ for (i = 0; i < in_bytes; i++) { -+ num = sprintf((char *)out + off, "%02x", in[i]); -+ if (num < 0) -+ break; -+ off += num; -+ if (off + 2 >= out_bytes) -+ break; -+ } -+ return off; -+} -+ -+#define ID_BUFSIZE 1024 -+ -+/* -+ * based on linux kernel function -+ */ -+int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids) -+{ -+ char id[ID_BUFSIZE]; -+ unsigned char tmp_str[ID_BUFSIZE]; -+ const unsigned char *d, *cur_id_str; -+ size_t id_len = ID_BUFSIZE; -+ int id_size = -1; -+ uint8_t cur_id_size = 0; -+ -+ memset(id, 0, ID_BUFSIZE); -+ for (d = vpd_data + 4; -+ d < vpd_data + vpd_datalen; -+ d += d[3] + 4) { -+ memset(tmp_str, 0, sizeof(tmp_str)); -+ -+ switch (d[1] & 0xf) { -+ case 0x1: -+ /* T10 Vendor ID */ -+ cur_id_size = d[3]; -+ if (cur_id_size + 4 > id_len) -+ cur_id_size = id_len - 4; -+ cur_id_str = d + 4; -+ format_t10_id(cur_id_str, cur_id_size, tmp_str, sizeof(tmp_str)); -+ id_size = snprintf(id, ID_BUFSIZE, "t10.%s", tmp_str); -+ if (id_size < 0) -+ break; -+ if (id_size >= ID_BUFSIZE) -+ id_size = ID_BUFSIZE - 1; -+ add_wwid(id, 1, ids); -+ break; -+ case 0x2: -+ /* EUI-64 */ -+ cur_id_size = d[3]; -+ cur_id_str = d + 4; -+ switch (cur_id_size) { -+ case 8: -+ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str)); -+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); -+ break; -+ case 12: -+ _to_hex(cur_id_str, 12, tmp_str, sizeof(tmp_str)); -+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); -+ break; -+ case 16: -+ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str)); -+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); -+ break; -+ default: -+ break; -+ } -+ if (id_size < 0) -+ break; -+ if (id_size >= ID_BUFSIZE) -+ id_size = ID_BUFSIZE - 1; -+ add_wwid(id, 2, ids); -+ break; -+ case 0x3: -+ /* NAA */ -+ cur_id_size = d[3]; -+ cur_id_str = d + 4; -+ switch (cur_id_size) { -+ case 8: -+ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str)); -+ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str); -+ break; -+ case 16: -+ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str)); -+ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str); -+ break; -+ default: -+ break; -+ } -+ if (id_size < 0) -+ break; -+ if (id_size >= ID_BUFSIZE) -+ id_size = ID_BUFSIZE - 1; -+ add_wwid(id, 3, ids); -+ break; -+ case 0x8: -+ /* SCSI name string */ -+ cur_id_size = d[3]; -+ cur_id_str = d + 4; -+ if (cur_id_size >= id_len) -+ cur_id_size = id_len - 1; -+ memcpy(id, cur_id_str, cur_id_size); -+ id_size = cur_id_size; -+ -+ /* -+ * Not in the kernel version, copying multipath code, -+ * which checks if this string begins with naa or eui -+ * and if so does tolower() on the chars. -+ */ -+ if (!strncmp(id, "naa.", 4) || !strncmp(id, "eui.", 4)) { -+ int i; -+ for (i = 0; i < id_size; i++) -+ id[i] = tolower(id[i]); -+ } -+ add_wwid(id, 8, ids); -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return id_size; -+} --- -2.34.3 - diff --git a/SOURCES/0004-vgimportclone-fix-importing-PV-without-metadata.patch b/SOURCES/0004-vgimportclone-fix-importing-PV-without-metadata.patch new file mode 100644 index 0000000..becc161 --- /dev/null +++ b/SOURCES/0004-vgimportclone-fix-importing-PV-without-metadata.patch @@ -0,0 +1,48 @@ +From 8f7b4456ad93c3907a82fd03d0feceb9785e3bfc Mon Sep 17 00:00:00 2001 +From: David Teigland +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 + diff --git a/SOURCES/0005-lvmdbusd-Move-get_error_msg-to-utils.patch b/SOURCES/0005-lvmdbusd-Move-get_error_msg-to-utils.patch new file mode 100644 index 0000000..a250689 --- /dev/null +++ b/SOURCES/0005-lvmdbusd-Move-get_error_msg-to-utils.patch @@ -0,0 +1,89 @@ +From 4e34edd6e4e52328dd77b6a55aeadd9b0454c743 Mon Sep 17 00:00:00 2001 +From: Tony Asleson +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 + diff --git a/SOURCES/0005-pvdisplay-restore-reportformat-option.patch b/SOURCES/0005-pvdisplay-restore-reportformat-option.patch deleted file mode 100644 index b437a9c..0000000 --- a/SOURCES/0005-pvdisplay-restore-reportformat-option.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 3cfb00e5f7c720549100c5297be18600c9abf530 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Fri, 24 Jun 2022 10:40:54 -0500 -Subject: [PATCH 5/7] pvdisplay: restore --reportformat option - -Fixes commit b8f4ec846 "display: ignore --reportformat" -by restoring the --reportformat option to pvdisplay. -Adding -C to pvdisplay turns the command into a reporting -command (like pvs, vgs, lvs) in which --reportformat can -be useful. - -(cherry picked from commit db5277c97155632ce83e1125e348eda97c871968) ---- - tools/command-lines.in | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tools/command-lines.in b/tools/command-lines.in -index b64fd0dda..b6a03d158 100644 ---- a/tools/command-lines.in -+++ b/tools/command-lines.in -@@ -1593,10 +1593,10 @@ pvdisplay - OO: --aligned, --all, --binary, --colon, --columns, --configreport ConfigReport, - --foreign, --ignorelockingfailure, - --logonly, --maps, --noheadings, --nosuffix, --options String, ----readonly, --select String, --separator String, --shared, -+--readonly, --reportformat ReportFmt, --select String, --separator String, --shared, - --short, --sort String, --unbuffered, --units Units - OP: PV|Tag ... --IO: --ignoreskippedcluster, --reportformat ReportFmt -+IO: --ignoreskippedcluster - ID: pvdisplay_general - - --- --- -2.34.3 - diff --git a/SOURCES/0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch b/SOURCES/0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch deleted file mode 100644 index 273c939..0000000 --- a/SOURCES/0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch +++ /dev/null @@ -1,247 +0,0 @@ -From a369a7fd1fccf3c50103dd294b79055cc7c9d005 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Tue, 5 Jul 2022 17:08:00 -0500 -Subject: [PATCH 6/7] exit with error when --devicesfile name doesn't exist - -(cherry picked from commit 92b4fcf57f3c6d212d06b72b097e1a06e6efb84b) ---- - lib/cache/lvmcache.c | 3 ++- - lib/label/label.c | 4 ++-- - test/shell/devicesfile-basic.sh | 1 + - tools/pvcreate.c | 3 ++- - tools/pvremove.c | 3 ++- - tools/pvscan.c | 3 ++- - tools/toollib.c | 27 +++++++++++++++++++++------ - tools/vgcfgrestore.c | 5 ++++- - tools/vgcreate.c | 5 ++++- - tools/vgextend.c | 3 ++- - tools/vgmerge.c | 3 ++- - tools/vgsplit.c | 3 ++- - 12 files changed, 46 insertions(+), 17 deletions(-) - -diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c -index 22edcfd84..a1c4a61c8 100644 ---- a/lib/cache/lvmcache.c -+++ b/lib/cache/lvmcache.c -@@ -1612,7 +1612,8 @@ int lvmcache_label_scan(struct cmd_context *cmd) - * with infos/vginfos based on reading headers from - * each device, and a vg summary from each mda. - */ -- label_scan(cmd); -+ if (!label_scan(cmd)) -+ return_0; - - /* - * When devnames are used as device ids (which is dispreferred), -diff --git a/lib/label/label.c b/lib/label/label.c -index 711edb6f4..f845abb96 100644 ---- a/lib/label/label.c -+++ b/lib/label/label.c -@@ -801,7 +801,7 @@ static int _setup_bcache(void) - } - - if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) { -- log_error("Failed to create bcache with %d cache blocks.", cache_blocks); -+ log_error("Failed to set up io layer with %d blocks.", cache_blocks); - return 0; - } - -@@ -1292,7 +1292,7 @@ int label_scan(struct cmd_context *cmd) - * data to invalidate.) - */ - if (!(iter = dev_iter_create(NULL, 0))) { -- log_error("Scanning failed to get devices."); -+ log_error("Failed to get device list."); - return 0; - } - while ((dev = dev_iter_get(cmd, iter))) { -diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh -index 77fe265a0..715c579b3 100644 ---- a/test/shell/devicesfile-basic.sh -+++ b/test/shell/devicesfile-basic.sh -@@ -107,6 +107,7 @@ not vgs --devicesfile test.devices $vg2 - # misspelled override name fails - not vgs --devicesfile doesnotexist $vg1 - not vgs --devicesfile doesnotexist $vg2 -+not vgs --devicesfile doesnotexist - - # devicesfile and devices cannot be used together - not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1 -diff --git a/tools/pvcreate.c b/tools/pvcreate.c -index 71eb060a3..a1ef0e9e1 100644 ---- a/tools/pvcreate.c -+++ b/tools/pvcreate.c -@@ -144,7 +144,8 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv) - - cmd->create_edit_devices_file = 1; - -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) -+ return_ECMD_FAILED; - - if (!(handle = init_processing_handle(cmd, NULL))) { - log_error("Failed to initialize processing handle."); -diff --git a/tools/pvremove.c b/tools/pvremove.c -index 2dfdbd016..5c39ee0c7 100644 ---- a/tools/pvremove.c -+++ b/tools/pvremove.c -@@ -45,7 +45,8 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv) - - clear_hint_file(cmd); - -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) -+ return_ECMD_FAILED; - - /* When forcibly clearing a PV we don't care about a VG lock. */ - if (pp.force == DONT_PROMPT_OVERRIDE) -diff --git a/tools/pvscan.c b/tools/pvscan.c -index 1e47d754a..72c3279c3 100644 ---- a/tools/pvscan.c -+++ b/tools/pvscan.c -@@ -1407,7 +1407,8 @@ static int _pvscan_cache_all(struct cmd_context *cmd, int argc, char **argv, - * which we want 'pvscan --cache' to do, and that uses - * info from lvmcache, e.g. duplicate pv info. - */ -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) -+ return_0; - - cmd->pvscan_recreate_hints = 0; - cmd->use_hints = 0; -diff --git a/tools/toollib.c b/tools/toollib.c -index d77092d89..544791808 100644 ---- a/tools/toollib.c -+++ b/tools/toollib.c -@@ -1655,7 +1655,10 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv, - - log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LABEL); - -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) { -+ ret_max = ECMD_FAILED; -+ goto_out; -+ } - - if (argc) { - for (; opt < argc; opt++) { -@@ -2435,8 +2438,13 @@ int process_each_vg(struct cmd_context *cmd, - * Scan all devices to populate lvmcache with initial - * list of PVs and VGs. - */ -- if (!(read_flags & PROCESS_SKIP_SCAN)) -- lvmcache_label_scan(cmd); -+ if (!(read_flags & PROCESS_SKIP_SCAN)) { -+ if (!lvmcache_label_scan(cmd)) { -+ ret_max = ECMD_FAILED; -+ goto_out; -+ } -+ } -+ - - /* - * A list of all VGs on the system is needed when: -@@ -3987,7 +3995,10 @@ int process_each_lv(struct cmd_context *cmd, - * Scan all devices to populate lvmcache with initial - * list of PVs and VGs. - */ -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) { -+ ret_max = ECMD_FAILED; -+ goto_out; -+ } - - /* - * A list of all VGs on the system is needed when: -@@ -4623,8 +4634,12 @@ int process_each_pv(struct cmd_context *cmd, - goto_out; - } - -- if (!(read_flags & PROCESS_SKIP_SCAN)) -- lvmcache_label_scan(cmd); -+ if (!(read_flags & PROCESS_SKIP_SCAN)) { -+ if (!lvmcache_label_scan(cmd)) { -+ ret_max = ECMD_FAILED; -+ goto_out; -+ } -+ } - - if (!lvmcache_get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) { - ret_max = ret; -diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c -index e49313d14..9fcba89d4 100644 ---- a/tools/vgcfgrestore.c -+++ b/tools/vgcfgrestore.c -@@ -132,7 +132,10 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv) - - clear_hint_file(cmd); - -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) { -+ unlock_vg(cmd, NULL, vg_name); -+ return_ECMD_FAILED; -+ } - - cmd->handles_unknown_segments = 1; - -diff --git a/tools/vgcreate.c b/tools/vgcreate.c -index dde3f1eac..14608777f 100644 ---- a/tools/vgcreate.c -+++ b/tools/vgcreate.c -@@ -84,7 +84,10 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) - - cmd->create_edit_devices_file = 1; - -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) { -+ unlock_vg(cmd, NULL, vp_new.vg_name); -+ return_ECMD_FAILED; -+ } - - if (lvmcache_vginfo_from_vgname(vp_new.vg_name, NULL)) { - unlock_vg(cmd, NULL, vp_new.vg_name); -diff --git a/tools/vgextend.c b/tools/vgextend.c -index 0856b4c78..fecd6bdd5 100644 ---- a/tools/vgextend.c -+++ b/tools/vgextend.c -@@ -160,7 +160,8 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv) - - cmd->edit_devices_file = 1; - -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) -+ return_ECMD_FAILED; - - if (!(handle = init_processing_handle(cmd, NULL))) { - log_error("Failed to initialize processing handle."); -diff --git a/tools/vgmerge.c b/tools/vgmerge.c -index 08615cd62..4ed4a8f0b 100644 ---- a/tools/vgmerge.c -+++ b/tools/vgmerge.c -@@ -72,7 +72,8 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to, - return ECMD_FAILED; - } - -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) -+ return_ECMD_FAILED; - - if (strcmp(vg_name_to, vg_name_from) > 0) - lock_vg_from_first = 1; -diff --git a/tools/vgsplit.c b/tools/vgsplit.c -index 5f113b363..c7f4b8af4 100644 ---- a/tools/vgsplit.c -+++ b/tools/vgsplit.c -@@ -559,7 +559,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv) - return ECMD_FAILED; - } - -- lvmcache_label_scan(cmd); -+ if (!lvmcache_label_scan(cmd)) -+ return_ECMD_FAILED; - - if (!(vginfo_to = lvmcache_vginfo_from_vgname(vg_name_to, NULL))) { - if (!validate_name(vg_name_to)) { --- -2.34.3 - diff --git a/SOURCES/0006-lvmdbusd-Add-command_log_selection-to-command-line.patch b/SOURCES/0006-lvmdbusd-Add-command_log_selection-to-command-line.patch new file mode 100644 index 0000000..6a41458 --- /dev/null +++ b/SOURCES/0006-lvmdbusd-Add-command_log_selection-to-command-line.patch @@ -0,0 +1,79 @@ +From 0441d340e752427d0d355a85e5e5e465e911a102 Mon Sep 17 00:00:00 2001 +From: Tony Asleson +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 + diff --git a/SOURCES/0007-make-generate.patch b/SOURCES/0007-make-generate.patch deleted file mode 100644 index 3e51442..0000000 --- a/SOURCES/0007-make-generate.patch +++ /dev/null @@ -1,43 +0,0 @@ -From a8588f39219a2794fad562b38e6dc63aee791f82 Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Mon, 11 Jul 2022 01:02:22 +0200 -Subject: [PATCH 7/7] make: generate - -(cherry picked from commit c0f8e6675c62332263acdc7c3c2f61eca20bd60f) ---- - man/pvdisplay.8_pregen | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen -index 23d41b29b..e7767d0c4 100644 ---- a/man/pvdisplay.8_pregen -+++ b/man/pvdisplay.8_pregen -@@ -61,6 +61,8 @@ and more, using a more compact and configurable output format. - .br - [ \fB--readonly\fP ] - .br -+[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ] -+.br - [ \fB--separator\fP \fIString\fP ] - .br - [ \fB--shared\fP ] -@@ -320,6 +322,16 @@ device-mapper kernel driver, so this option is unable to report whether - or not LVs are actually in use. - . - .HP -+\fB--reportformat\fP \fBbasic\fP|\fBjson\fP -+.br -+Overrides current output format for reports which is defined globally by -+the report/output_format setting in \fBlvm.conf\fP(5). -+\fBbasic\fP is the original format with columns and rows. -+If there is more than one report per command, each report is prefixed -+with the report name for identification. \fBjson\fP produces report -+output in JSON format. See \fBlvmreport\fP(7) for more information. -+. -+.HP - \fB-S\fP|\fB--select\fP \fIString\fP - .br - Select objects for processing and reporting based on specified criteria. --- -2.34.3 - diff --git a/SOURCES/0007-tests-lvresize-fs-crypt-using-helper-only-for-crypt-.patch b/SOURCES/0007-tests-lvresize-fs-crypt-using-helper-only-for-crypt-.patch new file mode 100644 index 0000000..2a97a50 --- /dev/null +++ b/SOURCES/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/SOURCES/0008-apply-multipath_component_detection-0-to-duplicate-P.patch b/SOURCES/0008-apply-multipath_component_detection-0-to-duplicate-P.patch deleted file mode 100644 index 6070b2c..0000000 --- a/SOURCES/0008-apply-multipath_component_detection-0-to-duplicate-P.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 2a31250c445911eb07057f077a17e3a281ac0049 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Mon, 25 Jul 2022 13:50:43 -0500 -Subject: [PATCH] apply multipath_component_detection=0 to duplicate PV - handling - -multipath_component_detection=0 has always applied to the filter-based -component detection. Also apply this setting to the duplicate-PV -handling which also eliminates multipath components (based on duplicate -PVs having the same wwid.) - -(cherry picked from commit 99ce09ae778c2cc4aa2611e425bba5287b8b9513) ---- - lib/cache/lvmcache.c | 3 +++ - test/shell/duplicate-pvs-multipath.sh | 10 +++++++--- - 2 files changed, 10 insertions(+), 3 deletions(-) - -diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c -index a1c4a61c8..00916885c 100644 ---- a/lib/cache/lvmcache.c -+++ b/lib/cache/lvmcache.c -@@ -652,6 +652,9 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in - - *dev_mpath = NULL; - -+ if (!find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL)) -+ return 0; -+ - /* This function only makes sense with more than one dev. */ - if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) { - log_debug("Skip multipath component checks with single device for PVID %s", pvid); -diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh -index 59c15b0d4..bc98d2d5a 100644 ---- a/test/shell/duplicate-pvs-multipath.sh -+++ b/test/shell/duplicate-pvs-multipath.sh -@@ -24,9 +24,13 @@ modprobe --dry-run scsi_debug || skip - multipath -l || skip - multipath -l | grep scsi_debug && skip - --# Turn off multipath_component_detection so that the duplicate --# resolution of mpath components is used. --aux lvmconf 'devices/multipath_component_detection = 0' -+# FIXME: setting multipath_component_detection=0 now also disables -+# the wwid-based mpath component detection, so this test will need -+# to find another way to disable only the filter-mpath code (using -+# sysfs and multipath/wwids) while keeping the code enabled that -+# eliminates duplicates based on their matching wwids which this -+# tries to test. -+ - # Prevent wwids from being used for filtering. - aux lvmconf 'devices/multipath_wwids_file = "/dev/null"' - # Need to use /dev/mapper/mpath --- -2.37.1 - diff --git a/SOURCES/0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch b/SOURCES/0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch new file mode 100644 index 0000000..36f9669 --- /dev/null +++ b/SOURCES/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/SOURCES/0009-lvmdbusd-Correct-conditional-for-lvm-child-process-r.patch b/SOURCES/0009-lvmdbusd-Correct-conditional-for-lvm-child-process-r.patch deleted file mode 100644 index e32528a..0000000 --- a/SOURCES/0009-lvmdbusd-Correct-conditional-for-lvm-child-process-r.patch +++ /dev/null @@ -1,30 +0,0 @@ -From f7277061859740712b67ef6b229c2fc07482ef16 Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Wed, 25 May 2022 15:51:14 -0500 -Subject: [PATCH 1/9] lvmdbusd: Correct conditional for lvm child process - running - -Poll returns None when process is running, else exit value. If poll returns -0 we will fail to exit the select loop. - -(cherry picked from commit 37733cd4eb5116db371ac1ae6e971e3c336c3ddb) ---- - daemons/lvmdbusd/lvm_shell_proxy.py.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in -index 7816daa8b..78fe1e422 100644 ---- a/daemons/lvmdbusd/lvm_shell_proxy.py.in -+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in -@@ -75,7 +75,7 @@ class LVMShellProxy(object): - stderr += read_decoded(self.lvm_shell.stderr) - - # Check to see if the lvm process died on us -- if self.lvm_shell.poll(): -+ if self.lvm_shell.poll() is not None: - raise Exception(self.lvm_shell.returncode, "%s" % stderr) - - if stdout.endswith(SHELL_PROMPT): --- -2.37.1 - diff --git a/SOURCES/0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch b/SOURCES/0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch new file mode 100644 index 0000000..3a87788 --- /dev/null +++ b/SOURCES/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/SOURCES/0010-lvmdbusd-Simplify-child-process-env.patch b/SOURCES/0010-lvmdbusd-Simplify-child-process-env.patch deleted file mode 100644 index 09ee5fd..0000000 --- a/SOURCES/0010-lvmdbusd-Simplify-child-process-env.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ece4c18a42af8fde41f55fd43e8cc0ca34ab2f7d Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Wed, 25 May 2022 15:52:20 -0500 -Subject: [PATCH 2/9] lvmdbusd: Simplify child process env - -We don't need to duplicate the entire env from the parent, supply only what -is needed. - -(cherry picked from commit 58c6c9e9aa8d6aa6d3be14a04ec0f4257b61495e) ---- - daemons/lvmdbusd/lvm_shell_proxy.py.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in -index 78fe1e422..10719c67e 100644 ---- a/daemons/lvmdbusd/lvm_shell_proxy.py.in -+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in -@@ -135,7 +135,8 @@ class LVMShellProxy(object): - self.report_stream = os.fdopen(self.report_fd, 'rb', 0) - - # Setup the environment for using our own socket for reporting -- local_env = copy.deepcopy(os.environ) -+ local_env = {} -+ local_env["LC_ALL"] = "C" - local_env["LVM_REPORT_FD"] = "32" - local_env["LVM_COMMAND_PROFILE"] = "lvmdbusd" - --- -2.37.1 - diff --git a/SOURCES/0010-udev-import-previous-results-of-blkid-when-in-suspen.patch b/SOURCES/0010-udev-import-previous-results-of-blkid-when-in-suspen.patch new file mode 100644 index 0000000..78c3f72 --- /dev/null +++ b/SOURCES/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/SOURCES/0011-filesystem-use-PATH_MAX-for-linux-paths.patch b/SOURCES/0011-filesystem-use-PATH_MAX-for-linux-paths.patch new file mode 100644 index 0000000..27c2720 --- /dev/null +++ b/SOURCES/0011-filesystem-use-PATH_MAX-for-linux-paths.patch @@ -0,0 +1,49 @@ +From cbcf65c6518652242aab6960eeb983c6bc771bd3 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +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 + diff --git a/SOURCES/0011-lvmdbusd-re-work-lvm-shell-main.patch b/SOURCES/0011-lvmdbusd-re-work-lvm-shell-main.patch deleted file mode 100644 index ad1cc42..0000000 --- a/SOURCES/0011-lvmdbusd-re-work-lvm-shell-main.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 6d0ad276260c902dba66df73beac1bafc3f4c254 Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Wed, 25 May 2022 15:58:15 -0500 -Subject: [PATCH 3/9] lvmdbusd: re-work lvm shell main - -Add an optional single argument "bisect" to use with git bisect for -automation. Normal case is no arguments when running stand-alone. - -(cherry picked from commit b3407b16c1c7b5bff01e3bde4e0f62a2608682f8) ---- - daemons/lvmdbusd/lvm_shell_proxy.py.in | 46 ++++++++++++++++---------- - 1 file changed, 28 insertions(+), 18 deletions(-) - -diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in -index 10719c67e..40639442c 100644 ---- a/daemons/lvmdbusd/lvm_shell_proxy.py.in -+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in -@@ -238,24 +238,34 @@ class LVMShellProxy(object): - - - if __name__ == "__main__": -- shell = LVMShellProxy() -- in_line = "start" -+ print("USING LVM BINARY: %s " % LVM_CMD) -+ - try: -- while in_line: -- in_line = input("lvm> ") -- if in_line: -- start = time.time() -- ret, out, err = shell.call_lvm(in_line.split()) -- end = time.time() -- -- print(("RC: %d" % ret)) -- print(("OUT:\n%s" % out)) -- print(("ERR:\n%s" % err)) -- -- print("Command = %f seconds" % (end - start)) -- except KeyboardInterrupt: -- pass -- except EOFError: -- pass -+ if len(sys.argv) > 1 and sys.argv[1] == "bisect": -+ shell = LVMShellProxy() -+ shell.exit_shell() -+ else: -+ shell = LVMShellProxy() -+ in_line = "start" -+ try: -+ while in_line: -+ in_line = input("lvm> ") -+ if in_line: -+ start = time.time() -+ ret, out, err = shell.call_lvm(in_line.split()) -+ end = time.time() -+ -+ print(("RC: %d" % ret)) -+ print(("OUT:\n%s" % out)) -+ print(("ERR:\n%s" % err)) -+ -+ print("Command = %f seconds" % (end - start)) -+ except KeyboardInterrupt: -+ pass -+ except EOFError: -+ pass - except Exception: - traceback.print_exc(file=sys.stdout) -+ sys.exit(1) -+ -+ sys.exit(0) --- -2.37.1 - diff --git a/SOURCES/0012-lvmdbusd-Add-debug-output-for-which-lvm-binary-is-us.patch b/SOURCES/0012-lvmdbusd-Add-debug-output-for-which-lvm-binary-is-us.patch deleted file mode 100644 index ba9c433..0000000 --- a/SOURCES/0012-lvmdbusd-Add-debug-output-for-which-lvm-binary-is-us.patch +++ /dev/null @@ -1,26 +0,0 @@ -From a9ca83b880c19a72d6e00e13b6a638fb11630819 Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Wed, 25 May 2022 15:59:11 -0500 -Subject: [PATCH 4/9] lvmdbusd: Add debug output for which lvm binary is used - -(cherry picked from commit 51d9b686c08d963c61898d407d15abf39f129d72) ---- - daemons/lvmdbusd/main.py | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/daemons/lvmdbusd/main.py b/daemons/lvmdbusd/main.py -index b0a82d492..1e717ef69 100644 ---- a/daemons/lvmdbusd/main.py -+++ b/daemons/lvmdbusd/main.py -@@ -127,6 +127,8 @@ def main(): - log_error("You cannot specify --lvmshell and --nojson") - sys.exit(1) - -+ log_debug("Using lvm binary: %s" % cfg.LVM_CMD) -+ - # We will dynamically add interfaces which support vdo if it - # exists. - cfg.vdo_support = supports_vdo() --- -2.37.1 - diff --git a/SOURCES/0013-lvmdbusd-Change-unit-test-vdo-minimum-size.patch b/SOURCES/0013-lvmdbusd-Change-unit-test-vdo-minimum-size.patch deleted file mode 100644 index 5252f4e..0000000 --- a/SOURCES/0013-lvmdbusd-Change-unit-test-vdo-minimum-size.patch +++ /dev/null @@ -1,73 +0,0 @@ -From aa5ec0804d151e5951c4516c3bc08d37e2494349 Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Wed, 25 May 2022 16:03:27 -0500 -Subject: [PATCH 5/9] lvmdbusd: Change unit test vdo minimum size - -(cherry picked from commit 47c61907b4adbdead50f5bb5ac95c0f5d0fe263e) ---- - test/dbus/lvmdbustest.py | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py -index 6d692223f..3eef77fd7 100755 ---- a/test/dbus/lvmdbustest.py -+++ b/test/dbus/lvmdbustest.py -@@ -23,6 +23,9 @@ import os - - g_tmo = 0 - -+# Approx. min size -+VDO_MIN_SIZE = mib(8192) -+ - # Prefix on created objects to enable easier clean-up - g_prefix = os.getenv('PREFIX', '') - -@@ -1155,7 +1158,7 @@ class TestDbusService(unittest.TestCase): - return - - # This may not pass -- for i in [48, 64, 128]: -+ for i in [64, 128]: - yes = self._test_expired_timer(i) - if yes: - break -@@ -1907,8 +1910,8 @@ class TestDbusService(unittest.TestCase): - vdo_pool_object_path = self.handle_return( - vg_proxy.VgVdo.CreateVdoPoolandLv( - pool_name, lv_name, -- dbus.UInt64(mib(4096)), # Appears to be minimum size -- dbus.UInt64(mib(8192)), -+ dbus.UInt64(VDO_MIN_SIZE), -+ dbus.UInt64(VDO_MIN_SIZE * 2), - dbus.Int32(g_tmo), - EOD)) - -@@ -1950,7 +1953,7 @@ class TestDbusService(unittest.TestCase): - vg_proxy = self._vg_create(vg_prefix="vdo_conv_") - lv = self._test_lv_create( - vg_proxy.Vg.LvCreate, -- (dbus.String(pool_name), dbus.UInt64(mib(4096)), -+ (dbus.String(pool_name), dbus.UInt64(VDO_MIN_SIZE), - dbus.Array([], signature='(ott)'), dbus.Int32(g_tmo), - EOD), vg_proxy.Vg, LV_BASE_INT) - lv_obj_path = self._lookup("%s/%s" % (vg_proxy.Vg.Name, pool_name)) -@@ -1959,7 +1962,7 @@ class TestDbusService(unittest.TestCase): - vdo_pool_path = self.handle_return( - vg_proxy.VgVdo.CreateVdoPool( - dbus.ObjectPath(lv.object_path), lv_name, -- dbus.UInt64(mib(8192)), -+ dbus.UInt64(VDO_MIN_SIZE), - dbus.Int32(g_tmo), - EOD)) - -@@ -2083,6 +2086,7 @@ if __name__ == '__main__': - std_err_print('\n*** Testing only lvm shell mode ***\n') - - for g_tmo in [0, 15]: -+ std_err_print('Testing TMO=%d\n' % g_tmo) - if mode == 0: - if set_execution(False, r): - r.register_result(unittest.main(exit=False)) --- -2.37.1 - diff --git a/SOURCES/0014-lvmdbusd-Fix-env-variable-LVM_DBUSD_TEST_MODE.patch b/SOURCES/0014-lvmdbusd-Fix-env-variable-LVM_DBUSD_TEST_MODE.patch deleted file mode 100644 index 7af9d4d..0000000 --- a/SOURCES/0014-lvmdbusd-Fix-env-variable-LVM_DBUSD_TEST_MODE.patch +++ /dev/null @@ -1,54 +0,0 @@ -From d978fe593b3c75d4b5b66d743b4f5c3632861559 Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Wed, 25 May 2022 16:21:14 -0500 -Subject: [PATCH 6/9] lvmdbusd: Fix env variable LVM_DBUSD_TEST_MODE - -Make it more logical. - -(cherry picked from commit b3d7aff6a3a8fd55790f61b9b0b33d599841030b) ---- - test/dbus/lvmdbustest.py | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py -index 3eef77fd7..d876a1748 100755 ---- a/test/dbus/lvmdbustest.py -+++ b/test/dbus/lvmdbustest.py -@@ -40,9 +40,10 @@ pv_device_list = os.getenv('LVM_DBUSD_PV_DEVICE_LIST', None) - - # Default is to test all modes - # 0 == Only test fork & exec mode --# 1 == Test both fork & exec & lvm shell mode (default) -+# 1 == Only test lvm shell mode -+# 2 == Test both fork & exec & lvm shell mode (default) - # Other == Test just lvm shell mode --test_shell = os.getenv('LVM_DBUSD_TEST_MODE', 1) -+test_shell = os.getenv('LVM_DBUSD_TEST_MODE', 2) - - # LVM binary to use - LVM_EXECUTABLE = os.getenv('LVM_BINARY', '/usr/sbin/lvm') -@@ -2081,16 +2082,19 @@ if __name__ == '__main__': - if mode == 0: - std_err_print('\n*** Testing only lvm fork & exec test mode ***\n') - elif mode == 1: -+ std_err_print('\n*** Testing only lvm shell mode ***\n') -+ elif mode == 2: - std_err_print('\n*** Testing fork & exec & lvm shell mode ***\n') - else: -- std_err_print('\n*** Testing only lvm shell mode ***\n') -+ std_err_print("Unsupported \"LVM_DBUSD_TEST_MODE\"=%d, [0-2] valid" % mode) -+ sys.exit(1) - - for g_tmo in [0, 15]: - std_err_print('Testing TMO=%d\n' % g_tmo) - if mode == 0: - if set_execution(False, r): - r.register_result(unittest.main(exit=False)) -- elif mode == 2: -+ elif mode == 1: - if set_execution(True, r): - r.register_result(unittest.main(exit=False)) - else: --- -2.37.1 - diff --git a/SOURCES/0015-lvmdbusd-Remove-the-use-of-sub-shell-for-lvm-shell.patch b/SOURCES/0015-lvmdbusd-Remove-the-use-of-sub-shell-for-lvm-shell.patch deleted file mode 100644 index 1eb4144..0000000 --- a/SOURCES/0015-lvmdbusd-Remove-the-use-of-sub-shell-for-lvm-shell.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 8e724393079784edbf779678df6937dd838c4149 Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Thu, 26 May 2022 10:44:02 -0500 -Subject: [PATCH 7/9] lvmdbusd: Remove the use of sub shell for lvm shell - -This reduces the number of processes and improves security. - -(cherry picked from commit 7a2090655d3ab5abde83b981594ed527e2a7f1f7) ---- - daemons/lvmdbusd/lvm_shell_proxy.py.in | 24 +++++++++++------------- - 1 file changed, 11 insertions(+), 13 deletions(-) - -diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in -index 40639442c..1a5051a92 100644 ---- a/daemons/lvmdbusd/lvm_shell_proxy.py.in -+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in -@@ -129,31 +129,29 @@ class LVMShellProxy(object): - except FileExistsError: - pass - -- # We have to open non-blocking as the other side isn't open until -- # we actually fork the process. -+ # Open the fifo for use to read and for lvm child process to write to. - self.report_fd = os.open(tmp_file, os.O_NONBLOCK) - self.report_stream = os.fdopen(self.report_fd, 'rb', 0) -+ lvm_fd = os.open(tmp_file, os.O_WRONLY) - -- # Setup the environment for using our own socket for reporting -- local_env = {} -- local_env["LC_ALL"] = "C" -- local_env["LVM_REPORT_FD"] = "32" -- local_env["LVM_COMMAND_PROFILE"] = "lvmdbusd" -- -- # Disable the abort logic if lvm logs too much, which easily happens -- # when utilizing the lvm shell. -- local_env["LVM_LOG_FILE_MAX_LINES"] = "0" -+ # Set up the environment for using our own socket for reporting and disable the abort -+ # logic if lvm logs too much, which easily happens when utilizing the lvm shell. -+ local_env = {"LC_ALL": "C", "LVM_REPORT_FD": "%s" % lvm_fd, "LVM_COMMAND_PROFILE": "lvmdbusd", -+ "LVM_LOG_FILE_MAX_LINES": "0"} - - # run the lvm shell - self.lvm_shell = subprocess.Popen( -- [LVM_CMD + " 32>%s" % tmp_file], -+ [LVM_CMD], - stdin=subprocess.PIPE, stdout=subprocess.PIPE, env=local_env, -- stderr=subprocess.PIPE, close_fds=True, shell=True) -+ stderr=subprocess.PIPE, close_fds=True, pass_fds=(lvm_fd,), shell=False) - - try: - make_non_block(self.lvm_shell.stdout) - make_non_block(self.lvm_shell.stderr) - -+ # Close our copy of the lvm_fd, child process is open in its process space -+ os.close(lvm_fd) -+ - # wait for the first prompt - errors = self._read_until_prompt(no_output=True)[2] - if errors and len(errors): --- -2.37.1 - diff --git a/SOURCES/0016-lvmdbusd-Job-prop.-Get-GetAll-exec.-immediately.patch b/SOURCES/0016-lvmdbusd-Job-prop.-Get-GetAll-exec.-immediately.patch deleted file mode 100644 index 270d741..0000000 --- a/SOURCES/0016-lvmdbusd-Job-prop.-Get-GetAll-exec.-immediately.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 70714b7fbe4d6f1ee943614cc26a990f20e35450 Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Mon, 6 Jun 2022 09:51:54 -0500 -Subject: [PATCH 8/9] lvmdbusd: Job prop. Get/GetAll exec. immediately - -This allows API user the ability to check on the status of a long running -job without blocking in the request queue. - -(cherry picked from commit eee89a941eb4e63865356cfe9e513c24cfa8e0f9) ---- - daemons/lvmdbusd/job.py | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/daemons/lvmdbusd/job.py b/daemons/lvmdbusd/job.py -index 988b1147a..7629cafc7 100644 ---- a/daemons/lvmdbusd/job.py -+++ b/daemons/lvmdbusd/job.py -@@ -226,3 +226,21 @@ class Job(AutomatedProperties): - def Uuid(self): - import uuid - return uuid.uuid1() -+ -+ # Override the property "getters" implementation for the job interface, so a user can query a job while the queue -+ # is processing items. Originally all the property get methods were this way, but we changed this in -+ # e53454d6de07de56736303dd2157c3859f6fa848 -+ -+ # Properties -+ # noinspection PyUnusedLocal -+ @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, -+ in_signature='ss', out_signature='v') -+ def Get(self, interface_name, property_name): -+ # Note: If we get an exception in this handler we won't know about it, -+ # only the side effect of no returned value! -+ return AutomatedProperties._get_prop(self, interface_name, property_name) -+ -+ @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, -+ in_signature='s', out_signature='a{sv}') -+ def GetAll(self, interface_name): -+ return AutomatedProperties._get_all_prop(self, interface_name) --- -2.37.1 - diff --git a/SOURCES/0017-lvmdbusd-Don-t-require-lvm-prompt-for-shell.patch b/SOURCES/0017-lvmdbusd-Don-t-require-lvm-prompt-for-shell.patch deleted file mode 100644 index 2429858..0000000 --- a/SOURCES/0017-lvmdbusd-Don-t-require-lvm-prompt-for-shell.patch +++ /dev/null @@ -1,174 +0,0 @@ -From a3c2dcc3726261d6463ea35102d86863d698021b Mon Sep 17 00:00:00 2001 -From: Tony Asleson -Date: Mon, 6 Jun 2022 09:56:32 -0500 -Subject: [PATCH 9/9] lvmdbusd: Don't require "lvm> " prompt for shell - -Depending on how lvm is compiled, it may not present the "lvm> " prompt -when using the lvm shell. Don't require it to be present. - -Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2090391 -(cherry picked from commit 691494268502ddb20da2a14568984c0fa4f29f50) ---- - daemons/lvmdbusd/lvm_shell_proxy.py.in | 83 +++++++++++++------------- - 1 file changed, 43 insertions(+), 40 deletions(-) - -diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in -index 1a5051a92..e106ca36f 100644 ---- a/daemons/lvmdbusd/lvm_shell_proxy.py.in -+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in -@@ -19,7 +19,6 @@ import sys - import tempfile - import time - import select --import copy - - try: - import simplejson as json -@@ -31,8 +30,6 @@ from lvmdbusd.cfg import LVM_CMD - from lvmdbusd.utils import log_debug, log_error, add_no_notify, make_non_block,\ - read_decoded - --SHELL_PROMPT = "lvm> " -- - - def _quote_arg(arg): - if len(shlex.split(arg)) > 1: -@@ -43,10 +40,11 @@ def _quote_arg(arg): - - class LVMShellProxy(object): - -- # Read until we get prompt back and a result -- # @param: no_output Caller expects no output to report FD -- # Returns stdout, report, stderr (report is JSON!) -- def _read_until_prompt(self, no_output=False): -+ # Read REPORT FD until we have a complete and valid JSON record or give -+ # up trying to get one. -+ # -+ # Returns stdout, report (JSON), stderr -+ def _read_response(self): - stdout = "" - report = "" - stderr = "" -@@ -58,6 +56,7 @@ class LVMShellProxy(object): - # Try reading from all FDs to prevent one from filling up and causing - # a hang. Keep reading until we get the prompt back and the report - # FD does not contain valid JSON -+ - while keep_reading: - try: - rd_fd = [ -@@ -78,32 +77,33 @@ class LVMShellProxy(object): - if self.lvm_shell.poll() is not None: - raise Exception(self.lvm_shell.returncode, "%s" % stderr) - -- if stdout.endswith(SHELL_PROMPT): -- if no_output: -- keep_reading = False -- else: -- cur_report_len = len(report) -- if cur_report_len != 0: -- # Only bother to parse if we have more data -- if prev_report_len != cur_report_len: -- prev_report_len = cur_report_len -- # Parse the JSON if it's good we are done, -- # if not we will try to read some more. -- try: -- report_json = json.loads(report) -- keep_reading = False -- except ValueError: -- pass -- -- if keep_reading: -- extra_passes -= 1 -- if extra_passes <= 0: -- if len(report): -- raise ValueError("Invalid json: %s" % -- report) -- else: -- raise ValueError( -- "lvm returned no JSON output!") -+ cur_report_len = len(report) -+ if cur_report_len != 0: -+ # Only bother to parse if we have more data and the last 2 characters match expected -+ # complete JSON, prevents excessive JSON parsing attempts -+ if prev_report_len != cur_report_len and report[-2:] == "}\n": -+ prev_report_len = cur_report_len -+ -+ # Parse the JSON if it's good we are done, -+ # if not we will try to read some more. -+ try: -+ report_json = json.loads(report) -+ keep_reading = False -+ except ValueError: -+ pass -+ -+ # As long as lvm is spewing something on one of the FDs we will -+ # keep trying. If we get a few timeouts with no activity, and -+ # we don't have valid JSON, we will raise an error. -+ if len(ready) == 0 and keep_reading: -+ extra_passes -= 1 -+ if extra_passes <= 0: -+ if len(report): -+ raise ValueError("Invalid json: %s" % -+ report) -+ else: -+ raise ValueError( -+ "lvm returned no JSON output!") - - except IOError as ioe: - log_debug(str(ioe)) -@@ -118,7 +118,6 @@ class LVMShellProxy(object): - self.lvm_shell.stdin.flush() - - def __init__(self): -- - # Create a temp directory - tmp_dir = tempfile.mkdtemp(prefix="lvmdbus_") - tmp_file = "%s/lvmdbus_report" % (tmp_dir) -@@ -139,6 +138,11 @@ class LVMShellProxy(object): - local_env = {"LC_ALL": "C", "LVM_REPORT_FD": "%s" % lvm_fd, "LVM_COMMAND_PROFILE": "lvmdbusd", - "LVM_LOG_FILE_MAX_LINES": "0"} - -+ # If any env variables contain LVM we will propagate them too -+ for k, v in os.environ.items(): -+ if "LVM" in k: -+ local_env[k] = v -+ - # run the lvm shell - self.lvm_shell = subprocess.Popen( - [LVM_CMD], -@@ -152,10 +156,9 @@ class LVMShellProxy(object): - # Close our copy of the lvm_fd, child process is open in its process space - os.close(lvm_fd) - -- # wait for the first prompt -- errors = self._read_until_prompt(no_output=True)[2] -- if errors and len(errors): -- raise RuntimeError(errors) -+ # Assume we are ready as we may not get the lvm prompt message depending on -+ # if we are using readline or editline. -+ - except: - raise - finally: -@@ -169,7 +172,7 @@ class LVMShellProxy(object): - self._write_cmd('lastlog\n') - - # read everything from the STDOUT to the next prompt -- stdout, report_json, stderr = self._read_until_prompt() -+ stdout, report_json, stderr = self._read_response() - if 'log' in report_json: - error_msg = "" - # Walk the entire log array and build an error string -@@ -203,7 +206,7 @@ class LVMShellProxy(object): - self._write_cmd(cmd) - - # read everything from the STDOUT to the next prompt -- stdout, report_json, stderr = self._read_until_prompt() -+ stdout, report_json, stderr = self._read_response() - - # Parse the report to see what happened - if 'log' in report_json: --- -2.37.1 - diff --git a/SPECS/lvm2.spec b/SPECS/lvm2.spec index 491af12..cad29ba 100644 --- a/SPECS/lvm2.spec +++ b/SPECS/lvm2.spec @@ -1,4 +1,4 @@ -%global device_mapper_version 1.02.185 +%global device_mapper_version 1.02.187 %global enable_cache 1 %global enable_cluster 1 @@ -49,7 +49,7 @@ %global commit 4a1f6173d29a7d7ecab14a9313000aa5f81170d0 %global shortcommit %(c=%{commit}; echo ${c:0:7}) %endif -#%%global rel_suffix .test +#%%global rel_suffix .bz2141837 # Do not reset Release to 1 unless both lvm2 and device-mapper # versions are increased together. @@ -58,12 +58,12 @@ Name: lvm2 %if 0%{?rhel} Epoch: %{rhel} %endif -Version: 2.03.16 +Version: 2.03.17 %if 0%{?from_snapshot} #Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix} -Release: 4%{?dist} +Release: 4%{?dist}%{?rel_suffix} %else -Release: 3%{?dist} +Release: 7%{?dist}%{?rel_suffix} %endif License: GPLv2 URL: http://sourceware.org/lvm2 @@ -72,25 +72,26 @@ Source0: lvm2-%{shortcommit}.tgz %else Source0: ftp://sourceware.org/pub/lvm2/releases/LVM2.%{version}.tgz %endif -Patch1: 0001-devices-file-move-clean-up-after-command-is-run.patch -Patch2: 0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch -Patch3: 0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch -Patch4: 0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch -Patch5: 0005-pvdisplay-restore-reportformat-option.patch -Patch6: 0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch -Patch7: 0007-make-generate.patch -# BZ 2109351: -Patch8: 0008-apply-multipath_component_detection-0-to-duplicate-P.patch -# BZ 2090391: -Patch9: 0009-lvmdbusd-Correct-conditional-for-lvm-child-process-r.patch -Patch10: 0010-lvmdbusd-Simplify-child-process-env.patch -Patch11: 0011-lvmdbusd-re-work-lvm-shell-main.patch -Patch12: 0012-lvmdbusd-Add-debug-output-for-which-lvm-binary-is-us.patch -Patch13: 0013-lvmdbusd-Change-unit-test-vdo-minimum-size.patch -Patch14: 0014-lvmdbusd-Fix-env-variable-LVM_DBUSD_TEST_MODE.patch -Patch15: 0015-lvmdbusd-Remove-the-use-of-sub-shell-for-lvm-shell.patch -Patch16: 0016-lvmdbusd-Job-prop.-Get-GetAll-exec.-immediately.patch -Patch17: 0017-lvmdbusd-Don-t-require-lvm-prompt-for-shell.patch +# BZ 2150348: +Patch1: 0001-device_id-fix-segfault-verifying-serial-for-non-pv.patch +# BZ 2151601: +Patch2: 0002-lvextend-fix-overprovisioning-check-for-thin-lvs.patch +# BZ 2157591: +Patch3: 0003-lvresize-fix-cryptsetup-resize-in-helper.patch +# BZ 2158619: +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 +# BZ 2164226: +Patch11: 0011-filesystem-use-PATH_MAX-for-linux-paths.patch BuildRequires: make BuildRequires: gcc @@ -162,12 +163,6 @@ or more physical volumes and creating one or more logical volumes %patch9 -p1 -b .backup9 %patch10 -p1 -b .backup10 %patch11 -p1 -b .backup11 -%patch12 -p1 -b .backup12 -%patch13 -p1 -b .backup13 -%patch14 -p1 -b .backup14 -%patch15 -p1 -b .backup15 -%patch16 -p1 -b .backup16 -%patch17 -p1 -b .backup17 %build %global _default_pid_dir /run @@ -232,14 +227,14 @@ or more physical volumes and creating one or more logical volumes --enable-editline \ --disable-readline -%make_build +V=1 %make_build %install -%make_install -make install_system_dirs DESTDIR=$RPM_BUILD_ROOT -make install_systemd_units DESTDIR=$RPM_BUILD_ROOT -make install_systemd_generators DESTDIR=$RPM_BUILD_ROOT -make install_tmpfiles_configuration DESTDIR=$RPM_BUILD_ROOT +V=1 %make_install +V=1 make install_system_dirs DESTDIR=$RPM_BUILD_ROOT +V=1 make install_systemd_units DESTDIR=$RPM_BUILD_ROOT +V=1 make install_systemd_generators DESTDIR=$RPM_BUILD_ROOT +V=1 make install_tmpfiles_configuration DESTDIR=$RPM_BUILD_ROOT %if %{enable_testsuite} %make_install -C test %endif @@ -345,6 +340,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_sbindir}/vgs %{_sbindir}/vgscan %{_sbindir}/vgsplit +%attr(755, -, -) %{_libexecdir}/lvresize_fs_helper %{_mandir}/man5/lvm.conf.5.gz %{_mandir}/man7/lvmautoactivation.7.gz %{_mandir}/man7/lvmcache.7.gz @@ -738,6 +734,32 @@ An extensive functional testsuite for LVM2. %endif %changelog +* Thu Feb 16 2023 Marian Csontos - 2.03.17-7 +- Fix segfault in previous build. + +* 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. + +* Fri Jan 06 2023 Marian Csontos - 2.03.17-4 +- Fix missing warning on thin pool over provisioning. +- Fix infinite recursion in lvresize_fs_helper when resizing LUKS device. + +* Tue Dec 06 2022 Marian Csontos - 2.03.17-3 +- Fix segfault during scanning PVs. + +* Tue Nov 29 2022 Marian Csontos - 2.03.17-2 +- Fix permissions on lvresize_fs_helper. + +* Thu Nov 10 2022 Marian Csontos - 2.03.17-1 +- Update to upstream version 2.03.17. +- See WHATS_NEW and WHATS_NEW_DM for more information. + * Fri Jul 29 2022 Marian Csontos - 2.03.16-3 - Fix effect of setting multipath_component_detection to 0. - Fix lvmdbusd using lvm shell with editline.