From 14d381d8bb49112cb0c030677572b5f710ba1bbb Mon Sep 17 00:00:00 2001 From: eabdullin Date: Mon, 15 Sep 2025 12:22:00 +0000 Subject: [PATCH] import CS lvm2-2.03.32-2.el9 --- .gitignore | 2 +- .lvm2.metadata | 2 +- SOURCES/0001-RHEL9.patch | 18 +- ...dm.rules-bump-DM_UDEV_RULES_VSN-to-3.patch | 6 +- ...ules-don-t-export-and-save-DM_NOSCAN.patch | 12 +- ...ules-don-t-export-and-save-DM_SUSPEN.patch | 14 +- ....rules-don-t-restore-DM_UDEV_DISABLE.patch | 6 +- ...es-don-t-restore-DM_UDEV_DISABLE_OTH.patch | 6 +- SOURCES/0007-WHATS_NEW-update.patch | 27 - SOURCES/0007-WHATS_NEW_DM-update.patch | 30 + ...ipe-count-and-size-validation-for-RA.patch | 104 --- ...vmlockd-fix-hosts-check-for-vgremove.patch | 143 ++++ ...-same-param-validation-for-RAID-0-as.patch | 30 - ...ckd-fix-sanlock_release-for-vgremove.patch | 38 + ...-or-clear-transiently-failed-devices.patch | 460 ++++++++++ ...erfluous-a-option-for-df-used-in-lvr.patch | 31 - SOURCES/0011-WHATS_NEW-update.patch | 26 - ...lvconvert-allow-clearing-superblocks.patch | 64 ++ ...-test-check-raid-superblock-clearing.patch | 107 +++ ...-fix-input-units-for-minimim_io_size.patch | 59 -- SOURCES/0013-man-update-raid-man.patch | 50 ++ ...0013-tests-check-vdo-minimum_io_size.patch | 33 - SOURCES/0014-WHATS_NEW-update.patch | 25 + SOURCES/0014-raid-fix-name-rotation.patch | 62 -- ...sts-check-_tdata-conversion-to-raid1.patch | 28 - SOURCES/0016-WHATS_NEW-update.patch | 24 - ...nvme-devices-may-use-alternate-wwids.patch | 805 ------------------ ...configure.ac-add-support-for-libnvme.patch | 121 --- SOURCES/0019-configure-autoreconf.patch | 271 ------ ...in-deactivate-converted-volume-early.patch | 52 -- ...ts-check-conversion-of-in-use-volume.patch | 51 -- SOURCES/0022-WHATS_NEW-update.patch | 25 - ...s-resize-is-supported-before-LV-exte.patch | 176 ---- ...esize-xfs-tests-for-recent-lvextend-.patch | 65 -- SOURCES/0025-WHATS_NEW-update.patch | 24 - ...mlock-check-for-proper-reserved-size.patch | 42 - SOURCES/0027-WHATS_NEW-update.patch | 23 - ...escanning-DM-cache-after-taking-lock.patch | 60 -- ...-vg_read-matching-missed-empty-cache.patch | 44 - ...rrect-error-path-for-DM-cache-update.patch | 35 - SPECS/lvm2.spec | 53 +- 41 files changed, 971 insertions(+), 2283 deletions(-) delete mode 100644 SOURCES/0007-WHATS_NEW-update.patch create mode 100644 SOURCES/0007-WHATS_NEW_DM-update.patch delete mode 100644 SOURCES/0008-lv_manip-fix-stripe-count-and-size-validation-for-RA.patch create mode 100644 SOURCES/0008-lvmlockd-fix-hosts-check-for-vgremove.patch delete mode 100644 SOURCES/0009-lv_manip-use-the-same-param-validation-for-RAID-0-as.patch create mode 100644 SOURCES/0009-lvmlockd-fix-sanlock_release-for-vgremove.patch create mode 100644 SOURCES/0010-raid-count-or-clear-transiently-failed-devices.patch delete mode 100644 SOURCES/0010-tests-remove-superfluous-a-option-for-df-used-in-lvr.patch delete mode 100644 SOURCES/0011-WHATS_NEW-update.patch create mode 100644 SOURCES/0011-lvconvert-allow-clearing-superblocks.patch create mode 100644 SOURCES/0012-test-check-raid-superblock-clearing.patch delete mode 100644 SOURCES/0012-vdo-fix-input-units-for-minimim_io_size.patch create mode 100644 SOURCES/0013-man-update-raid-man.patch delete mode 100644 SOURCES/0013-tests-check-vdo-minimum_io_size.patch create mode 100644 SOURCES/0014-WHATS_NEW-update.patch delete mode 100644 SOURCES/0014-raid-fix-name-rotation.patch delete mode 100644 SOURCES/0015-tests-check-_tdata-conversion-to-raid1.patch delete mode 100644 SOURCES/0016-WHATS_NEW-update.patch delete mode 100644 SOURCES/0017-device_id-nvme-devices-may-use-alternate-wwids.patch delete mode 100644 SOURCES/0018-configure.ac-add-support-for-libnvme.patch delete mode 100644 SOURCES/0019-configure-autoreconf.patch delete mode 100644 SOURCES/0020-thin-deactivate-converted-volume-early.patch delete mode 100644 SOURCES/0021-tests-check-conversion-of-in-use-volume.patch delete mode 100644 SOURCES/0022-WHATS_NEW-update.patch delete mode 100644 SOURCES/0023-lv_manip-check-fs-resize-is-supported-before-LV-exte.patch delete mode 100644 SOURCES/0024-tests-adjust-lvresize-xfs-tests-for-recent-lvextend-.patch delete mode 100644 SOURCES/0025-WHATS_NEW-update.patch delete mode 100644 SOURCES/0026-memlock-check-for-proper-reserved-size.patch delete mode 100644 SOURCES/0027-WHATS_NEW-update.patch delete mode 100644 SOURCES/0028-vg_read-rescanning-DM-cache-after-taking-lock.patch delete mode 100644 SOURCES/0029-vg_read-matching-missed-empty-cache.patch delete mode 100644 SOURCES/0030-vg_read-correct-error-path-for-DM-cache-update.patch diff --git a/.gitignore b/.gitignore index 10143cf..026dd67 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/LVM2.2.03.28.tgz +SOURCES/LVM2.2.03.32.tgz diff --git a/.lvm2.metadata b/.lvm2.metadata index 3d42021..cd0e57f 100644 --- a/.lvm2.metadata +++ b/.lvm2.metadata @@ -1 +1 @@ -762d6924860a01973ca61543208d97ef385be1f6 SOURCES/LVM2.2.03.28.tgz +6b0df2dddc2ee883380969362f5e5d1e89a6960d SOURCES/LVM2.2.03.32.tgz diff --git a/SOURCES/0001-RHEL9.patch b/SOURCES/0001-RHEL9.patch index 265c402..5f7775c 100644 --- a/SOURCES/0001-RHEL9.patch +++ b/SOURCES/0001-RHEL9.patch @@ -1,7 +1,7 @@ -From 4ed40e67197778b28e4b822558614a517242e3e1 Mon Sep 17 00:00:00 2001 +From 4487d3c0b4e9e1bbb966a40876b2e481b90865a8 Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 3 Oct 2024 16:14:11 +0200 -Subject: [PATCH 01/13] RHEL9 +Subject: [PATCH 1/7] RHEL9 --- VERSION | 2 +- @@ -9,19 +9,19 @@ Subject: [PATCH 01/13] RHEL9 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION -index 7619e491b..f96b435a3 100644 +index e1934c88c..e4e055d17 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ --2.03.28(2) (2024-11-04) -+2.03.28(2)-RHEL9 (2024-11-04) +-2.03.32(2) (2025-05-05) ++2.03.32(2)-RHEL9 (2025-05-05) diff --git a/VERSION_DM b/VERSION_DM -index 16d64d69d..cd0c694ae 100644 +index 9016990a1..ea3811ba7 100644 --- a/VERSION_DM +++ b/VERSION_DM @@ -1 +1 @@ --1.02.202 (2024-11-04) -+1.02.202-RHEL9 (2024-11-04) +-1.02.206 (2025-05-05) ++1.02.206-RHEL9 (2025-05-05) -- -2.47.0 +2.49.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 index ad74ed9..18a326b 100644 --- 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 @@ -1,7 +1,7 @@ -From 290f2740efee0f9a3f6b9f84c277e0d4e81927db Mon Sep 17 00:00:00 2001 +From 408a80fdd46d3854c92dfce1bff3a376aea611d1 Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:02 +0200 -Subject: [PATCH 02/13] Revert "10-dm.rules: bump DM_UDEV_RULES_VSN to 3" +Subject: [PATCH 2/7] Revert "10-dm.rules: bump DM_UDEV_RULES_VSN to 3" This reverts commit 038f9254d9554654197b59c160e3f775af27cdb1. --- @@ -46,5 +46,5 @@ index db4ee771d..ca255c793 100644 ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="(DM_DIR)/$env{DM_NAME}" -- -2.47.0 +2.49.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 index cabb59b..b359940 100644 --- 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 @@ -1,7 +1,7 @@ -From 57fa9b840028112e9e455c960dad5bd595625428 Mon Sep 17 00:00:00 2001 +From 6a15577cb02603512afce0f13a591183105c8f73 Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:15 +0200 -Subject: [PATCH 03/13] Revert "dm udev rules: don't export and save DM_NOSCAN" +Subject: [PATCH 3/7] Revert "dm udev rules: don't export and save DM_NOSCAN" This reverts commit a196752969320cfc34a97cc97afa1978fa57da73. --- @@ -23,11 +23,11 @@ index 8b8d0561f..6dd556aa9 100644 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 03ea203ee..96f1efc00 100644 +index 9bfeebe13..a9ad67e9f 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}" +@@ -20,9 +20,9 @@ ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}" + ENV{DISKSEQ}=="?*", SYMLINK+="disk/by-diskseq/$env{DISKSEQ}" 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" @@ -39,5 +39,5 @@ index 03ea203ee..96f1efc00 100644 (BLKID_RULE) GOTO="dm_link" -- -2.47.0 +2.49.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 index f94cb2b..a52af49 100644 --- 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 @@ -1,7 +1,7 @@ -From 885113b30d7873ac671490715312431f706d26e8 Mon Sep 17 00:00:00 2001 +From 2280f85310b82c03b43dfd88e0712c5921a36ffc Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:24 +0200 -Subject: [PATCH 04/13] Revert "dm udev rules: don't export and save +Subject: [PATCH 4/7] Revert "dm udev rules: don't export and save DM_SUSPENDED" This reverts commit 21ca92c4325b6b161fb1e1f10942ad9f8d23c144. @@ -68,12 +68,12 @@ index 9624ddc5e..8d3bc224a 100644 # 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 96f1efc00..3e1eaa6ee 100644 +index a9ad67e9f..e136ee441 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}" +@@ -19,9 +19,9 @@ ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}" + + ENV{DISKSEQ}=="?*", SYMLINK+="disk/by-diskseq/$env{DISKSEQ}" -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" @@ -84,5 +84,5 @@ index 96f1efc00..3e1eaa6ee 100644 (BLKID_RULE) -- -2.47.0 +2.49.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 index cde324e..1e56f78 100644 --- 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 @@ -1,7 +1,7 @@ -From 89058bc0687baec653df87f14fd25da32577cc6d Mon Sep 17 00:00:00 2001 +From 4316c786f25f8b01b831458f8baf1f77faad79ba Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:37 +0200 -Subject: [PATCH 05/13] Revert "11-dm-lvm.rules: don't restore +Subject: [PATCH 5/7] Revert "11-dm-lvm.rules: don't restore DM_UDEV_DISABLE_OTHER_RULES_FLAG from db" This reverts commit 2b2f11a74cd5cc05f266fd0c65f0e55eb8bafd9f. @@ -34,5 +34,5 @@ index 6dd556aa9..9836f41ca 100644 ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end" -- -2.47.0 +2.49.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 index 9edf4a0..8f4a6c0 100644 --- 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 @@ -1,7 +1,7 @@ -From cccc336a97ce85cf68ec7a80390c42dae243621b Mon Sep 17 00:00:00 2001 +From ebd5feaca2779c9379a14ba6f74a47214d03d94b Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:48 +0200 -Subject: [PATCH 06/13] Revert "10-dm-rules: don't restore +Subject: [PATCH 6/7] Revert "10-dm-rules: don't restore DM_UDEV_DISABLE_OTHER_RULES_FLAG from db" This reverts commit f98d020eadafe7d8db7bec1f5a26915615e5a6a9. @@ -45,5 +45,5 @@ index 29fe71527..2c6903da7 100644 # If DISK_RO is set, it's an uevent that changes the ro attribute of the device. -- -2.47.0 +2.49.0 diff --git a/SOURCES/0007-WHATS_NEW-update.patch b/SOURCES/0007-WHATS_NEW-update.patch deleted file mode 100644 index 5f251c9..0000000 --- a/SOURCES/0007-WHATS_NEW-update.patch +++ /dev/null @@ -1,27 +0,0 @@ -From e6f8d9855336dbf1cbf212f60b84a03946365795 Mon Sep 17 00:00:00 2001 -From: Marian Csontos -Date: Thu, 16 May 2024 15:34:28 +0200 -Subject: [PATCH 07/13] WHATS_NEW: update - ---- - WHATS_NEW_DM | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM -index f8ca946d6..74b356bf2 100644 ---- a/WHATS_NEW_DM -+++ b/WHATS_NEW_DM -@@ -1,3 +1,10 @@ -+Version 1.02.203 - -+===================================== -+ 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.202 - 04th November 2024 - ===================================== - Introduce dm_config_parse_only_section to stop parsing after section. --- -2.47.0 - diff --git a/SOURCES/0007-WHATS_NEW_DM-update.patch b/SOURCES/0007-WHATS_NEW_DM-update.patch new file mode 100644 index 0000000..6207b18 --- /dev/null +++ b/SOURCES/0007-WHATS_NEW_DM-update.patch @@ -0,0 +1,30 @@ +From 72f203a02d7f30d5afdaa853a082b2b1d1f56297 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Mon, 5 May 2025 17:36:05 +0200 +Subject: [PATCH 7/7] WHATS_NEW_DM: update + +--- + WHATS_NEW_DM | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index 62ad0a055..0b167ec36 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,3 +1,13 @@ ++Version 1.02.207 - ++================================ ++ ++RHEL9 - 05th May 2025 ++===================== ++ 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.206 - 05th May 2025 + ================================ + Add support for using regex in selection criteria for string lists. +-- +2.49.0 + diff --git a/SOURCES/0008-lv_manip-fix-stripe-count-and-size-validation-for-RA.patch b/SOURCES/0008-lv_manip-fix-stripe-count-and-size-validation-for-RA.patch deleted file mode 100644 index edc9c8f..0000000 --- a/SOURCES/0008-lv_manip-fix-stripe-count-and-size-validation-for-RA.patch +++ /dev/null @@ -1,104 +0,0 @@ -From f2e8b49e1dd70f3735ff556f3f7296078a057a5e Mon Sep 17 00:00:00 2001 -From: Peter Rajnoha -Date: Tue, 5 Nov 2024 09:26:03 +0100 -Subject: [PATCH 08/13] lv_manip: fix stripe count and size validation for RAID - LVs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fix stripe count and size parameter validation for RAID LVs and -include existing automatic setting of these parameters based -on current shape of the RAID LV in case these are not set -on command line fully. - -Previously, this was done only to a certain subset given by this -condition (where the 'stripes' is the '-i|--stripes' cmd line arg -and the 'stripe_size' is actually the '-I|--stripesize' cmd line arg): - - !(stripes == 1 || (stripes > 1 && stripe_size)) - -This condition is a bit harder to follow at first sight and there -are no comments around with explanation for why this one is used, -so let's analyze it a bit more. - -First, let's convert this to an equivalent condition (De Morgan law) -so it's easier to read for humans: - - stripes != 1 && !(stripes > 1 && stripe_size) - -Note: Both stripe and stripesize are unsigned integers, so they can't be negative. - -Now, based on that condition, we were running the code to deduce the -stripe/stripesize and do the checks ("the code") only if both of these -are true: - - - stripes is different from 1 - - - we don't have stripes > 1 and stripe_size defined at the same time - -But this is not correct in all cases, because: - - A) if someone uses stripes = 0, then "the code" is executed - (correct) - - B) if someone uses stripes = 1, then "the code" is not executed - (wrong: we still need to be able to check the args against - existing RAID LV stripes whether it matches) - - - if someone uses stripes > 1, then "the code" is: - - C) if stripe_size = 0, executed - (correct) - - D) if stripe_size > 0, not executed - (wrong: we still want to check against existing RAID LV stripes) - -Current issues with this condition: - The B) ends up with segfault. - - ❯ lvextend -i 1 -l+1 vg/lvol0 - Rounding size 4.00 MiB (1 extents) up to stripe boundary size 8.00 MiB (2 extents). - Segmentation fault (core dumped) - - The D) ends up with errors like: - - ❯ lvextend -i 3 -l+1 -I128k vg/lvol0 - Rounding size 4.00 MiB (1 extents) up to stripe boundary size 8.00 MiB (2 extents). - Rounding size (4 extents) up to stripe boundary size for segment (5 extents). - Size of logical volume vg/lvol0 changed from 8.00 MiB (2 extents) to 20.00 MiB (5 extents). - LV lvol0: segment 1 with len=5 has inconsistent area_len 3 - Couldn't read all logical volumes for volume group vg. - Failed to write VG vg. - -Conclusion: - The condition needs to be removed so we always run "the code" to check - given striping args given on command line against existing RAID LV - striping. The reason is that we don't want to allow changing stripe - count for RAID LVs through lvextend and we need to end up with the - error: - "Unable to extend segment type with different number of stripes" - - (We do support changing the striping by lvconvert's reshaping functionality only). - -(cherry picked from commit b5249fa3c20fe5d9e1d4811e7e5bfd957b15a820) ---- - lib/metadata/lv_manip.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index a1d4f641a..e14947357 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -5468,7 +5468,7 @@ static int _lvresize_adjust_extents(struct logical_volume *lv, - } else if (seg_is_raid0(seg_last)) { - lp->stripes = seg_last->area_count; - lp->stripe_size = seg_last->stripe_size; -- } else if (!(lp->stripes == 1 || (lp->stripes > 1 && lp->stripe_size))) { -+ } else { - /* If extending, find stripes, stripesize & size of last segment */ - /* FIXME Don't assume mirror seg will always be AREA_LV */ - /* FIXME We will need to support resize for metadata LV as well, --- -2.47.0 - diff --git a/SOURCES/0008-lvmlockd-fix-hosts-check-for-vgremove.patch b/SOURCES/0008-lvmlockd-fix-hosts-check-for-vgremove.patch new file mode 100644 index 0000000..2eab959 --- /dev/null +++ b/SOURCES/0008-lvmlockd-fix-hosts-check-for-vgremove.patch @@ -0,0 +1,143 @@ +From 54d5564f0fc375278c940635c449bdeb24334b71 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 7 May 2025 17:51:01 -0500 +Subject: [PATCH 08/14] lvmlockd: fix hosts check for vgremove + +errors from lock manager were not being considered. +EAGAIN from sanlock should be considered EBUSY. + +(cherry picked from commit 53752ef851d3210e52297ebb4744fdd766c060c6) +--- + daemons/lvmlockd/lvmlockd-core.c | 11 ++++++++--- + daemons/lvmlockd/lvmlockd-dlm.c | 8 ++++++++ + daemons/lvmlockd/lvmlockd-sanlock.c | 26 ++++++++++++++++++++++---- + 3 files changed, 38 insertions(+), 7 deletions(-) + +diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c +index c65a3cc39..e4aa91216 100644 +--- a/daemons/lvmlockd/lvmlockd-core.c ++++ b/daemons/lvmlockd/lvmlockd-core.c +@@ -2708,13 +2708,16 @@ static void *lockspace_thread_main(void *arg_in) + rv = lm_hosts(ls, 1); + if (rv) { + /* ++ * rv < 0: error (don't remove) ++ * rv > 0: other hosts in lockspace (cannot remove) ++ * rv = 0: only local host in lockspace (can remove) + * Checking for hosts here in addition to after the + * main loop allows vgremove to fail and be rerun + * after the ls is stopped on other hosts. + */ + log_error("S %s lockspace hosts %d", ls->name, rv); + list_del(&act->list); +- act->result = -EBUSY; ++ act->result = (rv < 0) ? rv : -EBUSY; + add_client_result(act); + continue; + } +@@ -2727,7 +2730,9 @@ static void *lockspace_thread_main(void *arg_in) + if (act->op == LD_OP_BUSY && act->rt == LD_RT_VG) { + log_debug("S %s checking if lockspace is busy", ls->name); + rv = lm_hosts(ls, 0); +- if (rv) ++ if (rv < 0) ++ act->result = rv; ++ else if (rv) + act->result = -EBUSY; + else + act->result = 0; +@@ -2743,7 +2748,7 @@ static void *lockspace_thread_main(void *arg_in) + if (rv) { + log_error("S %s lockspace hosts %d", ls->name, rv); + list_del(&act->list); +- act->result = -EBUSY; ++ act->result = (rv < 0) ? rv : -EBUSY; + add_client_result(act); + continue; + } +diff --git a/daemons/lvmlockd/lvmlockd-dlm.c b/daemons/lvmlockd/lvmlockd-dlm.c +index 72b139170..7529ad327 100644 +--- a/daemons/lvmlockd/lvmlockd-dlm.c ++++ b/daemons/lvmlockd/lvmlockd-dlm.c +@@ -799,6 +799,14 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r, + * the stale lockspaces on the others eventually.) + */ + ++/* ++ * On error, returns < 0 ++ * ++ * On success: ++ * If other hosts are found, returns the number. ++ * If no other hosts are found (only ourself), returns 0. ++ */ ++ + int lm_hosts_dlm(struct lockspace *ls, int notify) + { + char ls_nodes_path[PATH_MAX]; +diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c +index 1a3982071..d50d0ce4b 100644 +--- a/daemons/lvmlockd/lvmlockd-sanlock.c ++++ b/daemons/lvmlockd/lvmlockd-sanlock.c +@@ -2296,6 +2296,13 @@ int lm_unlock_sanlock(struct lockspace *ls, struct resource *r, + return 0; + } + ++/* ++ * On error, returns < 0 ++ * Else: ++ * If other hosts are found, returns the number. ++ * If no other hosts are found (only ourself), returns 0. ++ */ ++ + int lm_hosts_sanlock(struct lockspace *ls, int notify) + { + struct sanlk_host *hss = NULL; +@@ -2310,14 +2317,25 @@ int lm_hosts_sanlock(struct lockspace *ls, int notify) + return 0; + + rv = sanlock_get_hosts(ls->name, 0, &hss, &hss_count, 0); ++ ++ if (rv == -EAGAIN) { ++ /* ++ * No host info is available yet (perhaps lockspace was ++ * just started so other host state is unknown.) Pretend ++ * there is one other host (busy). ++ */ ++ log_debug("S %s hosts_san no info, retry later", ls->name); ++ return 1; ++ } ++ + if (rv < 0) { + log_error("S %s hosts_san get_hosts error %d", ls->name, rv); +- return 0; ++ return -1; + } + + if (!hss || !hss_count) { + log_error("S %s hosts_san zero hosts", ls->name); +- return 0; ++ return -1; + } + + hs = hss; +@@ -2336,7 +2354,7 @@ int lm_hosts_sanlock(struct lockspace *ls, int notify) + } + + state = hs->flags & SANLK_HOST_MASK; +- if (state == SANLK_HOST_LIVE) ++ if ((state == SANLK_HOST_LIVE) || (state == SANLK_HOST_UNKNOWN)) + found_others++; + hs++; + } +@@ -2358,7 +2376,7 @@ int lm_hosts_sanlock(struct lockspace *ls, int notify) + + if (!found_self) { + log_error("S %s hosts_san self not found others %d", ls->name, found_others); +- return 0; ++ return -1; + } + + return found_others; +-- +2.49.0 + diff --git a/SOURCES/0009-lv_manip-use-the-same-param-validation-for-RAID-0-as.patch b/SOURCES/0009-lv_manip-use-the-same-param-validation-for-RAID-0-as.patch deleted file mode 100644 index 31d31cb..0000000 --- a/SOURCES/0009-lv_manip-use-the-same-param-validation-for-RAID-0-as.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 75d4056f39886b6cc3e6546dbb03bc7be1923990 Mon Sep 17 00:00:00 2001 -From: Peter Rajnoha -Date: Tue, 5 Nov 2024 14:48:23 +0100 -Subject: [PATCH 09/13] lv_manip: use the same param validation for RAID 0 as - for RAID 1/4/5/6 - -This actually reverts commit 83ae675f8df53010c984b78d0318d0d92d5ac83a. - -(cherry picked from commit 1d8a4c4817895f45a5fee00ccf721b351e5a4668) ---- - lib/metadata/lv_manip.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index e14947357..15a7f3c9a 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -5465,9 +5465,6 @@ static int _lvresize_adjust_extents(struct logical_volume *lv, - /* FIXME Warn if command line values are being overridden? */ - lp->stripes = seg_last->area_count / seg_mirrors; - lp->stripe_size = seg_last->stripe_size; -- } else if (seg_is_raid0(seg_last)) { -- lp->stripes = seg_last->area_count; -- lp->stripe_size = seg_last->stripe_size; - } else { - /* If extending, find stripes, stripesize & size of last segment */ - /* FIXME Don't assume mirror seg will always be AREA_LV */ --- -2.47.0 - diff --git a/SOURCES/0009-lvmlockd-fix-sanlock_release-for-vgremove.patch b/SOURCES/0009-lvmlockd-fix-sanlock_release-for-vgremove.patch new file mode 100644 index 0000000..6bef1a7 --- /dev/null +++ b/SOURCES/0009-lvmlockd-fix-sanlock_release-for-vgremove.patch @@ -0,0 +1,38 @@ +From 0b375ab5f49c4eea0c705ef8e27e94a366b0f6d6 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 8 May 2025 10:54:50 -0500 +Subject: [PATCH 09/14] lvmlockd: fix sanlock_release for vgremove + +incorrect data was being copied to lease structs passed +to sanlock_release(), making the lease removal fail. + +(cherry picked from commit 88910c200f9e24a454dc9fcbf39c2df1d4887f3b) +--- + daemons/lvmlockd/lvmlockd-sanlock.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c +index d50d0ce4b..b17cbad7e 100644 +--- a/daemons/lvmlockd/lvmlockd-sanlock.c ++++ b/daemons/lvmlockd/lvmlockd-sanlock.c +@@ -2192,12 +2192,15 @@ static int release_rename(struct lockspace *ls, struct resource *r) + if (!res_args) + return -ENOMEM; + +- memcpy(&rd1, rds, sizeof(struct rd_sanlock)); +- memcpy(&rd2, rds, sizeof(struct rd_sanlock)); ++ memcpy(&rd1, &rds->rs, sizeof(struct rd_sanlock)); ++ memcpy(&rd2, &rds->rs, sizeof(struct rd_sanlock)); + + res1 = (struct sanlk_resource *)&rd1; + res2 = (struct sanlk_resource *)&rd2; + ++ if (memcmp(res1->name, r->name, SANLK_NAME_LEN)) ++ log_error("%s:%s unlock_san release rename bad name %.48s", ls->name, r->name, res1->name); ++ + strcpy_name_len(res2->name, "invalid_removed", SANLK_NAME_LEN); + + res_args[0] = res1; +-- +2.49.0 + diff --git a/SOURCES/0010-raid-count-or-clear-transiently-failed-devices.patch b/SOURCES/0010-raid-count-or-clear-transiently-failed-devices.patch new file mode 100644 index 0000000..7917805 --- /dev/null +++ b/SOURCES/0010-raid-count-or-clear-transiently-failed-devices.patch @@ -0,0 +1,460 @@ +From ad632cf9f19f3b8efbcf087cbf60527160ba5fec Mon Sep 17 00:00:00 2001 +From: Heinz Mauelshagen +Date: Tue, 5 Nov 2024 18:33:19 +0100 +Subject: [PATCH 10/14] raid: count or clear transiently failed devices + +Count or clear transiently failed devices as of dm-raid superblocks. +Updated debuging. +Use lvconvert --repair to repair transiently failed legs. +Activating all 'meta' LVs with single sync_local_dev_names(). +Using proper DM path for meta LV. + +Modified-by: zkabelac@redhat.com +(cherry picked from commit 03d8661657bb3d1cb5dd764f3a450a8211f892e6) +--- + device_mapper/Makefile | 1 + + device_mapper/all.h | 1 + + device_mapper/raid/raid_parser.c | 164 ++++++++++++++++++++++++++++ + device_mapper/raid/target.h | 23 ++++ + lib/activate/activate.h | 2 + + lib/metadata/raid_manip.c | 179 ++++++++++++++++++++++++++++++- + 6 files changed, 369 insertions(+), 1 deletion(-) + create mode 100644 device_mapper/raid/raid_parser.c + create mode 100644 device_mapper/raid/target.h + +diff --git a/device_mapper/Makefile b/device_mapper/Makefile +index b1aa53c36..4dfcd4f12 100644 +--- a/device_mapper/Makefile ++++ b/device_mapper/Makefile +@@ -25,6 +25,7 @@ DEVICE_MAPPER_SOURCE=\ + device_mapper/libdm-targets.c \ + device_mapper/libdm-timestamp.c \ + device_mapper/mm/pool.c \ ++ device_mapper/raid/raid_parser.c \ + device_mapper/regex/matcher.c \ + device_mapper/regex/parse_rx.c \ + device_mapper/regex/ttree.c \ +diff --git a/device_mapper/all.h b/device_mapper/all.h +index 91c085e76..97279c10b 100644 +--- a/device_mapper/all.h ++++ b/device_mapper/all.h +@@ -19,6 +19,7 @@ + + #include "base/data-struct/list.h" + #include "base/data-struct/hash.h" ++#include "raid/target.h" + #include "vdo/target.h" + + #include +diff --git a/device_mapper/raid/raid_parser.c b/device_mapper/raid/raid_parser.c +new file mode 100644 +index 000000000..adef7bb6c +--- /dev/null ++++ b/device_mapper/raid/raid_parser.c +@@ -0,0 +1,164 @@ ++/* ++ * Copyright (C) 2024 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of the device-mapper userspace tools. ++ * ++ * 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 ++ */ ++ ++/* ++ * Support counting number of failed device bits in dm-raid superblock bit arrays or clear them out. ++ */ ++ ++#include "device_mapper/misc/dmlib.h" ++#include "device_mapper/all.h" ++#include "device_mapper/raid/target.h" ++#include ++#include ++ ++/* Copied/derived from kernel's drivers/md/dm-raid.c so this is prone to out-of-sync (factor out to header file?). */ ++#define MAX_RAID_DEVICES 253 /* md-raid kernel limit? */ ++#define UINT64_BITS (sizeof(uint64_t) * 8) ++#define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (UINT64_BITS - 1)) / UINT64_BITS) ++#define DM_RAID_SB_MAGIC 0x446D5264 /* "DmRd" */ ++#define FEATURE_FLAG_SUPPORTS_V190 0x1 /* Supports extended superblock */ ++ ++/* RAID superblock at beginning of rmeta SubLVs trimmed down to mandatory members. */ ++struct dm_raid_superblock { ++ __le32 magic; /* "DmRd" */ ++ __le32 compat_features; /* Used to indicate compatible features (like 1.9.0 ondisk metadata extension) */ ++ __le32 dummy[4]; ++ __le64 failed_devices; /* Pre 1.9.0 part of bit field of devices to */ ++ /* indicate device failures (see extension below) */ ++ __le32 dummy1[7]; ++ ++ /******************************************************************** ++ * BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!! ++ * ++ * FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist ++ */ ++ __le32 flags; /* Flags defining array states for reshaping */ ++ __le32 dummy2[14]; ++ __le64 extended_failed_devices[DISKS_ARRAY_ELEMS - 1]; ++ ++ __le32 dummy3; ++ /* Always set rest up to logical block size to 0 when writing ... */ ++} __packed; ++/* END: Copied from ... */ ++ ++/* Superblock I/O buffer size to be able to Cope with 4K native devices... */ ++#define SB_BUFSZ 4096 ++ ++static size_t _get_sb_size(const struct dm_raid_superblock *sb) ++{ ++ return (FEATURE_FLAG_SUPPORTS_V190 & le32toh(sb->compat_features)) ? ++ sizeof(*sb) : ((char *) &sb->flags - (char *) sb); ++} ++ ++static uint32_t _hweight64(__le64 v) ++{ ++ uint32_t r = 0; ++ ++ while (v) { ++ r += v & 1; ++ v >>= 1; ++ } ++ ++ return r; ++} ++ ++static uint32_t _hweight_failed(struct dm_raid_superblock *sb) ++{ ++ uint32_t r = _hweight64(sb->failed_devices); ++ ++ if (_get_sb_size(sb) == sizeof(*sb)) { ++ size_t i = DM_ARRAY_SIZE(sb->extended_failed_devices); ++ ++ while (i--) ++ r = max(r, _hweight64(sb->extended_failed_devices[i])); ++ } ++ ++ return r; ++} ++ ++static void _clear_failed_devices(struct dm_raid_superblock *sb) ++{ ++ ++ sb->failed_devices = 0; ++ ++ if (_get_sb_size(sb) == sizeof(*sb)) ++ memset(sb->extended_failed_devices, 0, sizeof(sb->extended_failed_devices)); ++} ++ ++static int _count_or_clear_failed_devices(const char *dev_path, bool clear, uint32_t *nr_failed) ++{ ++ struct dm_raid_superblock *sb = NULL; ++ size_t sz; ++ int fd, r = 0; ++ ++ if (posix_memalign((void *) &sb, SB_BUFSZ, SB_BUFSZ)) { ++ log_sys_error("Failed to allocate RAID superblock buffer", dev_path); ++ return 0; ++ } ++ ++ fd = open(dev_path, O_EXCL | ((clear) ? O_RDWR : O_RDONLY) | O_DIRECT); ++ if (fd < 0) { ++ log_sys_error("Failed to open RAID metadata volume", dev_path); ++ goto out; ++ } ++ ++ if (read(fd, sb, SB_BUFSZ) != SB_BUFSZ) { ++ log_sys_error("Failed to read RAID metadata volume", dev_path); ++ goto out; ++ } ++ ++ /* FIXME: big endian??? */ ++ if (sb->magic != htobe32(DM_RAID_SB_MAGIC)) { ++ log_error("No RAID signature on %s.", dev_path); ++ goto out; ++ } ++ ++ if (nr_failed) ++ *nr_failed = _hweight_failed(sb); ++ ++ if (clear) { ++ if (lseek(fd, 0, SEEK_SET) < 0) { ++ log_sys_error("Failed to seek RAID metadata volume", dev_path); ++ goto out; ++ } ++ ++ sz = _get_sb_size(sb); ++ memset((void *)((char *) sb + sz), 0, SB_BUFSZ - sz); ++ _clear_failed_devices(sb); ++ if (write(fd, sb, SB_BUFSZ) != SB_BUFSZ) { ++ log_sys_error("Failed to clear RAID metadata volume", dev_path); ++ goto out; ++ } ++ } ++ ++ r = 1; ++ ++out: ++ if ((fd >= 0) && close(fd)) ++ log_sys_debug("close", dev_path); ++ ++ free(sb); ++ ++ return r; ++} ++ ++int dm_raid_count_failed_devices(const char *dev_path, uint32_t *nr_failed) ++{ ++ return _count_or_clear_failed_devices(dev_path, false, nr_failed); ++} ++ ++int dm_raid_clear_failed_devices(const char *dev_path, uint32_t *nr_failed) ++{ ++ return _count_or_clear_failed_devices(dev_path, true, nr_failed); ++} +diff --git a/device_mapper/raid/target.h b/device_mapper/raid/target.h +new file mode 100644 +index 000000000..3e3ec024c +--- /dev/null ++++ b/device_mapper/raid/target.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2024 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of the device-mapper userspace tools. ++ * ++ * 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 ++ */ ++ ++#ifndef DEVICE_MAPPER_RAID_TARGET_H ++#define DEVICE_MAPPER_RAID_TARGET_H ++ ++#include ++ ++int dm_raid_count_failed_devices(const char *dev_path, uint32_t *nr_failed); ++int dm_raid_clear_failed_devices(const char *dev_path, uint32_t *nr_failed); ++ ++#endif +diff --git a/lib/activate/activate.h b/lib/activate/activate.h +index bd30e2655..155936135 100644 +--- a/lib/activate/activate.h ++++ b/lib/activate/activate.h +@@ -197,6 +197,8 @@ int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt); + int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action); + int lv_raid_message(const struct logical_volume *lv, const char *msg); + int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status); ++int lv_raid_clear_failed_devices(const struct logical_volume *lv); ++int lv_raid_count_failed_devices(const struct logical_volume *lv, uint32_t *failed_cnt); + int lv_writecache_message(const struct logical_volume *lv, const char *msg); + int lv_cache_status(const struct logical_volume *cache_lv, + struct lv_status_cache **status); +diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c +index eb4a2eb45..2a78a0bec 100644 +--- a/lib/metadata/raid_manip.c ++++ b/lib/metadata/raid_manip.c +@@ -3242,7 +3242,7 @@ static int _raid_leg_degraded(struct lv_segment *raid_seg, uint32_t s) + _sublv_is_degraded(seg_metalv(raid_seg, s)))); + } + +-/* Return failed component SubLV count for @lv. */ ++/* Return failed component SubLV pair count for @lv. */ + static uint32_t _lv_get_nr_failed_components(const struct logical_volume *lv) + { + uint32_t r = 0, s; +@@ -7328,6 +7328,183 @@ int lv_raid_remove_missing(struct logical_volume *lv) + return 1; + } + ++/* ++ * Count number of failed device bits in dm-raid superblock bit arrays -or- clear them out. ++ * ++ * If any failed devices, return != 0 maximum of failed SubLVs and parity_devs so that the ++ * caller will ask to clear and try activation of the RaidLV unless more than parity_devs ++ * component device pairs (rmeta and rimage) are still failed. This'll allow early exit ++ * in the caller preventing MD kernel rejection to activate the RAID array with > parity_devs ++ * failed component device pairs. ++ */ ++static int _count_or_clear_failed_devices_bits(struct logical_volume *meta_lv, ++ bool clear, uint32_t *nr_failed) ++{ ++ char *meta_path = lv_dmpath_dup(meta_lv->vg->cmd->mem, meta_lv); ++ ++ if (!meta_path) { ++ log_error("Failed to build device path for %s.", ++ display_lvname(meta_lv)); ++ return 0; ++ } ++ ++ if (!clear) /* only counting */ ++ return dm_raid_count_failed_devices(meta_path, nr_failed); ++ ++ return dm_raid_clear_failed_devices(meta_path, nr_failed); ++} ++ ++/* Count or clear failed devices bits in RAID superblocks for ++ * recurred transiently failed component SubLV pairs. */ ++static int _raid_count_or_clear_failed_devices(const struct logical_volume *lv, ++ bool clear, uint32_t *failed_devices) ++{ ++ uint32_t nr_failed = 0, nr_failed_tmp = 0, failed_sublvs = 0, s; ++ struct lv_segment *raid_seg = first_seg(lv); ++ struct logical_volume *meta_lv; ++ const char *str; ++ int r = 1, cleared_devs = 0; ++ ++ /* Prevent bogus use. */ ++ if (!seg_is_raid_with_meta(raid_seg)) { ++ log_error("%s is not a RaidLV with metadata.", display_lvname(lv)); ++ return 0; ++ } ++ ++ failed_sublvs = _lv_get_nr_failed_components(lv); ++ ++ if (clear && (failed_sublvs > raid_seg->segtype->parity_devs)) { ++ log_error("Can't clear transiently failed devices on still failed %s.", ++ display_lvname(lv)); ++ return 0; ++ } ++ ++ if (!raid_seg->meta_areas) { ++ log_error(INTERNAL_ERROR "Missing metadata areas on %s!", display_lvname(lv)); ++ return 0; ++ } ++ ++ /* Check if there isn't any meta LV already active */ ++ for (s = 0; s < raid_seg->area_count; s++) { ++ if (_raid_leg_degraded(raid_seg, s)) ++ continue; ++ ++ meta_lv = seg_metalv(raid_seg, s); ++ ++ if (lv_is_active(meta_lv)) { ++ /* DM table is in some unknown condition, aborting... */ ++ log_error("Can't %s failed devices with active %s metadata volume %s.", ++ clear ? "clear" : "count", ++ lvseg_name(raid_seg), display_lvname(meta_lv)); ++ return 0; ++ } ++ } ++ ++ /* Activate all non degraded meta LVs before count or clear */ ++ for (s = 0; s < raid_seg->area_count; s++) { ++ meta_lv = seg_metalv(raid_seg, s); ++ ++ if (_raid_leg_degraded(raid_seg, s)) { ++ log_debug("Skipping activation of failed devices for degraded %s metadata volume %s.", ++ lvseg_name(raid_seg), display_lvname(meta_lv)); ++ continue; ++ } ++ ++ if (!activate_lv(lv->vg->cmd, meta_lv)) { ++ log_error("Failed to activate %s metadata volume %s.", ++ lvseg_name(raid_seg), display_lvname(meta_lv)); ++ r = 0; /* how many can be counted... */ ++ } ++ } ++ ++ /* Wait for meta activation. */ ++ if (!sync_local_dev_names(lv->vg->cmd)) ++ stack; ++ ++ for (s = 0; s < raid_seg->area_count; s++) { ++ meta_lv = seg_metalv(raid_seg, s); ++ ++ if (_raid_leg_degraded(raid_seg, s)) { ++ if (clear) ++ log_debug("Skipping clear of failed devices for degraded %s metadata volume %s.", ++ lvseg_name(raid_seg), display_lvname(meta_lv)); ++ continue; ++ } ++ ++ if (lv_is_active(meta_lv) && ++ !_count_or_clear_failed_devices_bits(meta_lv, clear, ++ &nr_failed_tmp)) { ++ log_error("Failed to %s failed device(s) in superblock of %s metadata volume %s.", ++ clear ? "clear" : "count", ++ lvseg_name(raid_seg), display_lvname(meta_lv)); ++ r = 0; ++ continue; ++ } ++ ++ if (nr_failed_tmp) { ++ log_verbose("%s %u failed device(s) in superblock of %s metadata volume %s.", ++ clear ? "Cleared" : "Counted", nr_failed_tmp, ++ lvseg_name(raid_seg), display_lvname(meta_lv)); ++ cleared_devs++; ++ } ++ ++ if (nr_failed_tmp > nr_failed) ++ nr_failed = nr_failed_tmp; ++ } ++ ++ /* Deactivate meta LVs */ ++ for (s = 0; s < raid_seg->area_count; s++) { ++ if (_raid_leg_degraded(raid_seg, s)) ++ continue; ++ ++ if (!deactivate_lv(lv->vg->cmd, seg_metalv(raid_seg, s))) { ++ stack; ++ r = 0; ++ } ++ } ++ ++ if (clear) { ++ if (!failed_sublvs) ++ str = "fully operational"; ++ else if (failed_sublvs <= raid_seg->segtype->parity_devs) ++ str = "degraded"; ++ else ++ str = "still failed"; ++ ++ log_print_unless_silent("The %s volume %s is %s with %u transiently failed device(s).", ++ lvseg_name(raid_seg), display_lvname(lv), str, ++ nr_failed - failed_sublvs); ++ ++ if (r && cleared_devs && ++ (failed_sublvs <= raid_seg->segtype->parity_devs)) ++ /* TODO: maybe we want to activate RAID volume here ? */ ++ log_print_unless_silent("Volume has been restored after clearing %u superblocks(s). Once online please check its content.", ++ cleared_devs); ++ } ++ ++ if (failed_devices) ++ *failed_devices = max(failed_sublvs, raid_seg->segtype->parity_devs); ++ ++ return r; ++} ++ ++/* Clear failed device bits in RAID superblocks for recurred ++ * transiently failed component SubLV pairs. */ ++int lv_raid_clear_failed_devices(const struct logical_volume *lv) ++{ ++ return _raid_count_or_clear_failed_devices(lv, true, NULL); ++} ++ ++/* Count failed device bits in RAID superblocks for recurred ++ * transiently failed component SubLV pairs. ++ * ++ * On success, @failed_cnt contains the current number. ++ */ ++int lv_raid_count_failed_devices(const struct logical_volume *lv, uint32_t *failed_cnt) ++{ ++ return _raid_count_or_clear_failed_devices(lv, false, failed_cnt); ++} ++ + /* Return 1 if a partial raid LV can be activated redundantly */ + static int _partial_raid_lv_is_redundant(const struct logical_volume *lv) + { +-- +2.49.0 + diff --git a/SOURCES/0010-tests-remove-superfluous-a-option-for-df-used-in-lvr.patch b/SOURCES/0010-tests-remove-superfluous-a-option-for-df-used-in-lvr.patch deleted file mode 100644 index f75a204..0000000 --- a/SOURCES/0010-tests-remove-superfluous-a-option-for-df-used-in-lvr.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 66aa04c39c00e1b32ad0dfb85910afeaf8b5e88d Mon Sep 17 00:00:00 2001 -From: Peter Rajnoha -Date: Tue, 5 Nov 2024 14:20:59 +0100 -Subject: [PATCH 10/13] tests: remove superfluous -a option for df used in - lvresize-xfs.sh - -The df -a looks at whole system and it returns an error code in case -there's an inaccessible fs which is not even part of the testing environment. -The -a for df is not actually needed here in the lvresize-xfs test, so remove it. - -(cherry picked from commit a2ca20dad98f4d7389d449672b3ff0b16858f02b) ---- - test/shell/lvresize-xfs.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/test/shell/lvresize-xfs.sh b/test/shell/lvresize-xfs.sh -index da204dac6..87fbf6f9d 100644 ---- a/test/shell/lvresize-xfs.sh -+++ b/test/shell/lvresize-xfs.sh -@@ -113,7 +113,7 @@ dd if=/dev/zero of="$mount_dir_space/zeros1" bs=1M count=20 oflag=direct - # succeeds, then the xfs extend fails because it cannot be done unmounted - not lvextend --fs resize --fsmode offline -L+20M $vg/$lv - check lv_field $vg/$lv lv_size "320.00m" --df -a | tee dfa -+df | tee dfa - grep "$mount_dir_space" dfa - df --output=size "$mount_dir_space" |tee df2 - # fs not extended so fs size not changed --- -2.47.0 - diff --git a/SOURCES/0011-WHATS_NEW-update.patch b/SOURCES/0011-WHATS_NEW-update.patch deleted file mode 100644 index 5c7ccc2..0000000 --- a/SOURCES/0011-WHATS_NEW-update.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 06dae73111fb4b2d5ce22ab566fb60b0e1d3b7b3 Mon Sep 17 00:00:00 2001 -From: Peter Rajnoha -Date: Wed, 6 Nov 2024 10:39:27 +0100 -Subject: [PATCH 11/13] WHATS_NEW: update - -(cherry picked from commit 44a04b71f8e8ff730b5538c4b6323041cf904ece) ---- - WHATS_NEW | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 85ffe0d0c..d07a1eaeb 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,3 +1,8 @@ -+Version 2.03.29 - -+================== -+ Fix segfault/VG write error for raid LV lvextend -i|--stripes -I|--stripesize. -+ Revert ignore -i|--stripes, -I|--stripesize for lvextend on raid0 LV (2.03.27). -+ - Version 2.03.28 - 04th November 2024 - ==================================== - Use radix_tree to lookup for UUID within committed metadata. --- -2.47.0 - diff --git a/SOURCES/0011-lvconvert-allow-clearing-superblocks.patch b/SOURCES/0011-lvconvert-allow-clearing-superblocks.patch new file mode 100644 index 0000000..342eac4 --- /dev/null +++ b/SOURCES/0011-lvconvert-allow-clearing-superblocks.patch @@ -0,0 +1,64 @@ +From 4fbda3d36dc02bb682dd8579c8a4ebfc692cbfe3 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 31 Jan 2025 21:45:57 +0100 +Subject: [PATCH 11/14] lvconvert: allow clearing superblocks + +(cherry picked from commit 0a8f560c759de0f3335213896c2a3383009c7206) +--- + tools/lvconvert.c | 38 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +diff --git a/tools/lvconvert.c b/tools/lvconvert.c +index 72ef74cef..270bae7d0 100644 +--- a/tools/lvconvert.c ++++ b/tools/lvconvert.c +@@ -3874,10 +3874,44 @@ static int _lvconvert_repair_pvs_raid(struct cmd_context *cmd, struct logical_vo + { + struct dm_list *failed_pvs; + int do_it; ++ uint32_t failed_cnt = 0; ++ struct lv_segment *raid_seg; + + if (!lv_is_active(lv_lock_holder(lv))) { +- log_error("%s must be active to perform this operation.", display_lvname(lv)); +- return 0; ++ if (!lv_raid_count_failed_devices(lv, &failed_cnt)) ++ return_0; ++ ++ if (!failed_cnt) { ++ log_error("Logical volume %s must be active to perform this operation.", ++ display_lvname(lv)); ++ return 0; ++ } ++ ++ raid_seg = first_seg(lv); ++ ++ if (failed_cnt > raid_seg->segtype->parity_devs) { ++ log_error("Can't clear %u failed superblock(s) in %s volume %s.", ++ failed_cnt, lvseg_name(raid_seg), display_lvname(lv)); ++ log_print_unless_silent("The maximum number of degraded devices allowed is %u.", ++ raid_seg->segtype->parity_devs); ++ return 0; ++ } ++ ++ if (!arg_count(cmd, yes_ARG) && ++ yes_no_prompt("Attempt to clear %u transiently failed %s superblock(s) in %s? [y/n]: ", ++ failed_cnt, lvseg_name(raid_seg), display_lvname(lv)) == 'n') { ++ log_error("Logical volume %s with %u transiently failed %s superblock(s) NOT repaired.", ++ display_lvname(lv), failed_cnt, lvseg_name(raid_seg)); ++ return 0; ++ } ++ ++ log_verbose("Clearing %u transiently failed %s superblock(s) in %s.", ++ failed_cnt, lvseg_name(raid_seg), display_lvname(lv)); ++ ++ if (!lv_raid_clear_failed_devices(lv)) ++ return_0; ++ ++ return 1; + } + + lv_check_transient(lv); /* TODO check this in lib for all commands? */ +-- +2.49.0 + diff --git a/SOURCES/0012-test-check-raid-superblock-clearing.patch b/SOURCES/0012-test-check-raid-superblock-clearing.patch new file mode 100644 index 0000000..187f5e5 --- /dev/null +++ b/SOURCES/0012-test-check-raid-superblock-clearing.patch @@ -0,0 +1,107 @@ +From 7ef2e32ab91194abfcacb96eae2577cf19e66123 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sun, 2 Feb 2025 19:21:05 +0100 +Subject: [PATCH 12/14] test: check raid superblock clearing + +(cherry picked from commit 0cafb18978d4a720845c2830fcff129ce9b79327) +--- + test/shell/lvconvert-repair-raid5.sh | 62 +++++++++++++++++++++------- + 1 file changed, 47 insertions(+), 15 deletions(-) + +diff --git a/test/shell/lvconvert-repair-raid5.sh b/test/shell/lvconvert-repair-raid5.sh +index a14d90be9..66485c536 100644 +--- a/test/shell/lvconvert-repair-raid5.sh ++++ b/test/shell/lvconvert-repair-raid5.sh +@@ -1,6 +1,6 @@ + #!/usr/bin/env bash + +-# Copyright (C) 2024 Red Hat, Inc. All rights reserved. ++# Copyright (C) 2024-2025 Red Hat, Inc. All rights reserved. + # + # This copyrighted material is made available to anyone wishing to use, + # modify, copy, or redistribute it subject to the terms and conditions +@@ -24,17 +24,31 @@ SKIP_WITH_LVMPOLLD=1 + # + aux have_raid 1 8 0 || skip + +-aux prepare_vg 4 +-get_devs ++aux prepare_vg 6 + +-#offset=$(get first_extent_sector "$dev1") + +-# It's possible small raid arrays do have problems with reporting in-sync. +-# So try bigger size +-RAID_SIZE=8 ++lvcreate --type raid5 -i 5 -L8 -n $lv1 $vg ++aux wait_for_sync $vg $lv1 ++ ++lvs -ao+devices $vg ++ ++# fail 2 drives out of 4 ++aux error_dev "$dev2" ++aux error_dev "$dev3" ++ ++lvchange -an $vg ++ ++aux enable_dev "$dev2" ++aux enable_dev "$dev3" ++ ++lvconvert --yes --repair $vg/$lv1 -v ++ ++lvremove -f $vg + +-# RAID1 transient failure check +-lvcreate --type raid5 -i 3 -L $RAID_SIZE -n $lv1 $vg ++ ++# Raid5 transient failure check ++ ++lvcreate --type raid5 -i 3 -L8 -n $lv1 $vg + aux wait_for_sync $vg $lv1 + + lvs -ao+devices $vg +@@ -43,17 +57,35 @@ lvs -ao+devices $vg + aux error_dev "$dev2" + aux error_dev "$dev3" + ++not lvconvert --yes --repair $vg/$lv1 ++ + # deactivate immediately + lvchange -an $vg + ++# Raid5 cannot activate with only 2 disks ++not lvchange -ay $vg ++ ++# also it cannot be repaired ++not lvconvert --yes --repair $vg/$lv1 ++ ++# restore 1st. failed drive + aux enable_dev "$dev2" ++ ++# Raid5 should be now repairable ++lvconvert --yes --repair $vg/$lv1 ++ ++# Raid5 volume is working now ++lvchange -ay $vg ++ ++# again deactivate ++lvchange -an $vg ++ ++# restore 2nd. missing drive + aux enable_dev "$dev3" + +-# ATM we are failing here with this kernel message: +-# +-# md/raid:mdX: Cannot continue operation (2/4 failed). +-# +-# Raid5 LV cannot be started any more +-should lvchange -ay $vg ++# still repairable ++lvconvert --yes --repair $vg/$lv1 ++ ++lvchange -ay $vg + + vgremove -ff $vg +-- +2.49.0 + diff --git a/SOURCES/0012-vdo-fix-input-units-for-minimim_io_size.patch b/SOURCES/0012-vdo-fix-input-units-for-minimim_io_size.patch deleted file mode 100644 index 3097459..0000000 --- a/SOURCES/0012-vdo-fix-input-units-for-minimim_io_size.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 55bfaca8a87372887d401aaae7b5804b4f5ed826 Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Fri, 8 Nov 2024 16:12:30 +0100 -Subject: [PATCH 12/13] vdo: fix input units for minimim_io_size - -When specifying minimum_io_size with --vdosettings, -command assumed wrong unit (sectors). - -So '--vdosettings minimum_io_size=512|4096' resulted into -an error that only 512 or 4096 values are allowed, but -at the same time values 1 or 8 were accepted. - -So fix by converting any number >= 512 to 'sectors' and -keep input of 1 or 8 still valid if anyone has been using -this before. - -So now we take 512 or 4096 and still also 1 or 8 with the -same effect. - -Also correct the 'error' message when invalid minimum_io_size -is specified. - -(cherry picked from commit 158d3243b638f50f62c60128168c21840787f1ab) ---- - device_mapper/vdo/vdo_target.c | 2 +- - tools/toollib.c | 4 ++++ - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/device_mapper/vdo/vdo_target.c b/device_mapper/vdo/vdo_target.c -index a8a753e39..cdd3dbe6d 100644 ---- a/device_mapper/vdo/vdo_target.c -+++ b/device_mapper/vdo/vdo_target.c -@@ -28,7 +28,7 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp, - if ((vtp->minimum_io_size != (512 >> SECTOR_SHIFT)) && - (vtp->minimum_io_size != (4096 >> SECTOR_SHIFT))) { - log_error("VDO minimum io size %u is unsupported [512, 4096].", -- vtp->minimum_io_size); -+ (vtp->minimum_io_size << SECTOR_SHIFT)); - valid = false; - } - -diff --git a/tools/toollib.c b/tools/toollib.c -index dcb6c8f4f..f854d17c5 100644 ---- a/tools/toollib.c -+++ b/tools/toollib.c -@@ -1372,6 +1372,10 @@ int get_vdo_settings(struct cmd_context *cmd, - u |= VDO_CHANGE_ONLINE; - } - -+ /* store size in sector units */ -+ if (vtp->minimum_io_size >= 512) -+ vtp->minimum_io_size >>= SECTOR_SHIFT; -+ - // validation of updated VDO option - if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */)) - goto_out; --- -2.47.0 - diff --git a/SOURCES/0013-man-update-raid-man.patch b/SOURCES/0013-man-update-raid-man.patch new file mode 100644 index 0000000..d7ed1c8 --- /dev/null +++ b/SOURCES/0013-man-update-raid-man.patch @@ -0,0 +1,50 @@ +From 63312cb3343d6370c89ab0ff4e93aa39aab25fa5 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 12 May 2025 15:05:46 +0200 +Subject: [PATCH 13/14] man: update raid man + +Mention repair of transiently lost devices. + +(cherry picked from commit 22364ce9b68b3a2e03819bfd8fdc569df584b7e2) +--- + man/lvmraid.7_main | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/man/lvmraid.7_main b/man/lvmraid.7_main +index 5b429a410..db8009d46 100644 +--- a/man/lvmraid.7_main ++++ b/man/lvmraid.7_main +@@ -434,7 +434,7 @@ found, run: + # lvs -o name,raid_mismatch_count + .EE + .P +-Also, if mismatches were found, the ++Also, if mismatches were found, the + .BR lvs (8) + attr field will display the letter + "m" (mismatch) in the 9th position, e.g. +@@ -862,6 +862,21 @@ those PVs can be reconstructed with: + The rebuild option can be repeated with different PVs to replace the data + on multiple PVs. + . ++.SS Reactivating arrays after temporary device loss ++ ++When a RAID array loses a critical number of devices, ++causing it to lose its ability to function reliably, ++the array will stop and require repair. ++ ++Initiate repair process with this command: ++.P ++.B lvconvert --repair ++.I LV ++.P ++If the previously unavailable devices become accessible again, ++this repair process will update their metadata and ++the RAID array can be reactivated. ++. + .SH DATA INTEGRITY + . + The device mapper integrity target can be used in combination with RAID +-- +2.49.0 + diff --git a/SOURCES/0013-tests-check-vdo-minimum_io_size.patch b/SOURCES/0013-tests-check-vdo-minimum_io_size.patch deleted file mode 100644 index a0b7d4d..0000000 --- a/SOURCES/0013-tests-check-vdo-minimum_io_size.patch +++ /dev/null @@ -1,33 +0,0 @@ -From aa78a84b20861bb37ca420c1278967f42e6c24dc Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Fri, 8 Nov 2024 16:38:29 +0100 -Subject: [PATCH 13/13] tests: check vdo minimum_io_size - -(cherry picked from commit dcac774f0982470b29bf04f27b6394fe27c4df71) ---- - test/shell/lvcreate-vdo.sh | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/test/shell/lvcreate-vdo.sh b/test/shell/lvcreate-vdo.sh -index b24801375..87d6f98a1 100644 ---- a/test/shell/lvcreate-vdo.sh -+++ b/test/shell/lvcreate-vdo.sh -@@ -89,4 +89,15 @@ check lv_field $vg/$lv1 vdo_ack_threads "4" - lvs -a $vg - lvremove -ff $vg - -+lvcreate --type vdo --vdosettings 'minimum_io_size=512' -L10G -V1T -ky -n $lv1 $vg -+check lv_field $vg/$lv1 vdo_minimum_io_size "512b" -+lvremove -ff $vg -+ -+lvcreate --type vdo --vdosettings 'minimum_io_size=4096' -L10G -V1T -ky -n $lv1 $vg -+check lv_field $vg/$lv1 vdo_minimum_io_size "4.00k" -+lvremove -ff $vg -+ -+# only 512 or 4096 are valid values (and eventually 1 or 8 sectors) -+not lvcreate --type vdo --vdosettings 'minimum_io_size=8000' -L10G -V1T -ky -n $lv1 $vg -+ - vgremove -ff $vg --- -2.47.0 - diff --git a/SOURCES/0014-WHATS_NEW-update.patch b/SOURCES/0014-WHATS_NEW-update.patch new file mode 100644 index 0000000..fd54063 --- /dev/null +++ b/SOURCES/0014-WHATS_NEW-update.patch @@ -0,0 +1,25 @@ +From 14f920c81c9499bcfcc0414c494f7abc0b9f3d58 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 12 May 2025 15:07:15 +0200 +Subject: [PATCH 14/14] WHATS_NEW: update + +(cherry picked from commit 759d1bfe113ca7a80248821808d13ed9e011201c) +--- + WHATS_NEW | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 4d8b59681..c9af7be6e 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,3 +1,7 @@ ++Version 2.03.33 - ++================== ++ Repair raid arrays with transiently lost devices. ++ + Version 2.03.32 - 05th May 2025 + =============================== + Lvconvert vdopool conversion propperly validates acceptable LVs. +-- +2.49.0 + diff --git a/SOURCES/0014-raid-fix-name-rotation.patch b/SOURCES/0014-raid-fix-name-rotation.patch deleted file mode 100644 index 493e6c3..0000000 --- a/SOURCES/0014-raid-fix-name-rotation.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 2bc2dad1e2c7019dd33b1081d69e0cee4040d566 Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Wed, 13 Nov 2024 12:52:18 +0100 -Subject: [PATCH 1/3] raid: fix name rotation - -Since we now keep lv names valid all the time (as they are part -of radix_tree) - there is a problem with this renaming code, that -for a moment used duplicated name in vg struct. - -Fix it by interating LVs backwared - which avoids breaking consitency -and also actually makes code more simple. - -(cherry picked from commit c2f41c1a59351772b78f2328edd61f996cc37c3b) ---- - lib/metadata/raid_manip.c | 23 ++++++++--------------- - 1 file changed, 8 insertions(+), 15 deletions(-) - -diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c -index 60ae897ef..8abad8be7 100644 ---- a/lib/metadata/raid_manip.c -+++ b/lib/metadata/raid_manip.c -@@ -2637,6 +2637,7 @@ static int _raid_add_images_without_commit(struct logical_volume *lv, - struct lv_list *lvl; - struct lv_segment_area *new_areas; - struct segment_type *segtype; -+ const char *lv_name, *lv_name_tmp; - - if (lv_is_not_synced(lv)) { - log_error("Can't add image to out-of-sync RAID LV:" -@@ -2704,22 +2705,14 @@ static int _raid_add_images_without_commit(struct logical_volume *lv, - * commits the LVM metadata before clearing the LVs. - */ - if (seg_is_linear(seg)) { -- struct dm_list *l; -- struct lv_list *lvl_tmp; -- const char *lv_name; -- -- dm_list_iterate(l, &data_lvs) { -- if (l == dm_list_last(&data_lvs)) { -- lvl = dm_list_item(l, struct lv_list); -- if (!(lv_name = _generate_raid_name(lv, "rimage", count)) || -- !lv_set_name(lvl->lv, lv_name)) -- return_0; -- continue; -- } -- lvl = dm_list_item(l, struct lv_list); -- lvl_tmp = dm_list_item(l->n, struct lv_list); -- if (!lv_set_name(lvl->lv, lvl_tmp->lv->name)) -+ if (!(lv_name = _generate_raid_name(lv, "rimage", count))) -+ return_0; -+ -+ dm_list_iterate_back_items(lvl, &data_lvs) { -+ lv_name_tmp = lvl->lv->name; -+ if (!lv_set_name(lvl->lv, lv_name)) - return_0; -+ lv_name = lv_name_tmp; /* rotate name in list */ - } - } - --- -2.47.0 - diff --git a/SOURCES/0015-tests-check-_tdata-conversion-to-raid1.patch b/SOURCES/0015-tests-check-_tdata-conversion-to-raid1.patch deleted file mode 100644 index 6f3027f..0000000 --- a/SOURCES/0015-tests-check-_tdata-conversion-to-raid1.patch +++ /dev/null @@ -1,28 +0,0 @@ -From bdcd4f18fe03f6c3fca94e27e5469b1409dda3ad Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Wed, 13 Nov 2024 12:59:27 +0100 -Subject: [PATCH 2/3] tests: check _tdata conversion to raid1 - -(cherry picked from commit 7b9bdcb4d4aef7f0a079e2278869f19aa7fb7c83) ---- - test/shell/lvconvert-thin-raid.sh | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/test/shell/lvconvert-thin-raid.sh b/test/shell/lvconvert-thin-raid.sh -index c021e3b77..7b0e4a5c9 100644 ---- a/test/shell/lvconvert-thin-raid.sh -+++ b/test/shell/lvconvert-thin-raid.sh -@@ -58,4 +58,10 @@ lvconvert --merge $vg/${lv1}_tmeta_rimage_1 - lvconvert -y -m +1 $vg/${lv1}_tdata "$dev2" - lvconvert -y -m +1 $vg/${lv1}_tmeta "$dev1" - -+lvremove -f $vg -+ -+lvcreate -L10M -T $vg/pool -+lvconvert -y --type raid1 -m2 $vg/pool_tdata -+lvconvert -y --type raid1 -m2 $vg/pool_tmeta -+ - vgremove -ff $vg --- -2.47.0 - diff --git a/SOURCES/0016-WHATS_NEW-update.patch b/SOURCES/0016-WHATS_NEW-update.patch deleted file mode 100644 index cf83678..0000000 --- a/SOURCES/0016-WHATS_NEW-update.patch +++ /dev/null @@ -1,24 +0,0 @@ -From cce339d487194e3a27b7386a2e463416fb96b9f1 Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Wed, 13 Nov 2024 13:06:15 +0100 -Subject: [PATCH 3/3] WHATS_NEW: update - -(cherry picked from commit 473e93fbfff513f849e76eba919c44aa07608c30) ---- - WHATS_NEW | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index d07a1eaeb..bea47f154 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.03.29 - - ================== -+ Fix renaming of raid sub LVs when converting a volume to raid (2.03.28). - Fix segfault/VG write error for raid LV lvextend -i|--stripes -I|--stripesize. - Revert ignore -i|--stripes, -I|--stripesize for lvextend on raid0 LV (2.03.27). - --- -2.47.0 - diff --git a/SOURCES/0017-device_id-nvme-devices-may-use-alternate-wwids.patch b/SOURCES/0017-device_id-nvme-devices-may-use-alternate-wwids.patch deleted file mode 100644 index 995e6e0..0000000 --- a/SOURCES/0017-device_id-nvme-devices-may-use-alternate-wwids.patch +++ /dev/null @@ -1,805 +0,0 @@ -From 5f10e49c729eb6b723891426ceec59af2fe66c09 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Fri, 6 Dec 2024 15:02:20 -0600 -Subject: [PATCH 1/3] device_id: nvme devices may use alternate wwids - -Device quirks may cause sysfs wwid file to change what it -displays, from a bogus eui... string to an nvme... string. - -The old wwid may be saved in system.devices, so recognizing -the device requires finding the old value from libnvme. - -After matching the old bogus value using libnvme, system.devices -is updated with the current sysfs wwid value. - -(cherry picked from commit d952358636887348c390784a8ca5efb87b26784f) ---- - lib/Makefile.in | 1 + - lib/device/dev-mpath.c | 6 +- - lib/device/dev-type.c | 6 +- - lib/device/dev-type.h | 2 +- - lib/device/device.h | 16 ++- - lib/device/device_id.c | 174 +++++++++++++++++++++++--- - lib/device/device_id.h | 11 +- - lib/device/nvme.c | 273 +++++++++++++++++++++++++++++++++++++++++ - lib/device/parse_vpd.c | 8 +- - 9 files changed, 464 insertions(+), 33 deletions(-) - create mode 100644 lib/device/nvme.c - -diff --git a/lib/Makefile.in b/lib/Makefile.in -index 50c7a1fd2..8eab625aa 100644 ---- a/lib/Makefile.in -+++ b/lib/Makefile.in -@@ -43,6 +43,7 @@ SOURCES =\ - device/filesystem.c \ - device/online.c \ - device/parse_vpd.c \ -+ device/nvme.c \ - device/dev_util.c \ - display/display.c \ - error/errseg.c \ -diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c -index 72501e345..7450244b0 100644 ---- a/lib/device/dev-mpath.c -+++ b/lib/device/dev-mpath.c -@@ -595,7 +595,7 @@ static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev, - */ - lookup: - dm_list_iterate_items(dw, &dev->wwids) { -- if (dw->type == 1 || dw->type == 2 || dw->type == 3) -+ if (dw->scsi_type == 1 || dw->scsi_type == 2 || dw->scsi_type == 3) - wwid = &dw->id[4]; - else - wwid = dw->id; -@@ -615,7 +615,7 @@ lookup: - goto lookup; - - if (!(dev->flags & DEV_ADDED_SYS_WWID) && dev_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf), &dw)) { -- if (dw->type == 1 || dw->type == 2 || dw->type == 3) -+ if (dw->scsi_type == 1 || dw->scsi_type == 2 || dw->scsi_type == 3) - wwid = &dw->id[4]; - else - wwid = dw->id; -@@ -642,7 +642,7 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *h - /* - * multipath only uses SCSI or NVME devices - */ -- if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev)) -+ if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dev)) - return 0; - - /* -diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c -index c29fb21a8..7c6c10e01 100644 ---- a/lib/device/dev-type.c -+++ b/lib/device/dev-type.c -@@ -46,7 +46,7 @@ - * is excessive and unnecessary compared to just comparing /dev/name*. - */ - --int dev_is_nvme(struct dev_types *dt, struct device *dev) -+int dev_is_nvme(struct device *dev) - { - return (dev->flags & DEV_IS_NVME) ? 1 : 0; - } -@@ -562,7 +562,7 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev) - _loop_is_with_partscan(dev)) - return 1; - -- if (dev_is_nvme(dt, dev)) { -+ if (dev_is_nvme(dev)) { - /* If this dev is already a partition then it's not partitionable. */ - if (_has_sys_partition(dev)) - return 0; -@@ -790,7 +790,7 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result) - * block dev types that have their own major number, so - * the calculation based on minor number doesn't work. - */ -- if (dev_is_nvme(dt, dev)) -+ if (dev_is_nvme(dev)) - goto sys_partition; - - /* -diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h -index 60e5789f7..4708dd3e2 100644 ---- a/lib/device/dev-type.h -+++ b/lib/device/dev-type.h -@@ -98,7 +98,7 @@ int dev_is_rotational(struct dev_types *dt, struct device *dev); - - int dev_is_pmem(struct dev_types *dt, struct device *dev); - --int dev_is_nvme(struct dev_types *dt, struct device *dev); -+int dev_is_nvme(struct device *dev); - - int dev_is_lv(struct cmd_context *cmd, struct device *dev); - -diff --git a/lib/device/device.h b/lib/device/device.h -index af5e8a934..d5979e90b 100644 ---- a/lib/device/device.h -+++ b/lib/device/device.h -@@ -41,6 +41,8 @@ - #define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */ - #define DEV_SCAN_FOUND_NOLABEL 0x00100000 /* label_scan read, passed filters, but no lvm label */ - #define DEV_SCAN_NOT_READ 0x00200000 /* label_scan not able to read dev */ -+#define DEV_ADDED_NVME_WWIDS 0x00400000 /* wwids have been ready from libnvme */ -+#define DEV_UPDATE_USE_ID 0x00800000 /* update system.devices entry to use preferred wwid */ - - /* - * Support for external device info. -@@ -70,8 +72,12 @@ struct dev_ext { - #define DEV_ID_TYPE_WWID_NAA 9 - #define DEV_ID_TYPE_WWID_EUI 10 - #define DEV_ID_TYPE_WWID_T10 11 -+/* reserve 12 for "scsi name string" if we decide to add that */ -+#define DEV_ID_TYPE_NVME_EUI64 13 -+#define DEV_ID_TYPE_NVME_NGUID 14 -+#define DEV_ID_TYPE_NVME_UUID 15 - --/* Max length of WWID_NAA, WWID_EUI, WWID_T10 */ -+/* Max length of SCSI or NVME WWID */ - #define DEV_WWID_SIZE 128 - - /* -@@ -79,12 +85,14 @@ struct dev_ext { - * /sys/dev/block/%d:%d/device/wwid - * /sys/dev/block/%d:%d/wwid - * /sys/dev/block/%d:%d/device/vpd_pg83 -+ * or libnvme - */ - - struct dev_wwid { -- struct dm_list list; /* dev->wwids */ -- int type; /* 1,2,3 for NAA,EUI,T10 */ -- char id[DEV_WWID_SIZE]; /* includes prefix naa.,eui.,t10. */ -+ struct dm_list list; /* dev->wwids */ -+ uint16_t scsi_type; /* 1,2,3 for SCSI NAA,EUI,T10 */ -+ uint16_t nvme_type; /* 1,2,3 for NVME EUI64,NGUID,UUID */ -+ char id[DEV_WWID_SIZE]; /* includes prefix e.g. naa.,eui.,t10. */ - }; - - /* -diff --git a/lib/device/device_id.c b/lib/device/device_id.c -index 06788db32..34524f718 100644 ---- a/lib/device/device_id.c -+++ b/lib/device/device_id.c -@@ -568,7 +568,7 @@ static int _dev_has_lvmlv_uuid(struct cmd_context *cmd, struct device *dev, char - * The numbers 1,2,3 for NAA,EUI,T10 are part of the standard - * and are used in the vpd data. - */ --static int _wwid_type_num(char *id) -+static int _scsi_wwid_type_num(char *id) - { - if (!strncmp(id, "naa.", 4)) - return 3; -@@ -580,9 +580,9 @@ static int _wwid_type_num(char *id) - return 0; /* any unrecognized, non-standard prefix */ - } - --int wwid_type_to_idtype(int wwid_type) -+int scsi_type_to_idtype(int scsi_type) - { -- switch (wwid_type) { -+ switch (scsi_type) { - case 3: return DEV_ID_TYPE_WWID_NAA; - case 2: return DEV_ID_TYPE_WWID_EUI; - case 1: return DEV_ID_TYPE_WWID_T10; -@@ -591,7 +591,7 @@ int wwid_type_to_idtype(int wwid_type) - } - } - --int idtype_to_wwid_type(int idtype) -+int idtype_to_scsi_type(int idtype) - { - switch (idtype) { - case DEV_ID_TYPE_WWID_NAA: return 3; -@@ -602,6 +602,45 @@ int idtype_to_wwid_type(int idtype) - } - } - -+/* -+ * libnvme only returns the standard identifiers UUID/NGUID/EUI64 -+ * sysfs wwid file will return "nvme." identifier when one of the -+ * others is not available. -+ */ -+static int _nvme_wwid_type_num(char *id) -+{ -+ if (!strncmp(id, "uuid.", 5)) -+ return 3; /* UUID is 16 bytes */ -+ else if (!strncmp(id, "eui.", 4)) { -+ if (strlen(id) > 15) -+ return 2; /* NGUID is 16 bytes */ -+ return 1; /* EUI64 is 8 bytes */ -+ } -+ return 0; /* any other prefix, including "nvme.", which must come from sysfs wwid file */ -+} -+ -+int nvme_type_to_idtype(int nvme_type) -+{ -+ switch (nvme_type) { -+ case 3: return DEV_ID_TYPE_NVME_UUID; -+ case 2: return DEV_ID_TYPE_NVME_NGUID; -+ case 1: return DEV_ID_TYPE_NVME_EUI64; -+ case 0: return DEV_ID_TYPE_SYS_WWID; -+ default: return -1; -+ } -+} -+ -+int idtype_to_nvme_type(int idtype) -+{ -+ switch (idtype) { -+ case DEV_ID_TYPE_NVME_UUID: return 3; -+ case DEV_ID_TYPE_NVME_NGUID: return 2; -+ case DEV_ID_TYPE_NVME_EUI64: return 1; -+ case DEV_ID_TYPE_SYS_WWID: return 0; -+ default: return -1; -+ } -+} -+ - void free_wwids(struct dm_list *ids) - { - struct dev_wwid *dw, *safe; -@@ -620,22 +659,41 @@ void free_wwids(struct dm_list *ids) - * in /etc/multipath/wwids. - */ - --struct dev_wwid *dev_add_wwid(char *id, int id_type, struct dm_list *ids) -+struct dev_wwid *dev_add_wwid(char *id, int dw_type, int is_nvme, struct dm_list *ids) - { - struct dev_wwid *dw; -+ uint16_t scsi_type = 0; -+ uint16_t nvme_type = 0; -+ -+ if (is_nvme) -+ nvme_type = dw_type ?: _nvme_wwid_type_num(id); -+ else -+ scsi_type = dw_type ?: _scsi_wwid_type_num(id); - -- if (!id_type) -- id_type = _wwid_type_num(id); -+ /* nvme_type/scsi_type will be 0 for any sysfs wwid string that -+ doesn't begin with a prefix recognized by lvm, e.g. that -+ comes from sysfs wwid. */ - - if (!(dw = zalloc(sizeof(*dw)))) - return_NULL; - /* Copy id string with upto DEV_WWID_SIZE characters */ - dm_strncpy(dw->id, id, sizeof(dw->id)); -- dw->type = id_type; -+ dw->scsi_type = scsi_type; -+ dw->nvme_type = nvme_type; - dm_list_add(ids, &dw->list); - return dw; - } - -+struct dev_wwid *dev_add_scsi_wwid(char *id, int dw_type, struct dm_list *ids) -+{ -+ return dev_add_wwid(id, dw_type, 0, ids); -+} -+ -+struct dev_wwid *dev_add_nvme_wwid(char *id, int dw_type, struct dm_list *ids) -+{ -+ return dev_add_wwid(id, dw_type, 1, ids); -+} -+ - #define VPD_SIZE 4096 - - int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev) -@@ -693,9 +751,13 @@ int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev, - else - format_general_id((const char *)buf, sizeof(buf), (unsigned char *)outbuf, outbufsize); - -+ /* We don't currently add the sysfs wwid to dev->wwids for nvme, it's not needed. */ -+ if (dev_is_nvme(dev)) -+ return 1; -+ - /* Note, if wwids are also read from vpd, this same wwid will be added again. */ - -- if (!(dw = dev_add_wwid(buf, 0, &dev->wwids))) -+ if (!(dw = dev_add_wwid(buf, 0, dev_is_nvme(dev), &dev->wwids))) - return_0; - if (dw_out) - *dw_out = dw; -@@ -809,7 +871,17 @@ char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_ - if (!(dev->flags & DEV_ADDED_VPD_WWIDS)) - dev_read_vpd_wwids(cmd, dev); - dm_list_iterate_items(dw, &dev->wwids) { -- if (idtype_to_wwid_type(idtype) == dw->type) -+ if (idtype_to_scsi_type(idtype) == dw->scsi_type) -+ return strdup(dw->id); -+ } -+ return NULL; -+ case DEV_ID_TYPE_NVME_EUI64: -+ case DEV_ID_TYPE_NVME_NGUID: -+ case DEV_ID_TYPE_NVME_UUID: -+ if (!(dev->flags & DEV_ADDED_NVME_WWIDS)) -+ dev_read_nvme_wwids(dev); -+ dm_list_iterate_items(dw, &dev->wwids) { -+ if (idtype_to_nvme_type(idtype) == dw->nvme_type) - return strdup(dw->id); - } - return NULL; -@@ -823,6 +895,9 @@ char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_ - */ - if ((idtype != DEV_ID_TYPE_SYS_WWID) && - (idtype != DEV_ID_TYPE_SYS_SERIAL) && -+ (idtype != DEV_ID_TYPE_NVME_EUI64) && -+ (idtype != DEV_ID_TYPE_NVME_NGUID) && -+ (idtype != DEV_ID_TYPE_NVME_UUID) && - (idtype != DEV_ID_TYPE_WWID_NAA) && - (idtype != DEV_ID_TYPE_WWID_EUI) && - (idtype != DEV_ID_TYPE_WWID_T10)) { -@@ -1043,6 +1118,9 @@ static const char _dev_id_types[][16] = { - [DEV_ID_TYPE_WWID_NAA] = "wwid_naa", - [DEV_ID_TYPE_WWID_EUI] = "wwid_eui", - [DEV_ID_TYPE_WWID_T10] = "wwid_t10", -+ [DEV_ID_TYPE_NVME_EUI64] = "nvme_eui64", -+ [DEV_ID_TYPE_NVME_NGUID] = "nvme_nguid", -+ [DEV_ID_TYPE_NVME_UUID] = "nvme_uuid", - }; - - static int _is_idtype(uint16_t idtype) { -@@ -1107,6 +1185,17 @@ static const char *_dev_idname(struct device *dev, uint16_t idtype) - return NULL; - } - -+static struct dev_id *get_dev_id(struct device *dev, uint16_t idtype) -+{ -+ struct dev_id *id; -+ -+ dm_list_iterate_items(id, &dev->ids) { -+ if (id->idtype == idtype) -+ return id; -+ } -+ return NULL; -+} -+ - static int _dev_has_id(struct device *dev, uint16_t idtype, const char *idname) - { - struct dev_id *id; -@@ -2564,33 +2653,63 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct - */ - - /* -+ * SCSI: - * Make the du match this device if the dev has a vpd_pg83 wwid - * that matches du->idname, even if the sysfs wwid for dev did - * not match the du->idname. This could happen if sysfs changes - * which wwid it reports (there are often multiple), or if lvm in - * the future selects a sys_wwid value from vpd_pg83 data rather - * than from the sysfs wwid. -- * - * TODO: update the df entry IDTYPE somewhere? -+ * -+ * NVME: -+ * For some nvme drives (faulty hw, flagged with quirk), the sysfs wwid -+ * file changed to reporting a new/correct wwid. The du->idname may -+ * still have the wwid from the old sysfs wwid, so we need to look -+ * at the old wwids that can be found from libnvme. -+ * -+ * device_ids_validate updates system.devices to use the latest value -+ * from sysfs wwid. -+ * -+ * In future, we could limit dev_read_nvme_wwids() to only devices -+ * that have the quirk flag (indicating a bad wwid had been used.) -+ * dev_has_nvme_quirk() checks a flag in a newly exposed sysfs file. -+ * If that sysfs file doesn't exist because of an older kernel, then -+ * the function returns -1. When the quirk file exists and says 0, -+ * then the device hasn't changed its reported sys_wwid value, and -+ * we don't need to check libnvme for other wwids that the dev -+ * might have displayed in the past. - */ - if (du->idtype == DEV_ID_TYPE_SYS_WWID) { - struct dev_wwid *dw; - -- if (!(dev->flags & DEV_ADDED_VPD_WWIDS)) -+ if (!(dev->flags & DEV_ADDED_VPD_WWIDS) && !dev_is_nvme(dev)) - dev_read_vpd_wwids(cmd, dev); - -+ if (!(dev->flags & DEV_ADDED_NVME_WWIDS) && dev_is_nvme(dev)) -+ dev_read_nvme_wwids(dev); -+ - dm_list_iterate_items(dw, &dev->wwids) { - if (!strcmp(dw->id, du_idname)) { - if (!(id = zalloc(sizeof(struct dev_id)))) - return_0; -- /* wwid types are 1,2,3 and idtypes are DEV_ID_TYPE_ */ -- id->idtype = wwid_type_to_idtype(dw->type); -+ /* scsi/nvme types are 1,2,3 and idtypes are DEV_ID_TYPE_ */ -+ if (dev_is_nvme(dev)) -+ id->idtype = nvme_type_to_idtype(dw->nvme_type); -+ else -+ id->idtype = scsi_type_to_idtype(dw->scsi_type); - id->idname = strdup(dw->id); - dm_list_add(&dev->ids, &id->list); - du->dev = dev; - dev->id = id; - dev->flags |= DEV_MATCHED_USE_ID; -- log_debug("Match %s %s to %s: using vpd_pg83 %s %s", -+ -+ /* update system.devices with sysfs wwid value since IDTYPE=sys_wwid */ -+ /* FIXME: also do this for scsi */ -+ if (dev_is_nvme(dev)) -+ dev->flags |= DEV_UPDATE_USE_ID; -+ -+ log_debug("Match %s %s to %s: using extra %s %s", - idtype_to_str(du->idtype), du_idname, dev_name(dev), - idtype_to_str(id->idtype), id->idname ?: "."); - du->idtype = id->idtype; -@@ -2939,6 +3058,31 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, - du->dev ? dev_name(du->dev) : "not set"); - } - -+ /* -+ * Replace old wwid with new value displayed by sysfs wwid. -+ */ -+ dm_list_iterate_items(du, &cmd->use_devices) { -+ if (!du->dev) -+ continue; -+ if (!(du->dev->flags & DEV_UPDATE_USE_ID)) -+ continue; -+ if ((id = get_dev_id(du->dev, DEV_ID_TYPE_SYS_WWID)) && id->idname) { -+ log_debug("Validate %s %s PVID %s on %s: replace old wwid with %s", -+ idtype_to_str(du->idtype), du->idname ?: ".", du->pvid ?: ".", -+ dev_name(du->dev), id->idname); -+ if (!(tmpdup = strdup(id->idname))) -+ continue; -+ free(du->idname); -+ du->idtype = DEV_ID_TYPE_SYS_WWID; -+ du->idname = tmpdup; -+ du->dev->id = id; -+ update_file = 1; -+ } else { -+ log_warn("Device %s PVID %s is using only old wwid %s.", -+ dev_name(du->dev), du->pvid ?: ".", du->idname ?: "."); -+ } -+ } -+ - /* - * Validate entries with proper device id types. - * idname is the authority for pairing du and dev. -diff --git a/lib/device/device_id.h b/lib/device/device_id.h -index a67774f1b..b10df9bf4 100644 ---- a/lib/device/device_id.h -+++ b/lib/device/device_id.h -@@ -69,11 +69,16 @@ int read_sys_block_binary(struct cmd_context *cmd, struct device *dev, - - int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, char **idname_out); - --int wwid_type_to_idtype(int wwid_type); --int idtype_to_wwid_type(int idtype); -+int scsi_type_to_idtype(int wwid_type); -+int nvme_type_to_idtype(int wwid_type); -+int idtype_to_scsi_type(int idtype); -+int idtype_to_nvme_type(int idtype); - void free_wwids(struct dm_list *ids); --struct dev_wwid *dev_add_wwid(char *id, int id_type, struct dm_list *ids); -+struct dev_wwid *dev_add_wwid(char *id, int dw_type, int is_nvme, struct dm_list *ids); -+struct dev_wwid *dev_add_scsi_wwid(char *id, int dw_type, struct dm_list *ids); -+struct dev_wwid *dev_add_nvme_wwid(char *id, int dw_type, struct dm_list *ids); - int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev); -+void dev_read_nvme_wwids(struct device *dev); - int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev, - char *buf, int bufsize, struct dev_wwid **dw_out); - -diff --git a/lib/device/nvme.c b/lib/device/nvme.c -new file mode 100644 -index 000000000..aa4a7a947 ---- /dev/null -+++ b/lib/device/nvme.c -@@ -0,0 +1,273 @@ -+/* -+ * Copyright (C) 2024 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/commands/toolcontext.h" -+#include "lib/device/device.h" -+#include "lib/device/device_id.h" -+#include "lib/mm/xlate.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef NVME_SUPPORT -+#include -+ -+static int iszero(unsigned char *d, size_t n) -+{ -+ size_t i; -+ -+ for (i = 0; i < n; ++i) { -+ if (d[i]) -+ return 0; -+ } -+ return 1; -+} -+ -+static void _save_uuid(struct device *dev, unsigned char *uuid) -+{ -+ char idname[DEV_WWID_SIZE] = {0}; -+ int max, pos, num, i; -+ -+ max = sizeof(idname); -+ pos = 0; -+ -+ num = snprintf(idname + pos, max - pos, "uuid."); -+ if (num >= max - pos) -+ goto bad; -+ pos += num; -+ -+ for (i = 0; i < NVME_UUID_LEN; ++i) { -+ num = snprintf(idname + pos, max - pos, "%02x", uuid[i]); -+ if (num >= max - pos) -+ goto bad; -+ pos += num; -+ -+ if (i == 3 || i == 5 || i == 7 || i == 9) { -+ num = snprintf(idname + pos, max - pos, "-"); -+ if (num >= max - pos) -+ goto bad; -+ pos += num; -+ } -+ } -+ -+ idname[DEV_WWID_SIZE-1] = '\0'; -+ -+ dev_add_nvme_wwid(idname, 3, &dev->wwids); -+ -+ return; -+bad: -+ log_debug("dev_read_nvme_wwids ignore invalid uuid %s for %s", uuid, dev_name(dev)); -+} -+ -+static void _save_nguid(struct device *dev, unsigned char *nguid) -+{ -+ char idname[DEV_WWID_SIZE] = {0}; -+ int max, pos, num, i; -+ -+ max = sizeof(idname); -+ pos = 0; -+ -+ num = snprintf(idname + pos, max - pos, "eui."); -+ if (num >= max - pos) -+ goto bad; -+ pos += num; -+ -+ for (i = 0; i < 16; ++i) { -+ num = snprintf(idname + pos, max - pos, "%02x", nguid[i]); -+ if (num >= max - pos) -+ goto bad; -+ pos += num; -+ } -+ -+ idname[DEV_WWID_SIZE-1] = '\0'; -+ -+ dev_add_nvme_wwid(idname, 2, &dev->wwids); -+ -+ return; -+bad: -+ log_debug("dev_read_nvme_wwids ignore invalid nguid %s for %s", nguid, dev_name(dev)); -+} -+ -+static void _save_eui64(struct device *dev, unsigned char *eui64) -+{ -+ char idname[DEV_WWID_SIZE] = {0}; -+ int max, pos, num, i; -+ -+ max = sizeof(idname); -+ pos = 0; -+ -+ num = snprintf(idname + pos, max - pos, "eui."); -+ if (num >= max - pos) -+ goto bad; -+ pos += num; -+ -+ for (i = 0; i < 8; ++i) { -+ num = snprintf(idname + pos, max - pos, "%02x", eui64[i]); -+ if (num >= max - pos) -+ goto bad; -+ pos += num; -+ } -+ -+ idname[DEV_WWID_SIZE-1] = '\0'; -+ -+ dev_add_nvme_wwid(idname, 1, &dev->wwids); -+ -+ return; -+bad: -+ log_debug("dev_read_nvme_wwids ignore invalid eui64 %s for %s", eui64, dev_name(dev)); -+} -+ -+#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) -+static void *_nvme_alloc(size_t len) -+{ -+ size_t _len = ROUND_UP(len, 0x1000); -+ void *p; -+ -+ if (posix_memalign((void *)&p, getpagesize(), _len)) -+ return NULL; -+ -+ memset(p, 0, _len); -+ return p; -+} -+ -+void dev_read_nvme_wwids(struct device *dev) -+{ -+ const char *devpath; -+ unsigned char *data = NULL; -+ struct nvme_id_ns *ns = NULL; -+ struct nvme_id_ctrl *ctrl_id = NULL; -+ unsigned char nguid[16] = {0}; -+ unsigned char eui64[8] = {0}; -+ unsigned char uuid[NVME_UUID_LEN] = {0}; -+ uint32_t nsid; -+ int fd, i, len; -+ -+ dev->flags |= DEV_ADDED_NVME_WWIDS; -+ -+ /* shouldn't happen */ -+ if (dm_list_empty(&dev->aliases)) -+ return; -+ -+ devpath = dev_name(dev); -+ -+ if ((fd = open(devpath, O_RDONLY)) < 0) { -+ log_debug("dev_read_nvme_wwids cannot open %s", devpath); -+ return; -+ } -+ -+ if (nvme_get_nsid(fd, &nsid)) { -+ log_print("dev_read_nvme_wwids nvme_get_nsid error %d %s", errno, devpath); -+ goto out; -+ } -+ -+ if (!(ns = _nvme_alloc(sizeof(*ns)))) -+ goto_out; -+ -+ if (nvme_identify_ns(fd, nsid, ns)) { -+ log_debug("dev_read_nvme_wwids nvme_identify_ns error %d %s", errno, devpath); -+ goto out; -+ } -+ -+ memcpy(nguid, ns->nguid, 16); -+ memcpy(eui64, ns->eui64, 8); -+ -+ if (!iszero(nguid, 16)) -+ _save_nguid(dev, nguid); -+ if (!iszero(eui64, 8)) -+ _save_eui64(dev, eui64); -+ -+ if (!(ctrl_id = _nvme_alloc(sizeof(struct nvme_id_ctrl)))) -+ goto_out; -+ -+ /* Avoid using nvme_identify_ns_descs before ver 1.3. */ -+ if (!nvme_identify_ctrl(fd, ctrl_id)) { -+ if (le32_to_cpu(ctrl_id->ver) < 0x10300) -+ goto_out; -+ } -+ -+ if (!(data = _nvme_alloc(NVME_IDENTIFY_DATA_SIZE))) -+ goto_out; -+ -+ if (nvme_identify_ns_descs(fd, nsid, (struct nvme_ns_id_desc *)data)) { -+ log_debug("dev_read_nvme_wwids nvme_identify_ns_descs error %d %s", errno, devpath); -+ goto out; -+ } -+ -+ for (i = 0; i < NVME_IDENTIFY_DATA_SIZE; i += len) { -+ struct nvme_ns_id_desc *cur = (struct nvme_ns_id_desc *)(data + i); -+ -+ if (cur->nidl == 0) -+ break; -+ -+ memset(eui64, 0, sizeof(eui64)); -+ memset(nguid, 0, sizeof(nguid)); -+ memset(uuid, 0, sizeof(uuid)); -+ -+ switch (cur->nidt) { -+ case NVME_NIDT_EUI64: -+ memcpy(eui64, data + i + sizeof(*cur), sizeof(eui64)); -+ len = sizeof(eui64); -+ break; -+ case NVME_NIDT_NGUID: -+ memcpy(nguid, data + i + sizeof(*cur), sizeof(nguid)); -+ len = sizeof(nguid); -+ break; -+ case NVME_NIDT_UUID: -+ memcpy(uuid, data + i + sizeof(*cur), NVME_UUID_LEN); -+ len = sizeof(uuid); -+ break; -+ case NVME_NIDT_CSI: -+ len = 1; -+ break; -+ default: -+ len = cur->nidl; -+ break; -+ } -+ -+ len += sizeof(*cur); -+ -+ if (!iszero(uuid, NVME_UUID_LEN)) -+ _save_uuid(dev, uuid); -+ else if (!iszero(nguid, 16)) -+ _save_nguid(dev, nguid); -+ else if (!iszero(eui64, 8)) -+ _save_eui64(dev, eui64); -+ } -+out: -+ free(ctrl_id); -+ free(ns); -+ free(data); -+ close(fd); -+} -+#else -+void dev_read_nvme_wwids(struct device *dev) -+{ -+} -+#endif -diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c -index 968fd1f9c..16a653a14 100644 ---- a/lib/device/parse_vpd.c -+++ b/lib/device/parse_vpd.c -@@ -177,7 +177,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list - break; - if (id_size >= ID_BUFSIZE) - id_size = ID_BUFSIZE - 1; -- dev_add_wwid(id, 1, ids); -+ dev_add_scsi_wwid(id, 1, ids); - break; - case 0x2: - /* EUI-64 */ -@@ -203,7 +203,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list - break; - if (id_size >= ID_BUFSIZE) - id_size = ID_BUFSIZE - 1; -- dev_add_wwid(id, 2, ids); -+ dev_add_scsi_wwid(id, 2, ids); - break; - case 0x3: - /* NAA */ -@@ -225,7 +225,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list - break; - if (id_size >= ID_BUFSIZE) - id_size = ID_BUFSIZE - 1; -- dev_add_wwid(id, 3, ids); -+ dev_add_scsi_wwid(id, 3, ids); - break; - case 0x8: - /* SCSI name string */ -@@ -257,7 +257,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list - for (i = 0; i < strlen(id); i++) - id[i] = tolower(id[i]); - } -- dev_add_wwid(id, type, ids); -+ dev_add_scsi_wwid(id, type, ids); - break; - default: - break; --- -2.47.1 - diff --git a/SOURCES/0018-configure.ac-add-support-for-libnvme.patch b/SOURCES/0018-configure.ac-add-support-for-libnvme.patch deleted file mode 100644 index d1d0005..0000000 --- a/SOURCES/0018-configure.ac-add-support-for-libnvme.patch +++ /dev/null @@ -1,121 +0,0 @@ -From b2cec1fc0e879f5a7c7808c54e6eb92575d0e1cc Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Mon, 9 Dec 2024 14:33:39 +0100 -Subject: [PATCH 2/3] configure.ac: add support for libnvme - -Add 2 new options for linking libnvme with lvm2. -Option --without-libnvme, --disable-nvme-wwid - -(cherry picked from commit cb87e184bcbade1ac2da8fb611177f520169decd) ---- - configure.ac | 34 ++++++++++++++++++++++++++++++++++ - include/configure.h.in | 3 +++ - lib/Makefile.in | 2 +- - make.tmpl.in | 5 ++++- - 4 files changed, 42 insertions(+), 2 deletions(-) - -diff --git a/configure.ac b/configure.ac -index cbea6adc6..5d4999b2d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -217,6 +217,8 @@ test "$exec_prefix" = "NONE" && exec_prefix='${prefix}' - - AC_ARG_WITH(blkid, [AS_HELP_STRING([--without-blkid], [do not build with blkid library])], - [], with_blkid="yes") -+AC_ARG_WITH(libnvme, [AS_HELP_STRING([--without-libnvme], [do not build with libnvme library])], -+ [], with_libnvme="yes") - AC_ARG_WITH(systemd, [AS_HELP_STRING([--without-systemd], [do not build with systemd library])], - [], with_systemd="yes") - AC_ARG_WITH(udev, [AS_HELP_STRING([--without-udev], [do not build with udev library])], -@@ -1139,6 +1141,38 @@ AC_MSG_RESULT([$BLKID_WIPING]) - AC_DEFINE_UNQUOTED(DEFAULT_USE_BLKID_WIPING, [$DEFAULT_USE_BLKID_WIPING], - [Use blkid wiping by default.]) - -+################################################################################ -+dnl -- Enable nvme alternate WWID via libnvme -+AC_ARG_ENABLE(nvme-wwid, -+ AS_HELP_STRING([--disable-nvme-wwid], -+ [do not use libnvme to detect alternate WWIDs]), -+ NVME_WWID=$enableval, -+ [AS_IF([test "$with_libnvme" = "yes"], [NVME_WWID="maybe"], [NVME_WWID="no"])]) -+ -+# ATM NVME_WWID is the only user of libnvme, so skip checking for libnvme when disabled -+AS_IF([test "$NVME_WWID" = "no"], [with_libnvme="no"]) -+ -+AS_IF([test "$with_libnvme" = "yes"], [ -+ PKG_CHECK_MODULES([LIBNVME], [libnvme >= 1.4], [ -+ AC_CACHE_CHECK([for NVME_NIDT_CSI in libnvme.h], -+ [ac_cv_have_libnvme_csi], -+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include -+const int a = NVME_NIDT_CSI; -+ ])], [ac_cv_have_libnvme_csi="yes"], [ac_cv_have_libnvme_csi="no"])]) -+ -+ AS_IF([test "$NVME_WWID" != "no"], [ -+ AC_IF_YES(ac_cv_have_libnvme_csi, [NVME_WWID="yes" -+ AC_DEFINE(NVME_SUPPORT, 1, [Use libnvme for WWID.])], -+ [NVME_WWID="error"])]) -+ ], [AS_IF([test "$NVME_WWID" = "yes"], [NVME_WWID="error"])]) -+], [AS_IF([test "$NVME_WWID" = "yes"], [NVME_WWID="error"])]) -+ -+AS_IF([test "$NVME_WWID" = "error"], -+ [AC_MSG_ERROR([--enable-nvme-wwid requires libnvme library >= 1.1. (--with-libnvme=$with_libnvme)])]) -+ -+AC_MSG_CHECKING([whether to use libnvme for alternate WWIDs]) -+AC_MSG_RESULT([$NVME_WWID]) -+ - ################################################################################ - dnl -- Enable udev synchronization - AC_MSG_CHECKING([whether to enable synchronization with udev processing]) -diff --git a/include/configure.h.in b/include/configure.h.in -index 1dabd23c6..5a09f1d11 100644 ---- a/include/configure.h.in -+++ b/include/configure.h.in -@@ -633,6 +633,9 @@ - /* Define to 1 to include code that uses dbus notification. */ - #undef NOTIFYDBUS_SUPPORT - -+/* Use libnvme for WWID. */ -+#undef NVME_SUPPORT -+ - /* Define to 1 to enable O_DIRECT support. */ - #undef O_DIRECT_SUPPORT - -diff --git a/lib/Makefile.in b/lib/Makefile.in -index 8eab625aa..8424ac952 100644 ---- a/lib/Makefile.in -+++ b/lib/Makefile.in -@@ -143,7 +143,7 @@ LIB_STATIC = $(LIB_NAME).a - CFLOW_LIST = $(SOURCES) - CFLOW_LIST_TARGET = $(LIB_NAME).cflow - --PROGS_CFLAGS = $(BLKID_CFLAGS) $(UDEV_CFLAGS) -+PROGS_CFLAGS = $(BLKID_CFLAGS) $(LIBNVME_CFLAGS) $(UDEV_CFLAGS) - - include $(top_builddir)/make.tmpl - -diff --git a/make.tmpl.in b/make.tmpl.in -index c8a870a8e..878288938 100644 ---- a/make.tmpl.in -+++ b/make.tmpl.in -@@ -57,7 +57,8 @@ PYTHON3 = @PYTHON3@ - PYCOMPILE = $(top_srcdir)/autoconf/py-compile - - LIBS += @LIBS@ $(SELINUX_LIBS) $(UDEV_LIBS) $(RT_LIBS) $(M_LIBS) --LVMLIBS = $(DMEVENT_LIBS) $(READLINE_LIBS) $(EDITLINE_LIBS) $(LIBSYSTEMD_LIBS) $(BLKID_LIBS) $(AIO_LIBS) $(LIBS) -+LVMLIBS = $(DMEVENT_LIBS) $(READLINE_LIBS) $(EDITLINE_LIBS) $(LIBSYSTEMD_LIBS)\ -+ $(BLKID_LIBS) $(LIBNVME_LIBS) $(AIO_LIBS) $(LIBS) - # Extra libraries always linked with static binaries - STATIC_LIBS = $(PTHREAD_LIBS) $(SELINUX_STATIC_LIBS) $(UDEV_STATIC_LIBS) $(BLKID_STATIC_LIBS) $(M_LIBS) - DEFS += @DEFS@ -@@ -88,6 +89,8 @@ LIBDLM_CFLAGS = @LIBDLM_CFLAGS@ - LIBDLM_LIBS = @LIBDLM_LIBS@ - LIBDLMCONTROL_CFLAGS = @LIBDLMCONTROL_CFLAGS@ - LIBDLMCONTROL_LIBS = @LIBDLMCONTROL_LIBS@ -+LIBNVME_CFLAGS = @LIBNVME_CFLAGS@ -+LIBNVME_LIBS = @LIBNVME_LIBS@ - LIBSANLOCKCLIENT_CFLAGS = @LIBSANLOCKCLIENT_CFLAGS@ - LIBSANLOCKCLIENT_LIBS = @LIBSANLOCKCLIENT_LIBS@ - LIBSEAGATEILM_CFLAGS = @LIBSEAGATEILM_CFLAGS@ --- -2.47.1 - diff --git a/SOURCES/0019-configure-autoreconf.patch b/SOURCES/0019-configure-autoreconf.patch deleted file mode 100644 index 716e99e..0000000 --- a/SOURCES/0019-configure-autoreconf.patch +++ /dev/null @@ -1,271 +0,0 @@ -From f8d2dda397803b2c274da8eec78b04423c5150dd Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Mon, 9 Dec 2024 14:35:16 +0100 -Subject: [PATCH 3/3] configure: autoreconf - -(cherry picked from commit 928b8e9c6eaf871b3405b91c64eac5ea854f2572) ---- - configure | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 191 insertions(+) - -diff --git a/configure b/configure -index 5147c7910..e98f7c1f3 100755 ---- a/configure -+++ b/configure -@@ -787,6 +787,8 @@ LIBSYSTEMD_LIBS - LIBSYSTEMD_CFLAGS - UDEV_LIBS - UDEV_CFLAGS -+LIBNVME_LIBS -+LIBNVME_CFLAGS - BLKID_LIBS - BLKID_CFLAGS - SYSTEMD_RUN_CMD -@@ -912,6 +914,7 @@ enable_silent_rules - enable_static_link - enable_shared - with_blkid -+with_libnvme - with_systemd - with_udev - with_user -@@ -973,6 +976,7 @@ enable_systemd_journal - enable_app_machineid - with_systemd_run - enable_blkid_wiping -+enable_nvme_wwid - enable_udev_sync - enable_udev_rules - enable_udev_rule_exec_detection -@@ -1045,6 +1049,8 @@ LIBSEAGATEILM_CFLAGS - LIBSEAGATEILM_LIBS - BLKID_CFLAGS - BLKID_LIBS -+LIBNVME_CFLAGS -+LIBNVME_LIBS - UDEV_CFLAGS - UDEV_LIBS - LIBSYSTEMD_CFLAGS -@@ -1715,6 +1721,7 @@ Optional Features: - --disable-app-machineid disable LVM system ID using app-specific machine-id - --disable-blkid_wiping disable libblkid detection of signatures when wiping - and use native code instead -+ --disable-nvme-wwid do not use libnvme to detect alternate WWIDs - --enable-udev_sync enable synchronization with udev processing - --enable-udev_rules install rule files needed for udev synchronization - --enable-udev-rule-exec-detection -@@ -1741,6 +1748,7 @@ Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --without-blkid do not build with blkid library -+ --without-libnvme do not build with libnvme library - --without-systemd do not build with systemd library - --without-udev do not build with udev library - --with-user=USER set the owner of installed files [USER=] -@@ -1880,6 +1888,10 @@ Some influential environment variables: - BLKID_CFLAGS - C compiler flags for BLKID, overriding pkg-config - BLKID_LIBS linker flags for BLKID, overriding pkg-config -+ LIBNVME_CFLAGS -+ C compiler flags for LIBNVME, overriding pkg-config -+ LIBNVME_LIBS -+ linker flags for LIBNVME, overriding pkg-config - UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config - UDEV_LIBS linker flags for UDEV, overriding pkg-config - LIBSYSTEMD_CFLAGS -@@ -9128,6 +9140,16 @@ esac - fi - - -+# Check whether --with-libnvme was given. -+if test ${with_libnvme+y} -+then : -+ withval=$with_libnvme; -+else case e in #( -+ e) with_libnvme="yes" ;; -+esac -+fi -+ -+ - # Check whether --with-systemd was given. - if test ${with_systemd+y} - then : -@@ -13129,6 +13151,175 @@ printf "%s\n" "$BLKID_WIPING" >&6; } - printf "%s\n" "#define DEFAULT_USE_BLKID_WIPING $DEFAULT_USE_BLKID_WIPING" >>confdefs.h - - -+################################################################################ -+# Check whether --enable-nvme-wwid was given. -+if test ${enable_nvme_wwid+y} -+then : -+ enableval=$enable_nvme_wwid; NVME_WWID=$enableval -+else case e in #( -+ e) if test "$with_libnvme" = "yes" -+then : -+ NVME_WWID="maybe" -+else case e in #( -+ e) NVME_WWID="no" ;; -+esac -+fi ;; -+esac -+fi -+ -+ -+# ATM NVME_WWID is the only user of libnvme, so skip checking for libnvme when disabled -+if test "$NVME_WWID" = "no" -+then : -+ with_libnvme="no" -+fi -+ -+if test "$with_libnvme" = "yes" -+then : -+ -+ -+pkg_failed=no -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libnvme >= 1.4" >&5 -+printf %s "checking for libnvme >= 1.4... " >&6; } -+ -+if test -n "$LIBNVME_CFLAGS"; then -+ pkg_cv_LIBNVME_CFLAGS="$LIBNVME_CFLAGS" -+ elif test -n "$PKG_CONFIG"; then -+ if test -n "$PKG_CONFIG" && \ -+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnvme >= 1.4\""; } >&5 -+ ($PKG_CONFIG --exists --print-errors "libnvme >= 1.4") 2>&5 -+ ac_status=$? -+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ pkg_cv_LIBNVME_CFLAGS=`$PKG_CONFIG --cflags "libnvme >= 1.4" 2>/dev/null` -+ test "x$?" != "x0" && pkg_failed=yes -+else -+ pkg_failed=yes -+fi -+ else -+ pkg_failed=untried -+fi -+if test -n "$LIBNVME_LIBS"; then -+ pkg_cv_LIBNVME_LIBS="$LIBNVME_LIBS" -+ elif test -n "$PKG_CONFIG"; then -+ if test -n "$PKG_CONFIG" && \ -+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnvme >= 1.4\""; } >&5 -+ ($PKG_CONFIG --exists --print-errors "libnvme >= 1.4") 2>&5 -+ ac_status=$? -+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ pkg_cv_LIBNVME_LIBS=`$PKG_CONFIG --libs "libnvme >= 1.4" 2>/dev/null` -+ test "x$?" != "x0" && pkg_failed=yes -+else -+ pkg_failed=yes -+fi -+ else -+ pkg_failed=untried -+fi -+ -+ -+ -+if test $pkg_failed = yes; then -+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+printf "%s\n" "no" >&6; } -+ -+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then -+ _pkg_short_errors_supported=yes -+else -+ _pkg_short_errors_supported=no -+fi -+ if test $_pkg_short_errors_supported = yes; then -+ LIBNVME_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnvme >= 1.4" 2>&1` -+ else -+ LIBNVME_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnvme >= 1.4" 2>&1` -+ fi -+ # Put the nasty error message in config.log where it belongs -+ echo "$LIBNVME_PKG_ERRORS" >&5 -+ -+ if test "$NVME_WWID" = "yes" -+then : -+ NVME_WWID="error" -+fi -+elif test $pkg_failed = untried; then -+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+printf "%s\n" "no" >&6; } -+ if test "$NVME_WWID" = "yes" -+then : -+ NVME_WWID="error" -+fi -+else -+ LIBNVME_CFLAGS=$pkg_cv_LIBNVME_CFLAGS -+ LIBNVME_LIBS=$pkg_cv_LIBNVME_LIBS -+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+printf "%s\n" "yes" >&6; } -+ -+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for NVME_NIDT_CSI in libnvme.h" >&5 -+printf %s "checking for NVME_NIDT_CSI in libnvme.h... " >&6; } -+if test ${ac_cv_have_libnvme_csi+y} -+then : -+ printf %s "(cached) " >&6 -+else case e in #( -+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+#include -+const int a = NVME_NIDT_CSI; -+ -+int -+main (void) -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_compile "$LINENO" -+then : -+ ac_cv_have_libnvme_csi="yes" -+else case e in #( -+ e) ac_cv_have_libnvme_csi="no" ;; -+esac -+fi -+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -+esac -+fi -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_libnvme_csi" >&5 -+printf "%s\n" "$ac_cv_have_libnvme_csi" >&6; } -+ -+ if test "$NVME_WWID" != "no" -+then : -+ -+ if test $ac_cv_have_libnvme_csi = yes -+then : -+ NVME_WWID="yes" -+ -+printf "%s\n" "#define NVME_SUPPORT 1" >>confdefs.h -+ -+else case e in #( -+ e) NVME_WWID="error" ;; -+esac -+fi -+fi -+ -+fi -+ -+else case e in #( -+ e) if test "$NVME_WWID" = "yes" -+then : -+ NVME_WWID="error" -+fi ;; -+esac -+fi -+ -+if test "$NVME_WWID" = "error" -+then : -+ as_fn_error $? "--enable-nvme-wwid requires libnvme library >= 1.1. (--with-libnvme=$with_libnvme)" "$LINENO" 5 -+fi -+ -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use libnvme for alternate WWIDs" >&5 -+printf %s "checking whether to use libnvme for alternate WWIDs... " >&6; } -+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NVME_WWID" >&5 -+printf "%s\n" "$NVME_WWID" >&6; } -+ - ################################################################################ - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable synchronization with udev processing" >&5 - printf %s "checking whether to enable synchronization with udev processing... " >&6; } --- -2.47.1 - diff --git a/SOURCES/0020-thin-deactivate-converted-volume-early.patch b/SOURCES/0020-thin-deactivate-converted-volume-early.patch deleted file mode 100644 index b3ae59e..0000000 --- a/SOURCES/0020-thin-deactivate-converted-volume-early.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 4627ca20dc6314aa382aa21e22aacd32a81a50a2 Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Thu, 19 Dec 2024 14:47:16 +0100 -Subject: [PATCH 20/27] thin: deactivate converted volume early - -Deactivate converted volume to pool early, so the conversion -exits early and does not leave some already created metadata -volumes that needed manual cleanup by user after command -aborted its conversion operation when the converted volume -was actually in-use (i.e. when user tried to convert -a mounted LV into a thin-pool, 2 extra volumes needed removal). - -(cherry picked from commit 6326d0093730fe945eeb4748738ddda55bf8a3c9) ---- - tools/lvconvert.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/tools/lvconvert.c b/tools/lvconvert.c -index 8dd8eea1b..d15e01fd7 100644 ---- a/tools/lvconvert.c -+++ b/tools/lvconvert.c -@@ -3154,6 +3154,13 @@ static int _lvconvert_to_pool(struct cmd_context *cmd, - - activate_pool = to_thinpool && is_active; - -+ /* Before the conversion starts, make sure the volume is unused and can be deactivated -+ * (as it needs to change target type) */ -+ if (is_active && !to_thin && !deactivate_lv(cmd, lv)) { -+ log_error("Cannot convert logical volume %s.", display_lvname(lv)); -+ return 0; -+ } -+ - /* Wipe metadata_lv by default, but allow skipping this for cache pools. */ - zero_metadata = (to_cachepool) ? arg_int_value(cmd, zero_ARG, 1) : 1; - -@@ -3405,13 +3412,6 @@ static int _lvconvert_to_pool(struct cmd_context *cmd, - if (!(pool_lv = _lvconvert_insert_thin_layer(lv))) - goto_bad; - } else { -- /* Deactivate the data LV (changing target type) */ -- if (!deactivate_lv(cmd, lv)) { -- log_error("Aborting. Failed to deactivate logical volume %s.", -- display_lvname(lv)); -- goto bad; -- } -- - if (data_vdo) { - if (lv_is_vdo(lv)) { - if ((seg = first_seg(lv))) --- -2.47.1 - diff --git a/SOURCES/0021-tests-check-conversion-of-in-use-volume.patch b/SOURCES/0021-tests-check-conversion-of-in-use-volume.patch deleted file mode 100644 index 21d11b1..0000000 --- a/SOURCES/0021-tests-check-conversion-of-in-use-volume.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 41aaea4349ff2ef9b80de285e72ba7b94adfcf1a Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Thu, 19 Dec 2024 14:50:32 +0100 -Subject: [PATCH 21/27] tests: check conversion of in-use volume - -Thin-pool conversion fails early when trying to convert -volume which is in use (simulated by sleep <) - -(cherry picked from commit 3e641578d80bc7a28bcb451115b06da87d232b3a) ---- - test/shell/lvconvert-thin-vdo.sh | 20 +++++++++++++++++++- - 1 file changed, 19 insertions(+), 1 deletion(-) - -diff --git a/test/shell/lvconvert-thin-vdo.sh b/test/shell/lvconvert-thin-vdo.sh -index d61126276..5b4fe9d97 100644 ---- a/test/shell/lvconvert-thin-vdo.sh -+++ b/test/shell/lvconvert-thin-vdo.sh -@@ -34,11 +34,29 @@ which mkfs.ext4 || skip - - aux prepare_vg 4 6400 - --# convert to thin-pool with VDO backend from existing VG/LV -+# Convert to thin-pool with VDO backend from existing VG/LV - lvcreate -L5G --name $lv1 $vg -+ -+# Keep volume in use for 6 seconds -+# - lvm retries for ~5sec to deactivate -+sleep 6 < "$DM_DEV_DIR/$vg/$lv1" & -+ -+# Volume in use cannot be converted -+fail lvconvert -y --type thin-pool $vg/$lv1 --pooldatavdo y -+ -+# Wait for sleep to not use LV anymore -+wait -+ -+# No extra volume should appear in VG after failure -+test "$(get vg_field $vg lv_count)" -eq "1" -+ - mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1" - # Conversion caught present filesystem and should fail - fail lvconvert -Wy --type thin-pool -c 256K --deduplication n --pooldatavdo y $vg/$lv1 -+ -+# No extra volume should appear in VG after failure -+test "$(get vg_field $vg lv_count)" -eq "1" -+ - # With --yes it should work over prompt - lvconvert --yes -Wy --type thin-pool -c 256K --deduplication n --pooldatavdo y $vg/$lv1 - --- -2.47.1 - diff --git a/SOURCES/0022-WHATS_NEW-update.patch b/SOURCES/0022-WHATS_NEW-update.patch deleted file mode 100644 index 334f06a..0000000 --- a/SOURCES/0022-WHATS_NEW-update.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 93aed329721d82d3110014f3f3b1b2803a60f50c Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Thu, 19 Dec 2024 14:57:43 +0100 -Subject: [PATCH 22/27] WHATS_NEW: update - -(cherry picked from commit 5ef958704c82c45a6bd8215d920e4366c0c5e1bd) ---- - WHATS_NEW | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index bea47f154..e63dfc393 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,3 +1,7 @@ -+Version 2.03.30 - -+================== -+ lvconvert detects early volume in use when converting it to a pool. -+ - Version 2.03.29 - - ================== - Fix renaming of raid sub LVs when converting a volume to raid (2.03.28). --- -2.47.1 - diff --git a/SOURCES/0023-lv_manip-check-fs-resize-is-supported-before-LV-exte.patch b/SOURCES/0023-lv_manip-check-fs-resize-is-supported-before-LV-exte.patch deleted file mode 100644 index 987e0f3..0000000 --- a/SOURCES/0023-lv_manip-check-fs-resize-is-supported-before-LV-exte.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 9d9c8b8676b4fe21a0ff69e4c5d9e4a4a861f76e Mon Sep 17 00:00:00 2001 -From: Peter Rajnoha -Date: Fri, 3 Jan 2025 10:52:47 +0100 -Subject: [PATCH 23/27] lv_manip: check fs resize is supported before LV - extension -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This avoids a situation where we would extend an LV and then we would -not do anything to the FS on it because the FS info check failed for some -reason, like the type was not supported (e.g. swap) or we could not resize -the FS unless being in some supported state (e.g. XFS to be mounted for -the xfs_growfs to work). - -Before this patch (LV resized, FS not resized): - -❯ lvextend --fs resize -L+4M vg/swap - Size of logical volume vg/swap changed from 32.00 MiB (8 extents) to 36.00 MiB (9 extents). - File system extend is not supported (swap). - File system extend error. - Logical volume vg/swap successfully resized. - -With this patch (LV not resized, FS not resized): - -❯ lvextend --fs resize -L+4M vg/swap - File system extend is not supported (swap). - -(cherry picked from commit 5f53ecda3600834e920eef14065d35cd0fb6c59b) ---- - lib/metadata/lv_manip.c | 71 +++++++++++++++++++++-------------------- - 1 file changed, 36 insertions(+), 35 deletions(-) - -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index 15a7f3c9a..dab160234 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -6550,23 +6550,18 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv, - return ret; - } - --static int _fs_extend(struct cmd_context *cmd, struct logical_volume *lv, -- struct lvresize_params *lp) -+static int _fs_extend_check_fsinfo(struct cmd_context *cmd, struct logical_volume *lv, struct lvresize_params *lp, -+ struct fs_info *fsinfo, uint64_t *newsize_bytes_fs) - { -- struct fs_info fsinfo; - uint64_t newsize_bytes_lv; -- uint64_t newsize_bytes_fs; -- int ret = 0; - -- memset(&fsinfo, 0, sizeof(fsinfo)); -+ memset(fsinfo, 0, sizeof(*fsinfo)); - -- if (!fs_get_info(cmd, lv, &fsinfo, 1)) -- goto_out; -+ if (!fs_get_info(cmd, lv, fsinfo, 1)) -+ return 0; - -- if (fsinfo.nofs) { -- ret = 1; -- goto_out; -- } -+ if (fsinfo->nofs) -+ return 1; - - /* - * Note: here in the case of extend, newsize_bytes_lv/newsize_bytes_fs -@@ -6577,40 +6572,43 @@ static int _fs_extend(struct cmd_context *cmd, struct logical_volume *lv, - - /* extent_size units is SECTOR_SIZE (512) */ - newsize_bytes_lv = (uint64_t) lp->extents * lv->vg->extent_size * SECTOR_SIZE; -- newsize_bytes_fs = newsize_bytes_lv; -- if (fsinfo.needs_crypt) { -- newsize_bytes_fs -= fsinfo.crypt_offset_bytes; -+ *newsize_bytes_fs = newsize_bytes_lv; -+ if (fsinfo->needs_crypt) { -+ *newsize_bytes_fs -= fsinfo->crypt_offset_bytes; - log_print_unless_silent("File system size %llub is adjusted for crypt data offset %ub.", -- (unsigned long long)newsize_bytes_fs, fsinfo.crypt_offset_bytes); -+ (unsigned long long)*newsize_bytes_fs, fsinfo->crypt_offset_bytes); - } - - /* - * Decide if fs should be extended based on the --fs option, - * the fs type and the mount state. - */ -- if (!_fs_extend_allow(cmd, lv, lp, &fsinfo)) -- goto_out; -+ if (!_fs_extend_allow(cmd, lv, lp, fsinfo)) -+ return 0; -+ -+ return 1; -+} - -+static int _fs_extend(struct cmd_context *cmd, struct logical_volume *lv, -+ struct lvresize_params *lp, struct fs_info *fsinfo, uint64_t newsize_bytes_fs) -+{ - /* - * fs extend is not needed - */ -- if (!fsinfo.needs_extend) { -- ret = 1; -- goto_out; -- } -+ if (!fsinfo->needs_extend) -+ return 1; - - if (test_mode()) { -- if (fsinfo.needs_unmount) -+ if (fsinfo->needs_unmount) - log_print_unless_silent("Skip unmount in test mode."); -- if (fsinfo.needs_fsck) -+ if (fsinfo->needs_fsck) - log_print_unless_silent("Skip fsck in test mode."); -- if (fsinfo.needs_mount) -+ if (fsinfo->needs_mount) - log_print_unless_silent("Skip mount in test mode."); -- if (fsinfo.needs_crypt) -+ if (fsinfo->needs_crypt) - log_print_unless_silent("Skip cryptsetup in test mode."); - log_print_unless_silent("Skip fs extend in test mode."); -- ret = 1; -- goto out; -+ return 1; - } - - /* -@@ -6621,12 +6619,7 @@ static int _fs_extend(struct cmd_context *cmd, struct logical_volume *lv, - */ - unlock_vg(cmd, lv->vg, lv->vg->name); - -- if (!fs_extend_script(cmd, lv, &fsinfo, newsize_bytes_fs, lp->fsmode)) -- goto_out; -- -- ret = 1; -- out: -- return ret; -+ return fs_extend_script(cmd, lv, fsinfo, newsize_bytes_fs, lp->fsmode); - } - - int lv_resize(struct cmd_context *cmd, struct logical_volume *lv, -@@ -6640,6 +6633,8 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv, - struct logical_volume *lv_meta = NULL; - struct logical_volume *lv_main_layer = NULL; - struct logical_volume *lv_meta_layer = NULL; -+ struct fs_info fsinfo; -+ uint64_t newsize_bytes_fs; - int main_size_matches = 0; - int meta_size_matches = 0; - int is_extend = (lp->resize == LV_EXTEND); -@@ -7100,6 +7095,12 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv, - - if (!lv_main) - goto end_main; -+ -+ if (is_extend && lp->fsopt[0] && strcmp(lp->fsopt, "resize_fsadm")) { -+ if (!_fs_extend_check_fsinfo(cmd, lv_top, lp, &fsinfo, &newsize_bytes_fs)) -+ goto_out; -+ } -+ - if (!_lv_resize_volume(lv_main, lp, lp->pvh)) - goto_out; - if (!lp->size_changed) { -@@ -7145,7 +7146,7 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv, - } - } else { - /* New approach to fs handling using fs info. */ -- if (!_fs_extend(cmd, lv_top, lp)) { -+ if (!_fs_extend(cmd, lv_top, lp, &fsinfo, newsize_bytes_fs)) { - log_error("File system extend error."); - lp->extend_fs_error = 1; - goto out; --- -2.47.1 - diff --git a/SOURCES/0024-tests-adjust-lvresize-xfs-tests-for-recent-lvextend-.patch b/SOURCES/0024-tests-adjust-lvresize-xfs-tests-for-recent-lvextend-.patch deleted file mode 100644 index e7949fc..0000000 --- a/SOURCES/0024-tests-adjust-lvresize-xfs-tests-for-recent-lvextend-.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 97713c89cfa6d13488ecffa4eb66457619aa294a Mon Sep 17 00:00:00 2001 -From: Peter Rajnoha -Date: Fri, 3 Jan 2025 15:26:27 +0100 -Subject: [PATCH 24/27] tests: adjust lvresize-xfs tests for recent lvextend - changes - -Because now, we are doing the fsinfo check before extending an LV and if -that check fails, we do not proceed to the LV extension itself and the -lvextend command bails out immediatelly. - -(cherry picked from commit e86a75b4fe5873f563c930a575f54143ddca7c7c) ---- - test/shell/lvresize-xfs.sh | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/test/shell/lvresize-xfs.sh b/test/shell/lvresize-xfs.sh -index 87fbf6f9d..17bc6fba3 100644 ---- a/test/shell/lvresize-xfs.sh -+++ b/test/shell/lvresize-xfs.sh -@@ -104,13 +104,12 @@ lvremove -f $vg/$lv - #################### - - # lvextend, xfs, active, mounted, --fs resize --fsmode offline --lvcreate -n $lv -L 300M $vg -+lvcreate -n $lv -L 320M $vg - mkfs.xfs "$DM_DEV_DIR/$vg/$lv" - mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir_space" - df --output=size "$mount_dir_space" |tee df1 - dd if=/dev/zero of="$mount_dir_space/zeros1" bs=1M count=20 oflag=direct --# xfs_growfs requires the fs to be mounted, so extending the lv is --# succeeds, then the xfs extend fails because it cannot be done unmounted -+# xfs_growfs requires the fs to be mounted, so the lvextend fails here - not lvextend --fs resize --fsmode offline -L+20M $vg/$lv - check lv_field $vg/$lv lv_size "320.00m" - df | tee dfa -@@ -136,7 +135,7 @@ umount "$mount_dir_space" - # xfs_growfs requires the fs to be mounted to grow, so --fsmode nochange - # with an unmounted fs fails - not lvextend --fs resize --fsmode nochange -L+20M $vg/$lv --check lv_field $vg/$lv lv_size "380.00m" -+check lv_field $vg/$lv lv_size "360.00m" - mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir_space" - df --output=size "$mount_dir_space" |tee df4 - # fs not extended so fs size not changed -@@ -147,7 +146,7 @@ umount "$mount_dir_space" - # --yes needed because mount changes are required and plain "resize" - # fsopt did not specify if the user wants to change mount state - lvextend --yes --fs resize -L+10M $vg/$lv --check lv_field $vg/$lv lv_size "390.00m" -+check lv_field $vg/$lv lv_size "370.00m" - mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir_space" - df --output=size "$mount_dir_space" |tee df5 - not diff df4 df5 -@@ -155,7 +154,7 @@ umount "$mount_dir_space" - - # lvextend, xfs, active, unmounted, --fs resize_fsadm - lvextend --fs resize_fsadm -L+10M $vg/$lv --check lv_field $vg/$lv lv_size "400.00m" -+check lv_field $vg/$lv lv_size "380.00m" - mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir_space" - df --output=size "$mount_dir_space" |tee df6 - not diff df5 df6 --- -2.47.1 - diff --git a/SOURCES/0025-WHATS_NEW-update.patch b/SOURCES/0025-WHATS_NEW-update.patch deleted file mode 100644 index bc63217..0000000 --- a/SOURCES/0025-WHATS_NEW-update.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 7027d3897aba329a735998e3022482a1b7447ec1 Mon Sep 17 00:00:00 2001 -From: Peter Rajnoha -Date: Mon, 6 Jan 2025 15:35:44 +0100 -Subject: [PATCH 25/27] WHATS_NEW: update - -(cherry picked from commit 1576273273b84bc8d3d330f113ffb1ac67f2c0a2) ---- - WHATS_NEW | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index e63dfc393..40c6c2cd0 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.03.30 - - ================== -+ Do not extend an LV if FS resize unsupported and '--fs resize' used. - lvconvert detects early volume in use when converting it to a pool. - - Version 2.03.29 - --- -2.47.1 - diff --git a/SOURCES/0026-memlock-check-for-proper-reserved-size.patch b/SOURCES/0026-memlock-check-for-proper-reserved-size.patch deleted file mode 100644 index 53681b4..0000000 --- a/SOURCES/0026-memlock-check-for-proper-reserved-size.patch +++ /dev/null @@ -1,42 +0,0 @@ -From f3eb858a302ec27801ee8bbe90030c0c2f8cc3fe Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Wed, 8 Jan 2025 17:48:53 +0100 -Subject: [PATCH 26/27] memlock: check for proper reserved size - -Fix regression introduced with commit: -964012fdb924076e9ab97fabe00e759ddbf7c3bd -that effectively disabled memory locking before suspending volumes. -From merging/testing there remained wrong condition -as we really want to check for 0 memory reservation value -for both checked settings. - -(cherry picked from commit 4ef211a187dac348fa1857d577f5c17c9dace190) ---- - lib/mm/memlock.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/lib/mm/memlock.c b/lib/mm/memlock.c -index e28044df6..e7b0b4f7a 100644 ---- a/lib/mm/memlock.c -+++ b/lib/mm/memlock.c -@@ -517,7 +517,7 @@ static void _restore_priority_if_possible(struct cmd_context *cmd) - /* Stop memory getting swapped out */ - static void _lock_mem(struct cmd_context *cmd) - { -- if (!_size_stack || _size_malloc_tmp) { -+ if (!_size_stack || !_size_malloc_tmp) { - log_debug_mem("Skipping memory locking (reserved memory: " - FMTsize_t " stack: " FMTsize_t ").", - _size_malloc_tmp, _size_stack); -@@ -564,7 +564,7 @@ static void _unlock_mem(struct cmd_context *cmd) - { - size_t unlock_mstats = 0; - -- if (!_size_stack || _size_malloc_tmp) { -+ if (!_size_stack || !_size_malloc_tmp) { - log_debug_mem("Skipping memory unlocking (reserved memory: " - FMTsize_t " stack: " FMTsize_t ").", - _size_malloc_tmp, _size_stack); --- -2.47.1 - diff --git a/SOURCES/0027-WHATS_NEW-update.patch b/SOURCES/0027-WHATS_NEW-update.patch deleted file mode 100644 index 5120252..0000000 --- a/SOURCES/0027-WHATS_NEW-update.patch +++ /dev/null @@ -1,23 +0,0 @@ -From a468c4028a2a996e5651feaf728d4c126698d478 Mon Sep 17 00:00:00 2001 -From: Marian Csontos -Date: Thu, 9 Jan 2025 15:59:48 +0100 -Subject: [PATCH 27/27] WHATS_NEW: update - ---- - WHATS_NEW | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 40c6c2cd0..07493831f 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.03.30 - - ================== -+ Fix support for disabling memory locking (2.03.27). - Do not extend an LV if FS resize unsupported and '--fs resize' used. - lvconvert detects early volume in use when converting it to a pool. - --- -2.47.1 - diff --git a/SOURCES/0028-vg_read-rescanning-DM-cache-after-taking-lock.patch b/SOURCES/0028-vg_read-rescanning-DM-cache-after-taking-lock.patch deleted file mode 100644 index 4c19831..0000000 --- a/SOURCES/0028-vg_read-rescanning-DM-cache-after-taking-lock.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 4587190f41855d8549dc41486c0ee8eb0bedd4e4 Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Tue, 28 Jan 2025 12:45:39 +0100 -Subject: [PATCH 28/30] vg_read: rescanning DM cache after taking lock - -Since we started to use DM cache now also for basic checks -whether the DM devices is present in DM table, this cache -now needs to be actually refreshed when the LOCK is taken. -This hiddenly happend if there was enabled 'scan_lvs' however -still not at the right place. - -Move this explicit cache update call right after the moment -vg_read grabs the lock. - -TODO: in the optimal case, we should mark the 'cache invalid' -and later refresh this cache, when the first reader appears, -but since this would be large patch, do this little fix step patch -first and improve performance later. - -(cherry picked from commit dd09127608be1b390cf028508d448442b6347551) ---- - lib/device/dev-cache.c | 2 -- - lib/metadata/metadata.c | 8 ++++++++ - 2 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c -index 97d86a142..947995fb1 100644 ---- a/lib/device/dev-cache.c -+++ b/lib/device/dev-cache.c -@@ -1394,8 +1394,6 @@ void dm_devs_cache_label_invalidate(struct cmd_context *cmd) - struct dm_active_device *dm_dev; - struct device *dev; - -- dm_devs_cache_update(); -- - dm_list_iterate_items(dm_dev, _cache.dm_devs) { - if (dm_dev->uuid && - strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) { -diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c -index 511ebd8ae..14f54db23 100644 ---- a/lib/metadata/metadata.c -+++ b/lib/metadata/metadata.c -@@ -5031,6 +5031,14 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const - goto_bad; - } - -+ /* Update DM cache after grabbing lock -+ * TODO: do a lazy-update of this cache, only when it's really used */ -+ if (dm_devs_cache_use()) { -+ log_debug_cache("Rescanning DM cache."); -+ if (!dm_devs_cache_update()) -+ return_0; -+ } -+ - /* - * vgchange -ay (no vgname arg) will activate multiple local VGs with the same - * name, but if the vgs have the same lv name, activating those lvs will fail. --- -2.48.1 - diff --git a/SOURCES/0029-vg_read-matching-missed-empty-cache.patch b/SOURCES/0029-vg_read-matching-missed-empty-cache.patch deleted file mode 100644 index e121284..0000000 --- a/SOURCES/0029-vg_read-matching-missed-empty-cache.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ce545519e0f5d3d8b50deb3accbeffe41ef55f1d Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Thu, 23 Jan 2025 14:32:39 +0100 -Subject: [PATCH 29/30] vg_read: matching missed empty cache - -lvm2 is caching DM nodes with the use of DM_LIST_DEVICES ioctl(). -And tried to preserve the cached structure for the same list, -however there was 1 case where cache was empty, and new LIST ioctl -returned some elements - if this DM table change has happened -in the moment of 'scanning' and locking - lvm2 has then continued -to use 'invalid' empty cache. - -Fix by capturing this missed case and update cache properly. - -TODO: we could possibly use plain memcmp() with previous ioctl result. -(cherry picked from commit b32c0bb9c5474f39abffd9609ed486074ace6a2b) ---- - lib/device/dev-cache.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c -index 947995fb1..52f8804c4 100644 ---- a/lib/device/dev-cache.c -+++ b/lib/device/dev-cache.c -@@ -1314,7 +1314,7 @@ int dm_devs_cache_update(void) - unsigned devs_features; - uint32_t d; - struct dm_list *dm_devs_new, *l; -- int cache_changed = 0; -+ int cache_changed; - - if (!get_dm_active_devices(NULL, &dm_devs_new, &devs_features)) - return 1; -@@ -1329,6 +1329,7 @@ int dm_devs_cache_update(void) - /* Compare existing cached list with a new one. - * When there is any mismatch, just rebuild whole cache */ - if ((l = dm_list_first(dm_devs_new))) { -+ cache_changed = dm_list_empty(_cache.dm_devs); // 1 for empty cache and new list has entries */ - dm_list_iterate_items(dm_dev, _cache.dm_devs) { - dm_dev_new = dm_list_item(l, struct dm_active_device); - if ((dm_dev->devno != dm_dev_new->devno) || --- -2.48.1 - diff --git a/SOURCES/0030-vg_read-correct-error-path-for-DM-cache-update.patch b/SOURCES/0030-vg_read-correct-error-path-for-DM-cache-update.patch deleted file mode 100644 index e97a87d..0000000 --- a/SOURCES/0030-vg_read-correct-error-path-for-DM-cache-update.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 2b249a6ee51a79a5c28ffa591069158fd2c50e53 Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Thu, 30 Jan 2025 19:55:21 +0100 -Subject: [PATCH 30/30] vg_read: correct error path for DM cache update - -New code for updating DM cache traveled through couple destination -however in this place only 'return_0' is missing unlocking in -error path. - -(cherry picked from commit 46a48f1320c9d436286743461cd6e12d38ec45e0) ---- - lib/metadata/metadata.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c -index 14f54db23..b4da74247 100644 ---- a/lib/metadata/metadata.c -+++ b/lib/metadata/metadata.c -@@ -5035,8 +5035,11 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const - * TODO: do a lazy-update of this cache, only when it's really used */ - if (dm_devs_cache_use()) { - log_debug_cache("Rescanning DM cache."); -- if (!dm_devs_cache_update()) -- return_0; -+ if (!dm_devs_cache_update()) { -+ log_error("Can't allocate DM cache memory for VG %s.", vg_name); -+ failure |= FAILED_ALLOCATION; -+ goto bad; -+ } - } - - /* --- -2.48.1 - diff --git a/SPECS/lvm2.spec b/SPECS/lvm2.spec index 7cdabdc..ec696a5 100644 --- a/SPECS/lvm2.spec +++ b/SPECS/lvm2.spec @@ -1,4 +1,4 @@ -%global device_mapper_version 1.02.202 +%global device_mapper_version 1.02.206 %global enable_cache 1 %global enable_lvmdbusd 1 @@ -50,11 +50,11 @@ Name: lvm2 %if 0%{?rhel} Epoch: %{rhel} %endif -Version: 2.03.28 +Version: 2.03.32 %if 0%{?from_snapshot} Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix} %else -Release: 6%{?dist}%{?rel_suffix} +Release: 2%{?dist}%{?rel_suffix} %endif License: GPL-2.0-only URL: https://sourceware.org/lvm2 @@ -69,35 +69,16 @@ 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-lv_manip-fix-stripe-count-and-size-validation-for-RA.patch -Patch9: 0009-lv_manip-use-the-same-param-validation-for-RAID-0-as.patch -Patch10: 0010-tests-remove-superfluous-a-option-for-df-used-in-lvr.patch -Patch11: 0011-WHATS_NEW-update.patch -Patch12: 0012-vdo-fix-input-units-for-minimim_io_size.patch -Patch13: 0013-tests-check-vdo-minimum_io_size.patch -Patch14: 0014-raid-fix-name-rotation.patch -Patch15: 0015-tests-check-_tdata-conversion-to-raid1.patch -Patch16: 0016-WHATS_NEW-update.patch -# RHEL-68982: -Patch17: 0017-device_id-nvme-devices-may-use-alternate-wwids.patch -Patch18: 0018-configure.ac-add-support-for-libnvme.patch -Patch19: 0019-configure-autoreconf.patch -# RHEL-53866: -Patch20: 0020-thin-deactivate-converted-volume-early.patch -Patch21: 0021-tests-check-conversion-of-in-use-volume.patch -Patch22: 0022-WHATS_NEW-update.patch -# RHEL-65845: -Patch23: 0023-lv_manip-check-fs-resize-is-supported-before-LV-exte.patch -Patch24: 0024-tests-adjust-lvresize-xfs-tests-for-recent-lvextend-.patch -Patch25: 0025-WHATS_NEW-update.patch -# RHEL-60943: -Patch26: 0026-memlock-check-for-proper-reserved-size.patch -Patch27: 0027-WHATS_NEW-update.patch -# RHEL-76039: -Patch28: 0028-vg_read-rescanning-DM-cache-after-taking-lock.patch -Patch29: 0029-vg_read-matching-missed-empty-cache.patch -Patch30: 0030-vg_read-correct-error-path-for-DM-cache-update.patch +Patch7: 0007-WHATS_NEW_DM-update.patch +# RHEL-94577: +Patch8: 0008-lvmlockd-fix-hosts-check-for-vgremove.patch +Patch9: 0009-lvmlockd-fix-sanlock_release-for-vgremove.patch +# RHEL-67039: +Patch10: 0010-raid-count-or-clear-transiently-failed-devices.patch +Patch11: 0011-lvconvert-allow-clearing-superblocks.patch +Patch12: 0012-test-check-raid-superblock-clearing.patch +Patch13: 0013-man-update-raid-man.patch +Patch14: 0014-WHATS_NEW-update.patch BuildRequires: make BuildRequires: gcc @@ -729,6 +710,14 @@ An extensive functional testsuite for LVM2. %endif %changelog +* Tue Jun 03 2025 Marian Csontos - 2.03.32-2 +- Fix vgremove hanging immediately after lockstart. +- Add repair option for RAID volumes with too many transiently failed devices. + +* Tue May 06 2025 Marian Csontos - 2.03.32-1 +- Update to upstream version 2.03.32. +- See WHATS_NEW and WHATS_NEW_DM for more information. + * Mon Feb 03 2025 Marian Csontos - 2.03.28-6 - Fix race causing lvm2 not recognizing active devices.