diff --git a/.gitignore b/.gitignore index d09d4a1..b3024ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/LVM2.2.03.23.tgz +SOURCES/LVM2.2.03.24.tgz diff --git a/.lvm2.metadata b/.lvm2.metadata index 290bc78..473d21d 100644 --- a/.lvm2.metadata +++ b/.lvm2.metadata @@ -1 +1 @@ -a14d56c852ed0b04a2d91550f0180bdbf853b23b SOURCES/LVM2.2.03.23.tgz +7c2dcac585dc89dbd0070216262a3a8446e7f222 SOURCES/LVM2.2.03.24.tgz diff --git a/SOURCES/0001-RHEL9.patch b/SOURCES/0001-RHEL9.patch new file mode 100644 index 0000000..dc1320a --- /dev/null +++ b/SOURCES/0001-RHEL9.patch @@ -0,0 +1,78 @@ +From 645992ca32dfd41b07997a97b2aef81563ad6f02 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 16 May 2024 12:12:06 +0200 +Subject: [PATCH 1/7] RHEL9 + +--- + VERSION | 2 +- + VERSION_DM | 2 +- + WHATS_NEW | 4 ++++ + WHATS_NEW_DM | 4 ++++ + doc/release-notes/2.03.24.mdwn | 8 ++------ + 5 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/VERSION b/VERSION +index c41928e80..794c58868 100644 +--- a/VERSION ++++ b/VERSION +@@ -1 +1 @@ +-2.03.24(2) (2024-05-16) ++2.03.24(2)-RHEL9 (2024-05-16) +diff --git a/VERSION_DM b/VERSION_DM +index 63629f72c..8dea6c328 100644 +--- a/VERSION_DM ++++ b/VERSION_DM +@@ -1 +1 @@ +-1.02.198 (2024-05-16) ++1.02.198-RHEL9 (2024-05-16) +diff --git a/WHATS_NEW b/WHATS_NEW +index 1c5f4b223..c7de3914a 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,3 +1,6 @@ ++Version 2.03.25 - ++================== ++ + Version 2.03.24 - 16th May 2024 + =============================== + Lvconvert supports VDO options for thin-pool with vdo conversion. +@@ -5450,3 +5453,4 @@ Display output. Some metadata information cannot yet be displayed. + Recovery tools to salvage "lost" metadata directly from the disks: + but we hope the new format will mean such tools are hardly ever needed! + ++ +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index b1508f08f..a2277c53b 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,3 +1,6 @@ ++Version 1.02.199 - ++=================== ++ + Version 1.02.198 - 16th May 2024 + ================================ + Fix static only compilation of libdevmapper.a and dmsetup tool. +@@ -1554,3 +1557,4 @@ Version 1.00.08 - 27 Feb 2004 + Updated README/INSTALL to reflect move to sources.redhat.com. + Updated autoconf files to 2003-06-17. + ++ +diff --git a/doc/release-notes/2.03.24.mdwn b/doc/release-notes/2.03.24.mdwn +index 71aa8add7..4d2c57497 100644 +--- a/doc/release-notes/2.03.24.mdwn ++++ b/doc/release-notes/2.03.24.mdwn +@@ -72,9 +72,5 @@ Also few more minor improvements: + + """]] + +- +-[[!tag draft pending]] +- ++[[!tag]] ++[[meta date="Thu May 16 12:12:06 2024 +0200"]] +-- +2.44.0 + diff --git a/SOURCES/0001-spec-Install-and-package-etc-lvm-devices.patch b/SOURCES/0001-spec-Install-and-package-etc-lvm-devices.patch deleted file mode 100644 index 1b0c5aa..0000000 --- a/SOURCES/0001-spec-Install-and-package-etc-lvm-devices.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 40b5a4dfa9a19997b931f88ff69a9bb9bb68ac3d Mon Sep 17 00:00:00 2001 -From: Marian Csontos -Date: Wed, 29 Nov 2023 15:09:36 +0100 -Subject: [PATCH 1/4] spec: Install and package /etc/lvm/devices - -(cherry picked from commit ee31ba5023e6e1430c0d808f54015ccd3eb3931a) ---- - Makefile.in | 1 + - spec/packages.inc | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/Makefile.in b/Makefile.in -index 41f249fdc..d30f6e7fd 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -127,6 +127,7 @@ all_man: - - install_system_dirs: - $(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR) -+ $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)/devices - $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR) - $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_BACKUP_DIR) - $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_CACHE_DIR) -diff --git a/spec/packages.inc b/spec/packages.inc -index cc1655ece..05733e0df 100644 ---- a/spec/packages.inc -+++ b/spec/packages.inc -@@ -182,6 +182,7 @@ fi - %dir %{_sysconfdir}/lvm/backup - %dir %{_sysconfdir}/lvm/cache - %dir %{_sysconfdir}/lvm/archive -+%dir %{_sysconfdir}/lvm/devices - %dir %{_default_locking_dir} - %dir %{_default_run_dir} - %if %{enable_systemd} --- -2.43.0 - diff --git a/SOURCES/0002-Revert-10-dm.rules-bump-DM_UDEV_RULES_VSN-to-3.patch b/SOURCES/0002-Revert-10-dm.rules-bump-DM_UDEV_RULES_VSN-to-3.patch new file mode 100644 index 0000000..acc02d1 --- /dev/null +++ b/SOURCES/0002-Revert-10-dm.rules-bump-DM_UDEV_RULES_VSN-to-3.patch @@ -0,0 +1,50 @@ +From d6b3f4f4dd526a5a4413e84f4cccb2e92699d1d8 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 16 May 2024 15:30:02 +0200 +Subject: [PATCH 2/7] Revert "10-dm.rules: bump DM_UDEV_RULES_VSN to 3" + +This reverts commit 038f9254d9554654197b59c160e3f775af27cdb1. +--- + udev/10-dm.rules.in | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in +index db4ee771d..ca255c793 100644 +--- a/udev/10-dm.rules.in ++++ b/udev/10-dm.rules.in +@@ -12,9 +12,6 @@ + # DM_NAME - actual DM device's name + # DM_UUID - UUID set for DM device (blank if not specified) + # DM_UDEV_RULES_VSN - DM udev rules version +-# DM_UDEV_DISABLE_OTHER_RULES_FLAG - a flag that indicates that +-# stacked layers shouldn't attempt to probe the device, and +-# should try to import relevant properties from the udev db. + # + # These rules cover only basic device-mapper functionality in udev. + # +@@ -25,11 +22,6 @@ + # 11-dm-lvm.rules for LVM subsystem + # 11-dm-mpath.rules for multipath subsystem (since version 0.6.0, recommended!) + # +-# 11-dm.rules may use other DM related properties besides +-# those listed above, like .DM_SUSPENDED. These properties are considered +-# internal to device mapper, and subject to change without notice. +-# Rules that are executed after 13-dm-disk.rules shouldn't use them. +-# + # Even more specific rules may be required by subsystems so always + # check subsystem's upstream repository for recent set of rules. + # Also, keep in mind that recent rules may also require recent +@@ -152,9 +144,7 @@ LABEL="dm_suspended_set" + # possible future changes. + # VSN 1 - original rules + # VSN 2 - add support for synthesized events +-# VSN 3 - use DM_UDEV_DISABLE_OTHER_RULES_FLAG as the only "API" +-# to be consumed by non-dm rules. +-ENV{DM_UDEV_RULES_VSN}="3" ++ENV{DM_UDEV_RULES_VSN}="2" + + ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="(DM_DIR)/$env{DM_NAME}" + +-- +2.44.0 + diff --git a/SOURCES/0002-man-add-inte-g-rity-to-man-lvs.patch b/SOURCES/0002-man-add-inte-g-rity-to-man-lvs.patch deleted file mode 100644 index 1566223..0000000 --- a/SOURCES/0002-man-add-inte-g-rity-to-man-lvs.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 2808b67d52123ec709e5a6d6c6780c8d325e708a Mon Sep 17 00:00:00 2001 -From: Lukas Herbolt -Date: Tue, 5 Dec 2023 09:08:24 -0600 -Subject: [PATCH 2/4] man: add inte(g)rity to man lvs - -(cherry picked from commit 7b64d9946d6a3be84338ad976383b6ab53e97484) ---- - man/lvs.8_end | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/man/lvs.8_end b/man/lvs.8_end -index dc3a27446..e9897b4fc 100644 ---- a/man/lvs.8_end -+++ b/man/lvs.8_end -@@ -4,7 +4,7 @@ - The lv_attr bits are: - .IP 1 3 - Volume type: (\fBC\fP)ache, (\fBm\fP)irrored, (\fBM\fP)irrored without initial sync, (\fBo\fP)rigin, --(\fBO\fP)rigin with merging snapshot, (\fBr\fP)aid, (\fBR\fP)aid without initial sync, -+(\fBO\fP)rigin with merging snapshot, inte(\fBg\fP)rity, (\fBr\fP)aid, (\fBR\fP)aid without initial sync, - (\fBs\fP)napshot, merging (\fBS\fP)napshot, (\fBp\fP)vmove, (\fBv\fP)irtual, - mirror or raid (\fBi\fP)mage, mirror or raid (\fBI\fP)mage out-of-sync, mirror (\fBl\fP)og device, - under (\fBc\fP)onversion, thin (\fBV\fP)olume, (\fBt\fP)hin pool, (\fBT\fP)hin pool data, --- -2.43.0 - diff --git a/SOURCES/0003-Revert-dm-udev-rules-don-t-export-and-save-DM_NOSCAN.patch b/SOURCES/0003-Revert-dm-udev-rules-don-t-export-and-save-DM_NOSCAN.patch new file mode 100644 index 0000000..af2a4bf --- /dev/null +++ b/SOURCES/0003-Revert-dm-udev-rules-don-t-export-and-save-DM_NOSCAN.patch @@ -0,0 +1,43 @@ +From da6319b9f5d263a210cf51b471fdbf1c343facf3 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 16 May 2024 15:30:15 +0200 +Subject: [PATCH 3/7] Revert "dm udev rules: don't export and save DM_NOSCAN" + +This reverts commit a196752969320cfc34a97cc97afa1978fa57da73. +--- + udev/11-dm-lvm.rules.in | 2 +- + udev/13-dm-disk.rules.in | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/udev/11-dm-lvm.rules.in b/udev/11-dm-lvm.rules.in +index cfc022489..5b0cc5242 100644 +--- a/udev/11-dm-lvm.rules.in ++++ b/udev/11-dm-lvm.rules.in +@@ -30,7 +30,7 @@ IMPORT{program}="(DM_EXEC)/dmsetup splitname --nameprefixes --noheadings --rows + # so those selected rules are surely skipped. + # We don't need to save and restore the previous of DM_UDEV_DISABLE_OTHER_RULES_FLAG, + # that's taken care of in 10-dm.rules. +-ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" + + ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end" + +diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in +index b53bb62de..b748cc909 100644 +--- a/udev/13-dm-disk.rules.in ++++ b/udev/13-dm-disk.rules.in +@@ -18,9 +18,9 @@ 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_import" +-ENV{.DM_NOSCAN}=="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" ++ENV{DM_NOSCAN}=="1", GOTO="dm_watch" + + (BLKID_RULE) + GOTO="dm_link" +-- +2.44.0 + diff --git a/SOURCES/0003-archiving-Fix-doubled-filename-in-vgcfgrestore.patch b/SOURCES/0003-archiving-Fix-doubled-filename-in-vgcfgrestore.patch deleted file mode 100644 index fdc19f9..0000000 --- a/SOURCES/0003-archiving-Fix-doubled-filename-in-vgcfgrestore.patch +++ /dev/null @@ -1,25 +0,0 @@ -From fdfd76a3ff1e2863fa11e79217bd2a4fa7ff527e Mon Sep 17 00:00:00 2001 -From: Ranjith ML -Date: Wed, 24 Jan 2024 14:05:24 +0100 -Subject: [PATCH 3/4] archiving: Fix doubled filename in vgcfgrestore - ---- - lib/format_text/archive.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/format_text/archive.c b/lib/format_text/archive.c -index 5acf0c04a..0e848cc8f 100644 ---- a/lib/format_text/archive.c -+++ b/lib/format_text/archive.c -@@ -313,7 +313,7 @@ static void _display_archive(struct cmd_context *cmd, const char *dir, struct ar - } - - log_print(" "); -- log_print("File:\t\t%s/%s", path, af->name); -+ log_print("File:\t\t%s", path); - tc.path_live = path; - - fic.type = FMT_INSTANCE_PRIVATE_MDAS; --- -2.43.0 - diff --git a/SOURCES/0004-Revert-dm-udev-rules-don-t-export-and-save-DM_SUSPEN.patch b/SOURCES/0004-Revert-dm-udev-rules-don-t-export-and-save-DM_SUSPEN.patch new file mode 100644 index 0000000..5ddaa67 --- /dev/null +++ b/SOURCES/0004-Revert-dm-udev-rules-don-t-export-and-save-DM_SUSPEN.patch @@ -0,0 +1,88 @@ +From 2e2303dd559fda3fb7d97f79094d04c3ccd9d519 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 16 May 2024 15:30:24 +0200 +Subject: [PATCH 4/7] Revert "dm udev rules: don't export and save + DM_SUSPENDED" + +This reverts commit 21ca92c4325b6b161fb1e1f10942ad9f8d23c144. +--- + udev/10-dm.rules.in | 14 ++++++-------- + udev/12-dm-permissions.rules | 1 + + udev/13-dm-disk.rules.in | 4 ++-- + 3 files changed, 9 insertions(+), 10 deletions(-) + +diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in +index ca255c793..29fe71527 100644 +--- a/udev/10-dm.rules.in ++++ b/udev/10-dm.rules.in +@@ -11,6 +11,7 @@ + # for use in later rules: + # DM_NAME - actual DM device's name + # DM_UUID - UUID set for DM device (blank if not specified) ++# DM_SUSPENDED - suspended state of DM device (0 or 1) + # DM_UDEV_RULES_VSN - DM udev rules version + # + # These rules cover only basic device-mapper functionality in udev. +@@ -122,18 +123,15 @@ LABEL="dm_no_coldplug" + # The "suspended" item was added even later (kernels >= 2.6.31), + # so we also have to call dmsetup if the kernel version used + # is in between these releases. +-TEST=="dm", ENV{DM_NAME}="$attr{dm/name}", ENV{DM_UUID}="$attr{dm/uuid}", ENV{.DM_SUSPENDED}="$attr{dm/suspended}" ++TEST=="dm", ENV{DM_NAME}="$attr{dm/name}", ENV{DM_UUID}="$attr{dm/uuid}", ENV{DM_SUSPENDED}="$attr{dm/suspended}" + TEST!="dm", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o name,uuid,suspended" ++ENV{DM_SUSPENDED}!="?*", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended" + +-ENV{.DM_SUSPENDED}=="?*", GOTO="dm_suspended_set" +-TEST=="dm", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended" + # dmsetup tool provides suspended state information in textual + # form with values "Suspended"/"Active". We translate it to + # 0/1 respectively to be consistent with sysfs values. +-ENV{DM_SUSPENDED}=="Active", ENV{.DM_SUSPENDED}="0" +-ENV{DM_SUSPENDED}=="Suspended", ENV{.DM_SUSPENDED}="1" +-ENV{DM_SUSPENDED}="" +-LABEL="dm_suspended_set" ++ENV{DM_SUSPENDED}=="Active", ENV{DM_SUSPENDED}="0" ++ENV{DM_SUSPENDED}=="Suspended", ENV{DM_SUSPENDED}="1" + + # This variable provides a reliable way to check that device-mapper + # rules were installed. It means that all needed variables are set +@@ -151,7 +149,7 @@ ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="(DM_DIR)/ + # Avoid processing and scanning a DM device in the other (foreign) + # rules if it is in suspended state. However, we still keep 'disk' + # and 'DM subsystem' related rules enabled in this case. +-ENV{.DM_SUSPENDED}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" + + GOTO="dm_end" + +diff --git a/udev/12-dm-permissions.rules b/udev/12-dm-permissions.rules +index 9624ddc5e..8d3bc224a 100644 +--- a/udev/12-dm-permissions.rules ++++ b/udev/12-dm-permissions.rules +@@ -14,6 +14,7 @@ + # DM_UDEV_RULES_VSN - DM udev rules version + # DM_NAME - actual DM device's name + # DM_UUID - UUID set for DM device (blank if not specified) ++# DM_SUSPENDED - suspended state of DM device (0 or 1) + # DM_LV_NAME - logical volume name (not set if LVM device not present) + # DM_VG_NAME - volume group name (not set if LVM device not present) + # DM_LV_LAYER - logical volume layer (not set if LVM device not present) +diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in +index b748cc909..183693bf1 100644 +--- a/udev/13-dm-disk.rules.in ++++ b/udev/13-dm-disk.rules.in +@@ -17,9 +17,9 @@ 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_import" ++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_SUSPENDED}=="1", GOTO="dm_end" + ENV{DM_NOSCAN}=="1", GOTO="dm_watch" + + (BLKID_RULE) +-- +2.44.0 + diff --git a/SOURCES/0004-raid-add-messages-to-lvs-command-output-in-case-Raid.patch b/SOURCES/0004-raid-add-messages-to-lvs-command-output-in-case-Raid.patch deleted file mode 100644 index ddfad72..0000000 --- a/SOURCES/0004-raid-add-messages-to-lvs-command-output-in-case-Raid.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 2e2e122eef2fe7781341a9574487c063cbd27a69 Mon Sep 17 00:00:00 2001 -From: Heinz Mauelshagen -Date: Wed, 6 Dec 2023 12:58:14 +0100 -Subject: [PATCH 4/4] raid: add messages to lvs command output in case RaidLVs - require a refresh - -If a RaidLV mapping is required to be refreshed as a result of temporarily failed -and recurred RAID leg device (pairs) caused by writes to the LV during failure, -the requirement is reported by volume health character r' in position 9 of the -LV's attribute field (see 'man lvs' about additional volume health characters). - -As this character can be overlooked, this patch adds messages to the top -of the lvs command output informing the user explicitely about the fact. - -(cherry picked from commit b69f73b13ee55ef3feb7427c6dc099dc3472d9fc) ---- - tools/reporter.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/tools/reporter.c b/tools/reporter.c -index 61af33af5..a28780298 100644 ---- a/tools/reporter.c -+++ b/tools/reporter.c -@@ -150,6 +150,13 @@ static int _check_merging_origin(const struct logical_volume *lv, - return 1; - } - -+static void _cond_warn_raid_volume_health(struct cmd_context *cmd, const struct logical_volume *lv) -+{ -+ if (lv_is_raid(lv) && !lv_raid_healthy(lv) && !lv_is_partial(lv)) -+ log_warn("WARNING: RaidLV %s needs to be refreshed! See character 'r' at position 9 in the RaidLV's attributes%s.", display_lvname(lv), -+ arg_is_set(cmd, all_ARG) ? " and its SubLV(s)" : " and also its SubLV(s) with option '-a'"); -+} -+ - static int _do_lvs_with_info_and_status_single(struct cmd_context *cmd, - const struct logical_volume *lv, - int do_info, int do_status, -@@ -176,6 +183,8 @@ static int _do_lvs_with_info_and_status_single(struct cmd_context *cmd, - lv = lv->snapshot->lv; - } - -+ _cond_warn_raid_volume_health(cmd, lv); -+ - if (!report_object(sh ? : handle->custom_handle, sh != NULL, - lv->vg, lv, NULL, NULL, NULL, &status, NULL)) - goto out; -@@ -238,6 +247,8 @@ static int _do_segs_with_info_and_status_single(struct cmd_context *cmd, - seg = seg->lv->snapshot; - } - -+ _cond_warn_raid_volume_health(cmd, seg->lv); -+ - if (!report_object(sh ? : handle->custom_handle, sh != NULL, - seg->lv->vg, seg->lv, NULL, seg, NULL, &status, NULL)) - goto_out; --- -2.43.0 - diff --git a/SOURCES/0005-Revert-11-dm-lvm.rules-don-t-restore-DM_UDEV_DISABLE.patch b/SOURCES/0005-Revert-11-dm-lvm.rules-don-t-restore-DM_UDEV_DISABLE.patch new file mode 100644 index 0000000..9c5ec97 --- /dev/null +++ b/SOURCES/0005-Revert-11-dm-lvm.rules-don-t-restore-DM_UDEV_DISABLE.patch @@ -0,0 +1,38 @@ +From cc3214c24425eb283dd46435345c28e5398b3570 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 16 May 2024 15:30:37 +0200 +Subject: [PATCH 5/7] Revert "11-dm-lvm.rules: don't restore + DM_UDEV_DISABLE_OTHER_RULES_FLAG from db" + +This reverts commit 2b2f11a74cd5cc05f266fd0c65f0e55eb8bafd9f. +--- + udev/11-dm-lvm.rules.in | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/udev/11-dm-lvm.rules.in b/udev/11-dm-lvm.rules.in +index 5b0cc5242..5f04ab329 100644 +--- a/udev/11-dm-lvm.rules.in ++++ b/udev/11-dm-lvm.rules.in +@@ -26,11 +26,14 @@ IMPORT{program}="(DM_EXEC)/dmsetup splitname --nameprefixes --noheadings --rows + # to zero any stale metadata found within the LV data area. Such stale + # metadata could cause false claim of the LV device, keeping it open etc. + # +-# If the NOSCAN flag is present, set DM_UDEV_DISABLE_OTHER_RULES_FLAG +-# so those selected rules are surely skipped. +-# We don't need to save and restore the previous of DM_UDEV_DISABLE_OTHER_RULES_FLAG, +-# that's taken care of in 10-dm.rules. +-ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++# If the NOSCAN flag is present, backup selected existing flags used to ++# disable rules, then set them firmly so those selected rules are surely skipped. ++# Restore these flags once the NOSCAN flag is dropped (which is normally any ++# uevent that follows for this LV, even an artificially generated one). ++ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_NOSCAN}="1", ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++ENV{DM_SUBSYSTEM_UDEV_FLAG0}!="1", IMPORT{db}="DM_NOSCAN", IMPORT{db}="DM_DISABLE_OTHER_RULES_FLAG_OLD" ++ENV{DM_SUBSYSTEM_UDEV_FLAG0}!="1", ENV{DM_NOSCAN}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}", \ ++ ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="", ENV{DM_NOSCAN}="" + + ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end" + +-- +2.44.0 + diff --git a/SOURCES/0006-Revert-10-dm-rules-don-t-restore-DM_UDEV_DISABLE_OTH.patch b/SOURCES/0006-Revert-10-dm-rules-don-t-restore-DM_UDEV_DISABLE_OTH.patch new file mode 100644 index 0000000..45a04ed --- /dev/null +++ b/SOURCES/0006-Revert-10-dm-rules-don-t-restore-DM_UDEV_DISABLE_OTH.patch @@ -0,0 +1,49 @@ +From 147498a07fd4e7dd0698b443bbcf15cfe6a6e104 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 16 May 2024 15:30:48 +0200 +Subject: [PATCH 6/7] Revert "10-dm-rules: don't restore + DM_UDEV_DISABLE_OTHER_RULES_FLAG from db" + +This reverts commit f98d020eadafe7d8db7bec1f5a26915615e5a6a9. +--- + udev/10-dm.rules.in | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in +index 29fe71527..2c6903da7 100644 +--- a/udev/10-dm.rules.in ++++ b/udev/10-dm.rules.in +@@ -53,14 +53,7 @@ OPTIONS+="db_persist" + # These flags are encoded in DM_COOKIE variable that was introduced in + # kernel version 2.6.31. Therefore, we can use this feature with + # kernels >= 2.6.31 only. Cookie is not decoded for remove event. +-ENV{DM_COOKIE}!="?*", GOTO="dm_no_cookie" +-IMPORT{program}="(DM_EXEC)/dmsetup udevflags $env{DM_COOKIE}" +- +-# Store the original flag from the cookie as DM_COOKIE_DISABLE_OTHER_RULES_FLAG +-# in the udev db. DM_UDEV_DISABLE_OTHER_RULES_FLAG will be or'd with other +-# conditions for use by upper, non-dm layers. +-ENV{DM_COOKIE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" +-LABEL="dm_no_cookie" ++ENV{DM_COOKIE}=="?*", IMPORT{program}="(DM_EXEC)/dmsetup udevflags $env{DM_COOKIE}" + + # There is no cookie set nor any flags encoded in events not originating + # in libdevmapper so we need to detect this and try to behave correctly. +@@ -70,13 +63,12 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}="1", GOTO="dm_flags_do + IMPORT{db}="DM_UDEV_DISABLE_DM_RULES_FLAG" + IMPORT{db}="DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG" + IMPORT{db}="DM_UDEV_DISABLE_DISK_RULES_FLAG" +-IMPORT{db}="DM_COOKIE_DISABLE_OTHER_RULES_FLAG" ++IMPORT{db}="DM_UDEV_DISABLE_OTHER_RULES_FLAG" + IMPORT{db}="DM_UDEV_LOW_PRIORITY_FLAG" + IMPORT{db}="DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG" + IMPORT{db}="DM_UDEV_PRIMARY_SOURCE_FLAG" + IMPORT{db}="DM_UDEV_FLAG7" + IMPORT{db}="DM_UDEV_RULES_VSN" +-ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_COOKIE_DISABLE_OTHER_RULES_FLAG}" + LABEL="dm_flags_done" + + # If DISK_RO is set, it's an uevent that changes the ro attribute of the device. +-- +2.44.0 + diff --git a/SOURCES/0007-WHATS_NEW-update.patch b/SOURCES/0007-WHATS_NEW-update.patch new file mode 100644 index 0000000..80bd4ef --- /dev/null +++ b/SOURCES/0007-WHATS_NEW-update.patch @@ -0,0 +1,38 @@ +From 7d1b418ad8efa0c059197238ea3fcbf3f659d909 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 16 May 2024 15:34:28 +0200 +Subject: [PATCH 7/7] WHATS_NEW: update + +--- + WHATS_NEW | 1 + + WHATS_NEW_DM | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/WHATS_NEW b/WHATS_NEW +index c7de3914a..1d56f8675 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.03.25 - + ================== ++ Revert Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it. + + Version 2.03.24 - 16th May 2024 + =============================== +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index a2277c53b..da8df6914 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,5 +1,9 @@ + Version 1.02.199 - + =================== ++ Revert Increase DM_UDEV_RULES_VSN to 3 to indicate changed udev rules. ++ Revert Rename DM_NOSCAN to .DM_NOSCAN so it's not stored in udev db. ++ Revert Rename DM_SUSPENDED to .DM_SUSPENDED so it's not stored in udev db. ++ Revert Do not import DM_UDEV_DISABLE_OTHER_RULES_FLAG from db in 10-dm-disk.rules. + + Version 1.02.198 - 16th May 2024 + ================================ +-- +2.44.0 + diff --git a/SOURCES/0008-Allow-system.devices-to-be-automatically-created-on-.patch b/SOURCES/0008-Allow-system.devices-to-be-automatically-created-on-.patch new file mode 100644 index 0000000..591ea34 --- /dev/null +++ b/SOURCES/0008-Allow-system.devices-to-be-automatically-created-on-.patch @@ -0,0 +1,578 @@ +From 16af82a5afe337cc3b0db3eaed0372e130b049ed Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 23 Apr 2024 17:08:26 -0500 +Subject: [PATCH 08/13] Allow system.devices to be automatically created on + first boot + +An OS installer can create system.devices for the system and +disks, but an OS image cannot create the system-specific +system.devices. The OS image can instead configure the +image so that lvm will create system.devices on first boot. + +Image preparation steps to enable auto creation of system.devices: +- create empty file /etc/lvm/devices/auto-import-rootvg +- remove any existing /etc/lvm/devices/system.devices +- enable lvm-devices-import.path +- enable lvm-devices-import.service + +On first boot of the prepared image: +- udev triggers vgchange -aay --autoactivation event +- vgchange activates LVs in the root VG +- vgchange finds the file /etc/lvm/devices/auto-import-rootvg, + and no /etc/lvm/devices/system.devices, so it creates + /run/lvm/lvm-devices-import +- lvm-devices-import.path is run when /run/lvm/lvm-devices-import + appears, and triggers lvm-devices-import.service +- lvm-devices-import.service runs vgimportdevices --rootvg --auto +- vgimportdevices finds /etc/lvm/devices/auto-import-rootvg, + and no system.devices, so it creates system.devices containing + PVs in the root VG, and removes /etc/lvm/devices/auto-import-rootvg + and /run/lvm/lvm-devices-import + +Run directly, vgimportdevices --rootvg (without --auto), will create +a new system.devices for the root VG, or will add devices for the +root VG to an existing system.devices. + +(cherry picked from commit c609dedc2f035f770b5f645c4695924abf15c2ca) +(cherry picked from commit 3321a669d8f2df99df9d6dcd4ebb2b4d30731c7a) +--- + lib/commands/toolcontext.h | 1 + + lib/config/defaults.h | 2 + + lib/device/device_id.c | 5 +- + scripts/lvm-devices-import.path | 12 +++ + scripts/lvm-devices-import.service | 12 +++ + tools/args.h | 11 ++ + tools/command-lines.in | 5 + + tools/pvscan.c | 4 +- + tools/tools.h | 2 +- + tools/vgchange.c | 155 ++++++++++++++++++++++++++++- + tools/vgimportdevices.c | 114 ++++++++++++++++++++- + 11 files changed, 315 insertions(+), 8 deletions(-) + create mode 100644 scripts/lvm-devices-import.path + create mode 100644 scripts/lvm-devices-import.service + +diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h +index fec0a52cf..043afbf76 100644 +--- a/lib/commands/toolcontext.h ++++ b/lib/commands/toolcontext.h +@@ -217,6 +217,7 @@ struct cmd_context { + unsigned device_ids_check_hostname:1; + unsigned device_ids_refresh_trigger:1; + unsigned device_ids_invalid:1; ++ unsigned device_ids_auto_import:1; + unsigned get_vgname_from_options:1; /* used by lvconvert */ + + /* +diff --git a/lib/config/defaults.h b/lib/config/defaults.h +index ed0c4f404..efe36d1fa 100644 +--- a/lib/config/defaults.h ++++ b/lib/config/defaults.h +@@ -337,6 +337,8 @@ + #define VGS_ONLINE_DIR DEFAULT_RUN_DIR "/vgs_online" + #define PVS_LOOKUP_DIR DEFAULT_RUN_DIR "/pvs_lookup" + ++#define DEVICES_IMPORT_PATH DEFAULT_RUN_DIR "/lvm-devices-import" ++ + #define DEFAULT_DEVICE_ID_SYSFS_DIR "/sys/" /* trailing / to match dm_sysfs_dir() */ + + #define DEFAULT_DEVICESFILE_BACKUP_LIMIT 50 +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 2b183810a..1ce7927ed 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -1726,9 +1726,10 @@ int device_ids_write(struct cmd_context *cmd) + + if ((fc_bytes = snprintf(fc, sizeof(fc), + "# LVM uses devices listed in this file.\n" \ +- "# Created by LVM command %s pid %d at %s" \ ++ "# Created by LVM command %s%s pid %d at %s" \ + "# HASH=%u\n", +- cmd->name, getpid(), ctime(&t), hash)) < 0) { ++ cmd->name, cmd->device_ids_auto_import ? " (auto)" : "", ++ getpid(), ctime(&t), hash)) < 0) { + log_error("Failed to write buffer for devices file content."); + goto out; + } +diff --git a/scripts/lvm-devices-import.path b/scripts/lvm-devices-import.path +new file mode 100644 +index 000000000..bcf0dcd4c +--- /dev/null ++++ b/scripts/lvm-devices-import.path +@@ -0,0 +1,12 @@ ++[Unit] ++Description=lvm-devices-import to create system.devices ++ ++# /run/lvm/lvm-devices-import created by vgchange -aay ++ ++[Path] ++PathExists=/run/lvm/lvm-devices-import ++Unit=lvm-devices-import.service ++ConditionPathExists=!/etc/lvm/devices/system.devices ++ ++[Install] ++WantedBy=multi-user.target +diff --git a/scripts/lvm-devices-import.service b/scripts/lvm-devices-import.service +new file mode 100644 +index 000000000..9d3bda2ee +--- /dev/null ++++ b/scripts/lvm-devices-import.service +@@ -0,0 +1,12 @@ ++[Unit] ++Description=Create lvm system.devices ++ ++[Service] ++Type=oneshot ++RemainAfterExit=no ++ExecStart=/usr/sbin/vgimportdevices --rootvg --auto ++ConditionPathExists=!/etc/lvm/devices/system.devices ++ ++[Install] ++WantedBy=multi-user.target ++ +diff --git a/tools/args.h b/tools/args.h +index 09b2ad551..ed0fb9620 100644 +--- a/tools/args.h ++++ b/tools/args.h +@@ -94,6 +94,14 @@ arg(atversion_ARG, '\0', "atversion", string_VAL, 0, 0, + "which does not contain any newer settings for which LVM would\n" + "issue a warning message when checking the configuration.\n") + ++arg(auto_ARG, '\0', "auto", 0, 0, 0, ++ "This option is used when automatically importing devices for the root VG.\n" ++ "The auto import is intended to be done once, on first boot, to create an\n" ++ "initial system.devices file for the root VG.\n" ++ "When this option is used, the vgimportdevices --rootvg command does nothing\n" ++ "if system.devices exists, or the file auto-import-rootvg does not exist\n" ++ "(both in the /etc/lvm/devices/ directory.)\n") ++ + arg(autoactivation_ARG, '\0', "autoactivation", string_VAL, 0, 0, + "Specify if autoactivation is being used from an event.\n" + "This allows the command to apply settings that are specific\n" +@@ -754,6 +762,9 @@ arg(resync_ARG, '\0', "resync", 0, 0, 0, + "which the LV is without a complete redundant copy of the data.\n" + "See \\fBlvmraid\\fP(7) for more information.\n") + ++arg(rootvg_ARG, '\0', "rootvg", 0, 0, 0, ++ "Import devices used for the root VG.\n") ++ + arg(rows_ARG, '\0', "rows", 0, 0, 0, + "Output columns as rows.\n") + +diff --git a/tools/command-lines.in b/tools/command-lines.in +index 1c728afa0..3ad5d3c46 100644 +--- a/tools/command-lines.in ++++ b/tools/command-lines.in +@@ -1911,6 +1911,11 @@ OO: --foreign, --reportformat ReportFmt + ID: vgimportdevices_all + DESC: Add devices from all accessible VGs to the devices file. + ++vgimportdevices --rootvg ++OO: --auto, --reportformat ReportFmt ++ID: vgimportdevices_root ++DESC: Add devices from root VG to the devices file. ++ + --- + + vgmerge VG VG +diff --git a/tools/pvscan.c b/tools/pvscan.c +index f88e1b751..0a9cb59df 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -495,7 +495,7 @@ static int _pvscan_aa_single(struct cmd_context *cmd, const char *vg_name, + + log_debug("pvscan autoactivating VG %s.", vg_name); + +- if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1)) { ++ if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1, NULL)) { + log_error_pvscan(cmd, "%s: autoactivation failed.", vg->name); + pp->activate_errors++; + } +@@ -755,7 +755,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp + + log_debug("pvscan autoactivating VG %s.", vgname); + +- if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1)) { ++ if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1, NULL)) { + log_error_pvscan(cmd, "%s: autoactivation failed.", vg->name); + pp->activate_errors++; + } +diff --git a/tools/tools.h b/tools/tools.h +index f4a0c94d7..58708c695 100644 +--- a/tools/tools.h ++++ b/tools/tools.h +@@ -164,7 +164,7 @@ int mirror_remove_missing(struct cmd_context *cmd, + + + int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg, +- activation_change_t activate, int vg_complete_to_activate); ++ activation_change_t activate, int vg_complete_to_activate, char *root_dm_uuid); + + int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg); + +diff --git a/tools/vgchange.c b/tools/vgchange.c +index 378ded16e..2004d6e92 100644 +--- a/tools/vgchange.c ++++ b/tools/vgchange.c +@@ -16,11 +16,14 @@ + #include "tools.h" + #include "lib/device/device_id.h" + #include "lib/label/hints.h" ++#include "device_mapper/misc/dm-ioctl.h" ++#include + + struct vgchange_params { + int lock_start_count; + unsigned int lock_start_sanlock : 1; + unsigned int vg_complete_to_activate : 1; ++ char *root_dm_uuid; /* dm uuid of LV under root fs */ + }; + + /* +@@ -197,7 +200,7 @@ int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg + } + + int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg, +- activation_change_t activate, int vg_complete_to_activate) ++ activation_change_t activate, int vg_complete_to_activate, char *root_dm_uuid) + { + int lv_open, active, monitored = 0, r = 1; + const struct lv_list *lvl; +@@ -279,6 +282,43 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg, + r = 0; + } + ++ /* ++ * Possibly trigger auto-generation of system.devices: ++ * - if root_dm_uuid contains vg->id, and ++ * - /etc/lvm/devices/auto-import-rootvg exists, and ++ * - /etc/lvm/devices/system.devices does not exist, then ++ * - create /run/lvm/lvm-devices-import to ++ * trigger lvm-devices-import.path and .service ++ * - lvm-devices-import will run vgimportdevices --rootvg ++ * to create system.devices ++ */ ++ if (root_dm_uuid) { ++ char path[PATH_MAX]; ++ struct stat info; ++ FILE *fp; ++ ++ if (memcmp(root_dm_uuid + 4, &vg->id, ID_LEN)) ++ goto out; ++ ++ if (cmd->enable_devices_file || devices_file_exists(cmd)) ++ goto out; ++ ++ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0) ++ goto out; ++ ++ if (stat(path, &info) < 0) ++ goto out; ++ ++ log_debug("Found %s creating %s", path, DEVICES_IMPORT_PATH); ++ ++ if (!(fp = fopen(DEVICES_IMPORT_PATH, "w"))) { ++ log_debug("failed to create %s", DEVICES_IMPORT_PATH); ++ goto out; ++ } ++ if (fclose(fp)) ++ stack; ++ } ++out: + /* Print message only if there was not found a missing VG */ + log_print_unless_silent("%d logical volume(s) in volume group \"%s\" now active", + lvs_in_vg_activated(vg), vg->name); +@@ -714,7 +754,7 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name, + + if (arg_is_set(cmd, activate_ARG)) { + activate = (activation_change_t) arg_uint_value(cmd, activate_ARG, 0); +- if (!vgchange_activate(cmd, vg, activate, vp->vg_complete_to_activate)) ++ if (!vgchange_activate(cmd, vg, activate, vp->vg_complete_to_activate, vp->root_dm_uuid)) + return_ECMD_FAILED; + } else if (arg_is_set(cmd, refresh_ARG)) { + /* refreshes the visible LVs (which starts polling) */ +@@ -735,6 +775,115 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name, + return ret; + } + ++/* ++ * Automatic creation of system.devices for root VG on first boot ++ * is useful for OS images where the OS installer is not used to ++ * customize the OS for system. ++ * ++ * - OS image prep: ++ * . rm /etc/lvm/devices/system.devices (if it exists) ++ * . touch /etc/lvm/devices/auto-import-rootvg ++ * . enable lvm-devices-import.path ++ * . enable lvm-devices-import.service ++ * ++ * - lvchange -ay / ++ * . run by initrd so root fs can be mounted ++ * . does not use system.devices ++ * . named / comes from kernel command line rd.lvm ++ * . uses first device that appears containing the named root LV ++ * ++ * - vgchange -aay ++ * . triggered by udev when all PVs from root VG are online ++ * . activate LVs in root VG (in addition to the already active root LV) ++ * . check for /etc/lvm/devices/auto-import-rootvg (found) ++ * . check for /etc/lvm/devices/system.devices (not found) ++ * . create /run/lvm/lvm-devices-import because ++ * auto-import-rootvg was found and system.devices was not found ++ * ++ * - lvm-devices-import.path ++ * . triggered by /run/lvm/lvm-devices-import ++ * . start lvm-devices-import.service ++ * ++ * - lvm-devices-import.service ++ * . check for /etc/lvm/devices/system.devices, do nothing if found ++ * . run vgimportdevices --rootvg --auto ++ * ++ * - vgimportdevices --rootvg --auto ++ * . check for /etc/lvm/devices/auto-import-rootvg (found) ++ * . check for /etc/lvm/devices/system.devices (not found) ++ * . creates /etc/lvm/devices/system.devices for PVs in root VG ++ * . removes /etc/lvm/devices/auto-import-rootvg ++ * . removes /run/lvm/lvm-devices-import ++ * ++ * On future startup, /etc/lvm/devices/system.devices will exist, ++ * and /etc/lvm/devices/auto-import-rootvg will not exist, so ++ * vgchange -aay will not create /run/lvm/lvm-devices-import, ++ * and lvm-devices-import.path and lvm-device-import.service will not run. ++ * ++ * lvm-devices-import.path: ++ * [Path] ++ * PathExists=/run/lvm/lvm-devices-import ++ * Unit=lvm-devices-import.service ++ * ConditionPathExists=!/etc/lvm/devices/system.devices ++ * ++ * lvm-devices-import.service: ++ * [Service] ++ * Type=oneshot ++ * RemainAfterExit=no ++ * ExecStart=/usr/sbin/vgimportdevices --rootvg --auto ++ * ConditionPathExists=!/etc/lvm/devices/system.devices ++ */ ++ ++static void _get_rootvg_dev(struct cmd_context *cmd, char **dm_uuid_out) ++{ ++ char path[PATH_MAX]; ++ char dm_uuid[DM_UUID_LEN]; ++ struct stat info; ++ FILE *fme = NULL; ++ struct mntent *me; ++ int found = 0; ++ ++ if (cmd->enable_devices_file || devices_file_exists(cmd)) ++ return; ++ ++ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0) ++ return; ++ ++ if (stat(path, &info) < 0) ++ return; ++ ++ if (!(fme = setmntent("/etc/mtab", "r"))) ++ return; ++ ++ while ((me = getmntent(fme))) { ++ if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) { ++ found = 1; ++ break; ++ } ++ } ++ endmntent(fme); ++ ++ if (!found) ++ return; ++ ++ if (stat(me->mnt_dir, &info) < 0) ++ return; ++ ++ if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), (int)MAJOR(info.st_dev), (int)MINOR(info.st_dev))) ++ return; ++ ++ log_debug("Found root dm_uuid %s", dm_uuid); ++ ++ /* UUID_PREFIX = "LVM-" */ ++ if (strncmp(dm_uuid, UUID_PREFIX, 4)) ++ return; ++ ++ if (strlen(dm_uuid) < 4 + ID_LEN) ++ return; ++ ++ *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid); ++} ++ + static int _vgchange_autoactivation_setup(struct cmd_context *cmd, + struct vgchange_params *vp, + int *skip_command, +@@ -778,6 +927,8 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd, + + get_single_vgname_cmd_arg(cmd, NULL, &vgname); + ++ _get_rootvg_dev(cmd, &vp->root_dm_uuid); ++ + /* + * Lock the VG before scanning the PVs so _vg_read can avoid the normal + * lock_vol+rescan (READ_WITHOUT_LOCK avoids the normal lock_vol and +diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c +index bccd94f61..70d12e500 100644 +--- a/tools/vgimportdevices.c ++++ b/tools/vgimportdevices.c +@@ -15,11 +15,16 @@ + #include "tools.h" + #include "lib/cache/lvmcache.h" + #include "lib/device/device_id.h" ++#include "device_mapper/misc/dm-ioctl.h" + /* coverity[unnecessary_header] needed for MuslC */ + #include ++#include + + struct vgimportdevices_params { + uint32_t added_devices; ++ int root_vg_found; ++ char *root_dm_uuid; ++ char *root_vg_name; + }; + + static int _vgimportdevices_single(struct cmd_context *cmd, +@@ -35,6 +40,13 @@ static int _vgimportdevices_single(struct cmd_context *cmd, + int updated_pvs = 0; + const char *idtypestr = NULL; /* deviceidtype_ARG ? */ + ++ if (vp->root_dm_uuid) { ++ if (memcmp(vp->root_dm_uuid + 4, &vg->id, ID_LEN)) ++ return ECMD_PROCESSED; ++ vp->root_vg_found = 1; ++ vp->root_vg_name = dm_pool_strdup(cmd->mem, vg_name); ++ } ++ + dm_list_iterate_items(pvl, &vg->pvs) { + if (is_missing_pv(pvl->pv) || !pvl->pv->dev) { + memcpy(pvid, &pvl->pv->id.uuid, ID_LEN); +@@ -86,6 +98,87 @@ static int _vgimportdevices_single(struct cmd_context *cmd, + return ECMD_PROCESSED; + } + ++static int _get_rootvg_dev(struct cmd_context *cmd, char **dm_uuid_out, int *skip) ++{ ++ char path[PATH_MAX]; ++ char dm_uuid[DM_UUID_LEN]; ++ struct stat info; ++ FILE *fme = NULL; ++ struct mntent *me; ++ int found = 0; ++ ++ /* ++ * When --auto is set, the command does nothing ++ * if /etc/lvm/devices/system.devices exists, or ++ * if /etc/lvm/devices/auto-import-rootvg does not exist. ++ */ ++ if (arg_is_set(cmd, auto_ARG)) { ++ if (devices_file_exists(cmd)) { ++ *skip = 1; ++ return 1; ++ } ++ ++ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0) ++ return_0; ++ ++ if (stat(path, &info) < 0) { ++ *skip = 1; ++ return 1; ++ } ++ ++ /* ++ * This flag is just used in device_ids_write to enable ++ * an extra comment in system.devices indicating that ++ * the file was auto generated for the root vg. ++ */ ++ cmd->device_ids_auto_import = 1; ++ } ++ ++ if (!(fme = setmntent("/etc/mtab", "r"))) ++ return_0; ++ ++ while ((me = getmntent(fme))) { ++ if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) { ++ found = 1; ++ break; ++ } ++ } ++ endmntent(fme); ++ ++ if (!found) ++ return_0; ++ ++ if (stat(me->mnt_dir, &info) < 0) ++ return_0; ++ ++ if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), (int)MAJOR(info.st_dev), (int)MINOR(info.st_dev))) ++ return_0; ++ ++ /* UUID_PREFIX = "LVM-" */ ++ if (strncmp(dm_uuid, UUID_PREFIX, 4)) ++ return_0; ++ ++ if (strlen(dm_uuid) < 4 + ID_LEN) ++ return_0; ++ ++ *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid); ++ return 1; ++} ++ ++static void _clear_rootvg_auto(struct cmd_context *cmd) ++{ ++ char path[PATH_MAX]; ++ ++ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0) ++ return; ++ ++ if (unlink(path) < 0) ++ log_debug("Failed to unlink %s", path); ++ ++ if (unlink(DEVICES_IMPORT_PATH) < 0) ++ log_debug("Failed to unlink %s", DEVICES_IMPORT_PATH); ++} ++ + /* + * This command always scans all devices on the system, + * any pre-existing devices_file does not limit the scope. +@@ -130,6 +223,19 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + /* So that we can warn about this. */ + cmd->handles_missing_pvs = 1; + ++ /* Import devices for the root VG. */ ++ if (arg_is_set(cmd, rootvg_ARG)) { ++ int skip = 0; ++ if (!_get_rootvg_dev(cmd, &vp.root_dm_uuid, &skip)) { ++ log_error("Failed to find root VG."); ++ return ECMD_FAILED; ++ } ++ if (skip) { ++ log_print("Root VG auto import is not enabled."); ++ return ECMD_PROCESSED; ++ } ++ } ++ + if (!lock_global(cmd, "ex")) + return ECMD_FAILED; + +@@ -230,7 +336,13 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + goto out; + } + +- log_print("Added %u devices to devices file.", vp.added_devices); ++ if (vp.root_vg_found) ++ log_print("Added %u devices to devices file for root VG %s.", vp.added_devices, vp.root_vg_name); ++ else ++ log_print("Added %u devices to devices file.", vp.added_devices); ++ ++ if (vp.root_vg_found && arg_is_set(cmd, auto_ARG)) ++ _clear_rootvg_auto(cmd); + out: + if ((ret == ECMD_FAILED) && created_file) + if (unlink(cmd->devices_file_path) < 0) +-- +2.45.2 + diff --git a/SOURCES/0009-lvm-fix-shell-completion.patch b/SOURCES/0009-lvm-fix-shell-completion.patch new file mode 100644 index 0000000..a2451e2 --- /dev/null +++ b/SOURCES/0009-lvm-fix-shell-completion.patch @@ -0,0 +1,60 @@ +From fe58f4b87a2cd85f132775a2e475c128b89e7eb4 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 24 May 2024 19:49:08 +0200 +Subject: [PATCH 09/13] lvm: fix shell completion + +Previous commit 82617852a4d3c89b09124eddedcc2c1859b9d50e +introduce bug in complession - as the rl_completion_matches() +needs to always advance to next element where the index +is held in static variable. + +Add comment about this usage. + +(cherry picked from commit 73298635b9db2c2a11bc4cc291b15d0f21907598) +(cherry picked from commit c33b0e11878a52aeaa42b4ebfd0692e5da7f5e07) +--- + tools/lvm.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/tools/lvm.c b/tools/lvm.c +index 116b707b2..3a7e6dc6c 100644 +--- a/tools/lvm.c ++++ b/tools/lvm.c +@@ -52,7 +52,8 @@ static char *_list_cmds(const char *text, int state) + + for (;i < _cmdline->num_command_names;++i) + if (!strncmp(text, _cmdline->command_names[i].name, len)) +- return strdup(_cmdline->command_names[i].name); ++ /* increase position for next iteration */ ++ return strdup(_cmdline->command_names[i++].name); + + return NULL; + } +@@ -102,9 +103,10 @@ static char *_list_args(const char *text, int state) + + /* Short form arguments */ + if (len < 3) { +- for (;match_no < cna->num_args; ++match_no) { ++ while (match_no < cna->num_args) { + char s[3]; +- char c = (_cmdline->opt_names + cna->valid_args[match_no])->short_opt; ++ /* increase position for next iteration */ ++ char c = _cmdline->opt_names[cna->valid_args[match_no++]].short_opt; + if (c) { + sprintf(s, "-%c", c); + if (!strncmp(text, s, len)) +@@ -117,8 +119,9 @@ static char *_list_args(const char *text, int state) + if (match_no < cna->num_args) + match_no = cna->num_args; + +- for (;match_no - cna->num_args < cna->num_args; ++match_no) { +- const char *l = (_cmdline->opt_names + cna->valid_args[match_no - cna->num_args])->long_opt; ++ while ((match_no - cna->num_args) < cna->num_args) { ++ /* increase position for next iteration */ ++ const char *l = _cmdline->opt_names[cna->valid_args[match_no++ - cna->num_args]].long_opt; + if (*(l + 2) && !strncmp(text, l, len)) + return strdup(l); + } +-- +2.45.2 + diff --git a/SOURCES/0010-vgimportdevices-skip-global-lockd-locking.patch b/SOURCES/0010-vgimportdevices-skip-global-lockd-locking.patch new file mode 100644 index 0000000..a0663a4 --- /dev/null +++ b/SOURCES/0010-vgimportdevices-skip-global-lockd-locking.patch @@ -0,0 +1,31 @@ +From 4b33a5a3999fa443dfe5e124e8bd984a936ac77c Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 30 May 2024 14:51:22 -0500 +Subject: [PATCH 10/13] vgimportdevices: skip global lockd locking + +Fix commit b65a2c3f3a767 "vgimportdevices: skip lvmlockd locking" +which intended to disable lvmlockd locking, but the lockd_gl_disable +flag was mistakenly set after lock_global() so it wasn't effective. +This caused vgimportdevices to fail unless locking was started. + +(cherry picked from commit a8b8e1f074598d080bfb34e1fd04fe36ec122f93) +--- + tools/vgimportdevices.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c +index 70d12e500..2217fdad6 100644 +--- a/tools/vgimportdevices.c ++++ b/tools/vgimportdevices.c +@@ -236,7 +236,7 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + } + } + +- if (!lock_global(cmd, "ex")) ++ if (!lockf_global(cmd, "ex")) + return ECMD_FAILED; + + /* +-- +2.45.2 + diff --git a/SOURCES/0011-scripts-Install-services-for-devices-file-init.patch b/SOURCES/0011-scripts-Install-services-for-devices-file-init.patch new file mode 100644 index 0000000..5fb4449 --- /dev/null +++ b/SOURCES/0011-scripts-Install-services-for-devices-file-init.patch @@ -0,0 +1,43 @@ +From d94090dae6e20135f0e9ba8ca0a645f2e3470a48 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Wed, 26 Jun 2024 14:37:17 +0200 +Subject: [PATCH 11/13] scripts: Install services for devices file init + +Services introduced in commit c609dedc2f035f770b5f645c4695924abf15c2ca +need installing. + +(cherry picked from commit 1b9bf5007bbfba5bcd622f039a099e6f7e0a8162) +--- + scripts/Makefile.in | 2 ++ + spec/packages.inc | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/scripts/Makefile.in b/scripts/Makefile.in +index a79edbd4d..f683b7ab1 100644 +--- a/scripts/Makefile.in ++++ b/scripts/Makefile.in +@@ -108,6 +108,8 @@ endif + ifeq ("@BUILD_LVMDBUSD@", "yes") + $(Q) $(INSTALL_DATA) lvm2_lvmdbusd_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmdbusd.service + endif ++ $(Q) $(INSTALL_DATA) lvm-devices-import.path $(systemd_unit_dir)/lvm-devices-import.path ++ $(Q) $(INSTALL_DATA) lvm-devices-import.service $(systemd_unit_dir)/lvm-devices-import.service + + ifeq ("@BUILD_LVMDBUSD@", "yes") + install_dbus_service: +diff --git a/spec/packages.inc b/spec/packages.inc +index 05733e0df..ee67af590 100644 +--- a/spec/packages.inc ++++ b/spec/packages.inc +@@ -193,6 +193,8 @@ fi + %{_unitdir}/lvm2-lvmpolld.service + %{_unitdir}/lvm2-lvmpolld.socket + %endif ++ %{_unitdir}/lvm-devices-import.service ++ %{_unitdir}/lvm-devices-import.path + %else + %{_sysconfdir}/rc.d/init.d/blk-availability + %{_sysconfdir}/rc.d/init.d/lvm2-monitor +-- +2.45.2 + diff --git a/SOURCES/0012-lvmlockd-avoid-lockd_vg-for-local-VGs.patch b/SOURCES/0012-lvmlockd-avoid-lockd_vg-for-local-VGs.patch new file mode 100644 index 0000000..c84a2be --- /dev/null +++ b/SOURCES/0012-lvmlockd-avoid-lockd_vg-for-local-VGs.patch @@ -0,0 +1,330 @@ +From 0bb9ae53db66a2455b9655d16166877cd2c3f4c0 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 12 Jun 2024 15:36:45 -0500 +Subject: [PATCH 12/13] lvmlockd: avoid lockd_vg for local VGs + +Previously, a command would call lockd_vg() for a local VG, +which would go to lvmlockd, which would send back ENOLS, +and the command would not care when it saw the VG was local. +The pointless back-and-forth to lvmlockd for local VGs can +be avoided by checking the VG lock_type in lvmcache (which +label_scan now saves there; this wasn't the case back when +the original lockd_vg logic was added.) If the lock_type +saved during label_scan indicates a local VG, then the +lockd_vg step is skipped. + +(cherry picked from commit bf60cb4da23cac2f6b721170dd0d8bfd38b16466) +--- + lib/cache/lvmcache.c | 10 +++++++++ + lib/cache/lvmcache.h | 2 ++ + lib/locking/lvmlockd.c | 12 ++++++++--- + tools/lvconvert.c | 8 ++++--- + tools/polldaemon.c | 9 +++++--- + tools/toollib.c | 47 +++++++++++++++++++++++++++++++++++------- + 6 files changed, 71 insertions(+), 17 deletions(-) + +diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c +index 711a97fec..1ea4cb7db 100644 +--- a/lib/cache/lvmcache.c ++++ b/lib/cache/lvmcache.c +@@ -3002,6 +3002,16 @@ int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const ch + return ret; + } + ++int lvmcache_vg_is_lockd_type(struct cmd_context *cmd, const char *vgname, const char *vgid) ++{ ++ struct lvmcache_vginfo *vginfo; ++ ++ if ((vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) ++ return is_lockd_type(vginfo->lock_type); ++ ++ return 0; ++} ++ + /* + * Example of reading four devs in sequence from the same VG: + * +diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h +index eccf29eb2..760ff6ba1 100644 +--- a/lib/cache/lvmcache.h ++++ b/lib/cache/lvmcache.h +@@ -179,6 +179,8 @@ void lvmcache_get_max_name_lengths(struct cmd_context *cmd, + + int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid); + ++int lvmcache_vg_is_lockd_type(struct cmd_context *cmd, const char *vgname, const char *vgid); ++ + bool lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid); + + int lvmcache_vginfo_has_pvid(struct lvmcache_vginfo *vginfo, const char *pvid_arg); +diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c +index 9c24b619f..33150cb48 100644 +--- a/lib/locking/lvmlockd.c ++++ b/lib/locking/lvmlockd.c +@@ -2014,9 +2014,15 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode) + * this result is passed into vg_read(). After vg_read() reads the VG, + * it checks if the VG lock_type (sanlock or dlm) requires a lock to be + * held, and if so, it verifies that the lock was correctly acquired by +- * looking at lockd_state. If vg_read() sees that the VG is a local VG, +- * i.e. lock_type is not sanlock or dlm, then no lock is required, and it +- * ignores lockd_state (which would indicate no lock was found.) ++ * looking at lockd_state. ++ * ++ * If vg_read() sees that the VG is a local VG, i.e. lock_type is not ++ * sanlock or dlm, then no lock is required, and it ignores lockd_state, ++ * which would indicate no lock was found.... although a newer ++ * optimization avoids calling lockd_vg() at all for local VGs ++ * by checking the lock_type in lvmcache saved by label_scan. In extremely ++ * rare case where the lock_type changes between label_scan and vg_read, ++ * the caller will go back and repeat lockd_vg()+vg_read(). + */ + + int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, +diff --git a/tools/lvconvert.c b/tools/lvconvert.c +index dd40ef4f5..4e551a949 100644 +--- a/tools/lvconvert.c ++++ b/tools/lvconvert.c +@@ -5788,10 +5788,12 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd, + struct logical_volume *lv_fast; + uint32_t lockd_state, error_flags; + uint64_t dirty; ++ int is_lockd; + int ret = 0; + + idl = dm_list_item(dm_list_first(&lr->poll_idls), struct convert_poll_id_list); + id = idl->id; ++ is_lockd = lvmcache_vg_is_lockd_type(cmd, id->vg_name, NULL); + + /* + * TODO: we should be able to save info about the dm device for this LV +@@ -5806,7 +5808,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd, + lockd_state = 0; + error_flags = 0; + +- if (!lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) { ++ if (is_lockd && !lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) { + log_error("Detaching writecache interrupted - locking VG failed."); + return 0; + } +@@ -5843,7 +5845,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd, + if (!lv_writecache_is_clean(cmd, lv, &dirty)) { + unlock_and_release_vg(cmd, vg, vg->name); + +- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) ++ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) + stack; + + log_print_unless_silent("Detaching writecache cleaning %llu blocks", (unsigned long long)dirty); +@@ -5896,7 +5898,7 @@ out_release: + unlock_and_release_vg(cmd, vg, vg->name); + + out_lockd: +- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) ++ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) + stack; + + return ret; +diff --git a/tools/polldaemon.c b/tools/polldaemon.c +index 730dfbcbb..3a9211768 100644 +--- a/tools/polldaemon.c ++++ b/tools/polldaemon.c +@@ -156,6 +156,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id, + int finished = 0; + uint32_t lockd_state = 0; + uint32_t error_flags = 0; ++ int is_lockd; + int ret; + unsigned wait_before_testing = parms->wait_before_testing; + +@@ -171,11 +172,13 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id, + return 0; + } + ++ is_lockd = lvmcache_vg_is_lockd_type(cmd, id->vg_name, NULL); ++ + /* + * An ex VG lock is needed because the check can call finish_copy + * which writes the VG. + */ +- if (!lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) { ++ if (is_lockd && !lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) { + log_error("ABORTING: Can't lock VG for %s.", id->display_name); + return 0; + } +@@ -229,7 +232,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id, + + unlock_and_release_vg(cmd, vg, vg->name); + +- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) ++ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) + stack; + + wait_before_testing = 1; +@@ -240,7 +243,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id, + out: + if (vg) + unlock_and_release_vg(cmd, vg, vg->name); +- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) ++ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) + stack; + + return ret; +diff --git a/tools/toollib.c b/tools/toollib.c +index 080ee5429..686a5423c 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -2176,6 +2176,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, + int ret; + int skip; + int notfound; ++ int is_lockd; + int process_all = 0; + int do_report_ret_code = 1; + +@@ -2195,6 +2196,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, + vg_uuid = vgnl->vgid; + skip = 0; + notfound = 0; ++ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid); + + uuid[0] = '\0'; + if (is_orphan_vg(vg_name)) { +@@ -2212,8 +2214,8 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, + } + + log_very_verbose("Processing VG %s %s", vg_name, uuid); +- +- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { ++do_lockd: ++ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { + stack; + ret_max = ECMD_FAILED; + report_log_ret_code(ret_max); +@@ -2235,6 +2237,14 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, + if (skip || notfound) + goto endvg; + ++ if (!is_lockd && vg_is_shared(vg)) { ++ /* The lock_type changed since label_scan, won't really occur in practice. */ ++ log_debug("Repeat lock and read for local to shared vg"); ++ unlock_and_release_vg(cmd, vg, vg_name); ++ is_lockd = 1; ++ goto do_lockd; ++ } ++ + /* Process this VG? */ + if ((process_all || + (!dm_list_empty(arg_vgnames) && str_list_match_item(arg_vgnames, vg_name)) || +@@ -2255,7 +2265,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, + unlock_vg(cmd, vg, vg_name); + endvg: + release_vg(vg); +- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) ++ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) + stack; + + log_set_report_object_name_and_id(NULL, NULL); +@@ -3873,6 +3883,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag + int ret; + int skip; + int notfound; ++ int is_lockd; + int do_report_ret_code = 1; + + log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG); +@@ -3882,6 +3893,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag + vg_uuid = vgnl->vgid; + skip = 0; + notfound = 0; ++ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid); + + uuid[0] = '\0'; + if (vg_uuid && !id_write_format((const struct id*)vg_uuid, uuid, sizeof(uuid))) +@@ -3927,7 +3939,8 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag + + log_very_verbose("Processing VG %s %s", vg_name, vg_uuid ? uuid : ""); + +- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { ++do_lockd: ++ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { + ret_max = ECMD_FAILED; + report_log_ret_code(ret_max); + continue; +@@ -3948,6 +3961,14 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag + if (skip || notfound) + goto endvg; + ++ if (!is_lockd && vg_is_shared(vg)) { ++ /* The lock_type changed since label_scan, won't really occur in practice. */ ++ log_debug("Repeat lock and read for local to shared vg"); ++ unlock_and_release_vg(cmd, vg, vg_name); ++ is_lockd = 1; ++ goto do_lockd; ++ } ++ + ret = process_each_lv_in_vg(cmd, vg, &lvnames, tags_arg, 0, + handle, check_single_lv, process_single_lv); + if (ret != ECMD_PROCESSED) +@@ -3959,7 +3980,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag + unlock_vg(cmd, vg, vg_name); + endvg: + release_vg(vg); +- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) ++ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) + stack; + log_set_report_object_name_and_id(NULL, NULL); + } +@@ -4513,6 +4534,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags, + int ret; + int skip; + int notfound; ++ int is_lockd; + int do_report_ret_code = 1; + + log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG); +@@ -4522,6 +4544,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags, + vg_uuid = vgnl->vgid; + skip = 0; + notfound = 0; ++ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid); + + uuid[0] = '\0'; + if (is_orphan_vg(vg_name)) { +@@ -4537,8 +4560,8 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags, + ret_max = ECMD_FAILED; + goto_out; + } +- +- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { ++do_lockd: ++ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { + ret_max = ECMD_FAILED; + report_log_ret_code(ret_max); + continue; +@@ -4561,6 +4584,14 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags, + if (notfound) + goto endvg; + ++ if (vg && !is_lockd && vg_is_shared(vg)) { ++ /* The lock_type changed since label_scan, won't really occur in practice. */ ++ log_debug("Repeat lock and read for local to shared vg"); ++ unlock_and_release_vg(cmd, vg, vg_name); ++ is_lockd = 1; ++ goto do_lockd; ++ } ++ + /* + * Don't call "continue" when skip is set, because we need to remove + * error_vg->pvs entries from devices list. +@@ -4583,7 +4614,7 @@ endvg: + if (error_vg) + unlock_and_release_vg(cmd, error_vg, vg_name); + release_vg(vg); +- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) ++ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) + stack; + + /* Quit early when possible. */ +-- +2.45.2 + diff --git a/SOURCES/0013-lvmlockd-allow-forced-vgchange-locktype-from-none.patch b/SOURCES/0013-lvmlockd-allow-forced-vgchange-locktype-from-none.patch new file mode 100644 index 0000000..a32aca1 --- /dev/null +++ b/SOURCES/0013-lvmlockd-allow-forced-vgchange-locktype-from-none.patch @@ -0,0 +1,86 @@ +From a6dec74334d5b4c3d0774d8b120930dd6e008844 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 13 Jun 2024 13:34:23 -0500 +Subject: [PATCH 13/13] lvmlockd: allow forced vgchange locktype from none + +vgchange --locktype sanlock|dlm --lockopt force +can be used to change the lock type without lvmlockd or +the lock manager involved. + +(cherry picked from commit 4dc009c87227a137c8be50686b1104cebb9a88e2) +--- + man/lvmlockd.8_main | 5 +++++ + tools/vgchange.c | 17 +++++++++-------- + 2 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/man/lvmlockd.8_main b/man/lvmlockd.8_main +index ea967d73d..38f9d958d 100644 +--- a/man/lvmlockd.8_main ++++ b/man/lvmlockd.8_main +@@ -729,6 +729,11 @@ vgchange --locktype sanlock|dlm + Start the VG on hosts to use it: + .br + vgchange --lockstart ++.P ++If lvmlockd or the cluster manager are not available, the lock type can ++be forcibly changed with: ++.br ++vgchange --locktype sanlock|dlm \-\-lockopt force + . + .SS Changing a shared VG to a local VG + . +diff --git a/tools/vgchange.c b/tools/vgchange.c +index 2004d6e92..94c1feb8f 100644 +--- a/tools/vgchange.c ++++ b/tools/vgchange.c +@@ -1176,7 +1176,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv) + return ret; + } + +-static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg) ++static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg, int *no_change) + { + const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL); + const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL); +@@ -1206,6 +1206,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg) + if (lock_type && !strcmp(vg->lock_type, lock_type)) { + log_warn("WARNING: New lock type %s matches the current lock type %s.", + lock_type, vg->lock_type); ++ *no_change = 1; + return 1; + } + +@@ -1344,9 +1345,14 @@ static int _vgchange_locktype_single(struct cmd_context *cmd, const char *vg_nam + struct volume_group *vg, + struct processing_handle *handle) + { +- if (!_vgchange_locktype(cmd, vg)) ++ int no_change = 0; ++ ++ if (!_vgchange_locktype(cmd, vg, &no_change)) + return_ECMD_FAILED; + ++ if (no_change) ++ return ECMD_PROCESSED; ++ + if (!vg_write(vg) || !vg_commit(vg)) + return_ECMD_FAILED; + +@@ -1402,13 +1408,8 @@ int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv) + * just return success when they see the disable flag set. + */ + if (lockopt && !strcmp(lockopt, "force")) { +- if (lock_type && strcmp(lock_type, "none")) { +- log_error("Lock type can only be forced to \"none\" for recovery."); +- return 0; +- } +- + if (!arg_is_set(cmd, yes_ARG) && +- yes_no_prompt("Forcibly change VG lock type to none? [y/n]: ") == 'n') { ++ yes_no_prompt("Forcibly change VG lock type to %s? [y/n]: ", lock_type) == 'n') { + log_error("VG lock type not changed."); + return 0; + } +-- +2.45.2 + diff --git a/SOURCES/0014-lv_manip-avoid-unreleased-memory-pool-s-message-on-R.patch b/SOURCES/0014-lv_manip-avoid-unreleased-memory-pool-s-message-on-R.patch new file mode 100644 index 0000000..be31103 --- /dev/null +++ b/SOURCES/0014-lv_manip-avoid-unreleased-memory-pool-s-message-on-R.patch @@ -0,0 +1,60 @@ +From a5672ff088a027af04dc5586926841a48b693ee0 Mon Sep 17 00:00:00 2001 +From: Heinz Mauelshagen +Date: Wed, 17 Jul 2024 17:08:20 +0200 +Subject: [PATCH 14/14] lv_manip: avoid unreleased memory pool(s) message on + RAID extend + +In case of different PV sizes in a VG, the lvm2 allocator falls short +to define extended segments resiliently asked for 100%FREE RaidLV extension +and a RAID distinct allocation check fails. Fix is to release a memory pool +on the resulting error path. + +Until the lvm2 allocator gets enhanced (WIP) to do such complex (and other) +allocations proper, a workaround is to extend a RaidLV to any free space on +its already allocated PVs by defining those PVs on the lvextend command line +then iteratively run further such lvextend commands to extend it to its +final intended size. Mind, this may be a non-trivial extension interation. + +(cherry picked from commit 557b2850cef7fa49e2cbacd36e77f679181f09ae) +--- + WHATS_NEW | 5 +++++ + lib/metadata/lv_manip.c | 3 ++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 1d56f8675..8647a8f87 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,3 +1,8 @@ ++Version 2.03.26 - ++================== ++ Fix unreleased memory pools on RAID's lvextend. ++ ++ + Version 2.03.25 - + ================== + Revert Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it. +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index bec363ef8..871d3bec9 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -4415,6 +4415,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah, + log_error("Failed to remove LV"); + else if (!vg_write(vg) || !vg_commit(vg)) + log_error("Failed to commit VG %s", vg->name); ++ dm_pool_free(vg->vgmem, lvl); + return_0; + } + +@@ -4571,7 +4572,7 @@ int lv_extend(struct logical_volume *lv, + alloc != ALLOC_ANYWHERE && + !(r = _lv_raid_redundant_allocation(lv, allocatable_pvs))) { + log_error("Insufficient suitable allocatable extents for logical volume %s", display_lvname(lv)); +- if (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg)) ++ if (!old_extents && (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg))) + return_0; + goto out; + } +-- +2.45.2 + diff --git a/SPECS/lvm2.spec b/SPECS/lvm2.spec index 2aa13e0..8a21a15 100644 --- a/SPECS/lvm2.spec +++ b/SPECS/lvm2.spec @@ -1,4 +1,4 @@ -%global device_mapper_version 1.02.197 +%global device_mapper_version 1.02.198 %global enable_cache 1 %global enable_lvmdbusd 1 @@ -50,7 +50,7 @@ Name: lvm2 %if 0%{?rhel} Epoch: %{rhel} %endif -Version: 2.03.23 +Version: 2.03.24 %if 0%{?from_snapshot} Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix} %else @@ -63,13 +63,20 @@ Source0: lvm2-%{shortcommit}.tgz %else Source0: https://sourceware.org/pub/lvm2/releases/LVM2.%{version}.tgz %endif -Patch1: 0001-spec-Install-and-package-etc-lvm-devices.patch -# RHEL-14216: -Patch2: 0002-man-add-inte-g-rity-to-man-lvs.patch -# RHEL-20192: -Patch3: 0003-archiving-Fix-doubled-filename-in-vgcfgrestore.patch -# RHEL-8270: -Patch4: 0004-raid-add-messages-to-lvs-command-output-in-case-Raid.patch +Patch1: 0001-RHEL9.patch +Patch2: 0002-Revert-10-dm.rules-bump-DM_UDEV_RULES_VSN-to-3.patch +Patch3: 0003-Revert-dm-udev-rules-don-t-export-and-save-DM_NOSCAN.patch +Patch4: 0004-Revert-dm-udev-rules-don-t-export-and-save-DM_SUSPEN.patch +Patch5: 0005-Revert-11-dm-lvm.rules-don-t-restore-DM_UDEV_DISABLE.patch +Patch6: 0006-Revert-10-dm-rules-don-t-restore-DM_UDEV_DISABLE_OTH.patch +Patch7: 0007-WHATS_NEW-update.patch +Patch8: 0008-Allow-system.devices-to-be-automatically-created-on-.patch +Patch9: 0009-lvm-fix-shell-completion.patch +Patch10: 0010-vgimportdevices-skip-global-lockd-locking.patch +Patch11: 0011-scripts-Install-services-for-devices-file-init.patch +Patch12: 0012-lvmlockd-avoid-lockd_vg-for-local-VGs.patch +Patch13: 0013-lvmlockd-allow-forced-vgchange-locktype-from-none.patch +Patch14: 0014-lv_manip-avoid-unreleased-memory-pool-s-message-on-R.patch BuildRequires: make BuildRequires: gcc @@ -399,6 +406,8 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_unitdir}/lvm2-lvmpolld.socket %{_unitdir}/lvm2-lvmpolld.service %endif +%{_unitdir}/lvm-devices-import.service +%{_unitdir}/lvm-devices-import.path ############################################################################## # Library and Development subpackages @@ -698,6 +707,13 @@ An extensive functional testsuite for LVM2. %endif %changelog +* Wed Aug 07 2024 Marian Csontos - 2.03.24-2 +- Fix unreleased memory pools on RAID's lvextend. + +* Wed Jul 10 2024 Marian Csontos - 2.03.24-1 +- Update to upstream version 2.03.24. +- See WHATS_NEW and WHATS_NEW_DM for more information. + * Fri Feb 02 2024 Marian Csontos - 2.03.23-2 - Add warning message when mirror images have (r)efresh bit set. - Document lv_attr volume type bit (g) for raid+integrity in lvs(8).