diff --git a/.gitignore b/.gitignore index b3024ae..10143cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/LVM2.2.03.24.tgz +SOURCES/LVM2.2.03.28.tgz diff --git a/.lvm2.metadata b/.lvm2.metadata index 473d21d..3d42021 100644 --- a/.lvm2.metadata +++ b/.lvm2.metadata @@ -1 +1 @@ -7c2dcac585dc89dbd0070216262a3a8446e7f222 SOURCES/LVM2.2.03.24.tgz +762d6924860a01973ca61543208d97ef385be1f6 SOURCES/LVM2.2.03.28.tgz diff --git a/SOURCES/0001-RHEL9.patch b/SOURCES/0001-RHEL9.patch index dc1320a..265c402 100644 --- a/SOURCES/0001-RHEL9.patch +++ b/SOURCES/0001-RHEL9.patch @@ -1,78 +1,27 @@ -From 645992ca32dfd41b07997a97b2aef81563ad6f02 Mon Sep 17 00:00:00 2001 +From 4ed40e67197778b28e4b822558614a517242e3e1 Mon Sep 17 00:00:00 2001 From: Marian Csontos -Date: Thu, 16 May 2024 12:12:06 +0200 -Subject: [PATCH 1/7] RHEL9 +Date: Thu, 3 Oct 2024 16:14:11 +0200 +Subject: [PATCH 01/13] RHEL9 --- - VERSION | 2 +- - VERSION_DM | 2 +- - WHATS_NEW | 4 ++++ - WHATS_NEW_DM | 4 ++++ - doc/release-notes/2.03.24.mdwn | 8 ++------ - 5 files changed, 12 insertions(+), 8 deletions(-) + VERSION | 2 +- + VERSION_DM | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION -index c41928e80..794c58868 100644 +index 7619e491b..f96b435a3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ --2.03.24(2) (2024-05-16) -+2.03.24(2)-RHEL9 (2024-05-16) +-2.03.28(2) (2024-11-04) ++2.03.28(2)-RHEL9 (2024-11-04) diff --git a/VERSION_DM b/VERSION_DM -index 63629f72c..8dea6c328 100644 +index 16d64d69d..cd0c694ae 100644 --- a/VERSION_DM +++ b/VERSION_DM @@ -1 +1 @@ --1.02.198 (2024-05-16) -+1.02.198-RHEL9 (2024-05-16) -diff --git a/WHATS_NEW b/WHATS_NEW -index 1c5f4b223..c7de3914a 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,3 +1,6 @@ -+Version 2.03.25 - -+================== -+ - Version 2.03.24 - 16th May 2024 - =============================== - Lvconvert supports VDO options for thin-pool with vdo conversion. -@@ -5450,3 +5453,4 @@ Display output. Some metadata information cannot yet be displayed. - Recovery tools to salvage "lost" metadata directly from the disks: - but we hope the new format will mean such tools are hardly ever needed! - -+ -diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM -index b1508f08f..a2277c53b 100644 ---- a/WHATS_NEW_DM -+++ b/WHATS_NEW_DM -@@ -1,3 +1,6 @@ -+Version 1.02.199 - -+=================== -+ - Version 1.02.198 - 16th May 2024 - ================================ - Fix static only compilation of libdevmapper.a and dmsetup tool. -@@ -1554,3 +1557,4 @@ Version 1.00.08 - 27 Feb 2004 - Updated README/INSTALL to reflect move to sources.redhat.com. - Updated autoconf files to 2003-06-17. - -+ -diff --git a/doc/release-notes/2.03.24.mdwn b/doc/release-notes/2.03.24.mdwn -index 71aa8add7..4d2c57497 100644 ---- a/doc/release-notes/2.03.24.mdwn -+++ b/doc/release-notes/2.03.24.mdwn -@@ -72,9 +72,5 @@ Also few more minor improvements: - - """]] - -- --[[!tag draft pending]] -- -+[[!tag]] -+[[meta date="Thu May 16 12:12:06 2024 +0200"]] +-1.02.202 (2024-11-04) ++1.02.202-RHEL9 (2024-11-04) -- -2.44.0 +2.47.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 acc02d1..ad74ed9 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 d6b3f4f4dd526a5a4413e84f4cccb2e92699d1d8 Mon Sep 17 00:00:00 2001 +From 290f2740efee0f9a3f6b9f84c277e0d4e81927db Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:02 +0200 -Subject: [PATCH 2/7] Revert "10-dm.rules: bump DM_UDEV_RULES_VSN to 3" +Subject: [PATCH 02/13] 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.44.0 +2.47.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 af2a4bf..cabb59b 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 da6319b9f5d263a210cf51b471fdbf1c343facf3 Mon Sep 17 00:00:00 2001 +From 57fa9b840028112e9e455c960dad5bd595625428 Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:15 +0200 -Subject: [PATCH 3/7] Revert "dm udev rules: don't export and save DM_NOSCAN" +Subject: [PATCH 03/13] Revert "dm udev rules: don't export and save DM_NOSCAN" This reverts commit a196752969320cfc34a97cc97afa1978fa57da73. --- @@ -10,7 +10,7 @@ This reverts commit a196752969320cfc34a97cc97afa1978fa57da73. 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/udev/11-dm-lvm.rules.in b/udev/11-dm-lvm.rules.in -index cfc022489..5b0cc5242 100644 +index 8b8d0561f..6dd556aa9 100644 --- a/udev/11-dm-lvm.rules.in +++ b/udev/11-dm-lvm.rules.in @@ -30,7 +30,7 @@ IMPORT{program}="(DM_EXEC)/dmsetup splitname --nameprefixes --noheadings --rows @@ -23,7 +23,7 @@ index cfc022489..5b0cc5242 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 b53bb62de..b748cc909 100644 +index 03ea203ee..96f1efc00 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}" @@ -39,5 +39,5 @@ index b53bb62de..b748cc909 100644 (BLKID_RULE) GOTO="dm_link" -- -2.44.0 +2.47.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 5ddaa67..f94cb2b 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 2e2303dd559fda3fb7d97f79094d04c3ccd9d519 Mon Sep 17 00:00:00 2001 +From 885113b30d7873ac671490715312431f706d26e8 Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:24 +0200 -Subject: [PATCH 4/7] Revert "dm udev rules: don't export and save +Subject: [PATCH 04/13] Revert "dm udev rules: don't export and save DM_SUSPENDED" This reverts commit 21ca92c4325b6b161fb1e1f10942ad9f8d23c144. @@ -68,7 +68,7 @@ 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 b748cc909..183693bf1 100644 +index 96f1efc00..3e1eaa6ee 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" @@ -84,5 +84,5 @@ index b748cc909..183693bf1 100644 (BLKID_RULE) -- -2.44.0 +2.47.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 9c5ec97..cde324e 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 cc3214c24425eb283dd46435345c28e5398b3570 Mon Sep 17 00:00:00 2001 +From 89058bc0687baec653df87f14fd25da32577cc6d Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:37 +0200 -Subject: [PATCH 5/7] Revert "11-dm-lvm.rules: don't restore +Subject: [PATCH 05/13] Revert "11-dm-lvm.rules: don't restore DM_UDEV_DISABLE_OTHER_RULES_FLAG from db" This reverts commit 2b2f11a74cd5cc05f266fd0c65f0e55eb8bafd9f. @@ -10,7 +10,7 @@ This reverts commit 2b2f11a74cd5cc05f266fd0c65f0e55eb8bafd9f. 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/udev/11-dm-lvm.rules.in b/udev/11-dm-lvm.rules.in -index 5b0cc5242..5f04ab329 100644 +index 6dd556aa9..9836f41ca 100644 --- a/udev/11-dm-lvm.rules.in +++ b/udev/11-dm-lvm.rules.in @@ -26,11 +26,14 @@ IMPORT{program}="(DM_EXEC)/dmsetup splitname --nameprefixes --noheadings --rows @@ -34,5 +34,5 @@ index 5b0cc5242..5f04ab329 100644 ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end" -- -2.44.0 +2.47.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 45a04ed..9edf4a0 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 147498a07fd4e7dd0698b443bbcf15cfe6a6e104 Mon Sep 17 00:00:00 2001 +From cccc336a97ce85cf68ec7a80390c42dae243621b Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:30:48 +0200 -Subject: [PATCH 6/7] Revert "10-dm-rules: don't restore +Subject: [PATCH 06/13] 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.44.0 +2.47.0 diff --git a/SOURCES/0007-WHATS_NEW-update.patch b/SOURCES/0007-WHATS_NEW-update.patch index 80bd4ef..5f251c9 100644 --- a/SOURCES/0007-WHATS_NEW-update.patch +++ b/SOURCES/0007-WHATS_NEW-update.patch @@ -1,38 +1,27 @@ -From 7d1b418ad8efa0c059197238ea3fcbf3f659d909 Mon Sep 17 00:00:00 2001 +From e6f8d9855336dbf1cbf212f60b84a03946365795 Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Thu, 16 May 2024 15:34:28 +0200 -Subject: [PATCH 7/7] WHATS_NEW: update +Subject: [PATCH 07/13] WHATS_NEW: update --- - WHATS_NEW | 1 + - WHATS_NEW_DM | 4 ++++ - 2 files changed, 5 insertions(+) + WHATS_NEW_DM | 7 +++++++ + 1 file changed, 7 insertions(+) -diff --git a/WHATS_NEW b/WHATS_NEW -index c7de3914a..1d56f8675 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.03.25 - - ================== -+ Revert Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it. - - Version 2.03.24 - 16th May 2024 - =============================== diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM -index a2277c53b..da8df6914 100644 +index f8ca946d6..74b356bf2 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM -@@ -1,5 +1,9 @@ - Version 1.02.199 - - =================== +@@ -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.198 - 16th May 2024 - ================================ ++ + Version 1.02.202 - 04th November 2024 + ===================================== + Introduce dm_config_parse_only_section to stop parsing after section. -- -2.44.0 +2.47.0 diff --git a/SOURCES/0008-Allow-system.devices-to-be-automatically-created-on-.patch b/SOURCES/0008-Allow-system.devices-to-be-automatically-created-on-.patch deleted file mode 100644 index 591ea34..0000000 --- a/SOURCES/0008-Allow-system.devices-to-be-automatically-created-on-.patch +++ /dev/null @@ -1,578 +0,0 @@ -From 16af82a5afe337cc3b0db3eaed0372e130b049ed Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Tue, 23 Apr 2024 17:08:26 -0500 -Subject: [PATCH 08/13] Allow system.devices to be automatically created on - first boot - -An OS installer can create system.devices for the system and -disks, but an OS image cannot create the system-specific -system.devices. The OS image can instead configure the -image so that lvm will create system.devices on first boot. - -Image preparation steps to enable auto creation of system.devices: -- create empty file /etc/lvm/devices/auto-import-rootvg -- remove any existing /etc/lvm/devices/system.devices -- enable lvm-devices-import.path -- enable lvm-devices-import.service - -On first boot of the prepared image: -- udev triggers vgchange -aay --autoactivation event -- vgchange activates LVs in the root VG -- vgchange finds the file /etc/lvm/devices/auto-import-rootvg, - and no /etc/lvm/devices/system.devices, so it creates - /run/lvm/lvm-devices-import -- lvm-devices-import.path is run when /run/lvm/lvm-devices-import - appears, and triggers lvm-devices-import.service -- lvm-devices-import.service runs vgimportdevices --rootvg --auto -- vgimportdevices finds /etc/lvm/devices/auto-import-rootvg, - and no system.devices, so it creates system.devices containing - PVs in the root VG, and removes /etc/lvm/devices/auto-import-rootvg - and /run/lvm/lvm-devices-import - -Run directly, vgimportdevices --rootvg (without --auto), will create -a new system.devices for the root VG, or will add devices for the -root VG to an existing system.devices. - -(cherry picked from commit c609dedc2f035f770b5f645c4695924abf15c2ca) -(cherry picked from commit 3321a669d8f2df99df9d6dcd4ebb2b4d30731c7a) ---- - lib/commands/toolcontext.h | 1 + - lib/config/defaults.h | 2 + - lib/device/device_id.c | 5 +- - scripts/lvm-devices-import.path | 12 +++ - scripts/lvm-devices-import.service | 12 +++ - tools/args.h | 11 ++ - tools/command-lines.in | 5 + - tools/pvscan.c | 4 +- - tools/tools.h | 2 +- - tools/vgchange.c | 155 ++++++++++++++++++++++++++++- - tools/vgimportdevices.c | 114 ++++++++++++++++++++- - 11 files changed, 315 insertions(+), 8 deletions(-) - create mode 100644 scripts/lvm-devices-import.path - create mode 100644 scripts/lvm-devices-import.service - -diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h -index fec0a52cf..043afbf76 100644 ---- a/lib/commands/toolcontext.h -+++ b/lib/commands/toolcontext.h -@@ -217,6 +217,7 @@ struct cmd_context { - unsigned device_ids_check_hostname:1; - unsigned device_ids_refresh_trigger:1; - unsigned device_ids_invalid:1; -+ unsigned device_ids_auto_import:1; - unsigned get_vgname_from_options:1; /* used by lvconvert */ - - /* -diff --git a/lib/config/defaults.h b/lib/config/defaults.h -index ed0c4f404..efe36d1fa 100644 ---- a/lib/config/defaults.h -+++ b/lib/config/defaults.h -@@ -337,6 +337,8 @@ - #define VGS_ONLINE_DIR DEFAULT_RUN_DIR "/vgs_online" - #define PVS_LOOKUP_DIR DEFAULT_RUN_DIR "/pvs_lookup" - -+#define DEVICES_IMPORT_PATH DEFAULT_RUN_DIR "/lvm-devices-import" -+ - #define DEFAULT_DEVICE_ID_SYSFS_DIR "/sys/" /* trailing / to match dm_sysfs_dir() */ - - #define DEFAULT_DEVICESFILE_BACKUP_LIMIT 50 -diff --git a/lib/device/device_id.c b/lib/device/device_id.c -index 2b183810a..1ce7927ed 100644 ---- a/lib/device/device_id.c -+++ b/lib/device/device_id.c -@@ -1726,9 +1726,10 @@ int device_ids_write(struct cmd_context *cmd) - - if ((fc_bytes = snprintf(fc, sizeof(fc), - "# LVM uses devices listed in this file.\n" \ -- "# Created by LVM command %s pid %d at %s" \ -+ "# Created by LVM command %s%s pid %d at %s" \ - "# HASH=%u\n", -- cmd->name, getpid(), ctime(&t), hash)) < 0) { -+ cmd->name, cmd->device_ids_auto_import ? " (auto)" : "", -+ getpid(), ctime(&t), hash)) < 0) { - log_error("Failed to write buffer for devices file content."); - goto out; - } -diff --git a/scripts/lvm-devices-import.path b/scripts/lvm-devices-import.path -new file mode 100644 -index 000000000..bcf0dcd4c ---- /dev/null -+++ b/scripts/lvm-devices-import.path -@@ -0,0 +1,12 @@ -+[Unit] -+Description=lvm-devices-import to create system.devices -+ -+# /run/lvm/lvm-devices-import created by vgchange -aay -+ -+[Path] -+PathExists=/run/lvm/lvm-devices-import -+Unit=lvm-devices-import.service -+ConditionPathExists=!/etc/lvm/devices/system.devices -+ -+[Install] -+WantedBy=multi-user.target -diff --git a/scripts/lvm-devices-import.service b/scripts/lvm-devices-import.service -new file mode 100644 -index 000000000..9d3bda2ee ---- /dev/null -+++ b/scripts/lvm-devices-import.service -@@ -0,0 +1,12 @@ -+[Unit] -+Description=Create lvm system.devices -+ -+[Service] -+Type=oneshot -+RemainAfterExit=no -+ExecStart=/usr/sbin/vgimportdevices --rootvg --auto -+ConditionPathExists=!/etc/lvm/devices/system.devices -+ -+[Install] -+WantedBy=multi-user.target -+ -diff --git a/tools/args.h b/tools/args.h -index 09b2ad551..ed0fb9620 100644 ---- a/tools/args.h -+++ b/tools/args.h -@@ -94,6 +94,14 @@ arg(atversion_ARG, '\0', "atversion", string_VAL, 0, 0, - "which does not contain any newer settings for which LVM would\n" - "issue a warning message when checking the configuration.\n") - -+arg(auto_ARG, '\0', "auto", 0, 0, 0, -+ "This option is used when automatically importing devices for the root VG.\n" -+ "The auto import is intended to be done once, on first boot, to create an\n" -+ "initial system.devices file for the root VG.\n" -+ "When this option is used, the vgimportdevices --rootvg command does nothing\n" -+ "if system.devices exists, or the file auto-import-rootvg does not exist\n" -+ "(both in the /etc/lvm/devices/ directory.)\n") -+ - arg(autoactivation_ARG, '\0', "autoactivation", string_VAL, 0, 0, - "Specify if autoactivation is being used from an event.\n" - "This allows the command to apply settings that are specific\n" -@@ -754,6 +762,9 @@ arg(resync_ARG, '\0', "resync", 0, 0, 0, - "which the LV is without a complete redundant copy of the data.\n" - "See \\fBlvmraid\\fP(7) for more information.\n") - -+arg(rootvg_ARG, '\0', "rootvg", 0, 0, 0, -+ "Import devices used for the root VG.\n") -+ - arg(rows_ARG, '\0', "rows", 0, 0, 0, - "Output columns as rows.\n") - -diff --git a/tools/command-lines.in b/tools/command-lines.in -index 1c728afa0..3ad5d3c46 100644 ---- a/tools/command-lines.in -+++ b/tools/command-lines.in -@@ -1911,6 +1911,11 @@ OO: --foreign, --reportformat ReportFmt - ID: vgimportdevices_all - DESC: Add devices from all accessible VGs to the devices file. - -+vgimportdevices --rootvg -+OO: --auto, --reportformat ReportFmt -+ID: vgimportdevices_root -+DESC: Add devices from root VG to the devices file. -+ - --- - - vgmerge VG VG -diff --git a/tools/pvscan.c b/tools/pvscan.c -index f88e1b751..0a9cb59df 100644 ---- a/tools/pvscan.c -+++ b/tools/pvscan.c -@@ -495,7 +495,7 @@ static int _pvscan_aa_single(struct cmd_context *cmd, const char *vg_name, - - log_debug("pvscan autoactivating VG %s.", vg_name); - -- if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1)) { -+ if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1, NULL)) { - log_error_pvscan(cmd, "%s: autoactivation failed.", vg->name); - pp->activate_errors++; - } -@@ -755,7 +755,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp - - log_debug("pvscan autoactivating VG %s.", vgname); - -- if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1)) { -+ if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1, NULL)) { - log_error_pvscan(cmd, "%s: autoactivation failed.", vg->name); - pp->activate_errors++; - } -diff --git a/tools/tools.h b/tools/tools.h -index f4a0c94d7..58708c695 100644 ---- a/tools/tools.h -+++ b/tools/tools.h -@@ -164,7 +164,7 @@ int mirror_remove_missing(struct cmd_context *cmd, - - - int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg, -- activation_change_t activate, int vg_complete_to_activate); -+ activation_change_t activate, int vg_complete_to_activate, char *root_dm_uuid); - - int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg); - -diff --git a/tools/vgchange.c b/tools/vgchange.c -index 378ded16e..2004d6e92 100644 ---- a/tools/vgchange.c -+++ b/tools/vgchange.c -@@ -16,11 +16,14 @@ - #include "tools.h" - #include "lib/device/device_id.h" - #include "lib/label/hints.h" -+#include "device_mapper/misc/dm-ioctl.h" -+#include - - struct vgchange_params { - int lock_start_count; - unsigned int lock_start_sanlock : 1; - unsigned int vg_complete_to_activate : 1; -+ char *root_dm_uuid; /* dm uuid of LV under root fs */ - }; - - /* -@@ -197,7 +200,7 @@ int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg - } - - int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg, -- activation_change_t activate, int vg_complete_to_activate) -+ activation_change_t activate, int vg_complete_to_activate, char *root_dm_uuid) - { - int lv_open, active, monitored = 0, r = 1; - const struct lv_list *lvl; -@@ -279,6 +282,43 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg, - r = 0; - } - -+ /* -+ * Possibly trigger auto-generation of system.devices: -+ * - if root_dm_uuid contains vg->id, and -+ * - /etc/lvm/devices/auto-import-rootvg exists, and -+ * - /etc/lvm/devices/system.devices does not exist, then -+ * - create /run/lvm/lvm-devices-import to -+ * trigger lvm-devices-import.path and .service -+ * - lvm-devices-import will run vgimportdevices --rootvg -+ * to create system.devices -+ */ -+ if (root_dm_uuid) { -+ char path[PATH_MAX]; -+ struct stat info; -+ FILE *fp; -+ -+ if (memcmp(root_dm_uuid + 4, &vg->id, ID_LEN)) -+ goto out; -+ -+ if (cmd->enable_devices_file || devices_file_exists(cmd)) -+ goto out; -+ -+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0) -+ goto out; -+ -+ if (stat(path, &info) < 0) -+ goto out; -+ -+ log_debug("Found %s creating %s", path, DEVICES_IMPORT_PATH); -+ -+ if (!(fp = fopen(DEVICES_IMPORT_PATH, "w"))) { -+ log_debug("failed to create %s", DEVICES_IMPORT_PATH); -+ goto out; -+ } -+ if (fclose(fp)) -+ stack; -+ } -+out: - /* Print message only if there was not found a missing VG */ - log_print_unless_silent("%d logical volume(s) in volume group \"%s\" now active", - lvs_in_vg_activated(vg), vg->name); -@@ -714,7 +754,7 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name, - - if (arg_is_set(cmd, activate_ARG)) { - activate = (activation_change_t) arg_uint_value(cmd, activate_ARG, 0); -- if (!vgchange_activate(cmd, vg, activate, vp->vg_complete_to_activate)) -+ if (!vgchange_activate(cmd, vg, activate, vp->vg_complete_to_activate, vp->root_dm_uuid)) - return_ECMD_FAILED; - } else if (arg_is_set(cmd, refresh_ARG)) { - /* refreshes the visible LVs (which starts polling) */ -@@ -735,6 +775,115 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name, - return ret; - } - -+/* -+ * Automatic creation of system.devices for root VG on first boot -+ * is useful for OS images where the OS installer is not used to -+ * customize the OS for system. -+ * -+ * - OS image prep: -+ * . rm /etc/lvm/devices/system.devices (if it exists) -+ * . touch /etc/lvm/devices/auto-import-rootvg -+ * . enable lvm-devices-import.path -+ * . enable lvm-devices-import.service -+ * -+ * - lvchange -ay / -+ * . run by initrd so root fs can be mounted -+ * . does not use system.devices -+ * . named / comes from kernel command line rd.lvm -+ * . uses first device that appears containing the named root LV -+ * -+ * - vgchange -aay -+ * . triggered by udev when all PVs from root VG are online -+ * . activate LVs in root VG (in addition to the already active root LV) -+ * . check for /etc/lvm/devices/auto-import-rootvg (found) -+ * . check for /etc/lvm/devices/system.devices (not found) -+ * . create /run/lvm/lvm-devices-import because -+ * auto-import-rootvg was found and system.devices was not found -+ * -+ * - lvm-devices-import.path -+ * . triggered by /run/lvm/lvm-devices-import -+ * . start lvm-devices-import.service -+ * -+ * - lvm-devices-import.service -+ * . check for /etc/lvm/devices/system.devices, do nothing if found -+ * . run vgimportdevices --rootvg --auto -+ * -+ * - vgimportdevices --rootvg --auto -+ * . check for /etc/lvm/devices/auto-import-rootvg (found) -+ * . check for /etc/lvm/devices/system.devices (not found) -+ * . creates /etc/lvm/devices/system.devices for PVs in root VG -+ * . removes /etc/lvm/devices/auto-import-rootvg -+ * . removes /run/lvm/lvm-devices-import -+ * -+ * On future startup, /etc/lvm/devices/system.devices will exist, -+ * and /etc/lvm/devices/auto-import-rootvg will not exist, so -+ * vgchange -aay will not create /run/lvm/lvm-devices-import, -+ * and lvm-devices-import.path and lvm-device-import.service will not run. -+ * -+ * lvm-devices-import.path: -+ * [Path] -+ * PathExists=/run/lvm/lvm-devices-import -+ * Unit=lvm-devices-import.service -+ * ConditionPathExists=!/etc/lvm/devices/system.devices -+ * -+ * lvm-devices-import.service: -+ * [Service] -+ * Type=oneshot -+ * RemainAfterExit=no -+ * ExecStart=/usr/sbin/vgimportdevices --rootvg --auto -+ * ConditionPathExists=!/etc/lvm/devices/system.devices -+ */ -+ -+static void _get_rootvg_dev(struct cmd_context *cmd, char **dm_uuid_out) -+{ -+ char path[PATH_MAX]; -+ char dm_uuid[DM_UUID_LEN]; -+ struct stat info; -+ FILE *fme = NULL; -+ struct mntent *me; -+ int found = 0; -+ -+ if (cmd->enable_devices_file || devices_file_exists(cmd)) -+ return; -+ -+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0) -+ return; -+ -+ if (stat(path, &info) < 0) -+ return; -+ -+ if (!(fme = setmntent("/etc/mtab", "r"))) -+ return; -+ -+ while ((me = getmntent(fme))) { -+ if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) { -+ found = 1; -+ break; -+ } -+ } -+ endmntent(fme); -+ -+ if (!found) -+ return; -+ -+ if (stat(me->mnt_dir, &info) < 0) -+ return; -+ -+ if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), (int)MAJOR(info.st_dev), (int)MINOR(info.st_dev))) -+ return; -+ -+ log_debug("Found root dm_uuid %s", dm_uuid); -+ -+ /* UUID_PREFIX = "LVM-" */ -+ if (strncmp(dm_uuid, UUID_PREFIX, 4)) -+ return; -+ -+ if (strlen(dm_uuid) < 4 + ID_LEN) -+ return; -+ -+ *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid); -+} -+ - static int _vgchange_autoactivation_setup(struct cmd_context *cmd, - struct vgchange_params *vp, - int *skip_command, -@@ -778,6 +927,8 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd, - - get_single_vgname_cmd_arg(cmd, NULL, &vgname); - -+ _get_rootvg_dev(cmd, &vp->root_dm_uuid); -+ - /* - * Lock the VG before scanning the PVs so _vg_read can avoid the normal - * lock_vol+rescan (READ_WITHOUT_LOCK avoids the normal lock_vol and -diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c -index bccd94f61..70d12e500 100644 ---- a/tools/vgimportdevices.c -+++ b/tools/vgimportdevices.c -@@ -15,11 +15,16 @@ - #include "tools.h" - #include "lib/cache/lvmcache.h" - #include "lib/device/device_id.h" -+#include "device_mapper/misc/dm-ioctl.h" - /* coverity[unnecessary_header] needed for MuslC */ - #include -+#include - - struct vgimportdevices_params { - uint32_t added_devices; -+ int root_vg_found; -+ char *root_dm_uuid; -+ char *root_vg_name; - }; - - static int _vgimportdevices_single(struct cmd_context *cmd, -@@ -35,6 +40,13 @@ static int _vgimportdevices_single(struct cmd_context *cmd, - int updated_pvs = 0; - const char *idtypestr = NULL; /* deviceidtype_ARG ? */ - -+ if (vp->root_dm_uuid) { -+ if (memcmp(vp->root_dm_uuid + 4, &vg->id, ID_LEN)) -+ return ECMD_PROCESSED; -+ vp->root_vg_found = 1; -+ vp->root_vg_name = dm_pool_strdup(cmd->mem, vg_name); -+ } -+ - dm_list_iterate_items(pvl, &vg->pvs) { - if (is_missing_pv(pvl->pv) || !pvl->pv->dev) { - memcpy(pvid, &pvl->pv->id.uuid, ID_LEN); -@@ -86,6 +98,87 @@ static int _vgimportdevices_single(struct cmd_context *cmd, - return ECMD_PROCESSED; - } - -+static int _get_rootvg_dev(struct cmd_context *cmd, char **dm_uuid_out, int *skip) -+{ -+ char path[PATH_MAX]; -+ char dm_uuid[DM_UUID_LEN]; -+ struct stat info; -+ FILE *fme = NULL; -+ struct mntent *me; -+ int found = 0; -+ -+ /* -+ * When --auto is set, the command does nothing -+ * if /etc/lvm/devices/system.devices exists, or -+ * if /etc/lvm/devices/auto-import-rootvg does not exist. -+ */ -+ if (arg_is_set(cmd, auto_ARG)) { -+ if (devices_file_exists(cmd)) { -+ *skip = 1; -+ return 1; -+ } -+ -+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0) -+ return_0; -+ -+ if (stat(path, &info) < 0) { -+ *skip = 1; -+ return 1; -+ } -+ -+ /* -+ * This flag is just used in device_ids_write to enable -+ * an extra comment in system.devices indicating that -+ * the file was auto generated for the root vg. -+ */ -+ cmd->device_ids_auto_import = 1; -+ } -+ -+ if (!(fme = setmntent("/etc/mtab", "r"))) -+ return_0; -+ -+ while ((me = getmntent(fme))) { -+ if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) { -+ found = 1; -+ break; -+ } -+ } -+ endmntent(fme); -+ -+ if (!found) -+ return_0; -+ -+ if (stat(me->mnt_dir, &info) < 0) -+ return_0; -+ -+ if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), (int)MAJOR(info.st_dev), (int)MINOR(info.st_dev))) -+ return_0; -+ -+ /* UUID_PREFIX = "LVM-" */ -+ if (strncmp(dm_uuid, UUID_PREFIX, 4)) -+ return_0; -+ -+ if (strlen(dm_uuid) < 4 + ID_LEN) -+ return_0; -+ -+ *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid); -+ return 1; -+} -+ -+static void _clear_rootvg_auto(struct cmd_context *cmd) -+{ -+ char path[PATH_MAX]; -+ -+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0) -+ return; -+ -+ if (unlink(path) < 0) -+ log_debug("Failed to unlink %s", path); -+ -+ if (unlink(DEVICES_IMPORT_PATH) < 0) -+ log_debug("Failed to unlink %s", DEVICES_IMPORT_PATH); -+} -+ - /* - * This command always scans all devices on the system, - * any pre-existing devices_file does not limit the scope. -@@ -130,6 +223,19 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) - /* So that we can warn about this. */ - cmd->handles_missing_pvs = 1; - -+ /* Import devices for the root VG. */ -+ if (arg_is_set(cmd, rootvg_ARG)) { -+ int skip = 0; -+ if (!_get_rootvg_dev(cmd, &vp.root_dm_uuid, &skip)) { -+ log_error("Failed to find root VG."); -+ return ECMD_FAILED; -+ } -+ if (skip) { -+ log_print("Root VG auto import is not enabled."); -+ return ECMD_PROCESSED; -+ } -+ } -+ - if (!lock_global(cmd, "ex")) - return ECMD_FAILED; - -@@ -230,7 +336,13 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) - goto out; - } - -- log_print("Added %u devices to devices file.", vp.added_devices); -+ if (vp.root_vg_found) -+ log_print("Added %u devices to devices file for root VG %s.", vp.added_devices, vp.root_vg_name); -+ else -+ log_print("Added %u devices to devices file.", vp.added_devices); -+ -+ if (vp.root_vg_found && arg_is_set(cmd, auto_ARG)) -+ _clear_rootvg_auto(cmd); - out: - if ((ret == ECMD_FAILED) && created_file) - if (unlink(cmd->devices_file_path) < 0) --- -2.45.2 - diff --git a/SOURCES/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 new file mode 100644 index 0000000..edc9c8f --- /dev/null +++ b/SOURCES/0008-lv_manip-fix-stripe-count-and-size-validation-for-RA.patch @@ -0,0 +1,104 @@ +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/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 new file mode 100644 index 0000000..31d31cb --- /dev/null +++ b/SOURCES/0009-lv_manip-use-the-same-param-validation-for-RAID-0-as.patch @@ -0,0 +1,30 @@ +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-lvm-fix-shell-completion.patch b/SOURCES/0009-lvm-fix-shell-completion.patch deleted file mode 100644 index a2451e2..0000000 --- a/SOURCES/0009-lvm-fix-shell-completion.patch +++ /dev/null @@ -1,60 +0,0 @@ -From fe58f4b87a2cd85f132775a2e475c128b89e7eb4 Mon Sep 17 00:00:00 2001 -From: Zdenek Kabelac -Date: Fri, 24 May 2024 19:49:08 +0200 -Subject: [PATCH 09/13] lvm: fix shell completion - -Previous commit 82617852a4d3c89b09124eddedcc2c1859b9d50e -introduce bug in complession - as the rl_completion_matches() -needs to always advance to next element where the index -is held in static variable. - -Add comment about this usage. - -(cherry picked from commit 73298635b9db2c2a11bc4cc291b15d0f21907598) -(cherry picked from commit c33b0e11878a52aeaa42b4ebfd0692e5da7f5e07) ---- - tools/lvm.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/tools/lvm.c b/tools/lvm.c -index 116b707b2..3a7e6dc6c 100644 ---- a/tools/lvm.c -+++ b/tools/lvm.c -@@ -52,7 +52,8 @@ static char *_list_cmds(const char *text, int state) - - for (;i < _cmdline->num_command_names;++i) - if (!strncmp(text, _cmdline->command_names[i].name, len)) -- return strdup(_cmdline->command_names[i].name); -+ /* increase position for next iteration */ -+ return strdup(_cmdline->command_names[i++].name); - - return NULL; - } -@@ -102,9 +103,10 @@ static char *_list_args(const char *text, int state) - - /* Short form arguments */ - if (len < 3) { -- for (;match_no < cna->num_args; ++match_no) { -+ while (match_no < cna->num_args) { - char s[3]; -- char c = (_cmdline->opt_names + cna->valid_args[match_no])->short_opt; -+ /* increase position for next iteration */ -+ char c = _cmdline->opt_names[cna->valid_args[match_no++]].short_opt; - if (c) { - sprintf(s, "-%c", c); - if (!strncmp(text, s, len)) -@@ -117,8 +119,9 @@ static char *_list_args(const char *text, int state) - if (match_no < cna->num_args) - match_no = cna->num_args; - -- for (;match_no - cna->num_args < cna->num_args; ++match_no) { -- const char *l = (_cmdline->opt_names + cna->valid_args[match_no - cna->num_args])->long_opt; -+ while ((match_no - cna->num_args) < cna->num_args) { -+ /* increase position for next iteration */ -+ const char *l = _cmdline->opt_names[cna->valid_args[match_no++ - cna->num_args]].long_opt; - if (*(l + 2) && !strncmp(text, l, len)) - return strdup(l); - } --- -2.45.2 - diff --git a/SOURCES/0010-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 new file mode 100644 index 0000000..f75a204 --- /dev/null +++ b/SOURCES/0010-tests-remove-superfluous-a-option-for-df-used-in-lvr.patch @@ -0,0 +1,31 @@ +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/0010-vgimportdevices-skip-global-lockd-locking.patch b/SOURCES/0010-vgimportdevices-skip-global-lockd-locking.patch deleted file mode 100644 index a0663a4..0000000 --- a/SOURCES/0010-vgimportdevices-skip-global-lockd-locking.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 4b33a5a3999fa443dfe5e124e8bd984a936ac77c Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Thu, 30 May 2024 14:51:22 -0500 -Subject: [PATCH 10/13] vgimportdevices: skip global lockd locking - -Fix commit b65a2c3f3a767 "vgimportdevices: skip lvmlockd locking" -which intended to disable lvmlockd locking, but the lockd_gl_disable -flag was mistakenly set after lock_global() so it wasn't effective. -This caused vgimportdevices to fail unless locking was started. - -(cherry picked from commit a8b8e1f074598d080bfb34e1fd04fe36ec122f93) ---- - tools/vgimportdevices.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c -index 70d12e500..2217fdad6 100644 ---- a/tools/vgimportdevices.c -+++ b/tools/vgimportdevices.c -@@ -236,7 +236,7 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) - } - } - -- if (!lock_global(cmd, "ex")) -+ if (!lockf_global(cmd, "ex")) - return ECMD_FAILED; - - /* --- -2.45.2 - diff --git a/SOURCES/0011-WHATS_NEW-update.patch b/SOURCES/0011-WHATS_NEW-update.patch new file mode 100644 index 0000000..5c7ccc2 --- /dev/null +++ b/SOURCES/0011-WHATS_NEW-update.patch @@ -0,0 +1,26 @@ +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-scripts-Install-services-for-devices-file-init.patch b/SOURCES/0011-scripts-Install-services-for-devices-file-init.patch deleted file mode 100644 index 5fb4449..0000000 --- a/SOURCES/0011-scripts-Install-services-for-devices-file-init.patch +++ /dev/null @@ -1,43 +0,0 @@ -From d94090dae6e20135f0e9ba8ca0a645f2e3470a48 Mon Sep 17 00:00:00 2001 -From: Marian Csontos -Date: Wed, 26 Jun 2024 14:37:17 +0200 -Subject: [PATCH 11/13] scripts: Install services for devices file init - -Services introduced in commit c609dedc2f035f770b5f645c4695924abf15c2ca -need installing. - -(cherry picked from commit 1b9bf5007bbfba5bcd622f039a099e6f7e0a8162) ---- - scripts/Makefile.in | 2 ++ - spec/packages.inc | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/scripts/Makefile.in b/scripts/Makefile.in -index a79edbd4d..f683b7ab1 100644 ---- a/scripts/Makefile.in -+++ b/scripts/Makefile.in -@@ -108,6 +108,8 @@ endif - ifeq ("@BUILD_LVMDBUSD@", "yes") - $(Q) $(INSTALL_DATA) lvm2_lvmdbusd_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmdbusd.service - endif -+ $(Q) $(INSTALL_DATA) lvm-devices-import.path $(systemd_unit_dir)/lvm-devices-import.path -+ $(Q) $(INSTALL_DATA) lvm-devices-import.service $(systemd_unit_dir)/lvm-devices-import.service - - ifeq ("@BUILD_LVMDBUSD@", "yes") - install_dbus_service: -diff --git a/spec/packages.inc b/spec/packages.inc -index 05733e0df..ee67af590 100644 ---- a/spec/packages.inc -+++ b/spec/packages.inc -@@ -193,6 +193,8 @@ fi - %{_unitdir}/lvm2-lvmpolld.service - %{_unitdir}/lvm2-lvmpolld.socket - %endif -+ %{_unitdir}/lvm-devices-import.service -+ %{_unitdir}/lvm-devices-import.path - %else - %{_sysconfdir}/rc.d/init.d/blk-availability - %{_sysconfdir}/rc.d/init.d/lvm2-monitor --- -2.45.2 - diff --git a/SOURCES/0012-lvmlockd-avoid-lockd_vg-for-local-VGs.patch b/SOURCES/0012-lvmlockd-avoid-lockd_vg-for-local-VGs.patch deleted file mode 100644 index c84a2be..0000000 --- a/SOURCES/0012-lvmlockd-avoid-lockd_vg-for-local-VGs.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 0bb9ae53db66a2455b9655d16166877cd2c3f4c0 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Wed, 12 Jun 2024 15:36:45 -0500 -Subject: [PATCH 12/13] lvmlockd: avoid lockd_vg for local VGs - -Previously, a command would call lockd_vg() for a local VG, -which would go to lvmlockd, which would send back ENOLS, -and the command would not care when it saw the VG was local. -The pointless back-and-forth to lvmlockd for local VGs can -be avoided by checking the VG lock_type in lvmcache (which -label_scan now saves there; this wasn't the case back when -the original lockd_vg logic was added.) If the lock_type -saved during label_scan indicates a local VG, then the -lockd_vg step is skipped. - -(cherry picked from commit bf60cb4da23cac2f6b721170dd0d8bfd38b16466) ---- - lib/cache/lvmcache.c | 10 +++++++++ - lib/cache/lvmcache.h | 2 ++ - lib/locking/lvmlockd.c | 12 ++++++++--- - tools/lvconvert.c | 8 ++++--- - tools/polldaemon.c | 9 +++++--- - tools/toollib.c | 47 +++++++++++++++++++++++++++++++++++------- - 6 files changed, 71 insertions(+), 17 deletions(-) - -diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c -index 711a97fec..1ea4cb7db 100644 ---- a/lib/cache/lvmcache.c -+++ b/lib/cache/lvmcache.c -@@ -3002,6 +3002,16 @@ int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const ch - return ret; - } - -+int lvmcache_vg_is_lockd_type(struct cmd_context *cmd, const char *vgname, const char *vgid) -+{ -+ struct lvmcache_vginfo *vginfo; -+ -+ if ((vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) -+ return is_lockd_type(vginfo->lock_type); -+ -+ return 0; -+} -+ - /* - * Example of reading four devs in sequence from the same VG: - * -diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h -index eccf29eb2..760ff6ba1 100644 ---- a/lib/cache/lvmcache.h -+++ b/lib/cache/lvmcache.h -@@ -179,6 +179,8 @@ void lvmcache_get_max_name_lengths(struct cmd_context *cmd, - - int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid); - -+int lvmcache_vg_is_lockd_type(struct cmd_context *cmd, const char *vgname, const char *vgid); -+ - bool lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid); - - int lvmcache_vginfo_has_pvid(struct lvmcache_vginfo *vginfo, const char *pvid_arg); -diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c -index 9c24b619f..33150cb48 100644 ---- a/lib/locking/lvmlockd.c -+++ b/lib/locking/lvmlockd.c -@@ -2014,9 +2014,15 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode) - * this result is passed into vg_read(). After vg_read() reads the VG, - * it checks if the VG lock_type (sanlock or dlm) requires a lock to be - * held, and if so, it verifies that the lock was correctly acquired by -- * looking at lockd_state. If vg_read() sees that the VG is a local VG, -- * i.e. lock_type is not sanlock or dlm, then no lock is required, and it -- * ignores lockd_state (which would indicate no lock was found.) -+ * looking at lockd_state. -+ * -+ * If vg_read() sees that the VG is a local VG, i.e. lock_type is not -+ * sanlock or dlm, then no lock is required, and it ignores lockd_state, -+ * which would indicate no lock was found.... although a newer -+ * optimization avoids calling lockd_vg() at all for local VGs -+ * by checking the lock_type in lvmcache saved by label_scan. In extremely -+ * rare case where the lock_type changes between label_scan and vg_read, -+ * the caller will go back and repeat lockd_vg()+vg_read(). - */ - - int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, -diff --git a/tools/lvconvert.c b/tools/lvconvert.c -index dd40ef4f5..4e551a949 100644 ---- a/tools/lvconvert.c -+++ b/tools/lvconvert.c -@@ -5788,10 +5788,12 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd, - struct logical_volume *lv_fast; - uint32_t lockd_state, error_flags; - uint64_t dirty; -+ int is_lockd; - int ret = 0; - - idl = dm_list_item(dm_list_first(&lr->poll_idls), struct convert_poll_id_list); - id = idl->id; -+ is_lockd = lvmcache_vg_is_lockd_type(cmd, id->vg_name, NULL); - - /* - * TODO: we should be able to save info about the dm device for this LV -@@ -5806,7 +5808,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd, - lockd_state = 0; - error_flags = 0; - -- if (!lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) { -+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) { - log_error("Detaching writecache interrupted - locking VG failed."); - return 0; - } -@@ -5843,7 +5845,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd, - if (!lv_writecache_is_clean(cmd, lv, &dirty)) { - unlock_and_release_vg(cmd, vg, vg->name); - -- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) -+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) - stack; - - log_print_unless_silent("Detaching writecache cleaning %llu blocks", (unsigned long long)dirty); -@@ -5896,7 +5898,7 @@ out_release: - unlock_and_release_vg(cmd, vg, vg->name); - - out_lockd: -- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) -+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) - stack; - - return ret; -diff --git a/tools/polldaemon.c b/tools/polldaemon.c -index 730dfbcbb..3a9211768 100644 ---- a/tools/polldaemon.c -+++ b/tools/polldaemon.c -@@ -156,6 +156,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id, - int finished = 0; - uint32_t lockd_state = 0; - uint32_t error_flags = 0; -+ int is_lockd; - int ret; - unsigned wait_before_testing = parms->wait_before_testing; - -@@ -171,11 +172,13 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id, - return 0; - } - -+ is_lockd = lvmcache_vg_is_lockd_type(cmd, id->vg_name, NULL); -+ - /* - * An ex VG lock is needed because the check can call finish_copy - * which writes the VG. - */ -- if (!lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) { -+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) { - log_error("ABORTING: Can't lock VG for %s.", id->display_name); - return 0; - } -@@ -229,7 +232,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id, - - unlock_and_release_vg(cmd, vg, vg->name); - -- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) -+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) - stack; - - wait_before_testing = 1; -@@ -240,7 +243,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id, - out: - if (vg) - unlock_and_release_vg(cmd, vg, vg->name); -- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) -+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state)) - stack; - - return ret; -diff --git a/tools/toollib.c b/tools/toollib.c -index 080ee5429..686a5423c 100644 ---- a/tools/toollib.c -+++ b/tools/toollib.c -@@ -2176,6 +2176,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, - int ret; - int skip; - int notfound; -+ int is_lockd; - int process_all = 0; - int do_report_ret_code = 1; - -@@ -2195,6 +2196,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, - vg_uuid = vgnl->vgid; - skip = 0; - notfound = 0; -+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid); - - uuid[0] = '\0'; - if (is_orphan_vg(vg_name)) { -@@ -2212,8 +2214,8 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, - } - - log_very_verbose("Processing VG %s %s", vg_name, uuid); -- -- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { -+do_lockd: -+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { - stack; - ret_max = ECMD_FAILED; - report_log_ret_code(ret_max); -@@ -2235,6 +2237,14 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, - if (skip || notfound) - goto endvg; - -+ if (!is_lockd && vg_is_shared(vg)) { -+ /* The lock_type changed since label_scan, won't really occur in practice. */ -+ log_debug("Repeat lock and read for local to shared vg"); -+ unlock_and_release_vg(cmd, vg, vg_name); -+ is_lockd = 1; -+ goto do_lockd; -+ } -+ - /* Process this VG? */ - if ((process_all || - (!dm_list_empty(arg_vgnames) && str_list_match_item(arg_vgnames, vg_name)) || -@@ -2255,7 +2265,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags, - unlock_vg(cmd, vg, vg_name); - endvg: - release_vg(vg); -- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) -+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) - stack; - - log_set_report_object_name_and_id(NULL, NULL); -@@ -3873,6 +3883,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag - int ret; - int skip; - int notfound; -+ int is_lockd; - int do_report_ret_code = 1; - - log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG); -@@ -3882,6 +3893,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag - vg_uuid = vgnl->vgid; - skip = 0; - notfound = 0; -+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid); - - uuid[0] = '\0'; - if (vg_uuid && !id_write_format((const struct id*)vg_uuid, uuid, sizeof(uuid))) -@@ -3927,7 +3939,8 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag - - log_very_verbose("Processing VG %s %s", vg_name, vg_uuid ? uuid : ""); - -- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { -+do_lockd: -+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { - ret_max = ECMD_FAILED; - report_log_ret_code(ret_max); - continue; -@@ -3948,6 +3961,14 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag - if (skip || notfound) - goto endvg; - -+ if (!is_lockd && vg_is_shared(vg)) { -+ /* The lock_type changed since label_scan, won't really occur in practice. */ -+ log_debug("Repeat lock and read for local to shared vg"); -+ unlock_and_release_vg(cmd, vg, vg_name); -+ is_lockd = 1; -+ goto do_lockd; -+ } -+ - ret = process_each_lv_in_vg(cmd, vg, &lvnames, tags_arg, 0, - handle, check_single_lv, process_single_lv); - if (ret != ECMD_PROCESSED) -@@ -3959,7 +3980,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag - unlock_vg(cmd, vg, vg_name); - endvg: - release_vg(vg); -- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) -+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) - stack; - log_set_report_object_name_and_id(NULL, NULL); - } -@@ -4513,6 +4534,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags, - int ret; - int skip; - int notfound; -+ int is_lockd; - int do_report_ret_code = 1; - - log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG); -@@ -4522,6 +4544,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags, - vg_uuid = vgnl->vgid; - skip = 0; - notfound = 0; -+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid); - - uuid[0] = '\0'; - if (is_orphan_vg(vg_name)) { -@@ -4537,8 +4560,8 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags, - ret_max = ECMD_FAILED; - goto_out; - } -- -- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { -+do_lockd: -+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) { - ret_max = ECMD_FAILED; - report_log_ret_code(ret_max); - continue; -@@ -4561,6 +4584,14 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags, - if (notfound) - goto endvg; - -+ if (vg && !is_lockd && vg_is_shared(vg)) { -+ /* The lock_type changed since label_scan, won't really occur in practice. */ -+ log_debug("Repeat lock and read for local to shared vg"); -+ unlock_and_release_vg(cmd, vg, vg_name); -+ is_lockd = 1; -+ goto do_lockd; -+ } -+ - /* - * Don't call "continue" when skip is set, because we need to remove - * error_vg->pvs entries from devices list. -@@ -4583,7 +4614,7 @@ endvg: - if (error_vg) - unlock_and_release_vg(cmd, error_vg, vg_name); - release_vg(vg); -- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) -+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) - stack; - - /* Quit early when possible. */ --- -2.45.2 - diff --git a/SOURCES/0012-vdo-fix-input-units-for-minimim_io_size.patch b/SOURCES/0012-vdo-fix-input-units-for-minimim_io_size.patch new file mode 100644 index 0000000..3097459 --- /dev/null +++ b/SOURCES/0012-vdo-fix-input-units-for-minimim_io_size.patch @@ -0,0 +1,59 @@ +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-lvmlockd-allow-forced-vgchange-locktype-from-none.patch b/SOURCES/0013-lvmlockd-allow-forced-vgchange-locktype-from-none.patch deleted file mode 100644 index a32aca1..0000000 --- a/SOURCES/0013-lvmlockd-allow-forced-vgchange-locktype-from-none.patch +++ /dev/null @@ -1,86 +0,0 @@ -From a6dec74334d5b4c3d0774d8b120930dd6e008844 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Thu, 13 Jun 2024 13:34:23 -0500 -Subject: [PATCH 13/13] lvmlockd: allow forced vgchange locktype from none - -vgchange --locktype sanlock|dlm --lockopt force -can be used to change the lock type without lvmlockd or -the lock manager involved. - -(cherry picked from commit 4dc009c87227a137c8be50686b1104cebb9a88e2) ---- - man/lvmlockd.8_main | 5 +++++ - tools/vgchange.c | 17 +++++++++-------- - 2 files changed, 14 insertions(+), 8 deletions(-) - -diff --git a/man/lvmlockd.8_main b/man/lvmlockd.8_main -index ea967d73d..38f9d958d 100644 ---- a/man/lvmlockd.8_main -+++ b/man/lvmlockd.8_main -@@ -729,6 +729,11 @@ vgchange --locktype sanlock|dlm - Start the VG on hosts to use it: - .br - vgchange --lockstart -+.P -+If lvmlockd or the cluster manager are not available, the lock type can -+be forcibly changed with: -+.br -+vgchange --locktype sanlock|dlm \-\-lockopt force - . - .SS Changing a shared VG to a local VG - . -diff --git a/tools/vgchange.c b/tools/vgchange.c -index 2004d6e92..94c1feb8f 100644 ---- a/tools/vgchange.c -+++ b/tools/vgchange.c -@@ -1176,7 +1176,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv) - return ret; - } - --static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg) -+static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg, int *no_change) - { - const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL); - const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL); -@@ -1206,6 +1206,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg) - if (lock_type && !strcmp(vg->lock_type, lock_type)) { - log_warn("WARNING: New lock type %s matches the current lock type %s.", - lock_type, vg->lock_type); -+ *no_change = 1; - return 1; - } - -@@ -1344,9 +1345,14 @@ static int _vgchange_locktype_single(struct cmd_context *cmd, const char *vg_nam - struct volume_group *vg, - struct processing_handle *handle) - { -- if (!_vgchange_locktype(cmd, vg)) -+ int no_change = 0; -+ -+ if (!_vgchange_locktype(cmd, vg, &no_change)) - return_ECMD_FAILED; - -+ if (no_change) -+ return ECMD_PROCESSED; -+ - if (!vg_write(vg) || !vg_commit(vg)) - return_ECMD_FAILED; - -@@ -1402,13 +1408,8 @@ int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv) - * just return success when they see the disable flag set. - */ - if (lockopt && !strcmp(lockopt, "force")) { -- if (lock_type && strcmp(lock_type, "none")) { -- log_error("Lock type can only be forced to \"none\" for recovery."); -- return 0; -- } -- - if (!arg_is_set(cmd, yes_ARG) && -- yes_no_prompt("Forcibly change VG lock type to none? [y/n]: ") == 'n') { -+ yes_no_prompt("Forcibly change VG lock type to %s? [y/n]: ", lock_type) == 'n') { - log_error("VG lock type not changed."); - return 0; - } --- -2.45.2 - diff --git a/SOURCES/0013-tests-check-vdo-minimum_io_size.patch b/SOURCES/0013-tests-check-vdo-minimum_io_size.patch new file mode 100644 index 0000000..a0b7d4d --- /dev/null +++ b/SOURCES/0013-tests-check-vdo-minimum_io_size.patch @@ -0,0 +1,33 @@ +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-lv_manip-avoid-unreleased-memory-pool-s-message-on-R.patch b/SOURCES/0014-lv_manip-avoid-unreleased-memory-pool-s-message-on-R.patch deleted file mode 100644 index be31103..0000000 --- a/SOURCES/0014-lv_manip-avoid-unreleased-memory-pool-s-message-on-R.patch +++ /dev/null @@ -1,60 +0,0 @@ -From a5672ff088a027af04dc5586926841a48b693ee0 Mon Sep 17 00:00:00 2001 -From: Heinz Mauelshagen -Date: Wed, 17 Jul 2024 17:08:20 +0200 -Subject: [PATCH 14/14] lv_manip: avoid unreleased memory pool(s) message on - RAID extend - -In case of different PV sizes in a VG, the lvm2 allocator falls short -to define extended segments resiliently asked for 100%FREE RaidLV extension -and a RAID distinct allocation check fails. Fix is to release a memory pool -on the resulting error path. - -Until the lvm2 allocator gets enhanced (WIP) to do such complex (and other) -allocations proper, a workaround is to extend a RaidLV to any free space on -its already allocated PVs by defining those PVs on the lvextend command line -then iteratively run further such lvextend commands to extend it to its -final intended size. Mind, this may be a non-trivial extension interation. - -(cherry picked from commit 557b2850cef7fa49e2cbacd36e77f679181f09ae) ---- - WHATS_NEW | 5 +++++ - lib/metadata/lv_manip.c | 3 ++- - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 1d56f8675..8647a8f87 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,3 +1,8 @@ -+Version 2.03.26 - -+================== -+ Fix unreleased memory pools on RAID's lvextend. -+ -+ - Version 2.03.25 - - ================== - Revert Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it. -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index bec363ef8..871d3bec9 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -4415,6 +4415,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah, - log_error("Failed to remove LV"); - else if (!vg_write(vg) || !vg_commit(vg)) - log_error("Failed to commit VG %s", vg->name); -+ dm_pool_free(vg->vgmem, lvl); - return_0; - } - -@@ -4571,7 +4572,7 @@ int lv_extend(struct logical_volume *lv, - alloc != ALLOC_ANYWHERE && - !(r = _lv_raid_redundant_allocation(lv, allocatable_pvs))) { - log_error("Insufficient suitable allocatable extents for logical volume %s", display_lvname(lv)); -- if (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg)) -+ if (!old_extents && (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg))) - return_0; - goto out; - } --- -2.45.2 - diff --git a/SOURCES/0014-raid-fix-name-rotation.patch b/SOURCES/0014-raid-fix-name-rotation.patch new file mode 100644 index 0000000..493e6c3 --- /dev/null +++ b/SOURCES/0014-raid-fix-name-rotation.patch @@ -0,0 +1,62 @@ +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 new file mode 100644 index 0000000..6f3027f --- /dev/null +++ b/SOURCES/0015-tests-check-_tdata-conversion-to-raid1.patch @@ -0,0 +1,28 @@ +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 new file mode 100644 index 0000000..cf83678 --- /dev/null +++ b/SOURCES/0016-WHATS_NEW-update.patch @@ -0,0 +1,24 @@ +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 new file mode 100644 index 0000000..995e6e0 --- /dev/null +++ b/SOURCES/0017-device_id-nvme-devices-may-use-alternate-wwids.patch @@ -0,0 +1,805 @@ +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 new file mode 100644 index 0000000..d1d0005 --- /dev/null +++ b/SOURCES/0018-configure.ac-add-support-for-libnvme.patch @@ -0,0 +1,121 @@ +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 new file mode 100644 index 0000000..716e99e --- /dev/null +++ b/SOURCES/0019-configure-autoreconf.patch @@ -0,0 +1,271 @@ +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 new file mode 100644 index 0000000..b3ae59e --- /dev/null +++ b/SOURCES/0020-thin-deactivate-converted-volume-early.patch @@ -0,0 +1,52 @@ +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 new file mode 100644 index 0000000..21d11b1 --- /dev/null +++ b/SOURCES/0021-tests-check-conversion-of-in-use-volume.patch @@ -0,0 +1,51 @@ +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 new file mode 100644 index 0000000..334f06a --- /dev/null +++ b/SOURCES/0022-WHATS_NEW-update.patch @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..987e0f3 --- /dev/null +++ b/SOURCES/0023-lv_manip-check-fs-resize-is-supported-before-LV-exte.patch @@ -0,0 +1,176 @@ +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 new file mode 100644 index 0000000..e7949fc --- /dev/null +++ b/SOURCES/0024-tests-adjust-lvresize-xfs-tests-for-recent-lvextend-.patch @@ -0,0 +1,65 @@ +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 new file mode 100644 index 0000000..bc63217 --- /dev/null +++ b/SOURCES/0025-WHATS_NEW-update.patch @@ -0,0 +1,24 @@ +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 new file mode 100644 index 0000000..53681b4 --- /dev/null +++ b/SOURCES/0026-memlock-check-for-proper-reserved-size.patch @@ -0,0 +1,42 @@ +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 new file mode 100644 index 0000000..5120252 --- /dev/null +++ b/SOURCES/0027-WHATS_NEW-update.patch @@ -0,0 +1,23 @@ +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 new file mode 100644 index 0000000..4c19831 --- /dev/null +++ b/SOURCES/0028-vg_read-rescanning-DM-cache-after-taking-lock.patch @@ -0,0 +1,60 @@ +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 new file mode 100644 index 0000000..e121284 --- /dev/null +++ b/SOURCES/0029-vg_read-matching-missed-empty-cache.patch @@ -0,0 +1,44 @@ +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 new file mode 100644 index 0000000..e97a87d --- /dev/null +++ b/SOURCES/0030-vg_read-correct-error-path-for-DM-cache-update.patch @@ -0,0 +1,35 @@ +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 8a21a15..7cdabdc 100644 --- a/SPECS/lvm2.spec +++ b/SPECS/lvm2.spec @@ -1,4 +1,4 @@ -%global device_mapper_version 1.02.198 +%global device_mapper_version 1.02.202 %global enable_cache 1 %global enable_lvmdbusd 1 @@ -50,13 +50,13 @@ Name: lvm2 %if 0%{?rhel} Epoch: %{rhel} %endif -Version: 2.03.24 +Version: 2.03.28 %if 0%{?from_snapshot} Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix} %else -Release: 2%{?dist}%{?rel_suffix} +Release: 6%{?dist}%{?rel_suffix} %endif -License: GPLv2 +License: GPL-2.0-only URL: https://sourceware.org/lvm2 %if 0%{?from_snapshot} Source0: lvm2-%{shortcommit}.tgz @@ -70,13 +70,34 @@ Patch4: 0004-Revert-dm-udev-rules-don-t-export-and-save-DM_SUSPEN.patch Patch5: 0005-Revert-11-dm-lvm.rules-don-t-restore-DM_UDEV_DISABLE.patch Patch6: 0006-Revert-10-dm-rules-don-t-restore-DM_UDEV_DISABLE_OTH.patch Patch7: 0007-WHATS_NEW-update.patch -Patch8: 0008-Allow-system.devices-to-be-automatically-created-on-.patch -Patch9: 0009-lvm-fix-shell-completion.patch -Patch10: 0010-vgimportdevices-skip-global-lockd-locking.patch -Patch11: 0011-scripts-Install-services-for-devices-file-init.patch -Patch12: 0012-lvmlockd-avoid-lockd_vg-for-local-VGs.patch -Patch13: 0013-lvmlockd-allow-forced-vgchange-locktype-from-none.patch -Patch14: 0014-lv_manip-avoid-unreleased-memory-pool-s-message-on-R.patch +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 BuildRequires: make BuildRequires: gcc @@ -88,6 +109,7 @@ BuildRequires: libblkid-devel >= %{util_linux_version} BuildRequires: ncurses-devel BuildRequires: libedit-devel BuildRequires: libaio-devel +BuildRequires: libnvme-devel %if %{enable_lockd_dlm} BuildRequires: dlm-devel >= %{dlm_version} %endif @@ -414,7 +436,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : ############################################################################## %package devel Summary: Development libraries and headers -License: LGPLv2 +License: LGPL-2.1-only Requires: %{name} = %{?epoch}:%{version}-%{release} Requires: device-mapper-devel = %{?epoch}:%{device_mapper_version}-%{release} Requires: device-mapper-event-devel = %{?epoch}:%{device_mapper_version}-%{release} @@ -432,7 +454,7 @@ the lvm2 libraries. %package libs Summary: Shared libraries for lvm2 -License: LGPLv2 +License: LGPL-2.1-only Requires: device-mapper-event = %{?epoch}:%{device_mapper_version}-%{release} %description libs @@ -510,7 +532,7 @@ LVM commands use lvmlockd to coordinate access to shared storage. %package dbusd Summary: LVM2 D-Bus daemon -License: GPLv2 +License: GPL-2.0-only BuildArch: noarch Requires: lvm2 >= %{?epoch}:%{version}-%{release} Requires: dbus @@ -552,7 +574,7 @@ Daemon for access to LVM2 functionality through a D-Bus interface. %package -n device-mapper Summary: Device mapper utility Version: %{device_mapper_version} -License: GPLv2 +License: GPL-2.0-only URL: http://sources.redhat.com/dm Requires: device-mapper-libs = %{?epoch}:%{device_mapper_version}-%{release} Requires: util-linux-core >= %{util_linux_version} @@ -588,7 +610,7 @@ for the kernel device-mapper. %package -n device-mapper-devel Summary: Development libraries and headers for device-mapper Version: %{device_mapper_version} -License: LGPLv2 +License: LGPL-2.1-only Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release} Requires: pkgconfig @@ -605,7 +627,7 @@ the device-mapper libraries. %package -n device-mapper-libs Summary: Device-mapper shared library Version: %{device_mapper_version} -License: LGPLv2 +License: LGPL-2.1-only Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release} %description -n device-mapper-libs @@ -656,7 +678,7 @@ fi %package -n device-mapper-event-libs Summary: Device-mapper event daemon shared library Version: %{device_mapper_version} -License: LGPLv2 +License: LGPL-2.1-only %description -n device-mapper-event-libs This package contains the device-mapper event daemon shared library, @@ -673,7 +695,7 @@ libdevmapper-event. %package -n device-mapper-event-devel Summary: Development libraries and headers for the device-mapper event daemon Version: %{device_mapper_version} -License: LGPLv2 +License: LGPL-2.1-only Requires: device-mapper-event = %{?epoch}:%{device_mapper_version}-%{release} Requires: pkgconfig @@ -693,8 +715,8 @@ the device-mapper event library. %if %{enable_testsuite} %package testsuite Summary: LVM2 Testsuite -# Most of the code is GPLv2, the harness in test/lib/{brick-shelltest.h,runner.cpp} is BSD, and C files in test/api are LGPLv2... -License: LGPLv2 and GPLv2 and BSD-2-Clause +# Most of the code is GPL-2.0-only, the harness in test/lib/{brick-shelltest.h,runner.cpp} is BSD, and C files in test/api are LGPL-2.1-only... +License: LGPL-2.1-only AND GPL-2.0-only AND BSD-2-Clause %description testsuite An extensive functional testsuite for LVM2. @@ -707,12 +729,39 @@ An extensive functional testsuite for LVM2. %endif %changelog +* Mon Feb 03 2025 Marian Csontos - 2.03.28-6 +- Fix race causing lvm2 not recognizing active devices. + +* Fri Jan 10 2025 Marian Csontos - 2.03.28-5 +- Fix temporary LVs not cleaned when converting in use LV to a thin pool. +- Check FS resize is supported before extending LV. +- Fix issue affecting memory locking before suspend (2.03.27). + +* Tue Dec 17 2024 Marian Csontos - 2.03.28-4 +- Workaround for NVMe WWID changing after kernel update. + +* Thu Nov 14 2024 Marian Csontos - 2.03.28-3 +- Fix duplicate LV names when converting pools to RAID1 with more than 2 legs. + +* Wed Nov 13 2024 Marian Csontos - 2.03.28-2 +- Fix SPDX License identifiers. +- Fix input units for VDO LV's minimim_io_size. +- Fix stripe count and validation for RAID LVs. + +* Tue Nov 05 2024 Marian Csontos - 2.03.28-1 +- Update to upstream version 2.03.28. +- See WHATS_NEW and WHATS_NEW_DM for more information. + +* Wed Oct 09 2024 Marian Csontos - 2.03.27-1 +- Update to upstream version 2.03.27. +- See WHATS_NEW and WHATS_NEW_DM for more information. + * Wed Aug 07 2024 Marian Csontos - 2.03.24-2 - Fix unreleased memory pools on RAID's lvextend. * Wed Jul 10 2024 Marian Csontos - 2.03.24-1 -- Update to upstream version 2.03.24. -- See WHATS_NEW and WHATS_NEW_DM for more information. +- update to upstream version 2.03.24. +- see whats_new and whats_new_dm for more information. * Fri Feb 02 2024 Marian Csontos - 2.03.23-2 - Add warning message when mirror images have (r)efresh bit set.