import CS lvm2-2.03.28-6.el9

This commit is contained in:
eabdullin 2025-03-11 07:44:22 +00:00
parent a7271050b2
commit e388c38ba2
40 changed files with 2310 additions and 1320 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/LVM2.2.03.24.tgz
SOURCES/LVM2.2.03.28.tgz

View File

@ -1 +1 @@
7c2dcac585dc89dbd0070216262a3a8446e7f222 SOURCES/LVM2.2.03.24.tgz
762d6924860a01973ca61543208d97ef385be1f6 SOURCES/LVM2.2.03.28.tgz

View File

@ -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 <mcsontos@redhat.com>
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:
"""]]
-<!-- remove the pending tag on release, remove draft tag once editing is complete -->
-[[!tag draft pending]]
-<!--
-For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
-\[[!meta date="Tue Nov 21 14:26:07 2023 +0100"]]
--->
+[[!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

View File

@ -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 <mcsontos@redhat.com>
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

View File

@ -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 <mcsontos@redhat.com>
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

View File

@ -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 <mcsontos@redhat.com>
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

View File

@ -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 <mcsontos@redhat.com>
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

View File

@ -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 <mcsontos@redhat.com>
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

View File

@ -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 <mcsontos@redhat.com>
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

View File

@ -1,578 +0,0 @@
From 16af82a5afe337cc3b0db3eaed0372e130b049ed Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
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 <rootvg>
- 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 <rootvg>
+
+[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 <mntent.h>
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 <rootvg>/<rootlv>
+ * . run by initrd so root fs can be mounted
+ * . does not use system.devices
+ * . named <rootvg>/<rootlv> comes from kernel command line rd.lvm
+ * . uses first device that appears containing the named root LV
+ *
+ * - vgchange -aay <rootvg>
+ * . 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 <rootvg> 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 <sys/file.h>
+#include <mntent.h>
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

View File

@ -0,0 +1,104 @@
From f2e8b49e1dd70f3735ff556f3f7296078a057a5e Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
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 <RAID segment type> 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

View File

@ -0,0 +1,30 @@
From 75d4056f39886b6cc3e6546dbb03bc7be1923990 Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
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

View File

@ -1,60 +0,0 @@
From fe58f4b87a2cd85f132775a2e475c128b89e7eb4 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,31 @@
From 66aa04c39c00e1b32ad0dfb85910afeaf8b5e88d Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
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

View File

@ -1,31 +0,0 @@
From 4b33a5a3999fa443dfe5e124e8bd984a936ac77c Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
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

View File

@ -0,0 +1,26 @@
From 06dae73111fb4b2d5ce22ab566fb60b0e1d3b7b3 Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
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

View File

@ -1,43 +0,0 @@
From d94090dae6e20135f0e9ba8ca0a645f2e3470a48 Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
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

View File

@ -1,330 +0,0 @@
From 0bb9ae53db66a2455b9655d16166877cd2c3f4c0 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
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

View File

@ -0,0 +1,59 @@
From 55bfaca8a87372887d401aaae7b5804b4f5ed826 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -1,86 +0,0 @@
From a6dec74334d5b4c3d0774d8b120930dd6e008844 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
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 <vgname>
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 <vgname>
Start the VG on hosts to use it:
.br
vgchange --lockstart <vgname>
+.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 <vgname>
.
.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

View File

@ -0,0 +1,33 @@
From aa78a84b20861bb37ca420c1278967f42e6c24dc Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -1,60 +0,0 @@
From a5672ff088a027af04dc5586926841a48b693ee0 Mon Sep 17 00:00:00 2001
From: Heinz Mauelshagen <heinzm@redhat.com>
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

View File

@ -0,0 +1,62 @@
From 2bc2dad1e2c7019dd33b1081d69e0cee4040d566 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,28 @@
From bdcd4f18fe03f6c3fca94e27e5469b1409dda3ad Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,24 @@
From cce339d487194e3a27b7386a2e463416fb96b9f1 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,805 @@
From 5f10e49c729eb6b723891426ceec59af2fe66c09 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
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 <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <limits.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <assert.h>
+
+#ifdef NVME_SUPPORT
+#include <libnvme.h>
+
+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

View File

@ -0,0 +1,121 @@
From b2cec1fc0e879f5a7c7808c54e6eb92575d0e1cc Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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 <libnvme.h>
+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

View File

@ -0,0 +1,271 @@
From f8d2dda397803b2c274da8eec78b04423c5150dd Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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 <libnvme.h>
+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

View File

@ -0,0 +1,52 @@
From 4627ca20dc6314aa382aa21e22aacd32a81a50a2 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,51 @@
From 41aaea4349ff2ef9b80de285e72ba7b94adfcf1a Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,25 @@
From 93aed329721d82d3110014f3f3b1b2803a60f50c Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,176 @@
From 9d9c8b8676b4fe21a0ff69e4c5d9e4a4a861f76e Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
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

View File

@ -0,0 +1,65 @@
From 97713c89cfa6d13488ecffa4eb66457619aa294a Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
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

View File

@ -0,0 +1,24 @@
From 7027d3897aba329a735998e3022482a1b7447ec1 Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
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

View File

@ -0,0 +1,42 @@
From f3eb858a302ec27801ee8bbe90030c0c2f8cc3fe Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,23 @@
From a468c4028a2a996e5651feaf728d4c126698d478 Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
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

View File

@ -0,0 +1,60 @@
From 4587190f41855d8549dc41486c0ee8eb0bedd4e4 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,44 @@
From ce545519e0f5d3d8b50deb3accbeffe41ef55f1d Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -0,0 +1,35 @@
From 2b249a6ee51a79a5c28ffa591069158fd2c50e53 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
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

View File

@ -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 <mcsontos@redhat.com> - 2.03.28-6
- Fix race causing lvm2 not recognizing active devices.
* Fri Jan 10 2025 Marian Csontos <mcsontos@redhat.com> - 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 <mcsontos@redhat.com> - 2.03.28-4
- Workaround for NVMe WWID changing after kernel update.
* Thu Nov 14 2024 Marian Csontos <mcsontos@redhat.com> - 2.03.28-3
- Fix duplicate LV names when converting pools to RAID1 with more than 2 legs.
* Wed Nov 13 2024 Marian Csontos <mcsontos@redhat.com> - 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 <mcsontos@redhat.com> - 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 <mcsontos@redhat.com> - 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 <mcsontos@redhat.com> - 2.03.24-2
- Fix unreleased memory pools on RAID's lvextend.
* Wed Jul 10 2024 Marian Csontos <mcsontos@redhat.com> - 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 <mcsontos@redhat.com> - 2.03.23-2
- Add warning message when mirror images have (r)efresh bit set.