import lvm2-2.03.14-6.el8

This commit is contained in:
CentOS Sources 2022-09-27 16:33:39 -04:00 committed by Stepan Oksanichenko
parent b846c519e5
commit 6aec043f47
57 changed files with 6777 additions and 47 deletions

View File

@ -1,7 +1,7 @@
From 63c4458aaf67d114c677baf657a7e9e43440f349 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 20 Dec 2021 14:22:02 -0600
Subject: [PATCH 01/23] Revert "new udev autoactivation"
Subject: [PATCH 01/54] Revert "new udev autoactivation"
This reverts commit 67722b312390cdab29c076c912e14bd739c5c0f6.
---
@ -541,5 +541,5 @@ index e777dda16..e32cba921 100644
DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}')
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 2091305b796d5552fd991c527a0359a0b4d8fde0 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 20 Dec 2021 13:38:23 -0600
Subject: [PATCH 02/23] Revert "pvscan: only add device args to dev cache"
Subject: [PATCH 02/54] Revert "pvscan: only add device args to dev cache"
This reverts commit 33e47182f773c1a902b533580b63a803906de55d.
---
@ -446,5 +446,5 @@ index 95d593d57..8e2611361 100644
if (cmd->enable_devices_file && device_ids_use_devname(cmd)) {
relax_deviceid_filter = 1;
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From a5a2d5fa1ec47a5a548db4cf435dc84de7ce7c31 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 20 Oct 2021 16:12:41 -0500
Subject: [PATCH 03/23] pvscan: fix messages from coverity changes
Subject: [PATCH 03/54] pvscan: fix messages from coverity changes
---
tools/pvscan.c | 4 ++--
@ -30,5 +30,5 @@ index 8e2611361..f60c4a2ca 100644
continue;
}
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 074fce5c73c55e7a1547d5efff65a9f96e6db3b1 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 25 Oct 2021 12:11:17 -0500
Subject: [PATCH 04/23] vgimportdevices: skip lvmlockd locking
Subject: [PATCH 04/54] vgimportdevices: skip lvmlockd locking
Help bootstrapping existing shared vgs into the devices file.
Reading the vg in vgimportdevices would require locking to be
@ -35,5 +35,5 @@ index 3f315f98f..2580613c4 100644
* For each VG:
* device_id_add() each PV in the VG
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 00ebabfe6e1ebfceffcef335d44a6156a1c15418 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 1 Nov 2021 16:01:09 -0500
Subject: [PATCH 05/23] hints: remove the cmd hints list
Subject: [PATCH 05/54] hints: remove the cmd hints list
which is no longer used after commit
"toollib: remove all devices list from process_each_pv"
@ -91,5 +91,5 @@ index 3cd912270..479a5037a 100644
* Check if the devices_file content is up to date and
* if not update it.
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From f73be4480a5dd104a77e3ef84d7dcc80b834e593 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 2 Nov 2021 15:42:26 -0500
Subject: [PATCH 06/23] filter-sysfs: skip when device id is set
Subject: [PATCH 06/54] filter-sysfs: skip when device id is set
When a device id is set for a device, using an idtype other
than devname, it means that sysfs has been used with the device
@ -418,5 +418,5 @@ index 32ac324dd..672211057 100644
}
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From f732f3d53faee3732d0f4a666c378709e6c2f5e9 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 29 Oct 2021 14:49:36 -0500
Subject: [PATCH 07/23] lvmdevices: increase open file limit
Subject: [PATCH 07/54] lvmdevices: increase open file limit
---
lib/label/label.c | 4 ++--
@ -57,5 +57,5 @@ index 8d9634848..3f104f7de 100644
device_ids_match(cmd);
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From fad2b3dc8c44ba1222508ee78b5f161994efe638 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 9 Nov 2021 11:54:48 -0600
Subject: [PATCH 08/23] filter-sysfs: support old kernels without sys/dev/block
Subject: [PATCH 08/54] filter-sysfs: support old kernels without sys/dev/block
rhel5 for example doesn't have /sys/dev/block
---
@ -69,5 +69,5 @@ index 672211057..d8de7940b 100644
goto_bad;
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 459d931a9bfe4c9adcbbf2e76fdf35fda5b13c61 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 12 Nov 2021 16:42:51 -0600
Subject: [PATCH 09/23] device_id: match different dm device names
Subject: [PATCH 09/54] device_id: match different dm device names
If a devices file entry for a dm device is using the devname
for the device id, then recognize different dm names as matching.
@ -151,5 +151,5 @@ index eb06109ff..dea739fc4 100644
return 0;
}
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 5533cd7bf4c1edc5d8fb0e95d2f83b2b2d446339 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 16 Nov 2021 09:29:24 -0600
Subject: [PATCH 10/23] device_id: fix search on filtered device
Subject: [PATCH 10/54] device_id: fix search on filtered device
When devnames are used as device ids and devnames change,
then new devices need to be located for the PVs. If the old
@ -130,5 +130,5 @@ index f95be52b1..a99fe3e9a 100644
+
vgremove -ff $vg1
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 39adf3e513ac7b1cbbbf0189f973573ade3c8939 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 16 Nov 2021 11:26:41 -0600
Subject: [PATCH 11/23] device_id: searched_devnames improvements
Subject: [PATCH 11/54] device_id: searched_devnames improvements
Remove the searched_devnames file in a couple more places:
. When hints need refreshing it's possible that a missing
@ -98,5 +98,5 @@ index e444a0c82..3ce9634f2 100644
return 0;
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 9c9bf13186d387d807f279c112745768c8b32513 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 16 Nov 2021 14:21:07 -0600
Subject: [PATCH 12/23] tests pv-ext-flags: work with devices file
Subject: [PATCH 12/54] tests pv-ext-flags: work with devices file
---
test/shell/pv-ext-flags.sh | 4 ++++
@ -36,5 +36,5 @@ index 3e6bcff76..ae4d6b7ff 100644
# prepare a VG with $dev1 and $dev both having 1 MDA
aux enable_dev "$dev2"
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 594c1fec1644fdf291aa0ff23de20db65c4cfadf Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 17 Nov 2021 10:40:27 -0600
Subject: [PATCH 13/23] display: ignore --reportformat
Subject: [PATCH 13/54] display: ignore --reportformat
Using the option would do nothing useful but would
print extraneous braces.
@ -87,5 +87,5 @@ index 1e12bedca..1727ba089 100644
* Remaining position args after command name and --options are removed.
*/
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 7ac0b3c119b1cbb8e0b4969ece0b279637ace8c3 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 19 Nov 2021 12:02:35 -0600
Subject: [PATCH 14/23] fix spelling of pruning
Subject: [PATCH 14/54] fix spelling of pruning
---
lib/format_text/archive.c | 2 +-
@ -21,5 +21,5 @@ index 09a472b4c..2e8792a93 100644
}
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 25dbe3dd825a629ff7f67cb43342cc345071d3f7 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 24 Nov 2021 16:03:39 -0600
Subject: [PATCH 15/23] man: lvmautoactivation
Subject: [PATCH 15/54] man: lvmautoactivation
new topical man page describing autoactivation
---
@ -412,5 +412,5 @@ index b20b987da..4c5929955 100644
+.BR lvmautoactivation (7)
+for more information about how pvscan is used for autoactivation.
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 10a4478e9b778dd8d4ff9737a503474b00ce9510 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 1 Dec 2021 08:56:05 -0600
Subject: [PATCH 17/23] tests devicesfile-devname.sh drop mdadm chunk
Subject: [PATCH 17/54] tests devicesfile-devname.sh drop mdadm chunk
---
test/shell/devicesfile-devname.sh | 2 +-
@ -21,5 +21,5 @@ index a99fe3e9a..338637275 100644
sed -e "s|DEVNAME=$dev1|DEVNAME=$dev3|" "$ORIG" > tmp1.devices
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 04770589b49effdb064c9b3790e8dd2fee2c3547 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 1 Dec 2021 10:08:08 -0600
Subject: [PATCH 18/23] devices file: don't write in test mode
Subject: [PATCH 18/54] devices file: don't write in test mode
---
lib/device/device_id.c | 3 +++
@ -22,5 +22,5 @@ index ce7ded154..4c2b5a3dd 100644
if (sscanf(_devices_file_version, "%u.%u.%u", &df_major, &df_minor, &df_counter) != 3) {
/* don't update a file we can't parse */
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 604fd528fb4f00a9f77e084a1b22eff2aeef0259 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 2 Dec 2021 12:40:52 -0600
Subject: [PATCH 19/23] print warning about unrecognized journal option value
Subject: [PATCH 19/54] print warning about unrecognized journal option value
---
lib/log/log.c | 1 +
@ -20,5 +20,5 @@ index 7b4d537b3..5771a1d01 100644
}
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 357a807e81bbd1430b045eb2601a64b17d588400 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 2 Dec 2021 13:30:36 -0600
Subject: [PATCH 20/23] device_id: handle wwid with spaces or control
Subject: [PATCH 20/54] device_id: handle wwid with spaces or control
characters
non-standard wwid can be reported from sysfs with spaces/etc.
@ -46,5 +46,5 @@ index 4c2b5a3dd..0621bc858 100644
goto_bad;
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 7631c5b826b5a3eddfcd22db9b80574b249794c1 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 6 Dec 2021 13:20:32 -0600
Subject: [PATCH 21/23] man: add section about static autoactivation
Subject: [PATCH 21/54] man: add section about static autoactivation
---
man/lvmautoactivation.7_main | 48 ++++++++++++++++++++++++++++++------
@ -92,5 +92,5 @@ index 87c15a3d1..bf885991d 100644
.P
VG "vg" contains two PVs:
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From af4bfa1f1f84194000bc50f43ddc906c0cd4b104 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 13 Dec 2021 08:59:31 -0600
Subject: [PATCH 22/23] lvcreate: include recent options
Subject: [PATCH 22/54] lvcreate: include recent options
The permitted option list in lvcreate has not kept
up with command-lines.in.
@ -31,5 +31,5 @@ index 0121c09a8..79af42685 100644
permission_ARG,\
persistent_ARG,\
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 61833dd5b6117e8ace84289cff656d1dfb0ed123 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 14 Dec 2021 12:02:08 -0600
Subject: [PATCH 23/23] man lvmautoactivation: replace systemctl with
Subject: [PATCH 23/54] man lvmautoactivation: replace systemctl with
journalctl
---
@ -22,5 +22,5 @@ index bf885991d..54dab718b 100644
.
.SS pvscan options
--
2.31.1
2.34.3

View File

@ -1,7 +1,7 @@
From 4b26fb3543049f3d179b620ff937c44e922ada58 Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
Date: Tue, 4 Jan 2022 17:15:56 +0100
Subject: [PATCH] make: generate
Subject: [PATCH 24/54] make: generate
---
man/lvdisplay.8_pregen | 12 --------
@ -192,5 +192,5 @@ index 9c694921d..0a12b3c39 100644
.br
Select objects for processing and reporting based on specified criteria.
--
2.31.1
2.34.3

View File

@ -0,0 +1,141 @@
From a5c37afdca97d6565ea02bc4bc7d52f360823cd3 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 8 Sep 2021 16:30:11 -0500
Subject: [PATCH 25/54] pvcreate: overwrite partition header with -f
$ pvcreate /dev/sdc
Cannot use /dev/sdc: device is partitioned
$ pvcreate -f /dev/sdc
Physical volume "/dev/sdc" successfully created.
---
lib/commands/toolcontext.h | 1 +
lib/filters/filter-partitioned.c | 3 +++
man/pvcreate.8_des | 7 ++++---
test/shell/test-partition.sh | 12 ++++++++++--
tools/toollib.c | 10 ++++++++++
5 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 356c79f8a..b83883fb8 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -201,6 +201,7 @@ struct cmd_context {
unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */
unsigned backup_disabled:1; /* skip repeated debug message */
unsigned event_activation:1; /* whether event_activation is set */
+ unsigned filter_partitioned_skip:1; /* don't use filter-partitioned */
/*
* Devices and filtering.
diff --git a/lib/filters/filter-partitioned.c b/lib/filters/filter-partitioned.c
index 642553ef2..8f468a567 100644
--- a/lib/filters/filter-partitioned.c
+++ b/lib/filters/filter-partitioned.c
@@ -27,6 +27,9 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
if (cmd->filter_nodata_only)
return 1;
+ if (cmd->filter_partitioned_skip)
+ return 1;
+
dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
ret = dev_is_partitioned(cmd, dev);
diff --git a/man/pvcreate.8_des b/man/pvcreate.8_des
index 69bd133aa..4048eb71c 100644
--- a/man/pvcreate.8_des
+++ b/man/pvcreate.8_des
@@ -7,9 +7,10 @@ Use \fBvgcreate\fP(8) to create a new VG on the PV, or \fBvgextend\fP(8)
to add the PV to an existing VG. Use \fBpvremove\fP(8) to remove the LVM
disk label from the device.
.P
-The force option will create a PV without confirmation. Repeating the
-force option (\fB-ff\fP) will forcibly create a PV, overriding checks that
-normally prevent it, e.g. if the PV is already in a VG.
+The force option will create a PV without confirmation, and will overwrite
+partition headers. Repeating the force option (\fB-ff\fP) will override other
+checks that would normally prevent a pvcreate, e.g. if the PV is already in a
+VG.
.P
.B Metadata location, size, and alignment
.P
diff --git a/test/shell/test-partition.sh b/test/shell/test-partition.sh
index 0e92f00db..3a45f9089 100644
--- a/test/shell/test-partition.sh
+++ b/test/shell/test-partition.sh
@@ -16,7 +16,6 @@
#
-
SKIP_WITH_LVMPOLLD=1
LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
@@ -25,7 +24,7 @@ LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
which sfdisk || skip
-aux prepare_pvs 1 30
+aux prepare_pvs 2 30
pvs "$dev1"
@@ -33,3 +32,12 @@ pvs "$dev1"
echo "1 2" | sfdisk --force "$dev1"
not pvs "$dev1"
+
+wipefs -a "$dev2"
+echo "1 2" | sfdisk --force "$dev2"
+partprobe
+not pvcreate "$dev2"
+pvcreate -f "$dev2"
+pvs "$dev2"
+pvremove "$dev2"
+
diff --git a/tools/toollib.c b/tools/toollib.c
index d6f48aad2..80d3de57c 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -5243,6 +5243,10 @@ int pvcreate_each_device(struct cmd_context *cmd,
if (cmd->enable_devices_file && !pp->is_remove)
cmd->filter_deviceid_skip = 1;
+ /* pvcreate -f overwrites partitions */
+ if (pp->force && !pp->is_remove)
+ cmd->filter_partitioned_skip = 1;
+
log_debug("Scanning and filtering device args (%u).", dm_list_size(&scan_devs));
label_scan_devs(cmd, cmd->filter, &scan_devs);
@@ -5257,6 +5261,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
}
}
cmd->filter_deviceid_skip = 0;
+ cmd->filter_partitioned_skip = 0;
/*
* Can the command continue if some specified devices were not found?
@@ -5469,6 +5474,9 @@ do_command:
if (cmd->enable_devices_file && !pp->is_remove)
cmd->filter_deviceid_skip = 1;
+ if (pp->force && !pp->is_remove)
+ cmd->filter_partitioned_skip = 1;
+
log_debug("Rescanning and filtering device args with exclusive open");
if (!label_scan_devs_excl(cmd, cmd->filter, &rescan_devs)) {
log_debug("Failed to rescan devs excl");
@@ -5482,7 +5490,9 @@ do_command:
dm_list_add(&pp->arg_fail, &pd->list);
}
}
+
cmd->filter_deviceid_skip = 0;
+ cmd->filter_partitioned_skip = 0;
if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) {
log_debug("No devices to process.");
--
2.34.3

View File

@ -0,0 +1,166 @@
From bb477d63e336a10e5959962a9f26a028ea9e55eb Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 13 Jan 2022 14:52:54 -0600
Subject: [PATCH 26/54] lvmdevices check: error exit if update is needed
. error exit means that lvmdevices --update would make a change.
. remove check of PART field from --check because it isn't used.
. unlink searched_devnames file to ensure check|update will search
---
lib/device/device_id.c | 3 ++-
test/shell/devicesfile-realdevs.sh | 8 +++----
tools/args.h | 3 ++-
tools/lvmdevices.c | 37 +++++++++++++-----------------
4 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 0621bc858..a33dcebe0 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -2271,7 +2271,8 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
continue;
}
- log_warn("Devices file PVID %s updating IDNAME to %s.", dev->pvid, devname);
+ if (!noupdate)
+ log_warn("Devices file PVID %s updating IDNAME to %s.", dev->pvid, devname);
free(du->idname);
free(du->devname);
diff --git a/test/shell/devicesfile-realdevs.sh b/test/shell/devicesfile-realdevs.sh
index 8d4aa3e67..23d4bedb4 100644
--- a/test/shell/devicesfile-realdevs.sh
+++ b/test/shell/devicesfile-realdevs.sh
@@ -423,7 +423,7 @@ sed "s/$pvid1/badpvid/" "$DF.orig" |tee $DF
not grep $pvid1 $DF
grep $did1 $DF
-lvmdevices --check 2>&1|tee out
+not lvmdevices --check 2>&1|tee out
grep $dev1 out
grep badpvid out
grep $pvid1 out
@@ -493,7 +493,7 @@ rm $DF
d1=$(basename $dev1)
d3=$(basename $dev3)
sed "s/$d1/$d3/" "$DF.orig" |tee $DF
-lvmdevices --check 2>&1 |tee out
+not lvmdevices --check 2>&1 |tee out
grep $dev1 out
lvmdevices --update
@@ -515,7 +515,7 @@ sed "s/$d1/tmp/" "$DF.orig" |tee ${DF}_1
sed "s/$d2/$d1/" "${DF}_1" |tee ${DF}_2
sed "s/tmp/$d2/" "${DF}_2" |tee $DF
rm ${DF}_1 ${DF}_2
-lvmdevices --check 2>&1 |tee out
+not lvmdevices --check 2>&1 |tee out
grep $dev1 out
grep $dev2 out
@@ -536,7 +536,7 @@ rm $DF
d1=$(basename $dev1)
d3=$(basename $dev3)
sed "s/$d1/$d3/" "$DF.orig" |tee $DF
-lvmdevices --check 2>&1 |tee out
+not lvmdevices --check 2>&1 |tee out
grep $dev1 out
pvs -o+uuid,deviceid | grep $vg |tee out
diff --git a/tools/args.h b/tools/args.h
index 774ce33f4..9a7bf81b2 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -153,7 +153,8 @@ arg(cachesize_ARG, '\0', "cachesize", sizemb_VAL, 0, 0,
"The size of cache to use.\n")
arg(check_ARG, '\0', "check", 0, 0, 0,
- "Check the content of the devices file.\n")
+ "Checks the content of the devices file.\n"
+ "Reports incorrect device names or PVIDs for entries.\n")
arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0,
"The command profile to use for command configuration.\n"
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
index 3f104f7de..c50c09f90 100644
--- a/tools/lvmdevices.c
+++ b/tools/lvmdevices.c
@@ -128,7 +128,6 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
struct device *dev;
struct dev_use *du, *du2;
const char *deviceidtype;
- int changes = 0;
dm_list_init(&search_pvids);
dm_list_init(&found_devs);
@@ -184,8 +183,11 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
if (arg_is_set(cmd, check_ARG) || arg_is_set(cmd, update_ARG)) {
int search_count = 0;
+ int update_needed = 0;
int invalid = 0;
+ unlink_searched_devnames(cmd);
+
label_scan_setup_bcache();
dm_list_iterate_items(du, &cmd->use_devices) {
@@ -225,6 +227,8 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
* run just above.
*/
device_ids_validate(cmd, NULL, &invalid, 1);
+ if (invalid)
+ update_needed = 1;
/*
* Find and fix any devname entries that have moved to a
@@ -240,33 +244,24 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
label_scan_invalidate(du->dev);
}
- /*
- * check du->part
- */
- dm_list_iterate_items(du, &cmd->use_devices) {
- int part = 0;
- if (!du->dev)
- continue;
- dev = du->dev;
-
- dev_get_partition_number(dev, &part);
-
- if (part != du->part) {
- log_warn("Device %s partition %u has incorrect PART in devices file (%u)",
- dev_name(dev), part, du->part);
- du->part = part;
- changes++;
- }
- }
-
if (arg_is_set(cmd, update_ARG)) {
- if (invalid || !dm_list_empty(&found_devs)) {
+ if (update_needed || !dm_list_empty(&found_devs)) {
if (!device_ids_write(cmd))
goto_bad;
log_print("Updated devices file to version %s", devices_file_version());
} else {
log_print("No update for devices file is needed.");
}
+ } else {
+ /*
+ * --check exits with an error if the devices file
+ * needs updates, i.e. running --update would make
+ * changes.
+ */
+ if (update_needed) {
+ log_error("Updates needed for devices file.");
+ goto bad;
+ }
}
goto out;
}
--
2.34.3

View File

@ -0,0 +1,140 @@
From 9375aebad1db72267dd67e3ed768aa3b0e698d52 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 18 Jan 2022 12:16:52 -0600
Subject: [PATCH 27/54] Revert "pvcreate: overwrite partition header with -f"
This reverts commit a5c37afdca97d6565ea02bc4bc7d52f360823cd3.
This commit did not properly recognize GPT cases.
---
lib/commands/toolcontext.h | 1 -
lib/filters/filter-partitioned.c | 3 ---
man/pvcreate.8_des | 7 +++----
test/shell/test-partition.sh | 12 ++----------
tools/toollib.c | 10 ----------
5 files changed, 5 insertions(+), 28 deletions(-)
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index b83883fb8..356c79f8a 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -201,7 +201,6 @@ struct cmd_context {
unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */
unsigned backup_disabled:1; /* skip repeated debug message */
unsigned event_activation:1; /* whether event_activation is set */
- unsigned filter_partitioned_skip:1; /* don't use filter-partitioned */
/*
* Devices and filtering.
diff --git a/lib/filters/filter-partitioned.c b/lib/filters/filter-partitioned.c
index 8f468a567..642553ef2 100644
--- a/lib/filters/filter-partitioned.c
+++ b/lib/filters/filter-partitioned.c
@@ -27,9 +27,6 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
if (cmd->filter_nodata_only)
return 1;
- if (cmd->filter_partitioned_skip)
- return 1;
-
dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
ret = dev_is_partitioned(cmd, dev);
diff --git a/man/pvcreate.8_des b/man/pvcreate.8_des
index 4048eb71c..69bd133aa 100644
--- a/man/pvcreate.8_des
+++ b/man/pvcreate.8_des
@@ -7,10 +7,9 @@ Use \fBvgcreate\fP(8) to create a new VG on the PV, or \fBvgextend\fP(8)
to add the PV to an existing VG. Use \fBpvremove\fP(8) to remove the LVM
disk label from the device.
.P
-The force option will create a PV without confirmation, and will overwrite
-partition headers. Repeating the force option (\fB-ff\fP) will override other
-checks that would normally prevent a pvcreate, e.g. if the PV is already in a
-VG.
+The force option will create a PV without confirmation. Repeating the
+force option (\fB-ff\fP) will forcibly create a PV, overriding checks that
+normally prevent it, e.g. if the PV is already in a VG.
.P
.B Metadata location, size, and alignment
.P
diff --git a/test/shell/test-partition.sh b/test/shell/test-partition.sh
index 3a45f9089..0e92f00db 100644
--- a/test/shell/test-partition.sh
+++ b/test/shell/test-partition.sh
@@ -16,6 +16,7 @@
#
+
SKIP_WITH_LVMPOLLD=1
LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
@@ -24,7 +25,7 @@ LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
which sfdisk || skip
-aux prepare_pvs 2 30
+aux prepare_pvs 1 30
pvs "$dev1"
@@ -32,12 +33,3 @@ pvs "$dev1"
echo "1 2" | sfdisk --force "$dev1"
not pvs "$dev1"
-
-wipefs -a "$dev2"
-echo "1 2" | sfdisk --force "$dev2"
-partprobe
-not pvcreate "$dev2"
-pvcreate -f "$dev2"
-pvs "$dev2"
-pvremove "$dev2"
-
diff --git a/tools/toollib.c b/tools/toollib.c
index 80d3de57c..d6f48aad2 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -5243,10 +5243,6 @@ int pvcreate_each_device(struct cmd_context *cmd,
if (cmd->enable_devices_file && !pp->is_remove)
cmd->filter_deviceid_skip = 1;
- /* pvcreate -f overwrites partitions */
- if (pp->force && !pp->is_remove)
- cmd->filter_partitioned_skip = 1;
-
log_debug("Scanning and filtering device args (%u).", dm_list_size(&scan_devs));
label_scan_devs(cmd, cmd->filter, &scan_devs);
@@ -5261,7 +5257,6 @@ int pvcreate_each_device(struct cmd_context *cmd,
}
}
cmd->filter_deviceid_skip = 0;
- cmd->filter_partitioned_skip = 0;
/*
* Can the command continue if some specified devices were not found?
@@ -5474,9 +5469,6 @@ do_command:
if (cmd->enable_devices_file && !pp->is_remove)
cmd->filter_deviceid_skip = 1;
- if (pp->force && !pp->is_remove)
- cmd->filter_partitioned_skip = 1;
-
log_debug("Rescanning and filtering device args with exclusive open");
if (!label_scan_devs_excl(cmd, cmd->filter, &rescan_devs)) {
log_debug("Failed to rescan devs excl");
@@ -5490,9 +5482,7 @@ do_command:
dm_list_add(&pp->arg_fail, &pd->list);
}
}
-
cmd->filter_deviceid_skip = 0;
- cmd->filter_partitioned_skip = 0;
if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) {
log_debug("No devices to process.");
--
2.34.3

View File

@ -0,0 +1,462 @@
From 5403a6f05987b21addb50c9b056e36567d631df7 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 17 Nov 2021 17:10:45 -0600
Subject: [PATCH 28/54] devices: exclude multipath components based on matching
wwid
If multipath component devices get through the filter and
cause lvm to see duplicate PVs, then check the wwid of the
devs and drop the component devices as if they had been
filtered. If a dm mpath device was found among the duplicates
then use that as the PV, otherwise do not use any of the
components as the PV.
"duplicate PVs" associated with multipath configs will no
longer stop commands from working.
---
lib/cache/lvmcache.c | 186 +++++++++++++++++++++++++-
lib/device/dev-mpath.c | 71 ++++++++++
lib/device/dev-type.h | 2 +
lib/device/device_id.c | 4 +-
lib/device/device_id.h | 2 +
test/shell/duplicate-pvs-multipath.sh | 67 ++++++++++
6 files changed, 323 insertions(+), 9 deletions(-)
create mode 100644 test/shell/duplicate-pvs-multipath.sh
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index bee63ebb4..a0811d4ea 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -625,6 +625,102 @@ static void _warn_unused_duplicates(struct cmd_context *cmd)
}
}
+static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_info *info, const char *pvid,
+ struct dm_list *altdevs, struct device **dev_mpath)
+{
+ struct device_list *devl;
+ struct device *dev_mp = NULL;
+ struct device *dev1 = NULL;
+ struct device *dev;
+ const char *wwid1 = NULL;
+ const char *wwid;
+ int diff_wwid = 0;
+ int same_wwid = 0;
+ int dev_is_mp;
+
+ *dev_mpath = NULL;
+
+ /* This function only makes sense with more than one dev. */
+ if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) {
+ log_debug("Skip multipath component checks with single device for PVID %s", pvid);
+ return 0;
+ }
+
+ log_debug("Checking for multipath components for duplicate PVID %s", pvid);
+
+ if (info) {
+ dev = info->dev;
+ dev_is_mp = (cmd->dev_types->device_mapper_major == MAJOR(dev->dev)) && dev_has_mpath_uuid(cmd, dev, NULL);
+
+ if (dev_is_mp) {
+ if ((wwid1 = dev_mpath_component_wwid(cmd, dev))) {
+ dev_mp = dev;
+ dev1 = dev;
+ }
+ } else {
+ if ((wwid1 = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID)))
+ dev1 = dev;
+ }
+ }
+
+ dm_list_iterate_items(devl, altdevs) {
+ dev = devl->dev;
+ dev_is_mp = (cmd->dev_types->device_mapper_major == MAJOR(dev->dev)) && dev_has_mpath_uuid(cmd, dev, NULL);
+
+ if (dev_is_mp)
+ wwid = dev_mpath_component_wwid(cmd, dev);
+ else
+ wwid = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID);
+
+ if (!wwid && wwid1) {
+ log_print("Different wwids for duplicate PVs %s %s %s none",
+ dev_name(dev1), wwid1, dev_name(dev));
+ diff_wwid++;
+ continue;
+ }
+
+ if (!wwid)
+ continue;
+
+ if (!wwid1) {
+ wwid1 = wwid;
+ dev1 = dev;
+ continue;
+ }
+
+ /* Different wwids indicates these are not multipath components. */
+ if (strcmp(wwid1, wwid)) {
+ log_print("Different wwids for duplicate PVs %s %s %s %s",
+ dev_name(dev1), wwid1, dev_name(dev), wwid);
+ diff_wwid++;
+ continue;
+ }
+
+ /* Different mpath devs with the same wwid shouldn't happen. */
+ if (dev_is_mp && dev_mp) {
+ log_print("Found multiple multipath devices for PVID %s WWID %s: %s %s",
+ pvid, wwid1, dev_name(dev_mp), dev_name(dev));
+ continue;
+ }
+
+ log_debug("Same wwids for duplicate PVs %s %s", dev_name(dev1), dev_name(dev));
+ same_wwid++;
+
+ /* Save the mpath device so it can be used as the PV. */
+ if (dev_is_mp)
+ dev_mp = dev;
+ }
+
+ if (diff_wwid || !same_wwid)
+ return 0;
+
+ if (dev_mp)
+ log_debug("Found multipath device %s for PVID %s WWID %s.", dev_name(dev_mp), pvid, wwid1);
+
+ *dev_mpath = dev_mp;
+ return 1;
+}
+
/*
* If we've found devices with the same PVID, decide which one
* to use.
@@ -680,6 +776,8 @@ static void _choose_duplicates(struct cmd_context *cmd,
struct device_list *devl, *devl_safe, *devl_add, *devl_del;
struct lvmcache_info *info;
struct device *dev1, *dev2;
+ struct device *dev_mpath;
+ struct device *dev_drop;
const char *device_id = NULL, *device_id_type = NULL;
const char *idname1 = NULL, *idname2 = NULL;
uint32_t dev1_major, dev1_minor, dev2_major, dev2_minor;
@@ -702,6 +800,7 @@ static void _choose_duplicates(struct cmd_context *cmd,
next:
dm_list_init(&altdevs);
pvid = NULL;
+ dev_mpath = NULL;
dm_list_iterate_items_safe(devl, devl_safe, &_initial_duplicates) {
if (!pvid) {
@@ -720,23 +819,97 @@ next:
return;
}
+ info = lvmcache_info_from_pvid(pvid, NULL, 0);
+
/*
- * Get rid of any md components before comparing alternatives.
- * (Since an md component can never be used, it's not an
- * option to use like other kinds of alternatives.)
+ * Usually and ideally, components of md and multipath devs should have
+ * been excluded by filters, and not scanned for a PV. In some unusual
+ * cases the components can get through the filters, and a PV can be
+ * found on them. Detecting the same PVID on both the component and
+ * the md/mpath device gives us a last chance to drop the component.
+ * An md/mpath component device is completely ignored, as if it had
+ * been filtered, and not kept in the list unused duplicates.
*/
- info = lvmcache_info_from_pvid(pvid, NULL, 0);
+ /*
+ * Get rid of multipath components based on matching wwids.
+ */
+ if (_all_multipath_components(cmd, info, pvid, &altdevs, &dev_mpath)) {
+ if (info && dev_mpath && (info->dev != dev_mpath)) {
+ /*
+ * info should be dropped from lvmcache and info->dev
+ * should be treated as if it had been excluded by a filter.
+ * dev_mpath should be added to lvmcache by the caller.
+ */
+ dev_drop = info->dev;
+
+ /* Have caller add dev_mpath to lvmcache. */
+ log_debug("Using multipath device %s for PVID %s.", dev_name(dev_mpath), pvid);
+ if ((devl_add = zalloc(sizeof(*devl_add)))) {
+ devl_add->dev = dev_mpath;
+ dm_list_add(add_cache_devs, &devl_add->list);
+ }
+
+ /* Remove dev_mpath from altdevs. */
+ if ((devl = _get_devl_in_device_list(dev_mpath, &altdevs)))
+ dm_list_del(&devl->list);
+
+ /* Remove info from lvmcache that came from the component dev. */
+ log_debug("Ignoring multipath component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid);
+ lvmcache_del(info);
+ info = NULL;
+
+ /* Make the component dev look like it was filtered. */
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
+ }
+
+ if (info && !dev_mpath) {
+ /*
+ * Only mpath component devs were found and no actual
+ * multipath dev, so drop the component from lvmcache.
+ */
+ dev_drop = info->dev;
+
+ log_debug("Ignoring multipath component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid);
+ lvmcache_del(info);
+ info = NULL;
+
+ /* Make the component dev look like it was filtered. */
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
+ }
+
+ dm_list_iterate_items_safe(devl, devl_safe, &altdevs) {
+ /*
+ * The altdevs are all mpath components that should look
+ * like they were filtered, they are not in lvmcache.
+ */
+ dev_drop = devl->dev;
+
+ log_debug("Ignoring multipath component %s with PVID %s (dropping duplicate)", dev_name(dev_drop), pvid);
+ dm_list_del(&devl->list);
+
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
+ }
+ goto next;
+ }
+
+ /*
+ * Get rid of any md components.
+ * FIXME: use a function like _all_multipath_components to pick the actual md device.
+ */
if (info && dev_is_md_component(cmd, info->dev, NULL, 1)) {
/* does not go in del_cache_devs which become unused_duplicates */
- log_debug_cache("PV %s drop MD component from scan selection %s", pvid, dev_name(info->dev));
+ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(info->dev), pvid);
lvmcache_del(info);
info = NULL;
}
dm_list_iterate_items_safe(devl, devl_safe, &altdevs) {
if (dev_is_md_component(cmd, devl->dev, NULL, 1)) {
- log_debug_cache("PV %s drop MD component from scan duplicates %s", pvid, dev_name(devl->dev));
+ log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(devl->dev), pvid);
dm_list_del(&devl->list);
}
}
@@ -744,7 +917,6 @@ next:
if (dm_list_empty(&altdevs))
goto next;
-
/*
* Find the device for the pvid that's currently in lvmcache.
*/
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
index ba7bf9740..cbbad9dc9 100644
--- a/lib/device/dev-mpath.c
+++ b/lib/device/dev-mpath.c
@@ -482,3 +482,74 @@ found:
return 1;
}
+const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev)
+{
+ char slaves_path[PATH_MAX];
+ char wwid_path[PATH_MAX];
+ char sysbuf[PATH_MAX] = { 0 };
+ char *slave_name;
+ const char *wwid = NULL;
+ struct stat info;
+ DIR *dr;
+ struct dirent *de;
+
+ /* /sys/dev/block/253:7/slaves/sda/device/wwid */
+
+ if (dm_snprintf(slaves_path, sizeof(slaves_path), "%s/dev/block/%d:%d/slaves",
+ dm_sysfs_dir(), (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) {
+ log_warn("Sysfs path to check mpath components is too long.");
+ return NULL;
+ }
+
+ if (stat(slaves_path, &info))
+ return NULL;
+
+ if (!S_ISDIR(info.st_mode)) {
+ log_warn("Path %s is not a directory.", slaves_path);
+ return NULL;
+ }
+
+ /* Get wwid from first component */
+
+ if (!(dr = opendir(slaves_path))) {
+ log_debug("Device %s has no slaves dir", dev_name(dev));
+ return NULL;
+ }
+
+ while ((de = readdir(dr))) {
+ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+ continue;
+
+ /* slave_name "sda" */
+ slave_name = de->d_name;
+
+ /* read /sys/block/sda/device/wwid */
+
+ if (dm_snprintf(wwid_path, sizeof(wwid_path), "%s/block/%s/device/wwid",
+ dm_sysfs_dir(), slave_name) < 0) {
+ log_warn("Failed to create sysfs wwid path for %s", slave_name);
+ continue;
+ }
+
+ get_sysfs_value(wwid_path, sysbuf, sizeof(sysbuf), 0);
+ if (!sysbuf[0])
+ continue;
+
+ if (strstr(sysbuf, "scsi_debug")) {
+ int i;
+ for (i = 0; i < strlen(sysbuf); i++) {
+ if (sysbuf[i] == ' ')
+ sysbuf[i] = '_';
+ }
+ }
+
+ if ((wwid = dm_pool_strdup(cmd->mem, sysbuf)))
+ break;
+ }
+ if (closedir(dr))
+ stack;
+
+ return wwid;
+}
+
+
diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h
index f3521c6e0..36fb8f258 100644
--- a/lib/device/dev-type.h
+++ b/lib/device/dev-type.h
@@ -63,6 +63,8 @@ int dev_is_swap(struct cmd_context *cmd, struct device *dev, uint64_t *signature
int dev_is_luks(struct cmd_context *cmd, struct device *dev, uint64_t *signature, int full);
int dasd_is_cdl_formatted(struct device *dev);
+const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev);
+
int dev_is_lvm1(struct device *dev, char *buf, int buflen);
int dev_is_pool(struct device *dev, char *buf, int buflen);
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index a33dcebe0..625576ec6 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -243,7 +243,7 @@ static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix)
}
/* the dm uuid uses the wwid of the underlying dev */
-static int _dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out)
+int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out)
{
char sysbuf[PATH_MAX] = { 0 };
const char *idname;
@@ -988,7 +988,7 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
}
if (MAJOR(dev->dev) == cmd->dev_types->device_mapper_major) {
- if (_dev_has_mpath_uuid(cmd, dev, &idname)) {
+ if (dev_has_mpath_uuid(cmd, dev, &idname)) {
idtype = DEV_ID_TYPE_MPATH_UUID;
goto id_done;
}
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
index 939b3a0f4..4cf1374c8 100644
--- a/lib/device/device_id.h
+++ b/lib/device/device_id.h
@@ -55,4 +55,6 @@ void unlink_searched_devnames(struct cmd_context *cmd);
int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize);
+int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);
+
#endif
diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh
new file mode 100644
index 000000000..a145e4afb
--- /dev/null
+++ b/test/shell/duplicate-pvs-multipath.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU 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
+
+test_description='udev rule and systemd unit run vgchange'
+
+SKIP_WITH_LVMPOLLD=1
+SKIP_WITH_LVMLOCKD=1
+
+. lib/inittest
+
+# FIXME: skip until mpath/scsi_debug cleanup works after a failure
+skip
+
+modprobe --dry-run scsi_debug || skip
+multipath -l || skip
+multipath -l | grep scsi_debug && skip
+
+# Turn off multipath_component_detection so that the duplicate
+# resolution of mpath components is used.
+aux lvmconf 'devices/multipath_component_detection = 0'
+# Prevent wwids from being used for filtering.
+aux lvmconf 'devices/multipath_wwids_file = "/dev/null"'
+# Need to use /dev/mapper/mpath
+aux lvmconf 'devices/dir = "/dev"'
+aux lvmconf 'devices/scan = "/dev"'
+# Could set filter to $MP and the component /dev/sd devs
+aux lvmconf "devices/filter = [ \"a|.*|\" ]"
+aux lvmconf "devices/global_filter = [ \"a|.*|\" ]"
+
+modprobe scsi_debug dev_size_mb=100 num_tgts=1 vpd_use_hostno=0 add_host=4 delay=20 max_luns=2 no_lun_0=1
+sleep 2
+
+multipath -r
+sleep 2
+
+MPB=$(multipath -l | grep scsi_debug | cut -f1 -d ' ')
+echo $MPB
+MP=/dev/mapper/$MPB
+echo $MP
+
+pvcreate $MP
+vgcreate $vg1 $MP
+lvcreate -l1 $vg1
+vgchange -an $vg1
+
+pvs |tee out
+grep $MP out
+for i in $(grep -H scsi_debug /sys/block/sd*/device/model | cut -f4 -d /); do
+ not grep /dev/$i out;
+done
+
+vgchange -an $vg1
+vgremove -y $vg1
+
+sleep 2
+multipath -f $MP
+sleep 1
+rmmod scsi_debug
--
2.34.3

View File

@ -0,0 +1,268 @@
From 7b79acc6161b2cff81a03848c160dd6993a4477b Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 22 Nov 2021 15:10:43 -0600
Subject: [PATCH 29/54] devices: exclude md components when duplicate pvs are
seen
Improve handling of md components that get through the
filter, like the previous improvement for multipath.
If md components get through the filter and trigger
duplicate PV code, then eliminate any devs entirely
that are not an md device.
---
lib/cache/lvmcache.c | 168 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 149 insertions(+), 19 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index a0811d4ea..0e62cd267 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -673,7 +673,7 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
wwid = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID);
if (!wwid && wwid1) {
- log_print("Different wwids for duplicate PVs %s %s %s none",
+ log_debug("Different wwids for duplicate PVs %s %s %s none",
dev_name(dev1), wwid1, dev_name(dev));
diff_wwid++;
continue;
@@ -690,7 +690,7 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
/* Different wwids indicates these are not multipath components. */
if (strcmp(wwid1, wwid)) {
- log_print("Different wwids for duplicate PVs %s %s %s %s",
+ log_debug("Different wwids for duplicate PVs %s %s %s %s",
dev_name(dev1), wwid1, dev_name(dev), wwid);
diff_wwid++;
continue;
@@ -721,6 +721,52 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
return 1;
}
+static int _all_md_components(struct cmd_context *cmd, struct lvmcache_info *info, const char *pvid,
+ struct dm_list *altdevs, struct device **dev_md_out)
+{
+ struct device_list *devl;
+ struct device *dev_md = NULL;
+ struct device *dev;
+ int real_dup = 0;
+
+ *dev_md_out = NULL;
+
+ /* There will often be no info struct because of the extra_md_checks function. */
+
+ if (info && (cmd->dev_types->md_major == MAJOR(info->dev->dev)))
+ dev_md = info->dev;
+
+ dm_list_iterate_items(devl, altdevs) {
+ dev = devl->dev;
+
+ if (cmd->dev_types->md_major == MAJOR(dev->dev)) {
+ if (dev_md) {
+ /* md devs themselves are dups */
+ log_debug("Found multiple md devices for PVID %s: %s %s",
+ pvid, dev_name(dev_md), dev_name(dev));
+ real_dup = 1;
+ break;
+ } else
+ dev_md = dev;
+ } else {
+ if (!dev_is_md_component(cmd, dev, NULL, 1)) {
+ /* md dev copied to another device */
+ real_dup = 1;
+ break;
+ }
+ }
+ }
+
+ if (real_dup)
+ return 0;
+
+ if (dev_md)
+ log_debug("Found md device %s for PVID %s.", dev_name(dev_md), pvid);
+
+ *dev_md_out = dev_md;
+ return 1;
+}
+
/*
* If we've found devices with the same PVID, decide which one
* to use.
@@ -776,7 +822,7 @@ static void _choose_duplicates(struct cmd_context *cmd,
struct device_list *devl, *devl_safe, *devl_add, *devl_del;
struct lvmcache_info *info;
struct device *dev1, *dev2;
- struct device *dev_mpath;
+ struct device *dev_mpath, *dev_md;
struct device *dev_drop;
const char *device_id = NULL, *device_id_type = NULL;
const char *idname1 = NULL, *idname2 = NULL;
@@ -801,6 +847,7 @@ next:
dm_list_init(&altdevs);
pvid = NULL;
dev_mpath = NULL;
+ dev_md = NULL;
dm_list_iterate_items_safe(devl, devl_safe, &_initial_duplicates) {
if (!pvid) {
@@ -829,6 +876,11 @@ next:
* the md/mpath device gives us a last chance to drop the component.
* An md/mpath component device is completely ignored, as if it had
* been filtered, and not kept in the list unused duplicates.
+ *
+ * One issue related to eliminating mpath/md duplicate PVs here is
+ * that it occurs after label_scan, and hints are created based
+ * on what label_scan finds, so hints are disabled due to duplicate
+ * PVs that are later resolved here.
*/
/*
@@ -898,24 +950,89 @@ next:
/*
* Get rid of any md components.
- * FIXME: use a function like _all_multipath_components to pick the actual md device.
*/
- if (info && dev_is_md_component(cmd, info->dev, NULL, 1)) {
- /* does not go in del_cache_devs which become unused_duplicates */
- log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(info->dev), pvid);
- lvmcache_del(info);
- info = NULL;
- }
+ if (_all_md_components(cmd, info, pvid, &altdevs, &dev_md)) {
+ if (info && dev_md && (info->dev != dev_md)) {
+ /*
+ * info should be dropped from lvmcache and info->dev
+ * should be treated as if it had been excluded by a filter.
+ * dev_md should be added to lvmcache by the caller.
+ * Often this info struct has been removed by
+ * lvmcache_extra_md_component_checks.
+ */
+ dev_drop = info->dev;
- dm_list_iterate_items_safe(devl, devl_safe, &altdevs) {
- if (dev_is_md_component(cmd, devl->dev, NULL, 1)) {
- log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(devl->dev), pvid);
- dm_list_del(&devl->list);
+ /* Have caller add dev_md to lvmcache. */
+ log_debug("Using md device %s for PVID %s.", dev_name(dev_md), pvid);
+ if ((devl_add = zalloc(sizeof(*devl_add)))) {
+ devl_add->dev = dev_md;
+ dm_list_add(add_cache_devs, &devl_add->list);
+ }
+
+ /* Remove dev_md from altdevs. */
+ if ((devl = _get_devl_in_device_list(dev_md, &altdevs)))
+ dm_list_del(&devl->list);
+
+ /* Remove info from lvmcache that came from the component dev. */
+ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid);
+ lvmcache_del(info);
+ info = NULL;
+
+ /* Make the component dev look like it was filtered. */
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
}
- }
- if (dm_list_empty(&altdevs))
+ if (!info && dev_md) {
+ /*
+ * The info struct was from a component and was dropped
+ * and the actual md dev was found on initial_duplicates
+ * and the caller should add it to lvmcache.
+ */
+
+ /* Have caller add dev_md to lvmcache. */
+ log_debug("Using md device %s for PVID %s.", dev_name(dev_md), pvid);
+ if ((devl_add = zalloc(sizeof(*devl_add)))) {
+ devl_add->dev = dev_md;
+ dm_list_add(add_cache_devs, &devl_add->list);
+ }
+
+ /* Remove dev_md from altdevs. */
+ if ((devl = _get_devl_in_device_list(dev_md, &altdevs)))
+ dm_list_del(&devl->list);
+ }
+
+ if (info && !dev_md) {
+ /*
+ * Only md component devs were found and no actual
+ * md dev, so drop the component from lvmcache.
+ */
+ dev_drop = info->dev;
+
+ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid);
+ lvmcache_del(info);
+ info = NULL;
+
+ /* Make the component dev look like it was filtered. */
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
+ }
+
+ dm_list_iterate_items_safe(devl, devl_safe, &altdevs) {
+ /*
+ * The altdevs are all md components that should look
+ * like they were filtered, they are not in lvmcache.
+ */
+ dev_drop = devl->dev;
+
+ log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(dev_drop), pvid);
+ dm_list_del(&devl->list);
+
+ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL);
+ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL;
+ }
goto next;
+ }
/*
* Find the device for the pvid that's currently in lvmcache.
@@ -1321,6 +1438,18 @@ int lvmcache_label_reopen_vg_rw(struct cmd_context *cmd, const char *vgname, con
* times it can be a clue that label_scan mistakenly read the pv from an md
* component device instead of from the md device itself. So for unmatching
* sizes, we do a full md component check on the device.
+ *
+ * It might be nice to do this checking in the filter (when passes_filter is
+ * called after the initial read), but that doesn't work because passes_filter
+ * is called before _text_read so metadata/pvsummary info is not yet available
+ * which this function uses.
+ *
+ * The unique value of this function is that it can eliminate md components
+ * without there being duplicate PVs. But, there will often be duplicate PVs,
+ * handled by _all_md_components(), where other devs with the same pvid will be
+ * in _initial_duplicates. One could be the md device itself which will be
+ * added to lvmcache by choose_duplicates, and other duplicates that are
+ * components will be dropped.
*/
void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
@@ -1382,7 +1511,8 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
*/
if (pvsize && devsize && (pvsize != devsize))
do_check_size = 1;
- if (device_hint && !strncmp(device_hint, "/dev/md", 7))
+ if (device_hint && !strncmp(device_hint, "/dev/md", 7) &&
+ (MAJOR(info->dev->dev) != cmd->dev_types->md_major))
do_check_name = 1;
if (!do_check_size && !do_check_name)
@@ -1412,11 +1542,11 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
device_hint ?: "none", dev_name(dev));
if (dev_is_md_component(cmd, dev, NULL, 1)) {
- log_debug("dropping PV from md component %s", dev_name(dev));
+ log_debug("Ignoring PV from md component %s with PVID %s (metadata %s %llu)",
+ dev_name(dev), dev->pvid, device_hint ?: "none", (unsigned long long)pvsize);
dev->flags &= ~DEV_SCAN_FOUND_LABEL;
/* lvmcache_del will also delete vginfo if info was last one */
lvmcache_del(info);
- lvmcache_del_dev_from_duplicates(dev);
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
}
}
--
2.34.3

View File

@ -0,0 +1,246 @@
From 4e72068216b006edc69c8bafba5198051e3ed1dd Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 25 Jan 2022 11:35:36 -0600
Subject: [PATCH 30/54] lvmdevices: fix checks when adding entries
Removes some incorrect and unnecessary checks for other entries
when adding a new devices. The removed checks and corrections were
mostly redundant with what is already done by device id matching.
Other checking is reworked so the warnings are a bit different.
---
lib/device/device_id.c | 153 +++++++++++++----------------------------
1 file changed, 48 insertions(+), 105 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 625576ec6..ccc5f43a1 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -935,6 +935,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
struct dev_use *du, *update_du = NULL, *du_dev, *du_pvid, *du_devname, *du_devid;
struct dev_id *id;
int found_id = 0;
+ int part = 0;
+
+ if (!dev_get_partition_number(dev, &part))
+ return_0;
/*
* When enable_devices_file=0 and pending_devices_file=1 we let
@@ -953,10 +957,6 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
*/
memcpy(&pvid, pvid_arg, ID_LEN);
- du_dev = get_du_for_dev(cmd, dev);
- du_pvid = get_du_for_pvid(cmd, pvid);
- du_devname = _get_du_for_devname(cmd, dev_name(dev));
-
/*
* Choose the device_id type for the device being added.
*
@@ -1072,6 +1072,9 @@ id_done:
idtype = 0;
/*
+ * "dev" is the device we are adding.
+ * "id" is the device_id it's using, set in dev->id.
+ *
* Update the cmd->use_devices list for the new device. The
* use_devices list will be used to update the devices file.
*
@@ -1083,23 +1086,57 @@ id_done:
* those other entries to fix any incorrect info.
*/
+ /* Is there already an entry matched to this device? */
+ du_dev = get_du_for_dev(cmd, dev);
+
+ /* Is there already an entry matched to this device's pvid? */
+ du_pvid = get_du_for_pvid(cmd, pvid);
+
+ /* Is there already an entry using this device's name? */
+ du_devname = _get_du_for_devname(cmd, dev_name(dev));
+
+ /* Is there already an entry using the device_id for this device? */
du_devid = _get_du_for_device_id(cmd, id->idtype, id->idname);
if (du_dev)
- log_debug("device_id_add %s pvid %s matches du_dev %p dev %s",
+ log_debug("device_id_add %s pvid %s matches entry %p dev %s",
dev_name(dev), pvid, du_dev, dev_name(du_dev->dev));
if (du_pvid)
- log_debug("device_id_add %s pvid %s matches du_pvid %p dev %s pvid %s",
+ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same pvid %s",
dev_name(dev), pvid, du_pvid, du_pvid->dev ? dev_name(du_pvid->dev) : ".",
du_pvid->pvid);
if (du_devid)
- log_debug("device_id_add %s pvid %s matches du_devid %p dev %s pvid %s",
+ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same device_id %d %s",
dev_name(dev), pvid, du_devid, du_devid->dev ? dev_name(du_devid->dev) : ".",
- du_devid->pvid);
+ du_devid->idtype, du_devid->idname);
if (du_devname)
- log_debug("device_id_add %s pvid %s matches du_devname %p dev %s pvid %s",
+ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same devname %s",
dev_name(dev), pvid, du_devname, du_devname->dev ? dev_name(du_devname->dev) : ".",
- du_devname->pvid);
+ du_devname->devname);
+
+ if (du_pvid && (du_pvid->dev != dev))
+ log_warn("WARNING: adding device %s with PVID %s which is already used for %s.",
+ dev_name(dev), pvid, du_pvid->dev ? dev_name(du_pvid->dev) : "missing device");
+
+ if (du_devid && (du_devid->dev != dev)) {
+ if (!du_devid->dev) {
+ log_warn("WARNING: adding device %s with idname %s which is already used for missing device.",
+ dev_name(dev), id->idname);
+ } else {
+ int ret1, ret2;
+ dev_t devt1, devt2;
+ /* Check if both entries are partitions of the same device. */
+ ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1);
+ ret2 = dev_get_primary_dev(cmd->dev_types, du_devid->dev, &devt2);
+ if ((ret1 == 2) && (ret2 == 2) && (devt1 == devt2)) {
+ log_debug("Using separate entries for partitions of same device %s part %d %s part %d.",
+ dev_name(dev), part, dev_name(du_devid->dev), du_devid->part);
+ } else {
+ log_warn("WARNING: adding device %s with idname %s which is already used for %s.",
+ dev_name(dev), id->idname, dev_name(du_devid->dev));
+ }
+ }
+ }
/*
* If one of the existing entries (du_dev, du_pvid, du_devid, du_devname)
@@ -1112,29 +1149,6 @@ id_done:
dm_list_del(&update_du->list);
update_matching_kind = "device";
update_matching_name = dev_name(dev);
-
- if (du_devid && (du_devid != du_dev)) {
- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate device ID.",
- dev_name(dev), id->idname,
- (du_pvid && du_pvid->dev) ? dev_name(du_pvid->dev) : "none",
- du_pvid ? du_pvid->idname : "");
- }
-
- if (du_pvid && (du_pvid != du_dev)) {
- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate PVID %s",
- dev_name(dev), id->idname,
- du_pvid->dev ? dev_name(du_pvid->dev) : "none", du_pvid->idname,
- pvid);
- }
-
- if (du_devname && (du_devname != du_dev)) {
- /* clear devname in another entry with our devname */
- log_warn("Devices file PVID %s clearing wrong DEVNAME %s.",
- du_devname->pvid, du_devname->devname);
- free(du_devname->devname);
- du_devname->devname = NULL;
- }
-
} else if (du_pvid) {
/*
* If the device_id of the existing entry for PVID is the same
@@ -1154,11 +1168,6 @@ id_done:
update_matching_kind = "PVID";
update_matching_name = pvid;
} else {
- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate PVID %s",
- dev_name(dev), id->idname,
- du_pvid->dev ? dev_name(du_pvid->dev) : "none", du_pvid->idname,
- pvid);
-
if (!cmd->current_settings.yes &&
yes_no_prompt("Add device with duplicate PV to devices file?") == 'n') {
log_print("Device not added.");
@@ -1166,21 +1175,6 @@ id_done:
return 1;
}
}
-
- if (du_devid && (du_devid != du_pvid)) {
- /* warn about another entry using the same device_id */
- log_warn("WARNING: duplicate device_id %s for PVIDs %s %s",
- du_devid->idname, du_devid->pvid, du_pvid->pvid);
- }
-
- if (du_devname && (du_devname != du_pvid)) {
- /* clear devname in another entry with our devname */
- log_warn("Devices file PVID %s clearing wrong DEVNAME %s.",
- du_devname->pvid, du_devname->devname);
- free(du_devname->devname);
- du_devname->devname = NULL;
- }
-
} else if (du_devid) {
/*
* Do we create a new du or update the existing du?
@@ -1195,64 +1189,13 @@ id_done:
* the same device_id (create a new du for dev.)
* If not, then update the existing du_devid.
*/
-
- if (du_devid->dev != dev)
- check_idname = device_id_system_read(cmd, du_devid->dev, id->idtype);
-
- if (check_idname && !strcmp(check_idname, id->idname)) {
- int ret1, ret2;
- dev_t devt1, devt2;
-
- /*
- * two different devices have the same device_id,
- * create a new du for the device being added
- */
-
- /* dev_is_partitioned() the dev open to read it. */
- if (!label_scan_open(du_devid->dev))
- log_warn("Cannot open %s", dev_name(du_devid->dev));
-
- if (dev_is_partitioned(cmd, du_devid->dev)) {
- /* Check if existing entry is whole device and new entry is a partition of it. */
- ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1);
- if ((ret1 == 2) && (devt1 == du_devid->dev->dev))
- log_warn("Remove partitioned device %s from devices file.", dev_name(du_devid->dev));
- } else {
- /* Check if both entries are partitions of the same device. */
- ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1);
- ret2 = dev_get_primary_dev(cmd->dev_types, du_devid->dev, &devt2);
-
- if ((ret1 == 2) && (ret2 == 2) && (devt1 == devt2)) {
- log_warn("Partitions %s %s have same device_id %s",
- dev_name(dev), dev_name(du_devid->dev), id->idname);
- } else {
- log_warn("Duplicate device_id %s %s for %s and %s",
- idtype_to_str(id->idtype), check_idname,
- dev_name(dev), dev_name(du_devid->dev));
- }
- }
- } else {
+ if (du_devid->dev == dev) {
/* update the existing entry with matching devid */
update_du = du_devid;
dm_list_del(&update_du->list);
update_matching_kind = "device_id";
update_matching_name = id->idname;
}
-
- if (du_devname && (du_devname != du_devid)) {
- /* clear devname in another entry with our devname */
- log_warn("Devices file PVID %s clearing wrong DEVNAME %s",
- du_devname->pvid, du_devname->devname);
- free(du_devname->devname);
- du_devname->devname = NULL;
- }
-
- } else if (du_devname) {
- /* clear devname in another entry with our devname */
- log_warn("Devices file PVID %s clearing wrong DEVNAME %s",
- du_devname->pvid, du_devname->devname);
- free(du_devname->devname);
- du_devname->devname = NULL;
}
free((void *)check_idname);
--
2.34.3

View File

@ -0,0 +1,106 @@
From df2b1555aff71452cde156badec70117065c9e2c Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 3 Feb 2022 16:56:03 -0600
Subject: [PATCH 31/54] lvmdevices: make deldev work for missing device
---
lib/device/device_id.c | 6 +++---
lib/device/device_id.h | 1 +
tools/lvmdevices.c | 33 ++++++++++++++++-----------------
3 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index ccc5f43a1..aeaa1ffc6 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -894,7 +894,7 @@ struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid)
return NULL;
}
-static struct dev_use *_get_du_for_devname(struct cmd_context *cmd, const char *devname)
+struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname)
{
struct dev_use *du;
@@ -1093,7 +1093,7 @@ id_done:
du_pvid = get_du_for_pvid(cmd, pvid);
/* Is there already an entry using this device's name? */
- du_devname = _get_du_for_devname(cmd, dev_name(dev));
+ du_devname = get_du_for_devname(cmd, dev_name(dev));
/* Is there already an entry using the device_id for this device? */
du_devid = _get_du_for_device_id(cmd, id->idtype, id->idname);
@@ -1514,7 +1514,7 @@ int device_ids_match_dev(struct cmd_context *cmd, struct device *dev)
struct dev_use *du;
/* First check the du entry with matching devname since it's likely correct. */
- if ((du = _get_du_for_devname(cmd, dev_name(dev)))) {
+ if ((du = get_du_for_devname(cmd, dev_name(dev)))) {
if (_match_du_to_dev(cmd, du, dev))
return 1;
}
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
index 4cf1374c8..2cd2fd7c6 100644
--- a/lib/device/device_id.h
+++ b/lib/device/device_id.h
@@ -40,6 +40,7 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev);
struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid);
+struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname);
char *devices_file_version(void);
int devices_file_exists(struct cmd_context *cmd);
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
index c50c09f90..662b35f9a 100644
--- a/tools/lvmdevices.c
+++ b/tools/lvmdevices.c
@@ -383,28 +383,27 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
* No filter because we always want to allow removing a device
* by name from the devices file.
*/
- if (!(dev = dev_cache_get(cmd, devname, NULL))) {
- log_error("No device found for %s.", devname);
- goto bad;
- }
-
- /*
- * dev_cache_scan uses sysfs to check if an LV is using each dev
- * and sets this flag is so.
- */
- if (dev_is_used_by_active_lv(cmd, dev, NULL, NULL, NULL, NULL)) {
- if (!arg_count(cmd, yes_ARG) &&
- yes_no_prompt("Device %s is used by an active LV, continue to remove? ", devname) == 'n') {
- log_error("Device not removed.");
- goto bad;
+ if ((dev = dev_cache_get(cmd, devname, NULL))) {
+ /*
+ * dev_cache_scan uses sysfs to check if an LV is using each dev
+ * and sets this flag is so.
+ */
+ if (dev_is_used_by_active_lv(cmd, dev, NULL, NULL, NULL, NULL)) {
+ if (!arg_count(cmd, yes_ARG) &&
+ yes_no_prompt("Device %s is used by an active LV, continue to remove? ", devname) == 'n') {
+ log_error("Device not removed.");
+ goto bad;
+ }
}
+ if ((du = get_du_for_dev(cmd, dev)))
+ goto dev_del;
}
- if (!(du = get_du_for_dev(cmd, dev))) {
- log_error("Device not found in devices file.");
+ if (!(du = get_du_for_devname(cmd, devname))) {
+ log_error("No devices file entry for %s.", devname);
goto bad;
}
-
+ dev_del:
dm_list_del(&du->list);
free_du(du);
device_ids_write(cmd);
--
2.34.3

View File

@ -0,0 +1,144 @@
From 08a5619a1d7a5a8dd6e0df6e4dedec47ce2533b7 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 10 Feb 2022 14:00:25 -0600
Subject: [PATCH 32/54] devices file: do not clear PVID of unread devices
In a certain disconnected state, a block device is present on
the system, can be opened, reports a valid size, reports the
correct device id (wwid), and matches a devices file entry.
But, reading the device can still fail. In this case,
device_ids_validate() was misinterpreting the read error as
the device having no data/label on it (and no PVID).
The validate function would then clear the PVID from the
devices file entry for the device, thinking that it was
fixing the devices file (making it consistent with the on disk
state.) Fix this by not attempting to check and correct a
devices file entry that cannot be read. Also make this case
explicit in the hints validation code (which was doing the
right thing but indirectly.)
---
lib/device/device.h | 1 +
lib/device/device_id.c | 14 ++++++++++++++
lib/label/hints.c | 14 ++++++++++++++
lib/label/label.c | 8 ++++++++
4 files changed, 37 insertions(+)
diff --git a/lib/device/device.h b/lib/device/device.h
index 9e471a9b5..8c3a8c30e 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -40,6 +40,7 @@
#define DEV_IS_NVME 0x00040000 /* set if dev is nvme */
#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 */
/*
* Support for external device info.
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index aeaa1ffc6..7fe581571 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1724,6 +1724,13 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
if (scanned_devs && !dev_in_device_list(dev, scanned_devs))
continue;
+ /*
+ * The matched device could not be read so we do not have
+ * the PVID from disk and cannot verify the devices file entry.
+ */
+ if (dev->flags & DEV_SCAN_NOT_READ)
+ continue;
+
/*
* du and dev may have been matched, but the dev could still
* have been excluded by other filters during label scan.
@@ -1806,6 +1813,13 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
if (scanned_devs && !dev_in_device_list(dev, scanned_devs))
continue;
+ /*
+ * The matched device could not be read so we do not have
+ * the PVID from disk and cannot verify the devices file entry.
+ */
+ if (dev->flags & DEV_SCAN_NOT_READ)
+ continue;
+
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
log_warn("Devices file %s is excluded by filter: %s.",
dev_name(dev), dev_filtered_reason(dev));
diff --git a/lib/label/hints.c b/lib/label/hints.c
index 3ce9634f2..95d5d77b8 100644
--- a/lib/label/hints.c
+++ b/lib/label/hints.c
@@ -234,6 +234,7 @@ static int _touch_newhints(void)
return_0;
if (fclose(fp))
stack;
+ log_debug("newhints created");
return 1;
}
@@ -504,6 +505,19 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
if (!hint->chosen)
continue;
+ /*
+ * label_scan was unable to read the dev so we don't know its pvid.
+ * Since we are unable to verify the hint is correct, it's possible
+ * that the PVID is actually found on a different device, so don't
+ * depend on hints. (This would also fail the following pvid check.)
+ */
+ if (dev->flags & DEV_SCAN_NOT_READ) {
+ log_debug("Uncertain hint for unread device %d:%d %s",
+ major(hint->devt), minor(hint->devt), dev_name(dev));
+ ret = 0;
+ continue;
+ }
+
if (strcmp(dev->pvid, hint->pvid)) {
log_debug("Invalid hint device %d:%d %s pvid %s had hint pvid %s",
major(hint->devt), minor(hint->devt), dev_name(dev),
diff --git a/lib/label/label.c b/lib/label/label.c
index 9fac3e464..354ab35e2 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -686,6 +686,8 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
dm_list_iterate_items_safe(devl, devl2, devs) {
+ devl->dev->flags &= ~DEV_SCAN_NOT_READ;
+
/*
* If we prefetch more devs than blocks in the cache, then the
* cache will wait for earlier reads to complete, toss the
@@ -701,6 +703,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
dm_list_del(&devl->list);
dm_list_add(&reopen_devs, &devl->list);
+ devl->dev->flags |= DEV_SCAN_NOT_READ;
continue;
}
}
@@ -724,6 +727,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
log_debug_devs("Scan failed to read %s.", dev_name(devl->dev));
scan_read_errors++;
scan_failed_count++;
+ devl->dev->flags |= DEV_SCAN_NOT_READ;
lvmcache_del_dev(devl->dev);
if (bb)
bcache_put(bb);
@@ -1113,6 +1117,10 @@ int label_scan(struct cmd_context *cmd)
* filter", and this result needs to be cleared (wiped) so that the
* complete set of filters (including those that require data) can be
* checked in _process_block, where headers have been read.
+ *
+ * FIXME: devs that are filtered with data in _process_block
+ * are not moved to the filtered_devs list like devs filtered
+ * here without data. Does that have any effect?
*/
log_debug_devs("Filtering devices to scan (nodata)");
--
2.34.3

View File

@ -0,0 +1,35 @@
From cdefd8635de24200b55822fa0b6bc23a638fb87a Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 21 Feb 2022 11:35:58 -0600
Subject: [PATCH 33/54] man lvmcache: mention writecache memory usage
---
man/lvmcache.7_main | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main
index 48cf7b492..73680235b 100644
--- a/man/lvmcache.7_main
+++ b/man/lvmcache.7_main
@@ -240,6 +240,18 @@ The writecache block size should be chosen to match the xfs sectsz value.
It is also possible to specify a sector size of 4096 to mkfs.xfs when
creating the file system. In this case the writecache block size of 4096
can be used.
+.P
+.SS dm-writecache memory usage
+.P
+The amount of main system memory used by dm-writecache can be a factor
+when selecting the writecache cachevol size and the writecache block size.
+.P
+.IP \[bu] 2
+writecache block size 4096: each 100 GiB of writecache cachevol uses
+slighly over 2 GiB of system memory.
+.IP \[bu] 2
+writecache block size 512: each 100 GiB of writecache cachevol uses
+a little over 16 GiB of system memory.
.
.SS dm-writecache settings
.
--
2.34.3

View File

@ -0,0 +1,102 @@
From c047ff61f68d1b853569b153251f8bc5f88e23cd Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 21 Feb 2022 16:09:57 -0600
Subject: [PATCH 34/54] writecache: display block size from lvs
lvs was missing the ability to display writecache block size.
now possible with lvs -o writecache_block_size
---
lib/report/columns.h | 1 +
lib/report/properties.c | 2 ++
lib/report/report.c | 20 ++++++++++++++++++++
man/lvmcache.7_main | 4 ++++
test/shell/writecache-cache-blocksize.sh | 2 ++
5 files changed, 29 insertions(+)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 12b78b766..7e450dace 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -108,6 +108,7 @@ FIELD(LVS, lv, TIM, "RTime", lvid, 26, lvtimeremoved, lv_time_removed, "Removal
FIELD(LVS, lv, STR, "Host", lvid, 10, lvhost, lv_host, "Creation host of the LV, if known.", 0)
FIELD(LVS, lv, STR_LIST, "Modules", lvid, 0, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 0)
FIELD(LVS, lv, BIN, "Historical", lvid, 0, lvhistorical, lv_historical, "Set if the LV is historical.", 0)
+FIELD(LVS, lv, NUM, "WCacheBlkSize", lvid, 0, writecache_block_size, writecache_block_size, "The writecache block size", 0)
/*
* End of LVS type fields
*/
diff --git a/lib/report/properties.c b/lib/report/properties.c
index 12ea890f4..6f302360f 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -353,6 +353,8 @@ GET_PV_STR_PROPERTY_FN(pv_device_id_type, pv->device_id_type)
#define _writecache_writeback_blocks_get prop_not_implemented_get
#define _writecache_error_set prop_not_implemented_set
#define _writecache_error_get prop_not_implemented_get
+#define _writecache_block_size_set prop_not_implemented_set
+#define _writecache_block_size_get prop_not_implemented_get
#define _vdo_operating_mode_set prop_not_implemented_set
#define _vdo_operating_mode_get prop_not_implemented_get
diff --git a/lib/report/report.c b/lib/report/report.c
index 60df417a4..c06b22674 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -3346,6 +3346,26 @@ static int _integritymismatches_disp(struct dm_report *rh __attribute__((unused)
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
+static int _writecache_block_size_disp(struct dm_report *rh __attribute__((unused)),
+ struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data,
+ void *private __attribute__((unused)))
+{
+ struct logical_volume *lv = (struct logical_volume *) data;
+ uint32_t bs = 0;
+
+ if (lv_is_writecache(lv)) {
+ struct lv_segment *seg = first_seg(lv);
+ bs = seg->writecache_block_size;
+ }
+
+ if (!bs)
+ return dm_report_field_int32(rh, field, &GET_TYPE_RESERVED_VALUE(num_undef_32));
+
+ return dm_report_field_uint32(rh, field, &bs);
+}
+
static int _datapercent_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main
index 73680235b..519e352cb 100644
--- a/man/lvmcache.7_main
+++ b/man/lvmcache.7_main
@@ -241,6 +241,10 @@ It is also possible to specify a sector size of 4096 to mkfs.xfs when
creating the file system. In this case the writecache block size of 4096
can be used.
.P
+The writecache block size is displayed by the command:
+.br
+lvs -o writecacheblocksize VG/LV
+.P
.SS dm-writecache memory usage
.P
The amount of main system memory used by dm-writecache can be a factor
diff --git a/test/shell/writecache-cache-blocksize.sh b/test/shell/writecache-cache-blocksize.sh
index 2579ef7b7..4e17effe5 100644
--- a/test/shell/writecache-cache-blocksize.sh
+++ b/test/shell/writecache-cache-blocksize.sh
@@ -222,6 +222,8 @@ vgextend $vg "$dev2"
lvcreate -n $lv1 -l 8 -an $vg "$dev1"
lvcreate -n $lv2 -l 4 -an $vg "$dev2"
lvconvert --yes --type writecache --cachevol $lv2 --cachesettings "block_size=4096" $vg/$lv1
+lvs -o writecacheblocksize $vg/$lv1 |tee out
+grep 4096 out
lvchange -ay $vg/$lv1
mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1" |tee out
grep "sectsz=4096" out
--
2.34.3

View File

@ -0,0 +1,148 @@
From 8552290efae4905fd1a942be8e752842b11f1881 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 24 Feb 2022 15:57:29 -0600
Subject: [PATCH 35/54] devices: simplify dev_cache_get_by_devt
remove unused args, and no callers need or want a
repeated dev_cache_scan if there is no dev from the
lookup.
---
lib/device/dev-cache.c | 60 ++++--------------------------------------
lib/device/dev-cache.h | 2 +-
lib/label/label.c | 2 +-
tools/pvscan.c | 6 ++---
4 files changed, 10 insertions(+), 60 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index c6e5f68cf..cc1af7c7a 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1577,63 +1577,13 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
return dev;
}
-struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct dev_filter *f, int *filtered)
+struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt)
{
- char path[PATH_MAX];
- const char *sysfs_dir;
- struct stat info;
- struct device *d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
- int ret;
-
- if (filtered)
- *filtered = 0;
-
- if (!d) {
- sysfs_dir = dm_sysfs_dir();
- if (sysfs_dir && *sysfs_dir) {
- /* First check if dev is sysfs to avoid useless scan */
- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d",
- sysfs_dir, (int)MAJOR(dev), (int)MINOR(dev)) < 0) {
- log_error("dm_snprintf partition failed.");
- return NULL;
- }
-
- if (lstat(path, &info)) {
- log_debug("No sysfs entry for %d:%d errno %d at %s.",
- (int)MAJOR(dev), (int)MINOR(dev), errno, path);
- return NULL;
- }
- }
-
- log_debug_devs("Device num not found in dev_cache repeat dev_cache_scan for %d:%d",
- (int)MAJOR(dev), (int)MINOR(dev));
- dev_cache_scan(cmd);
- d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
-
- if (!d)
- return NULL;
- }
-
- if (d->flags & DEV_REGULAR)
- return d;
-
- if (!f)
- return d;
-
- ret = f->passes_filter(cmd, f, d, NULL);
-
- if (ret == -EAGAIN) {
- log_debug_devs("get device by number defer filter %s", dev_name(d));
- d->flags |= DEV_FILTER_AFTER_SCAN;
- ret = 1;
- }
-
- if (ret)
- return d;
-
- if (filtered)
- *filtered = 1;
+ struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt);
+ if (dev)
+ return dev;
+ log_debug_devs("No devno %d:%d in dev cache.", (int)MAJOR(devt), (int)MINOR(devt));
return NULL;
}
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 635dc4fc9..7305eeb0e 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -54,7 +54,7 @@ int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
-struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct dev_filter *f, int *filtered);
+struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
struct device *dev_hash_get(const char *name);
diff --git a/lib/label/label.c b/lib/label/label.c
index 354ab35e2..ffe925254 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1443,7 +1443,7 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv
if (lv_info(cmd, lv, 0, &lvinfo, 0, 0) && lvinfo.exists) {
/* FIXME: Still unclear what is it supposed to find */
devt = MKDEV(lvinfo.major, lvinfo.minor);
- if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
+ if ((dev = dev_cache_get_by_devt(cmd, devt)))
label_scan_invalidate(dev);
}
}
diff --git a/tools/pvscan.c b/tools/pvscan.c
index f60c4a2ca..160a2c9a0 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -857,7 +857,7 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, const char *vgname,
devno = MKDEV(file_major, file_minor);
- if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) {
+ if (!(dev = dev_cache_get_by_devt(cmd, devno))) {
log_error_pvscan(cmd, "No device found for %d:%d PVID %s", file_major, file_minor, pvid);
goto bad;
}
@@ -1195,7 +1195,7 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args,
if (arg->devname)
arg->dev = dev_cache_get(cmd, arg->devname, NULL);
else if (arg->devno)
- arg->dev = dev_cache_get_by_devt(cmd, arg->devno, NULL, NULL);
+ arg->dev = dev_cache_get_by_devt(cmd, arg->devno);
else
return_0;
}
@@ -1257,7 +1257,7 @@ static void _set_pv_devices_online(struct cmd_context *cmd, struct volume_group
devno = MKDEV(major, minor);
- if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) {
+ if (!(dev = dev_cache_get_by_devt(cmd, devno))) {
log_print_pvscan(cmd, "VG %s PV %s no device found for %d:%d",
vg->name, pvid, major, minor);
pvl->pv->status |= MISSING_PV;
--
2.34.3

View File

@ -0,0 +1,467 @@
From 8ba6259b24cd4b99e061f2610c5cd0bcde890039 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 24 Feb 2022 16:03:21 -0600
Subject: [PATCH 36/54] devices: drop incorrect paths from aliases list
along with some basic checks for cases when a device
has no aliases.
lvm itself creates many situations where a struct device
has no valid paths, when it activates and opens an LV,
does something with it, e.g. zeroing, and then closes
and deactivates it. (dev-cache is intended for PVs, and
the use of LVs should be moved out of dev-cache in a
future patch.)
---
lib/device/dev-cache.c | 223 ++++++++++++++++++++++++++---------------
lib/device/dev-cache.h | 2 +-
lib/device/dev-io.c | 34 ++++---
lib/device/device.h | 3 -
4 files changed, 164 insertions(+), 98 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index cc1af7c7a..58e67e130 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -351,7 +351,7 @@ static int _add_alias(struct device *dev, const char *path, enum add_hash hash)
goto out;
}
- if (!(path = dm_pool_strdup(_cache.mem, path)) ||
+ if (!(path = _strdup(path)) ||
!(sl = _zalloc(sizeof(*sl)))) {
log_error("Failed to add allias to dev cache.");
return 0;
@@ -1162,6 +1162,17 @@ static int _insert(const char *path, const struct stat *info,
return 1;
}
+static void _drop_all_aliases(struct device *dev)
+{
+ struct dm_str_list *strl, *strl2;
+
+ dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
+ log_debug("Drop alias for %d:%d %s.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str);
+ dm_hash_remove(_cache.names, strl->str);
+ dm_list_del(&strl->list);
+ }
+}
+
void dev_cache_scan(struct cmd_context *cmd)
{
log_debug_devs("Creating list of system devices.");
@@ -1371,59 +1382,6 @@ int dev_cache_add_dir(const char *path)
return 1;
}
-/* Check cached device name is still valid before returning it */
-/* This should be a rare occurrence */
-/* set quiet if the cache is expected to be out-of-date */
-/* FIXME Make rest of code pass/cache struct device instead of dev_name */
-const char *dev_name_confirmed(struct device *dev, int quiet)
-{
- struct stat buf;
- const char *name;
- int r;
-
- if ((dev->flags & DEV_REGULAR))
- return dev_name(dev);
-
- while ((r = stat(name = dm_list_item(dev->aliases.n,
- struct dm_str_list)->str, &buf)) ||
- (buf.st_rdev != dev->dev)) {
- if (r < 0) {
- if (quiet)
- log_sys_debug("stat", name);
- else
- log_sys_error("stat", name);
- }
- if (quiet)
- log_debug_devs("Path %s no longer valid for device(%d,%d)",
- name, (int) MAJOR(dev->dev),
- (int) MINOR(dev->dev));
- else
- log_warn("Path %s no longer valid for device(%d,%d)",
- name, (int) MAJOR(dev->dev),
- (int) MINOR(dev->dev));
-
- /* Remove the incorrect hash entry */
- dm_hash_remove(_cache.names, name);
-
- /* Leave list alone if there isn't an alternative name */
- /* so dev_name will always find something to return. */
- /* Otherwise add the name to the correct device. */
- if (dm_list_size(&dev->aliases) > 1) {
- dm_list_del(dev->aliases.n);
- if (!r)
- _insert(name, &buf, 0, obtain_device_list_from_udev());
- continue;
- }
-
- /* Scanning issues this inappropriately sometimes. */
- log_debug_devs("Aborting - please provide new pathname for what "
- "used to be %s", name);
- return NULL;
- }
-
- return dev_name(dev);
-}
-
struct device *dev_hash_get(const char *name)
{
return (struct device *) dm_hash_lookup(_cache.names, name);
@@ -1452,26 +1410,23 @@ static void _remove_alias(struct device *dev, const char *name)
* deactivated LV. Those old paths are all invalid and are dropped here.
*/
-static void _verify_aliases(struct device *dev, const char *newname)
+static void _verify_aliases(struct device *dev)
{
struct dm_str_list *strl, *strl2;
struct stat st;
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
- /* newname was just stat'd and added by caller */
- if (newname && !strcmp(strl->str, newname))
- continue;
-
if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) {
- log_debug("Drop invalid path %s for %d:%d (new path %s).",
- strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: "");
+ log_debug("Drop alias for %d:%d invalid path %s %d:%d.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str,
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev));
dm_hash_remove(_cache.names, strl->str);
dm_list_del(&strl->list);
}
}
}
-struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
+static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f, int existing)
{
struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name);
struct stat st;
@@ -1485,13 +1440,18 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
if (dev && (dev->flags & DEV_REGULAR))
return dev;
+ if (dev && dm_list_empty(&dev->aliases)) {
+ /* shouldn't happen */
+ log_warn("Ignoring dev with no valid paths for %s.", name);
+ return NULL;
+ }
+
/*
- * The requested path is invalid, remove any dev-cache
- * info for it.
+ * The requested path is invalid, remove any dev-cache info for it.
*/
if (stat(name, &st)) {
if (dev) {
- log_print("Device path %s is invalid for %d:%d %s.",
+ log_debug("Device path %s is invalid for %d:%d %s.",
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
dm_hash_remove(_cache.names, name);
@@ -1499,11 +1459,17 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
_remove_alias(dev, name);
/* Remove any other names in dev->aliases that are incorrect. */
- _verify_aliases(dev, NULL);
+ _verify_aliases(dev);
}
return NULL;
}
+ if (dev && dm_list_empty(&dev->aliases)) {
+ /* shouldn't happen */
+ log_warn("Ignoring dev with no valid paths for %s.", name);
+ return NULL;
+ }
+
if (!S_ISBLK(st.st_mode)) {
log_debug("Not a block device %s.", name);
return NULL;
@@ -1514,26 +1480,110 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
* Remove incorrect info and then add new dev-cache entry.
*/
if (dev && (st.st_rdev != dev->dev)) {
- log_debug("Device path %s does not match %d:%d %s.",
- name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
+ struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
+
+ /*
+ * lvm commands create this condition when they
+ * activate/deactivate LVs combined with creating new LVs.
+ * The command does not purge dev structs when deactivating
+ * an LV (which it probably should do), but the better
+ * approach would be not using dev-cache at all for LVs.
+ */
- dm_hash_remove(_cache.names, name);
+ log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev),
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
- _remove_alias(dev, name);
+ _drop_all_aliases(dev);
- /* Remove any other names in dev->aliases that are incorrect. */
- _verify_aliases(dev, NULL);
+ if (dev_by_devt) {
+ log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
+ (int)MAJOR(dev_by_devt->dev), (int)MINOR(dev_by_devt->dev), dev_name(dev_by_devt),
+ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
- /* Add new dev-cache entry next. */
- dev = NULL;
+ _drop_all_aliases(dev_by_devt);
+ }
+
+#if 0
+ /*
+ * I think only lvm's own dm devs should be added here, so use
+ * a warning to look for any other unknown cases.
+ */
+ if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
+ log_warn("WARNING: new device appeared %d:%d %s",
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
+ }
+#endif
+
+ if (!_insert_dev(name, st.st_rdev))
+ return_NULL;
+
+ /* Get the struct dev that was just added. */
+ dev = (struct device *) dm_hash_lookup(_cache.names, name);
+
+ if (!dev) {
+ log_error("Failed to get device %s", name);
+ return NULL;
+ }
+
+ goto out;
}
+ if (dev && dm_list_empty(&dev->aliases)) {
+ /* shouldn't happen */
+ log_warn("Ignoring dev with no valid paths for %s.", name);
+ return NULL;
+ }
+
+ if (!dev && existing)
+ return_NULL;
+
/*
- * Either add a new struct dev for st_rdev and name,
- * or add name as a new alias for an existing struct dev
- * for st_rdev.
+ * This case should never be hit for a PV. It should only
+ * happen when the command is opening a new LV it has created.
+ * Add an arg to all callers indicating when the arg should be
+ * new (for an LV) and not existing.
+ * FIXME: fix this further by not using dev-cache struct devs
+ * at all for new dm devs (LVs) that lvm uses. Make the
+ * dev-cache contain only devs for PVs.
+ * Places to fix that use a dev for LVs include:
+ * . lv_resize opening lv to discard
+ * . wipe_lv opening lv to zero it
+ * . _extend_sanlock_lv opening lv to extend it
+ * . _write_log_header opening lv to write header
+ * Also, io to LVs should not go through bcache.
+ * bcache should contain only labels and metadata
+ * scanned from PVs.
*/
if (!dev) {
+ /*
+ * This case should only be used for new devices created by this
+ * command (opening LVs it's created), so if a dev exists for the
+ * dev_t referenced by the name, then drop all aliases for before
+ * _insert_dev adds the new name. lvm commands actually hit this
+ * fairly often when it uses some LV, deactivates the LV, then
+ * creates some new LV which ends up with the same major:minor.
+ * Without dropping the aliases, it's plausible that lvm commands
+ * could end up using the wrong dm device.
+ */
+ struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
+ if (dev_by_devt) {
+ log_debug("Dropping aliases for %d:%d before adding new path %s.",
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
+ _drop_all_aliases(dev_by_devt);
+ }
+
+#if 0
+ /*
+ * I think only lvm's own dm devs should be added here, so use
+ * a warning to look for any other unknown cases.
+ */
+ if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
+ log_warn("WARNING: new device appeared %d:%d %s",
+ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
+ }
+#endif
+
if (!_insert_dev(name, st.st_rdev))
return_NULL;
@@ -1544,10 +1594,9 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
log_error("Failed to get device %s", name);
return NULL;
}
-
- _verify_aliases(dev, name);
}
+ out:
/*
* The caller passed a filter if they only want the dev if it
* passes filters.
@@ -1577,6 +1626,16 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d
return dev;
}
+struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f)
+{
+ return _dev_cache_get(cmd, name, f, 1);
+}
+
+struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
+{
+ return _dev_cache_get(cmd, name, f, 0);
+}
+
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt)
{
struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt);
@@ -1653,8 +1712,10 @@ int dev_fd(struct device *dev)
const char *dev_name(const struct device *dev)
{
- return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str :
- unknown_device_name();
+ if (dev && dev->aliases.n && !dm_list_empty(&dev->aliases))
+ return dm_list_item(dev->aliases.n, struct dm_str_list)->str;
+ else
+ return unknown_device_name();
}
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 7305eeb0e..51c3fc6c3 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -53,7 +53,7 @@ int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
-
+struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f);
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
struct device *dev_hash_get(const char *name);
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index b4f1930b1..811ad8978 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -58,6 +58,9 @@ static int _dev_get_size_file(struct device *dev, uint64_t *size)
const char *name = dev_name(dev);
struct stat info;
+ if (dm_list_empty(&dev->aliases))
+ return_0;
+
if (dev->size_seqno == _dev_size_seqno) {
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
name, dev->size);
@@ -87,7 +90,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
int do_close = 0;
if (dm_list_empty(&dev->aliases))
- return 0;
+ return_0;
if (dev->size_seqno == _dev_size_seqno) {
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
@@ -305,6 +308,13 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if ((flags & O_EXCL))
need_excl = 1;
+ if (dm_list_empty(&dev->aliases)) {
+ /* shouldn't happen */
+ log_print("Cannot open device %d:%d with no valid paths.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
+ return 0;
+ }
+ name = dev_name(dev);
+
if (dev->fd >= 0) {
if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
@@ -314,7 +324,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (dev->open_count && !need_excl)
log_debug_devs("%s: Already opened read-only. Upgrading "
- "to read-write.", dev_name(dev));
+ "to read-write.", name);
/* dev_close_immediate will decrement this */
dev->open_count++;
@@ -327,11 +337,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (critical_section())
/* FIXME Make this log_error */
- log_verbose("dev_open(%s) called while suspended",
- dev_name(dev));
-
- if (!(name = dev_name_confirmed(dev, quiet)))
- return_0;
+ log_verbose("dev_open(%s) called while suspended", name);
#ifdef O_DIRECT_SUPPORT
if (direct) {
@@ -372,9 +378,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
}
#endif
if (quiet)
- log_sys_debug("open", name);
+ log_debug("Failed to open device path %s (%d).", name, errno);
else
- log_sys_error("open", name);
+ log_error("Failed to open device path %s (%d).", name, errno);
dev->flags |= DEV_OPEN_FAILURE;
return 0;
@@ -415,10 +421,12 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if ((flags & O_CREAT) && !(flags & O_TRUNC))
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
- log_debug_devs("Opened %s %s%s%s", dev_name(dev),
- dev->flags & DEV_OPENED_RW ? "RW" : "RO",
- dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
- dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
+ if (!quiet) {
+ log_debug_devs("Opened %s %s%s%s", name,
+ dev->flags & DEV_OPENED_RW ? "RW" : "RO",
+ dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
+ dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
+ }
dev->flags &= ~DEV_OPEN_FAILURE;
return 1;
diff --git a/lib/device/device.h b/lib/device/device.h
index 8c3a8c30e..572994bb9 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -204,9 +204,6 @@ struct device *dev_create_file(const char *filename, struct device *dev,
struct dm_str_list *alias, int use_malloc);
void dev_destroy_file(struct device *dev);
-/* Return a valid device name from the alias list; NULL otherwise */
-const char *dev_name_confirmed(struct device *dev, int quiet);
-
int dev_mpath_init(const char *config_wwids_file);
void dev_mpath_exit(void);
--
2.34.3

View File

@ -0,0 +1,70 @@
From 7dc7ab8e99005da29aba22df2bb67e58e19a50f0 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 24 Feb 2022 16:10:37 -0600
Subject: [PATCH 37/54] devices: initial use of existing option
Use dev_cache_get_existing() in a few common, high level
locations where it's obvious that only existing dev-cache
entries are wanted. This can be expanded and used in more
locations (or dev_cache_get can stop creating new entries.)
---
lib/device/device_id.c | 4 ++--
tools/toollib.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 7fe581571..bcb2e6bcf 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1565,7 +1565,7 @@ void device_ids_match(struct cmd_context *cmd)
dm_list_iterate_items(du, &cmd->use_devices) {
if (du->dev)
continue;
- if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) {
+ if (!(du->dev = dev_cache_get_existing(cmd, du->devname, NULL))) {
log_warn("Device not found for %s.", du->devname);
} else {
/* Should we set dev->id? Which idtype? Use --deviceidtype? */
@@ -1603,7 +1603,7 @@ void device_ids_match(struct cmd_context *cmd)
* the du/dev pairs in preparation for using the filters.
*/
if (du->devname &&
- (dev = dev_cache_get(cmd, du->devname, NULL))) {
+ (dev = dev_cache_get_existing(cmd, du->devname, NULL))) {
/* On successful match, du, dev, and id are linked. */
if (_match_du_to_dev(cmd, du, dev))
continue;
diff --git a/tools/toollib.c b/tools/toollib.c
index d6f48aad2..16be336d4 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1434,7 +1434,7 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv,
goto out;
}
- if (!(dev = dev_cache_get(cmd, argv[opt], cmd->filter))) {
+ if (!(dev = dev_cache_get_existing(cmd, argv[opt], cmd->filter))) {
log_error("Failed to find device "
"\"%s\".", argv[opt]);
ret_max = ECMD_FAILED;
@@ -3870,7 +3870,7 @@ static int _get_arg_devices(struct cmd_context *cmd,
return ECMD_FAILED;
}
- if (!(dil->dev = dev_cache_get(cmd, sl->str, cmd->filter))) {
+ if (!(dil->dev = dev_cache_get_existing(cmd, sl->str, cmd->filter))) {
log_error("Cannot use %s: %s", sl->str, devname_error_reason(sl->str));
ret_max = EINIT_FAILED;
} else {
@@ -5206,7 +5206,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
struct device *dev;
/* No filter used here */
- if (!(dev = dev_cache_get(cmd, pd->name, NULL))) {
+ if (!(dev = dev_cache_get_existing(cmd, pd->name, NULL))) {
log_error("No device found for %s.", pd->name);
dm_list_del(&pd->list);
dm_list_add(&pp->arg_fail, &pd->list);
--
2.34.3

View File

@ -0,0 +1,270 @@
From 591b5f006fca7e06bfbf0d5512da3ae5b0f6bbdd Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 22 Feb 2022 15:03:11 -0600
Subject: [PATCH 38/54] devices: fix dev_name assumptions
dev_name(dev) returns "[unknown]" if there are no names
on dev->aliases. It's meant mainly for log messages.
Many places assume a valid path name is returned, and
use it directly. A caller that wants to use the path
from dev_name() must first check if the dev has any
paths with dm_list_empty(&dev->aliases).
---
lib/activate/dev_manager.c | 9 ++++++++-
lib/device/dev-type.c | 3 +++
lib/device/device_id.c | 13 +++++++++++--
lib/label/hints.c | 2 ++
lib/label/label.c | 16 +++++++++++++++-
lib/locking/lvmlockd.c | 4 ++++
lib/metadata/mirror.c | 17 +++++++++++++----
lib/metadata/pv_list.c | 5 +++++
lib/metadata/vg.c | 5 +++++
test/shell/losetup-partscan.sh | 2 ++
10 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index a73a556b2..284254d68 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2875,6 +2875,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
/* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
for (s = start_area; s < areas; s++) {
+
+ /* FIXME: dev_name() does not return NULL! It needs to check if dm_list_empty(&dev->aliases)
+ but this knot of logic is too complex to pull apart without careful deconstruction. */
+
if ((seg_type(seg, s) == AREA_PV &&
(!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) ||
!(name = dev_name(seg_dev(seg, s))) || !*name ||
@@ -2893,7 +2897,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
return_0;
num_error_areas++;
} else if (seg_type(seg, s) == AREA_PV) {
- if (!dm_tree_node_add_target_area(node, dev_name(seg_dev(seg, s)), NULL,
+ struct device *dev = seg_dev(seg, s);
+ name = dm_list_empty(&dev->aliases) ? NULL : dev_name(dev);
+
+ if (!dm_tree_node_add_target_area(node, name, NULL,
(seg_pv(seg, s)->pe_start + (extent_size * seg_pe(seg, s)))))
return_0;
num_existing_areas++;
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index 0e77a009d..c67a86fa3 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -966,6 +966,9 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam
/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
+ if (dm_list_empty(&dev->aliases))
+ goto_out;
+
if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
goto out;
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index bcb2e6bcf..82db6e4a5 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -347,6 +347,8 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
}
else if (idtype == DEV_ID_TYPE_DEVNAME) {
+ if (dm_list_empty(&dev->aliases))
+ goto_bad;
if (!(idname = strdup(dev_name(dev))))
goto_bad;
return idname;
@@ -940,6 +942,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
if (!dev_get_partition_number(dev, &part))
return_0;
+ /* Ensure valid dev_name(dev) below. */
+ if (dm_list_empty(&dev->aliases))
+ return_0;
+
/*
* When enable_devices_file=0 and pending_devices_file=1 we let
* pvcreate/vgcreate add new du's to cmd->use_devices. These du's may
@@ -1820,6 +1826,9 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
if (dev->flags & DEV_SCAN_NOT_READ)
continue;
+ if (dm_list_empty(&dev->aliases))
+ continue;
+
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
log_warn("Devices file %s is excluded by filter: %s.",
dev_name(dev), dev_filtered_reason(dev));
@@ -2197,14 +2206,14 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
dm_list_iterate_items(dil, &search_pvids) {
char *dup_devname1, *dup_devname2, *dup_devname3;
- if (!dil->dev) {
+ if (!dil->dev || dm_list_empty(&dil->dev->aliases)) {
not_found++;
continue;
}
- found++;
dev = dil->dev;
devname = dev_name(dev);
+ found++;
if (!(du = get_du_for_pvid(cmd, dil->pvid))) {
/* shouldn't happen */
diff --git a/lib/label/hints.c b/lib/label/hints.c
index 95d5d77b8..2a7b3dca7 100644
--- a/lib/label/hints.c
+++ b/lib/label/hints.c
@@ -498,6 +498,8 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
if (!(iter = dev_iter_create(NULL, 0)))
return 0;
while ((dev = dev_iter_get(cmd, iter))) {
+ if (dm_list_empty(&dev->aliases))
+ continue;
if (!(hint = _find_hint_name(hints, dev_name(dev))))
continue;
diff --git a/lib/label/label.c b/lib/label/label.c
index ffe925254..cf707f7a3 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1565,10 +1565,24 @@ int label_scan_open_rw(struct device *dev)
int label_scan_reopen_rw(struct device *dev)
{
+ const char *name;
int flags = 0;
int prev_fd = dev->bcache_fd;
int fd;
+ if (dm_list_empty(&dev->aliases)) {
+ log_error("Cannot reopen rw device %d:%d with no valid paths di %d fd %d.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
+ return 0;
+ }
+
+ name = dev_name(dev);
+ if (!name || name[0] != '/') {
+ log_error("Cannot reopen rw device %d:%d with no valid name di %d fd %d.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
+ return 0;
+ }
+
if (!(dev->flags & DEV_IN_BCACHE)) {
if ((dev->bcache_fd != -1) || (dev->bcache_di != -1)) {
/* shouldn't happen */
@@ -1598,7 +1612,7 @@ int label_scan_reopen_rw(struct device *dev)
flags |= O_NOATIME;
flags |= O_RDWR;
- fd = open(dev_name(dev), flags, 0777);
+ fd = open(name, flags, 0777);
if (fd < 0) {
log_error("Failed to open rw %s errno %d di %d fd %d.",
dev_name(dev), errno, dev->bcache_di, dev->bcache_fd);
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index b598df3d6..60c80f1b1 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -272,6 +272,8 @@ static void _lockd_retrive_vg_pv_list(struct volume_group *vg,
i = 0;
dm_list_iterate_items(pvl, &vg->pvs) {
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
+ continue;
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
if (!lock_pvs->path[i]) {
log_error("Fail to allocate PV path for VG %s", vg->name);
@@ -341,6 +343,8 @@ static void _lockd_retrive_lv_pv_list(struct volume_group *vg,
dm_list_iterate_items(pvl, &vg->pvs) {
if (lv_is_on_pv(lv, pvl->pv)) {
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
+ continue;
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
if (!lock_pvs->path[i]) {
log_error("Fail to allocate PV path for LV %s/%s",
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index e2bf191a1..46da57948 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -1231,14 +1231,23 @@ int remove_mirrors_from_segments(struct logical_volume *lv,
const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr)
{
struct lv_segment *seg;
+ struct device *dev;
dm_list_iterate_items(seg, &lv_mirr->segments) {
if (!seg_is_mirrored(seg))
continue;
- if (seg_type(seg, 0) == AREA_PV)
- return dev_name(seg_dev(seg, 0));
- if (seg_type(seg, 0) == AREA_LV)
- return dev_name(seg_dev(first_seg(seg_lv(seg, 0)), 0));
+ if (seg_type(seg, 0) == AREA_PV) {
+ dev = seg_dev(seg, 0);
+ if (!dev || dm_list_empty(&dev->aliases))
+ return NULL;
+ return dev_name(dev);
+ }
+ if (seg_type(seg, 0) == AREA_LV) {
+ dev = seg_dev(first_seg(seg_lv(seg, 0)), 0);
+ if (!dev || dm_list_empty(&dev->aliases))
+ return NULL;
+ return dev_name(dev);
+ }
}
return NULL;
diff --git a/lib/metadata/pv_list.c b/lib/metadata/pv_list.c
index 813e8e525..fc3667db0 100644
--- a/lib/metadata/pv_list.c
+++ b/lib/metadata/pv_list.c
@@ -152,6 +152,11 @@ static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
struct pv_list *new_pvl = NULL, *pvl2;
struct dm_list *pe_ranges;
+ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) {
+ log_error("Failed to create PV entry for missing device.");
+ return 0;
+ }
+
pvname = pv_dev_name(pvl->pv);
if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) {
log_warn("WARNING: Physical volume %s not allocatable.", pvname);
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 85482552a..adc954bab 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -679,6 +679,11 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
return r;
}
+ if (!pv->dev || dm_list_empty(&pv->dev->aliases)) {
+ log_error("No device found for PV.");
+ return r;
+ }
+
log_debug("vgreduce_single VG %s PV %s", vg->name, pv_dev_name(pv));
if (pv_pe_alloc_count(pv)) {
diff --git a/test/shell/losetup-partscan.sh b/test/shell/losetup-partscan.sh
index 99f552ad1..670568945 100644
--- a/test/shell/losetup-partscan.sh
+++ b/test/shell/losetup-partscan.sh
@@ -33,6 +33,8 @@ aux udev_wait
ls -la "${LOOP}"*
test -e "${LOOP}p1"
+aux lvmconf 'devices/scan = "/dev"'
+
aux extend_filter "a|$LOOP|"
aux extend_devices "$LOOP"
--
2.34.3

View File

@ -0,0 +1,272 @@
From 932b9720bb074e49ac920642b3fe9c3d84019787 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 28 Feb 2022 17:37:12 -0600
Subject: [PATCH 39/54] devices: use dev-cache aliases handling from label scan
functions
The label scan functions where doing some device alias validation
which is now better handled by the dev-cache layer, so just use
that.
---
lib/device/dev-cache.c | 4 +-
lib/device/dev-cache.h | 1 +
lib/label/label.c | 143 ++++++++++-------------------------------
3 files changed, 36 insertions(+), 112 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 58e67e130..b0759b06c 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1410,7 +1410,7 @@ static void _remove_alias(struct device *dev, const char *name)
* deactivated LV. Those old paths are all invalid and are dropped here.
*/
-static void _verify_aliases(struct device *dev)
+void dev_cache_verify_aliases(struct device *dev)
{
struct dm_str_list *strl, *strl2;
struct stat st;
@@ -1459,7 +1459,7 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
_remove_alias(dev, name);
/* Remove any other names in dev->aliases that are incorrect. */
- _verify_aliases(dev);
+ dev_cache_verify_aliases(dev);
}
return NULL;
}
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 51c3fc6c3..321a56d7b 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -55,6 +55,7 @@ int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f);
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
+void dev_cache_verify_aliases(struct device *dev);
struct device *dev_hash_get(const char *name);
diff --git a/lib/label/label.c b/lib/label/label.c
index cf707f7a3..06958b502 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -458,7 +458,6 @@ static int _scan_dev_open(struct device *dev)
const char *name;
const char *modestr;
struct stat sbuf;
- int retried = 0;
int flags = 0;
int fd, di;
@@ -478,14 +477,23 @@ static int _scan_dev_open(struct device *dev)
return 0;
}
+ next_name:
/*
* All the names for this device (major:minor) are kept on
* dev->aliases, the first one is the primary/preferred name.
+ *
+ * The default name preferences in dev-cache mean that the first
+ * name in dev->aliases is not a symlink for scsi devices, but is
+ * the /dev/mapper/ symlink for mpath devices.
+ *
+ * If preferred names are set to symlinks, should this
+ * first attempt to open using a non-symlink?
+ *
+ * dm_list_first() returns NULL if the list is empty.
*/
if (!(name_list = dm_list_first(&dev->aliases))) {
- /* Shouldn't happen */
- log_error("Device open %s %d:%d has no path names.",
- dev_name(dev), (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
+ log_error("Device open %d:%d has no path names.",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
return 0;
}
name_sl = dm_list_item(name_list, struct dm_str_list);
@@ -513,50 +521,34 @@ static int _scan_dev_open(struct device *dev)
modestr = "ro";
}
-retry_open:
-
fd = open(name, flags, 0777);
-
if (fd < 0) {
if ((errno == EBUSY) && (flags & O_EXCL)) {
log_error("Can't open %s exclusively. Mounted filesystem?",
dev_name(dev));
+ return 0;
} else {
- int major, minor;
-
/*
- * Shouldn't happen, if it does, print stat info to help figure
- * out what's wrong.
+ * drop name from dev->aliases and use verify_aliases to
+ * drop any other invalid aliases before retrying open with
+ * any remaining valid paths.
*/
-
- major = (int)MAJOR(dev->dev);
- minor = (int)MINOR(dev->dev);
-
- log_error("Device open %s %d:%d failed errno %d", name, major, minor, errno);
-
- if (stat(name, &sbuf)) {
- log_debug_devs("Device open %s %d:%d stat failed errno %d",
- name, major, minor, errno);
- } else if (sbuf.st_rdev != dev->dev) {
- log_debug_devs("Device open %s %d:%d stat %d:%d does not match.",
- name, major, minor,
- (int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
- }
-
- if (!retried) {
- /*
- * FIXME: remove this, the theory for this retry is that
- * there may be a udev race that we can sometimes mask by
- * retrying. This is here until we can figure out if it's
- * needed and if so fix the real problem.
- */
- usleep(5000);
- log_debug_devs("Device open %s retry", dev_name(dev));
- retried = 1;
- goto retry_open;
- }
+ log_debug("Drop alias for %d:%d failed open %s (%d)",
+ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), name, errno);
+ dev_cache_failed_path(dev, name);
+ dev_cache_verify_aliases(dev);
+ goto next_name;
}
- return 0;
+ }
+
+ /* Verify that major:minor from the path still match dev. */
+ if ((fstat(fd, &sbuf) < 0) || (sbuf.st_rdev != dev->dev)) {
+ log_warn("Invalid path %s for device %d:%d, trying different path.",
+ name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
+ (void)close(fd);
+ dev_cache_failed_path(dev, name);
+ dev_cache_verify_aliases(dev);
+ goto next_name;
}
dev->flags |= DEV_IN_BCACHE;
@@ -604,37 +596,6 @@ static int _scan_dev_close(struct device *dev)
return 1;
}
-static void _drop_bad_aliases(struct device *dev)
-{
- struct dm_str_list *strl, *strl2;
- const char *name;
- struct stat sbuf;
- int major = (int)MAJOR(dev->dev);
- int minor = (int)MINOR(dev->dev);
- int bad;
-
- dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
- name = strl->str;
- bad = 0;
-
- if (stat(name, &sbuf)) {
- bad = 1;
- log_debug_devs("Device path check %d:%d %s stat failed errno %d",
- major, minor, name, errno);
- } else if (sbuf.st_rdev != dev->dev) {
- bad = 1;
- log_debug_devs("Device path check %d:%d %s stat %d:%d does not match.",
- major, minor, name,
- (int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
- }
-
- if (bad) {
- log_debug_devs("Device path check %d:%d dropping path %s.", major, minor, name);
- dev_cache_failed_path(dev, name);
- }
- }
-}
-
// Like bcache_invalidate, only it throws any dirty data away if the
// write fails.
static void _invalidate_di(struct bcache *cache, int di)
@@ -662,10 +623,8 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
char headers_buf[HEADERS_BUF_SIZE];
struct dm_list wait_devs;
struct dm_list done_devs;
- struct dm_list reopen_devs;
struct device_list *devl, *devl2;
struct block *bb;
- int retried_open = 0;
int scan_read_errors = 0;
int scan_process_errors = 0;
int scan_failed_count = 0;
@@ -676,7 +635,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
dm_list_init(&wait_devs);
dm_list_init(&done_devs);
- dm_list_init(&reopen_devs);
log_debug_devs("Scanning %d devices for VG info", dm_list_size(devs));
@@ -700,9 +658,9 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
if (!_in_bcache(devl->dev)) {
if (!_scan_dev_open(devl->dev)) {
- log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
+ log_debug_devs("Scan failed to open %d:%d %s.",
+ (int)MAJOR(devl->dev->dev), (int)MINOR(devl->dev->dev), dev_name(devl->dev));
dm_list_del(&devl->list);
- dm_list_add(&reopen_devs, &devl->list);
devl->dev->flags |= DEV_SCAN_NOT_READ;
continue;
}
@@ -786,41 +744,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
if (!dm_list_empty(devs))
goto scan_more;
- /*
- * We're done scanning all the devs. If we failed to open any of them
- * the first time through, refresh device paths and retry. We failed
- * to open the devs on the reopen_devs list.
- *
- * FIXME: it's not clear if or why this helps.
- */
- if (!dm_list_empty(&reopen_devs)) {
- if (retried_open) {
- /* Don't try again. */
- scan_failed_count += dm_list_size(&reopen_devs);
- dm_list_splice(&done_devs, &reopen_devs);
- goto out;
- }
- retried_open = 1;
-
- dm_list_iterate_items_safe(devl, devl2, &reopen_devs) {
- _drop_bad_aliases(devl->dev);
-
- if (dm_list_empty(&devl->dev->aliases)) {
- log_warn("WARNING: Scan ignoring device %d:%d with no paths.",
- (int)MAJOR(devl->dev->dev),
- (int)MINOR(devl->dev->dev));
-
- dm_list_del(&devl->list);
- lvmcache_del_dev(devl->dev);
- scan_failed_count++;
- }
- }
-
- /* Put devs that failed to open back on the original list to retry. */
- dm_list_splice(devs, &reopen_devs);
- goto scan_more;
- }
-out:
log_debug_devs("Scanned devices: read errors %d process errors %d failed %d",
scan_read_errors, scan_process_errors, scan_failed_count);
--
2.34.3

View File

@ -0,0 +1,101 @@
From 10a598075a0fdf6d93cc2fefa73fc4a5f1d0de48 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 1 Mar 2022 14:31:39 -0600
Subject: [PATCH 40/54] writecache: check memory usage
warn if writecache neds > 50% of system memory, and
confirm if writecache needs > 90% of system memory.
---
tools/lvconvert.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 34b82ea02..a90946173 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -6072,6 +6072,69 @@ bad:
return 0;
}
+static int _check_writecache_memory(struct cmd_context *cmd, struct logical_volume *lv_fast,
+ uint32_t block_size_sectors)
+{
+ char line[128];
+ FILE *fp;
+ uint64_t cachevol_size_bytes = lv_fast->size * SECTOR_SIZE;
+ uint64_t need_mem_bytes = 0;
+ uint64_t proc_mem_bytes = 0;
+ uint64_t need_mem_gb;
+ uint64_t proc_mem_gb;
+ unsigned long long proc_mem_kb = 0;
+
+ if (!(fp = fopen("/proc/meminfo", "r")))
+ goto skip_proc;
+
+ while (fgets(line, sizeof(line), fp)) {
+ if (strncmp(line, "MemTotal:", 9))
+ continue;
+ if (sscanf(line, "%*s%llu%*s", &proc_mem_kb) != 1)
+ break;
+ break;
+ }
+ (void)fclose(fp);
+
+ proc_mem_bytes = proc_mem_kb * 1024;
+
+ skip_proc:
+ /* dm-writecache memory consumption per block is 88 bytes */
+ if (block_size_sectors == 8) {
+ need_mem_bytes = cachevol_size_bytes * 88 / 4096;
+ } else if (block_size_sectors == 1) {
+ need_mem_bytes = cachevol_size_bytes * 88 / 512;
+ } else {
+ /* shouldn't happen */
+ log_warn("Unknown memory usage for unknown writecache block_size_sectors %u", block_size_sectors);
+ return 1;
+ }
+
+ need_mem_gb = need_mem_bytes / 1073741824;
+ proc_mem_gb = proc_mem_bytes / 1073741824;
+
+ /*
+ * warn if writecache needs > 50% of main memory, and
+ * confirm if writecache needs > 90% of main memory.
+ */
+ if (need_mem_bytes >= (proc_mem_bytes / 2)) {
+ log_warn("WARNING: writecache size %s will use %llu GiB of system memory (%llu GiB).",
+ display_size(cmd, lv_fast->size),
+ (unsigned long long)need_mem_gb,
+ (unsigned long long)proc_mem_gb);
+
+ if (need_mem_gb >= (proc_mem_gb * 9 / 10)) {
+ if (!arg_is_set(cmd, yes_ARG) &&
+ yes_no_prompt("Continue adding writecache? [y/n]: ") == 'n') {
+ log_error("Conversion aborted.");
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
int lvconvert_writecache_attach_single(struct cmd_context *cmd,
struct logical_volume *lv,
struct processing_handle *handle)
@@ -6160,6 +6223,12 @@ int lvconvert_writecache_attach_single(struct cmd_context *cmd,
goto_bad;
}
+ if (!_check_writecache_memory(cmd, lv_fast, block_size_sectors)) {
+ if (!is_active && !deactivate_lv(cmd, lv))
+ stack;
+ goto_bad;
+ }
+
if (!is_active) {
if (!deactivate_lv(cmd, lv)) {
log_error("Failed to deactivate LV after checking block size %s", display_lvname(lv));
--
2.34.3

View File

@ -0,0 +1,108 @@
From 090dc0c320f0abee8ab79f4eaea6561c195b5009 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 31 Mar 2022 11:38:08 -0500
Subject: [PATCH 41/54] change messages about filtered devices
Change messages that refer to devices being "excluded by filters"
to say just "excluded". This will avoid mistaking the word
"filters" with the lvm.conf filter setting.
---
lib/device/device_id.c | 6 +++---
tools/lvmdevices.c | 4 ++--
tools/pvscan.c | 4 ++--
tools/vgimportclone.c | 4 ++--
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 82db6e4a5..6133e700a 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1744,7 +1744,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
* probably wants to do something about it.
*/
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
- log_warn("Devices file %s is excluded by filter: %s.",
+ log_warn("Devices file %s is excluded: %s.",
dev_name(dev), dev_filtered_reason(dev));
continue;
}
@@ -1830,7 +1830,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
continue;
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
- log_warn("Devices file %s is excluded by filter: %s.",
+ log_warn("Devices file %s is excluded: %s.",
dev_name(dev), dev_filtered_reason(dev));
/* FIXME: what if this dev is wrongly matched and should be checked below? */
continue;
@@ -2266,7 +2266,7 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) {
/* I don't think this would happen */
- log_warn("WARNING: new device %s for PVID %s does not pass filter %s.",
+ log_warn("WARNING: new device %s for PVID %s is excluded: %s.",
dev_name(dev), dil->pvid, dev_filtered_reason(dev));
if (du) /* Should not happen 'du' is NULL */
du->dev = NULL;
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
index 662b35f9a..8521b89ea 100644
--- a/tools/lvmdevices.c
+++ b/tools/lvmdevices.c
@@ -112,7 +112,7 @@ static void _search_devs_for_pvids(struct cmd_context *cmd, struct dm_list *sear
dev = devl->dev;
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) {
- log_warn("WARNING: PVID %s found on %s which is excluded by filter: %s",
+ log_warn("WARNING: PVID %s found on %s which is excluded: %s",
dev->pvid, dev_name(dev), dev_filtered_reason(dev));
dm_list_del(&devl->list);
}
@@ -310,7 +310,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
cmd->filter_deviceid_skip = 1;
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) {
- log_warn("WARNING: adding device %s that is excluded by filter: %s.",
+ log_warn("WARNING: adding device %s that is excluded: %s.",
dev_name(dev), dev_filtered_reason(dev));
}
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 160a2c9a0..50d46051a 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -1756,7 +1756,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
dm_list_iterate_items_safe(devl, devl2, &pvscan_devs) {
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
- log_print_pvscan(cmd, "%s excluded by filters: %s.",
+ log_print_pvscan(cmd, "%s excluded: %s.",
dev_name(devl->dev), dev_filtered_reason(devl->dev));
dm_list_del(&devl->list);
}
@@ -1813,7 +1813,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
/* Applies all filters, including those that need data from dev. */
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
- log_print_pvscan(cmd, "%s excluded by filters: %s.",
+ log_print_pvscan(cmd, "%s excluded: %s.",
dev_name(devl->dev), dev_filtered_reason(devl->dev));
dm_list_del(&devl->list);
}
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index 23bb6271f..cab501619 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -311,8 +311,8 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
*/
dm_list_iterate_items(devl, &vp.new_devs) {
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, "persistent")) {
- /* FIXME: print which filter */
- log_error("Device %s was excluded by filters.", dev_name(devl->dev));
+ log_error("Device %s is excluded: %s.",
+ dev_name(devl->dev), dev_filtered_reason(devl->dev));
goto out;
}
}
--
2.34.3

View File

@ -0,0 +1,31 @@
From 4aa92f3e18cb49470ee9b5d928abe6b4c86f3074 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 6 Apr 2022 12:20:26 -0500
Subject: [PATCH 42/54] vgimportdevices: fix incorrect deviceidtype usage
When a VG has PVs with different device id types,
it would try to use the idtype of the previous PV
in the loop. This would produce an unncessary warning,
or could lead to using the devname idtype when a better
idtype is available.
---
tools/vgimportdevices.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
index 2580613c4..ea205d941 100644
--- a/tools/vgimportdevices.c
+++ b/tools/vgimportdevices.c
@@ -57,8 +57,7 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
dm_list_iterate_items(pvl, &vg->pvs) {
pv = pvl->pv;
- if (!idtypestr && pv->device_id_type)
- idtypestr = pv->device_id_type;
+ idtypestr = pv->device_id_type;
memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
device_id_add(cmd, pv->dev, pvid, idtypestr, NULL);
--
2.34.3

View File

@ -0,0 +1,32 @@
From 6de2a6a378a7673168fad34aebe8ddcb564a5911 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 8 Apr 2022 11:28:53 -0500
Subject: [PATCH 43/54] lvmlockd: return error from vgcreate init_vg_sanlock
in vgcreate for shared sanlock vg, if sanlock_write_resource
returns an unexpected error, then make init_vg_sanlock fail
which will cause the vgcreate to fail.
---
daemons/lvmlockd/lvmlockd-sanlock.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
index e595eeffd..d87d1093b 100644
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
@@ -684,10 +684,10 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
break;
}
- if (rv) {
+ if (rv < 0) {
log_error("clear lv resource area %llu error %d",
(unsigned long long)offset, rv);
- break;
+ return rv;
}
offset += align_size;
}
--
2.34.3

View File

@ -0,0 +1,45 @@
From d96432835532fbcd8c72694c6ed68fca3ce98d5c Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 13 Apr 2022 12:16:57 -0500
Subject: [PATCH 44/54] devices file: remove extraneous unlock in vgchange -u
vgchange -u exit path was unlocking the devices file in cases
when it wasn't needed, which produced an warning.
---
lib/device/device_id.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 6133e700a..20901ab90 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1272,15 +1272,15 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
int update = 0;
if (!cmd->enable_devices_file)
- goto out;
+ return;
/* Without this setting there is no stacking LVs on PVs. */
if (!cmd->scan_lvs)
- goto out;
+ return;
/* Check if any devices file entries are stacked on LVs. */
if (!_device_ids_use_lvmlv(cmd))
- goto out;
+ return;
memcpy(old_vgid, old_vg_id, ID_LEN);
memcpy(new_vgid, &vg->id, ID_LEN);
@@ -1310,7 +1310,6 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
if (update &&
!device_ids_write(cmd))
stack;
- out:
unlock_devices_file(cmd);
}
--
2.34.3

View File

@ -0,0 +1,458 @@
From 5d40b91bd4aa8580ee1f40d467b848f7847f39e3 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 21 Apr 2022 13:45:01 -0500
Subject: [PATCH 45/54] filter-mpath: use multipath blacklist
Explicit wwid's from these sections control whether the
same wwid in /etc/multipath/wwids is recognized as a
multipath component. Other non-wwid keywords are not
used, and may require disabling the use of the multipath
wwids file in lvm.conf.
---
lib/device/dev-mpath.c | 181 ++++++++++++++++++++++++--
test/shell/duplicate-pvs-multipath.sh | 2 +-
test/shell/multipath-config.sh | 171 ++++++++++++++++++++++++
3 files changed, 342 insertions(+), 12 deletions(-)
create mode 100644 test/shell/multipath-config.sh
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
index cbbad9dc9..6eed03c5b 100644
--- a/lib/device/dev-mpath.c
+++ b/lib/device/dev-mpath.c
@@ -17,12 +17,14 @@
#include "lib/activate/activate.h"
#include "lib/commands/toolcontext.h"
#include "lib/device/device_id.h"
+#include "lib/datastruct/str_list.h"
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#include "lib/device/dev-ext-udev-constants.h"
#endif
#include <dirent.h>
+#include <ctype.h>
#define MPATH_PREFIX "mpath-"
@@ -35,15 +37,167 @@
* If dm-3 is not an mpath device, then the constant "1" is stored in
* the hash table with the key of the dm minor number.
*/
-static struct dm_pool *_hash_mem;
+static struct dm_pool *_wwid_mem;
static struct dm_hash_table *_minor_hash_tab;
static struct dm_hash_table *_wwid_hash_tab;
+static struct dm_list _ignored;
+static struct dm_list _ignored_exceptions;
#define MAX_WWID_LINE 512
-/*
- * do we need to check the multipath.conf blacklist?
- */
+static void _read_blacklist_file(const char *path)
+{
+ FILE *fp;
+ char line[MAX_WWID_LINE];
+ char wwid[MAX_WWID_LINE];
+ char *word, *p;
+ int section_black = 0;
+ int section_exceptions = 0;
+ int found_quote;
+ int found_three;
+ int i, j;
+
+ if (!(fp = fopen(path, "r")))
+ return;
+
+ while (fgets(line, sizeof(line), fp)) {
+ word = NULL;
+
+ /* skip initial white space on the line */
+ for (i = 0; i < MAX_WWID_LINE; i++) {
+ if ((line[i] == '\n') || (line[i] == '\0'))
+ break;
+ if (isspace(line[i]))
+ continue;
+ word = &line[i];
+ break;
+ }
+
+ if (!word || word[0] == '#')
+ continue;
+
+ /* identify the start of the section we want to read */
+ if (strchr(word, '{')) {
+ if (!strncmp(word, "blacklist_exceptions", 20))
+ section_exceptions = 1;
+ else if (!strncmp(word, "blacklist", 9))
+ section_black = 1;
+ continue;
+ }
+ /* identify the end of the section we've been reading */
+ if (strchr(word, '}')) {
+ section_exceptions = 0;
+ section_black = 0;
+ continue;
+ }
+ /* skip lines that are not in a section we want */
+ if (!section_black && !section_exceptions)
+ continue;
+
+ /*
+ * read a wwid from the blacklist{_exceptions} section.
+ * does not recognize other non-wwid entries in the
+ * section, and skips those (should the entire mp
+ * config filtering be disabled if non-wwids are seen?
+ */
+ if (!(p = strstr(word, "wwid")))
+ continue;
+
+ i += 4; /* skip "wwid" */
+
+ /*
+ * copy wwid value from the line.
+ * the wwids copied here need to match the
+ * wwids read from /etc/multipath/wwids,
+ * which are matched to wwids from sysfs.
+ */
+
+ memset(wwid, 0, sizeof(wwid));
+ found_quote = 0;
+ found_three = 0;
+ j = 0;
+
+ for (; i < MAX_WWID_LINE; i++) {
+ if ((line[i] == '\n') || (line[i] == '\0'))
+ break;
+ if (!j && isspace(line[i]))
+ continue;
+ if (isspace(line[i]))
+ break;
+ /* quotes around wwid are optional */
+ if ((line[i] == '"') && !found_quote) {
+ found_quote = 1;
+ continue;
+ }
+ /* second quote is end of wwid */
+ if ((line[i] == '"') && found_quote)
+ break;
+ /* ignore first "3" in wwid */
+ if ((line[i] == '3') && !found_three) {
+ found_three = 1;
+ continue;
+ }
+
+ wwid[j] = line[i];
+ j++;
+ }
+
+ if (j < 8)
+ continue;
+
+ log_debug("multipath wwid %s in %s %s",
+ wwid, section_exceptions ? "blacklist_exceptions" : "blacklist", path);
+
+ if (section_exceptions) {
+ if (!str_list_add(_wwid_mem, &_ignored_exceptions, dm_pool_strdup(_wwid_mem, wwid)))
+ stack;
+ } else {
+ if (!str_list_add(_wwid_mem, &_ignored, dm_pool_strdup(_wwid_mem, wwid)))
+ stack;
+ }
+ }
+
+ if (fclose(fp))
+ stack;
+}
+
+static void _read_wwid_exclusions(void)
+{
+ char path[PATH_MAX] = { 0 };
+ DIR *dir;
+ struct dirent *de;
+ struct dm_str_list *sl, *sl2;
+ int rem_count = 0;
+
+ _read_blacklist_file("/etc/multipath.conf");
+
+ if ((dir = opendir("/etc/multipath/conf.d"))) {
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.')
+ continue;
+ snprintf(path, PATH_MAX-1, "/etc/multipath/conf.d/%s", de->d_name);
+ _read_blacklist_file(path);
+ }
+ closedir(dir);
+ }
+
+ /* for each wwid in ignored_exceptions, remove it from ignored */
+
+ dm_list_iterate_items_safe(sl, sl2, &_ignored) {
+ if (str_list_match_item(&_ignored_exceptions, sl->str))
+ str_list_del(&_ignored, sl->str);
+ }
+
+ /* for each wwid in ignored, remove it from wwid_hash */
+
+ dm_list_iterate_items(sl, &_ignored) {
+ dm_hash_remove_binary(_wwid_hash_tab, sl->str, strlen(sl->str));
+ rem_count++;
+ }
+
+ if (rem_count)
+ log_debug("multipath config ignored %d wwids", rem_count);
+}
static void _read_wwid_file(const char *config_wwids_file)
{
@@ -93,6 +247,9 @@ int dev_mpath_init(const char *config_wwids_file)
struct dm_hash_table *minor_tab;
struct dm_hash_table *wwid_tab;
+ dm_list_init(&_ignored);
+ dm_list_init(&_ignored_exceptions);
+
if (!(mem = dm_pool_create("mpath", 256))) {
log_error("mpath pool creation failed.");
return 0;
@@ -104,7 +261,7 @@ int dev_mpath_init(const char *config_wwids_file)
return 0;
}
- _hash_mem = mem;
+ _wwid_mem = mem;
_minor_hash_tab = minor_tab;
/* multipath_wwids_file="" disables the use of the file */
@@ -116,16 +273,18 @@ int dev_mpath_init(const char *config_wwids_file)
if (!(wwid_tab = dm_hash_create(110))) {
log_error("mpath hash table creation failed.");
dm_hash_destroy(_minor_hash_tab);
- dm_pool_destroy(_hash_mem);
+ dm_pool_destroy(_wwid_mem);
_minor_hash_tab = NULL;
- _hash_mem = NULL;
+ _wwid_mem = NULL;
return 0;
}
_wwid_hash_tab = wwid_tab;
- if (config_wwids_file)
+ if (config_wwids_file) {
_read_wwid_file(config_wwids_file);
+ _read_wwid_exclusions();
+ }
return 1;
}
@@ -136,12 +295,12 @@ void dev_mpath_exit(void)
dm_hash_destroy(_minor_hash_tab);
if (_wwid_hash_tab)
dm_hash_destroy(_wwid_hash_tab);
- if (_hash_mem)
- dm_pool_destroy(_hash_mem);
+ if (_wwid_mem)
+ dm_pool_destroy(_wwid_mem);
_minor_hash_tab = NULL;
_wwid_hash_tab = NULL;
- _hash_mem = NULL;
+ _wwid_mem = NULL;
}
diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh
index a145e4afb..59c15b0d4 100644
--- a/test/shell/duplicate-pvs-multipath.sh
+++ b/test/shell/duplicate-pvs-multipath.sh
@@ -10,7 +10,7 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-test_description='udev rule and systemd unit run vgchange'
+test_description='duplicate pv detection of mpath components using wwid'
SKIP_WITH_LVMPOLLD=1
SKIP_WITH_LVMLOCKD=1
diff --git a/test/shell/multipath-config.sh b/test/shell/multipath-config.sh
new file mode 100644
index 000000000..ffb7d632a
--- /dev/null
+++ b/test/shell/multipath-config.sh
@@ -0,0 +1,171 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU 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
+
+test_description='using multipath blacklist'
+
+SKIP_WITH_LVMPOLLD=1
+SKIP_WITH_LVMLOCKD=1
+
+. lib/inittest
+
+# FIXME: don't run this test by default because it destroys the
+# local multipath config, the timing of multipath/dm/lvm interactions
+# is fragile, and there's insufficient cleanup after a test fails.
+skip
+
+systemctl stop multipathd
+multipath -F || true
+rm /etc/multipath/wwids || true
+rmmod scsi_debug || true
+rm /etc/multipath/conf.d/lvmtest.conf || true
+
+modprobe --dry-run scsi_debug || skip
+multipath -l || skip
+multipath -l | grep scsi_debug && skip
+ls /etc/multipath/wwids && skip
+
+# Need to use /dev/mapper/mpath
+aux lvmconf 'devices/dir = "/dev"'
+aux lvmconf 'devices/scan = "/dev"'
+# Could set filter to $MP and the component /dev/sd devs
+aux lvmconf "devices/filter = [ \"a|.*|\" ]"
+aux lvmconf "devices/global_filter = [ \"a|.*|\" ]"
+
+modprobe scsi_debug dev_size_mb=16 num_tgts=1
+sleep 2
+
+# Get scsi device name created by scsi_debug.
+# SD = sdh
+# SD_DEV = /dev/sdh
+
+SD=$(grep -H scsi_debug /sys/block/sd*/device/model | cut -f4 -d /);
+echo $SD
+SD_DEV=/dev/$SD
+echo $SD_DEV
+
+# if multipath claimed SD, then io will fail
+#dd if=$SD_DEV of=/dev/null bs=4k count=1 iflag=direct
+#dd if=/dev/zero of=$SD_DEV bs=4k count=1 oflag=direct
+
+# check if multipathd claimed the scsi dev when it appears and create mp dm device
+sleep 2
+multipath -l
+# create the mp dm device
+multipath $SD_DEV
+
+# Get mpath device name created by multipath.
+# MP = mpatha
+# MP_DEV = /dev/maper/mpatha
+
+MP=$(multipath -l | grep scsi_debug | cut -f1 -d ' ')
+echo $MP
+MP_DEV=/dev/mapper/$MP
+echo $MP_DEV
+
+dd if=$MP_DEV of=/dev/null bs=4k count=1 iflag=direct
+dd if=/dev/zero of=$MP_DEV bs=4k count=1 oflag=direct
+
+# Get wwid for the mp and sd dev.
+WWID=$(multipath -l $MP_DEV | head -1 | awk '{print $2}' | tr -d ')' | tr -d '(')
+echo $WWID
+
+grep $WWID /etc/multipath/wwids
+
+pvcreate $MP_DEV
+vgcreate $vg1 $MP_DEV
+
+not pvs $SD_DEV
+pvs $MP_DEV
+
+# remove mpath dm device then check that SD_DEV is
+# filtered based on /etc/multipath/wwids instead of
+# based on sysfs holder
+multipath -f $MP
+sleep 2
+not pvs $SD_DEV
+multipath $SD_DEV
+sleep 2
+multipath -l | grep $SD
+
+#
+# Add the wwid to the blacklist, then restart multipath
+# so the sd dev should no longer be used by multipath,
+# but the sd dev wwid is still in /etc/multipath/wwids.
+#
+
+mkdir /etc/multipath/conf.d/ || true
+rm -f /etc/multipath/conf.d/lvmtest.conf
+
+cat <<EOF > "/etc/multipath/conf.d/lvmtest.conf"
+blacklist {
+ wwid $WWID
+}
+EOF
+
+cat /etc/multipath/conf.d/lvmtest.conf
+
+multipath -r
+sleep 2
+
+grep $WWID /etc/multipath/wwids
+
+multipath -l |tee out
+not grep $SD out
+not grep $MP out
+not grep $WWID out
+
+not pvs $MP_DEV
+pvs $SD_DEV
+vgs $vg1
+
+#
+# Add the wwid to the blacklist_exceptions, in addition
+# to the blacklist, then restart multipath so the
+# sd dev should again be used by multipath.
+#
+
+rm -f /etc/multipath/conf.d/lvmtest.conf
+
+cat <<EOF > "/etc/multipath/conf.d/lvmtest.conf"
+blacklist {
+wwid $WWID
+}
+blacklist_exceptions {
+wwid $WWID
+}
+EOF
+
+cat /etc/multipath/conf.d/lvmtest.conf
+
+multipath -r
+sleep 2
+
+grep $WWID /etc/multipath/wwids
+
+multipath -l |tee out
+grep $SD out
+grep $MP out
+grep $WWID out
+
+pvs $MP_DEV
+not pvs $SD_DEV
+vgs $vg1
+lvs $vg1
+
+sleep 2
+vgremove -ff $vg1
+sleep 2
+multipath -f $MP
+rm /etc/multipath/conf.d/lvmtest.conf
+rm /etc/multipath/wwids
+sleep 1
+rmmod scsi_debug
--
2.34.3

View File

@ -0,0 +1,28 @@
From e027f4da9bc7b4ed9b225af75089e3443595bf81 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 2 May 2022 09:46:28 -0500
Subject: [PATCH 46/54] improve description of devices option
---
tools/args.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/args.h b/tools/args.h
index 9a7bf81b2..00a2ec817 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -235,8 +235,9 @@ arg(deviceidtype_ARG, '\0', "deviceidtype", string_VAL, 0, 0,
"then it will override the default type that lvm would use.\n")
arg(devices_ARG, '\0', "devices", pv_VAL, ARG_GROUPABLE, 0,
- "Devices that the command can use. This option can be repeated\n"
- "or accepts a comma separated list of devices. This overrides\n"
+ "Restricts the devices that are visible and accessible to the command.\n"
+ "Devices not listed will appear to be missing. This option can be\n"
+ "repeated, or accepts a comma separated list of devices. This overrides\n"
"the devices file.\n")
arg(devicesfile_ARG, '\0', "devicesfile", string_VAL, 0, 0,
--
2.34.3

View File

@ -0,0 +1,576 @@
From 9c6954bc61b22ca03df8897d88eb9618e65fc3c6 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Wed, 13 Apr 2022 15:09:08 +0200
Subject: [PATCH 47/54] vdo: support --vdosettings
Allow to use --vdosettings with lvcreate,lvconvert,lvchange.
Support settings currenly only configurable via lvm.conf.
With lvchange we require inactivate LV for changes to be applied.
Settings block_map_era_length has supported alias block_map_period.
---
device_mapper/vdo/target.h | 6 +-
man/lvmvdo.7_main | 39 ++++++--
test/shell/lvchange-vdo.sh | 8 ++
test/shell/lvconvert-vdo.sh | 8 +-
test/shell/lvcreate-vdo.sh | 6 +-
tools/args.h | 9 ++
tools/command-lines.in | 6 +-
tools/lvchange.c | 43 ++++++++-
tools/lvconvert.c | 9 +-
tools/lvcreate.c | 34 ++++---
tools/toollib.c | 177 ++++++++++++++++++++++++++++++++++++
tools/toollib.h | 6 ++
12 files changed, 312 insertions(+), 39 deletions(-)
diff --git a/device_mapper/vdo/target.h b/device_mapper/vdo/target.h
index 51dde3f4d..60c5bff56 100644
--- a/device_mapper/vdo/target.h
+++ b/device_mapper/vdo/target.h
@@ -77,8 +77,10 @@ enum dm_vdo_write_policy {
struct dm_vdo_target_params {
uint32_t minimum_io_size; // in sectors
uint32_t block_map_cache_size_mb;
- uint32_t block_map_era_length; // format period
-
+ union {
+ uint32_t block_map_era_length; // format period
+ uint32_t block_map_period; // supported alias
+ };
uint32_t check_point_frequency;
uint32_t index_memory_size_mb; // format
diff --git a/man/lvmvdo.7_main b/man/lvmvdo.7_main
index 3b77173c4..14bd640b5 100644
--- a/man/lvmvdo.7_main
+++ b/man/lvmvdo.7_main
@@ -132,6 +132,19 @@ that can keep 100% incompressible data there.
# lvconvert --type vdo-pool -n vdo0 -V10G vg/ExistingLV
.fi
.
+.SS \n+[step]. Change the compression and deduplication of a VDOPoolLV
+.
+Disable or enable the compression and deduplication for VDOPoolLV
+(the volume that maintains all VDO LV(s) associated with it).
+.P
+.B lvchange --compression y|n --deduplication y|n VG/VDOPoolLV
+.P
+.I Example
+.nf
+# lvchange --compression n vg/vdopool0
+# lvchange --deduplication y vg/vdopool1
+.fi
+.
.SS \n+[step]. Change the default settings used for creating a VDOPoolLV
.
VDO allows to set a large variety of options. Lots of these settings
@@ -173,17 +186,27 @@ EOF
# lvcreate --vdo -L10G --config 'allocation/vdo_cpu_threads=4' vg/vdopool1
.fi
.
-.SS \n+[step]. Change the compression and deduplication of a VDOPoolLV
-.
-Disable or enable the compression and deduplication for VDOPoolLV
-(the volume that maintains all VDO LV(s) associated with it).
-.P
-.B lvchange --compression y|n --deduplication y|n VG/VDOPoolLV
+.SS \n+[step]. Set or change VDO settings with option --vdosettings
+.
+Use the form 'option=value' or 'option1=value option2=value',
+or repeat --vdosettings for each option being set.
+Options are listed in the Example section above, for the full description see
+.BR lvm.conf (5).
+Options can omit 'vdo_' and 'vdo_use_' prefixes and all its underscores.
+So i.e. vdo_use_metadata_hints=1 and metadatahints=1 are equivalent.
+To change the option for an already existing VDOPoolLV use
+.BR lvchange (8)
+command. However not all option can be changed.
+Only compression and deduplication options can be also changed for an active VDO LV.
+Lowest priority options are specified with configuration file,
+then with --vdosettings and highest are expliction option --compression
+and --deduplication.
.P
.I Example
+.P
.nf
-# lvchange --compression n vg/vdopool0
-# lvchange --deduplication y vg/vdopool1
+# lvcreate --vdo -L10G --vdosettings 'ack_threads=1 hash_zone_threads=2' vg/vdopool0
+# lvchange --vdosettings 'bio_threads=2 deduplication=1' vg/vdopool0
.fi
.
.SS \n+[step]. Checking the usage of VDOPoolLV
diff --git a/test/shell/lvchange-vdo.sh b/test/shell/lvchange-vdo.sh
index 461b7821f..7cc44d6bc 100644
--- a/test/shell/lvchange-vdo.sh
+++ b/test/shell/lvchange-vdo.sh
@@ -48,9 +48,17 @@ check grep_dmsetup status $vg-vdopool-vpool " online online "
lvchange --compression n --deduplication n $vg/vdopool
check grep_dmsetup status $vg-vdopool-vpool " offline offline "
+# --vdosettings needs inactive LV
+not lvchange --vdosettings 'ack_threads=8' $vg/vdopool
lvchange -an $vg/$lv1
+# With inactive vdo-pool changes are applied
+# explicit option --compression has highest priority
+lvchange --vdosettings 'ack_threads=5 compression=0' --compression y $vg/vdopool
+check lv_field $vg/$lv1 vdo_ack_threads "5"
+check lv_field $vg/$lv1 vdo_compression "enabled"
+
# Test activation
lvchange -aly $vg/$lv1
check active $vg $lv1
diff --git a/test/shell/lvconvert-vdo.sh b/test/shell/lvconvert-vdo.sh
index 529f325bd..c42d8f25a 100644
--- a/test/shell/lvconvert-vdo.sh
+++ b/test/shell/lvconvert-vdo.sh
@@ -28,12 +28,12 @@ lvcreate -L5G -n $lv1 $vg
not lvconvert --type vdo-pool $vg/$lv1 |& tee out
grep "WARNING" out
-
-lvconvert -y --type vdo-pool $vg/$lv1
+# Check --vdosettings is also applied to converted vdo-pool
+lvconvert -y --type vdo-pool --vdosettings 'ack_threads=5' $vg/$lv1
+check lv_field $vg/$lv1 vdo_ack_threads "5"
lvremove -f $vg
-
-#
+#
lvcreate -L5G -n $lv1 $vg
lvconvert -y --vdopool $vg/$lv1
lvremove -f $vg
diff --git a/test/shell/lvcreate-vdo.sh b/test/shell/lvcreate-vdo.sh
index 44f8bf094..3e807ac94 100644
--- a/test/shell/lvcreate-vdo.sh
+++ b/test/shell/lvcreate-vdo.sh
@@ -79,8 +79,12 @@ not fsck -n "$DM_DEV_DIR/mapper/$vg-${lv2}"
lvremove -ff $vg
+# Unknown settings does not pass
+# TODO: try to catch this in parser and 'fail'
+not lvcreate --type vdo --vdosettings 'ack_Xthreads=4' -L10G -V1T -ky -n $lv1 $vg
-lvcreate --type vdo -L10G -V1T -ky -n $lv1 $vg
+lvcreate --type vdo --vdosettings 'ack_threads=4' -L10G -V1T -ky -n $lv1 $vg
+check lv_field $vg/$lv1 vdo_ack_threads "4"
lvs -a $vg
lvremove -ff $vg
diff --git a/tools/args.h b/tools/args.h
index 00a2ec817..bfd848ce9 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -900,6 +900,15 @@ arg(vdopool_ARG, '\0', "vdopool", lv_VAL, 0, 0,
"The name of a VDO pool LV.\n"
"See \\fBlvmvdo\\fP(7) for more information about VDO usage.\n")
+arg(vdosettings_ARG, '\0', "vdosettings", string_VAL, ARG_GROUPABLE, 0,
+ "Specifies tunable VDO options for VDO LVs.\n"
+ "Use the form 'option=value' or 'option1=value option2=value', or\n"
+ "repeat --vdosettings for each option being set.\n"
+ "These settings override the default VDO behaviors.\n"
+ "To remove vdosettings and revert to the default\n"
+ "VDO behaviors, use --vdosettings 'default'.\n"
+ "See \\fBlvmvdo\\fP(7) for more information.\n")
+
arg(version_ARG, '\0', "version", 0, 0, 0,
"Display version information.\n")
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 00ac08934..08302b34f 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -243,6 +243,7 @@ OO_LVCHANGE_META: --addtag Tag, --deltag Tag,
--setautoactivation Bool, --errorwhenfull Bool, --discards Discards, --zero Bool,
--cachemode CacheMode, --cachepolicy String, --cachesettings String,
--minrecoveryrate SizeKB, --maxrecoveryrate SizeKB,
+--vdosettings String,
--writebehind Number, --writemostly WriteMostlyPV, --persistent n
# It's unfortunate that activate needs to be optionally allowed here;
@@ -341,7 +342,8 @@ OO_LVCONVERT_CACHE: --cachemetadataformat CacheMetadataFormat,
--cachesettings String, --zero Bool
OO_LVCONVERT_VDO: --metadataprofile String, --readahead Readahead,
---compression Bool, --deduplication Bool, --zero Bool
+--compression Bool, --deduplication Bool, --vdosettings String,
+--zero Bool
OO_LVCONVERT: --alloc Alloc, --background, --force, --noudevsync
@@ -839,7 +841,7 @@ OO_LVCREATE_POOL: --poolmetadatasize SizeMB, --poolmetadataspare Bool, --chunksi
OO_LVCREATE_THINPOOL: --discards Discards, --errorwhenfull Bool
-OO_LVCREATE_VDO: --compression Bool, --deduplication Bool
+OO_LVCREATE_VDO: --compression Bool, --deduplication Bool, --vdosettings String
---
lvcreate --type error --size SizeMB VG
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 0525bc53c..dc51786d7 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -755,6 +755,43 @@ out:
return r;
}
+static int _lvchange_vdo(struct cmd_context *cmd,
+ struct logical_volume *lv,
+ uint32_t *mr)
+{
+ struct lv_segment *seg;
+ int updated = 0;
+
+ seg = first_seg(lv);
+
+ // With VDO LV given flip to VDO pool
+ if (seg_is_vdo(seg))
+ seg = first_seg(seg_lv(seg, 0));
+
+ if (!get_vdo_settings(cmd, &seg->vdo_params, &updated))
+ return_0;
+
+ if ((updated & VDO_CHANGE_OFFLINE) &&
+ lv_info(cmd, seg->lv, 1, NULL, 0, 0)) {
+ log_error("Cannot change VDO settings for active VDO pool %s.",
+ display_lvname(seg->lv));
+ // TODO maybe add --force support with prompt here
+ log_print_unless_silent("VDO pool %s with all its LVs needs to be deactivated.",
+ display_lvname(seg->lv));
+ return 0;
+ }
+
+ if (updated) {
+ if (!dm_vdo_validate_target_params(&seg->vdo_params, 0 /* vdo_size */))
+ return_0;
+
+ /* Request caller to commit and reload metadata */
+ *mr |= MR_RELOAD;
+ }
+
+ return 1;
+}
+
static int _lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv,
int arg, uint32_t *mr)
{
@@ -1154,6 +1191,7 @@ static int _option_requires_direct_commit(int opt_enum)
cachemode_ARG,
cachepolicy_ARG,
cachesettings_ARG,
+ vdosettings_ARG,
-1
};
@@ -1354,7 +1392,10 @@ static int _lvchange_properties_single(struct cmd_context *cmd,
docmds++;
doit += _lvchange_cache(cmd, lv, &mr);
break;
-
+ case vdosettings_ARG:
+ docmds++;
+ doit += _lvchange_vdo(cmd, lv, &mr);
+ break;
default:
log_error(INTERNAL_ERROR "Failed to check for option %s",
arg_long_option_name(i));
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index a90946173..3d4b24fe3 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -5456,13 +5456,8 @@ static int _lvconvert_to_vdopool_single(struct cmd_context *cmd,
if (!fill_vdo_target_params(cmd, &vdo_params, &vdo_pool_header_size, vg->profile))
goto_out;
- if (arg_is_set(cmd, compression_ARG))
- vdo_params.use_compression =
- arg_int_value(cmd, compression_ARG, 0);
-
- if (arg_is_set(cmd, deduplication_ARG))
- vdo_params.use_deduplication =
- arg_int_value(cmd, deduplication_ARG, 0);
+ if (!get_vdo_settings(cmd, &vdo_params, NULL))
+ return_0;
if (!activate_lv(cmd, lv)) {
log_error("Cannot activate %s.", display_lvname(lv));
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 79af42685..8de6f3408 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -698,6 +698,23 @@ static int _read_cache_params(struct cmd_context *cmd,
return 1;
}
+static int _read_vdo_params(struct cmd_context *cmd,
+ struct lvcreate_params *lp)
+{
+ if (!seg_is_vdo(lp))
+ return 1;
+
+ // prefiling settings here
+ if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
+ return_0;
+
+ // override with optional vdo settings
+ if (!get_vdo_settings(cmd, &lp->vdo_params, NULL))
+ return_0;
+
+ return 1;
+}
+
static int _read_activation_params(struct cmd_context *cmd,
struct volume_group *vg,
struct lvcreate_params *lp)
@@ -888,7 +905,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
#define VDO_POOL_ARGS \
vdopool_ARG,\
compression_ARG,\
- deduplication_ARG
+ deduplication_ARG,\
+ vdosettings_ARG
/* Cache and cache-pool segment type */
if (seg_is_cache(lp)) {
@@ -1098,19 +1116,6 @@ static int _lvcreate_params(struct cmd_context *cmd,
zero_ARG,
-1))
return_0;
-
- // FIXME: prefiling here - this is wrong place
- // but will work for this moment
- if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL))
- return_0;
-
- if (arg_is_set(cmd, compression_ARG))
- lp->vdo_params.use_compression =
- arg_int_value(cmd, compression_ARG, 0);
-
- if (arg_is_set(cmd, deduplication_ARG))
- lp->vdo_params.use_deduplication =
- arg_int_value(cmd, deduplication_ARG, 0);
}
/* Check options shared between more segment types */
@@ -1198,6 +1203,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
&lp->pool_metadata_size, &lp->pool_metadata_spare,
&lp->chunk_size, &lp->discards, &lp->zero_new_blocks)) ||
!_read_cache_params(cmd, lp) ||
+ !_read_vdo_params(cmd, lp) ||
!_read_mirror_and_raid_params(cmd, lp))
return_0;
diff --git a/tools/toollib.c b/tools/toollib.c
index 16be336d4..697baee82 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1192,6 +1192,183 @@ out:
return ok;
}
+/*
+ * Compare VDO option name, skip any '_' in name
+ * and also allow to use it without vdo_[use_] prefix
+ */
+static int _compare_vdo_option(const char *b1, const char *b2)
+{
+ if (strncasecmp(b1, "vdo", 3) == 0) // skip vdo prefix
+ b1 += 3;
+
+ if ((tolower(*b1) != tolower(*b2)) &&
+ (strncmp(b2, "use_", 4) == 0))
+ b2 += 4; // try again with skipped prefix 'use_'
+
+ while (*b1 && *b2) {
+ if (tolower(*b1) == tolower(*b2)) {
+ ++b1;
+ ++b2;
+ continue; // matching char
+ }
+
+ if (*b1 == '_')
+ ++b1; // skip to next char
+ else if (*b2 == '_')
+ ++b2; // skip to next char
+ else
+ break; // mismatch
+ }
+
+ return (*b1 || *b2) ? 0 : 1;
+}
+
+#define CHECK_AND_SET(var, onoff) \
+ option = #var;\
+ if (_compare_vdo_option(cn->key, option)) {\
+ if (is_lvchange || !cn->v || (cn->v->type != DM_CFG_INT))\
+ goto err;\
+ if (vtp->var != cn->v->v.i) {\
+ vtp->var = cn->v->v.i;\
+ u |= onoff;\
+ }\
+ continue;\
+ }
+
+#define DO_OFFLINE(var) \
+ CHECK_AND_SET(var, VDO_CHANGE_OFFLINE)
+
+#define DO_ONLINE(var) \
+ CHECK_AND_SET(var, VDO_CHANGE_ONLINE)
+
+int get_vdo_settings(struct cmd_context *cmd,
+ struct dm_vdo_target_params *vtp,
+ int *updated)
+{
+ const char *str, *option = NULL;
+ struct arg_value_group_list *group;
+ struct dm_config_tree *result = NULL, *prev = NULL, *current = NULL;
+ struct dm_config_node *cn;
+ int r = 0, u = 0, is_lvchange;
+ int use_compression = vtp->use_compression;
+ int use_deduplication = vtp->use_deduplication;
+ int checked_lvchange;
+
+ if (updated)
+ *updated = 0;
+
+ // Group all --vdosettings
+ dm_list_iterate_items(group, &cmd->arg_value_groups) {
+ if (!grouped_arg_is_set(group->arg_values, vdosettings_ARG))
+ continue;
+
+ if (!(current = dm_config_create()))
+ goto_out;
+ if (prev)
+ current->cascade = prev;
+ prev = current;
+
+ if (!(str = grouped_arg_str_value(group->arg_values,
+ vdosettings_ARG,
+ NULL)))
+ goto_out;
+
+ if (!dm_config_parse_without_dup_node_check(current, str, str + strlen(str)))
+ goto_out;
+ }
+
+ if (current) {
+ if (!(result = dm_config_flatten(current)))
+ goto_out;
+
+ checked_lvchange = !strcmp(cmd->name, "lvchange");
+
+ /* Use all acceptable VDO options */
+ for (cn = result->root; cn; cn = cn->sib) {
+ is_lvchange = 0;
+ DO_OFFLINE(ack_threads);
+ DO_OFFLINE(bio_rotation);
+ DO_OFFLINE(bio_threads);
+ DO_OFFLINE(block_map_cache_size_mb);
+ DO_OFFLINE(block_map_era_length);
+ DO_OFFLINE(block_map_period); // alias for block_map_era_length
+ DO_OFFLINE(cpu_threads);
+ DO_OFFLINE(hash_zone_threads);
+ DO_OFFLINE(logical_threads);
+ DO_OFFLINE(max_discard);
+ DO_OFFLINE(physical_threads);
+
+ // Support also these - even when we have regular opts for them
+ DO_ONLINE(use_compression);
+ DO_ONLINE(use_deduplication);
+
+ // Settings bellow cannot be changed with lvchange command
+ is_lvchange = checked_lvchange;
+
+ DO_OFFLINE(check_point_frequency);
+ DO_OFFLINE(index_memory_size_mb);
+ DO_OFFLINE(minimum_io_size);
+ DO_OFFLINE(slab_size_mb);
+ DO_OFFLINE(use_metadata_hints);
+ DO_OFFLINE(use_sparse_index);
+
+ option = "write_policy";
+ if (_compare_vdo_option(cn->key, option)) {
+ if (is_lvchange || !cn->v || (cn->v->type != DM_CFG_STRING))
+ goto err;
+ if (!set_vdo_write_policy(&vtp->write_policy, cn->v->v.str))
+ goto_out;
+ u |= VDO_CHANGE_OFFLINE;
+ continue;
+ }
+
+ log_error("Unknown VDO setting \"%s\".", cn->key);
+ goto out;
+ }
+ }
+
+ if (arg_is_set(cmd, compression_ARG)) {
+ vtp->use_compression = arg_int_value(cmd, compression_ARG, 0);
+ if (vtp->use_compression != use_compression)
+ u |= VDO_CHANGE_ONLINE;
+ }
+
+ if (arg_is_set(cmd, deduplication_ARG)) {
+ vtp->use_deduplication = arg_int_value(cmd, deduplication_ARG, 0);
+ if (vtp->use_deduplication != use_deduplication)
+ u |= VDO_CHANGE_ONLINE;
+ }
+
+ if (updated) {
+ // validation of updated VDO option
+ if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */)) {
+err:
+ if (is_lvchange)
+ log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.",
+ option);
+ else
+ log_error("Invalid argument for VDO setting \"vdo_%s\".",
+ option);
+ goto out;
+ }
+
+ *updated = u;
+ }
+
+ r = 1;
+out:
+ if (result)
+ dm_config_destroy(result);
+
+ while (prev) {
+ current = prev->cascade;
+ dm_config_destroy(prev);
+ prev = current;
+ }
+
+ return r;
+}
+
static int _get_one_writecache_setting(struct cmd_context *cmd, struct writecache_settings *settings,
char *key, char *val, uint32_t *block_size_sectors)
{
diff --git a/tools/toollib.h b/tools/toollib.h
index f3a60fbc4..2b38e4e4f 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -217,6 +217,12 @@ int get_cache_params(struct cmd_context *cmd,
const char **name,
struct dm_config_tree **settings);
+#define VDO_CHANGE_ONLINE 1
+#define VDO_CHANGE_OFFLINE 2
+int get_vdo_settings(struct cmd_context *cmd,
+ struct dm_vdo_target_params *vtp,
+ int *updated);
+
int get_writecache_settings(struct cmd_context *cmd, struct writecache_settings *settings,
uint32_t *block_size_sectors);
--
2.34.3

View File

@ -0,0 +1,45 @@
From 45a2ccfa3bdf4c5b3f8b9e0cc5330fca345b0d26 Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
Date: Thu, 5 May 2022 11:02:32 +0200
Subject: [PATCH 48/54] toollib: fix segfault when handling selection with
historical LVs
When processing historical LVs inside process_each_lv_in_vg for
selection, we need to use dummy "_historical_lv" for select_match_lv.
This is because a historical LV is not an actual LV, but only a tiny
representation with subset of original properties that we recorded
(name, uuid...).
To use the same processing functions we use for full-fledged non-historical
LVs, we need to use the prefilled "_historical_lv" structure which has all
the other missing properties hard-coded.
---
tools/toollib.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 697baee82..01ba03658 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3392,13 +3392,14 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
process_lv = 1;
}
- process_lv = process_lv && select_match_lv(cmd, handle, vg, lvl->lv) && _select_matches(handle);
+ _historical_lv.this_glv = glvl->glv;
+ _historical_lv.name = glvl->glv->historical->name;
+
+ process_lv = process_lv && select_match_lv(cmd, handle, vg, &_historical_lv) && _select_matches(handle);
if (!process_lv)
continue;
- _historical_lv.this_glv = glvl->glv;
- _historical_lv.name = glvl->glv->historical->name;
log_very_verbose("Processing historical LV %s in VG %s.", glvl->glv->historical->name, vg->name);
ret = process_single_lv(cmd, &_historical_lv, handle);
--
2.34.3

View File

@ -0,0 +1,39 @@
From eda98e4b9418568d6793d2c853aaa54db051cc9f Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 27 May 2022 12:38:43 -0500
Subject: [PATCH 49/54] devices file: move clean up after command is run
devices_file_exit wasn't being called between lvm_shell
commands, so the file lock wouldn't be released.
---
lib/commands/toolcontext.c | 1 -
tools/lvmcmdline.c | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index a0c78ddd6..7db5e11a1 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1912,7 +1912,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
- devices_file_exit(cmd);
if (!dev_cache_exit())
stack;
_destroy_dev_types(cmd);
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 1727ba089..eb63fd9b5 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -3306,6 +3306,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
hints_exit(cmd);
lvmcache_destroy(cmd, 1, 1);
label_scan_destroy(cmd);
+ devices_file_exit(cmd);
if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
dm_config_destroy(config_string_cft);
--
2.34.3

View File

@ -0,0 +1,53 @@
From bf0b3962088fb18f4a2aba00f38955e1fc6e31fe Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 27 May 2022 14:27:03 -0500
Subject: [PATCH 50/54] devices file: fail if --devicesfile filename doesn't
exist
A typo of the filename after --devicesfile should result in a
command error rather than the command falling back to using no
devices file at all. Exception is vgcreate|pvcreate which
create a new devices file if the file name doesn't exist.
---
lib/device/dev-cache.c | 9 +++++++++
test/shell/devicesfile-basic.sh | 4 ++++
2 files changed, 13 insertions(+)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index b0759b06c..0eb2568b5 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1882,6 +1882,15 @@ static int _setup_devices(struct cmd_context *cmd, int no_file_match)
file_exists = devices_file_exists(cmd);
+ /*
+ * Fail if user specifies a file name that doesn't exist and
+ * the command is not creating a new devices file.
+ */
+ if (!file_exists && !cmd->create_edit_devices_file && cmd->devicesfile && strlen(cmd->devicesfile)) {
+ log_error("Devices file not found: %s", cmd->devices_file_path);
+ return 0;
+ }
+
/*
* Removing the devices file is another way of disabling the use of
* a devices file, unless the command creates the devices file.
diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh
index 7ba9e2c7f..d1cfb6a35 100644
--- a/test/shell/devicesfile-basic.sh
+++ b/test/shell/devicesfile-basic.sh
@@ -104,6 +104,10 @@ not ls "$DFDIR/system.devices"
vgs --devicesfile test.devices $vg1
not vgs --devicesfile test.devices $vg2
+# misspelled override name fails
+not vgs --devicesfile doesnotexist $vg1
+not vgs --devicesfile doesnotexist $vg2
+
# devicesfile and devices cannot be used together
not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1
--
2.34.3

View File

@ -0,0 +1,52 @@
From 25abb5730f4d8f79df69f0817881ffb9eed195a9 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 6 Jun 2022 11:39:02 -0500
Subject: [PATCH 51/54] filter-mpath: handle other wwid types in blacklist
Fixes commit 494372b4eed0c8f6040e3357939eb7511ac25745
"filter-mpath: use multipath blacklist"
to handle wwids with initial type digits 1 and 2 used
for t10 and eui ids. Originally recognized type 3 naa.
---
lib/device/dev-mpath.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
index 6eed03c5b..7abbfb289 100644
--- a/lib/device/dev-mpath.c
+++ b/lib/device/dev-mpath.c
@@ -54,7 +54,7 @@ static void _read_blacklist_file(const char *path)
int section_black = 0;
int section_exceptions = 0;
int found_quote;
- int found_three;
+ int found_type;
int i, j;
if (!(fp = fopen(path, "r")))
@@ -114,7 +114,7 @@ static void _read_blacklist_file(const char *path)
memset(wwid, 0, sizeof(wwid));
found_quote = 0;
- found_three = 0;
+ found_type = 0;
j = 0;
for (; i < MAX_WWID_LINE; i++) {
@@ -132,9 +132,10 @@ static void _read_blacklist_file(const char *path)
/* second quote is end of wwid */
if ((line[i] == '"') && found_quote)
break;
- /* ignore first "3" in wwid */
- if ((line[i] == '3') && !found_three) {
- found_three = 1;
+ /* exclude initial 3/2/1 for naa/eui/t10 */
+ if (!j && !found_type &&
+ ((line[i] == '3') || (line[i] == '2') || (line[i] == '1'))) {
+ found_type = 1;
continue;
}
--
2.34.3

View File

@ -0,0 +1,56 @@
From 7cb63b05dad453d015bbe462b799fb031dd6952c Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Tue, 31 May 2022 22:48:38 +0200
Subject: [PATCH 52/54] vdo: fix conversion of vdo_slab_size_mb
When converting VDO volume, the parameter vdo_slabSize was
incorrectly copied as vdo_blockMapCacheSize, however this parameter
is then no longer used for any table line creation so the wrong
value was only stored in metadata.
Also use just single get_kb_size_with_unit_ and remove it's duplicate
functionality with get_mb_size_with_unit_.
Use $VERB for vdo remove call.
---
scripts/lvm_import_vdo.sh | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh
index 61a82e41e..beb55dbdb 100755
--- a/scripts/lvm_import_vdo.sh
+++ b/scripts/lvm_import_vdo.sh
@@ -125,15 +125,6 @@ get_kb_size_with_unit_() {
esac
}
-get_mb_size_with_unit_() {
- case "$1" in
- *[mM]) echo $(( ${1%[mM]} )) ;;
- *[gG]) echo $(( ${1%[gG]} * 1024 )) ;;
- *[tT]) echo $(( ${1%[tT]} * 1024 * 1024 )) ;;
- *[pP]) echo $(( ${1%[pP]} * 1024 * 1024 * 1024 )) ;;
- esac
-}
-
# Figure out largest possible extent size usable for VG
# $1 physical size
# $2 logical size
@@ -328,12 +319,12 @@ allocation {
vdo_use_deduplication = $(get_enabled_value_ "$vdo_deduplication")
vdo_use_metadata_hints=1
vdo_minimum_io_size = $vdo_logicalBlockSize
- vdo_block_map_cache_size_mb = $(get_mb_size_with_unit_ "$vdo_blockMapCacheSize")
+ vdo_block_map_cache_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 ))
vdo_block_map_period = $vdo_blockMapPeriod
vdo_check_point_frequency = $vdo_indexCfreq
vdo_use_sparse_index = $(get_enabled_value_ "$vdo_indexSparse")
vdo_index_memory_size_mb = $(awk "BEGIN {print $vdo_indexMemory * 1024}")
- vdo_slab_size_mb = $(get_mb_size_with_unit_ "$vdo_blockMapCacheSize")
+ vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 ))
vdo_ack_threads = $vdo_ackThreads
vdo_bio_threads = $vdo_bioThreads
vdo_bio_rotation = $vdo_bioRotationInterval
--
2.34.3

View File

@ -0,0 +1,741 @@
From e36b180a6983c4fa07d6714a0bf81e6935487359 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 6 Jun 2022 14:04:20 -0500
Subject: [PATCH 53/54] filter-mpath: get wwids from sysfs vpd_pg83
to compare with wwids in /etc/multipath/wwids when
excluding multipath components. The wwid printed
from the sysfs wwid file may not be the wwid used
in multipath wwids. Save the wwids found for each
device on dev->wwids to avoid repeating reading
and parsing the sysfs files.
---
lib/Makefile.in | 1 +
lib/device/dev-cache.c | 18 ++++
lib/device/dev-cache.h | 1 +
lib/device/dev-mpath.c | 232 ++++++++++++++++++++++++++++++++++-------
lib/device/device.h | 13 +++
lib/device/device_id.c | 31 +++++-
lib/device/device_id.h | 2 +
lib/device/parse_vpd.c | 199 +++++++++++++++++++++++++++++++++++
8 files changed, 454 insertions(+), 43 deletions(-)
create mode 100644 lib/device/parse_vpd.c
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 8b3eac60a..3077825d2 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -40,6 +40,7 @@ SOURCES =\
device/dev-luks.c \
device/dev-dasd.c \
device/dev-lvm1-pool.c \
+ device/parse_vpd.c \
display/display.c \
error/errseg.c \
unknown/unknown.c \
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 0eb2568b5..65e1cb138 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -80,6 +80,7 @@ static void _dev_init(struct device *dev)
dm_list_init(&dev->aliases);
dm_list_init(&dev->ids);
+ dm_list_init(&dev->wwids);
}
void dev_destroy_file(struct device *dev)
@@ -383,6 +384,22 @@ out:
return 1;
}
+int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen)
+{
+ int ret;
+ int fd;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return 0;
+ ret = read(fd, buf, buf_size);
+ close(fd);
+ if (ret <= 0)
+ return 0;
+ *retlen = ret;
+ return 1;
+}
+
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
{
FILE *fp;
@@ -1336,6 +1353,7 @@ int dev_cache_exit(void)
dm_hash_iterate(n, _cache.names) {
dev = (struct device *) dm_hash_get_data(_cache.names, n);
free_dids(&dev->ids);
+ free_wwids(&dev->wwids);
}
}
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 321a56d7b..c49e6265d 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -74,6 +74,7 @@ void dev_cache_failed_path(struct device *dev, const char *path);
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt);
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value);
+int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen);
int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor);
int setup_devices_file(struct cmd_context *cmd);
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
index 7abbfb289..3795c992d 100644
--- a/lib/device/dev-mpath.c
+++ b/lib/device/dev-mpath.c
@@ -200,11 +200,12 @@ static void _read_wwid_exclusions(void)
log_debug("multipath config ignored %d wwids", rem_count);
}
-static void _read_wwid_file(const char *config_wwids_file)
+static void _read_wwid_file(const char *config_wwids_file, int *entries)
{
FILE *fp;
char line[MAX_WWID_LINE];
char *wwid, *p;
+ char typestr[2] = { 0 };
int count = 0;
if (config_wwids_file[0] != '/') {
@@ -226,8 +227,17 @@ static void _read_wwid_file(const char *config_wwids_file)
if (line[0] == '/')
wwid++;
- /* skip the initial '3' */
- wwid++;
+
+ /*
+ * the initial character is the id type,
+ * 1 is t10, 2 is eui, 3 is naa, 8 is scsi name.
+ * wwids are stored in the hash table without the type charater.
+ * It seems that sometimes multipath does not include
+ * the type charater (seen with t10 scsi_debug devs).
+ */
+ typestr[0] = *wwid;
+ if (typestr[0] == '1' || typestr[0] == '2' || typestr[0] == '3')
+ wwid++;
if ((p = strchr(wwid, '/')))
*p = '\0';
@@ -240,6 +250,7 @@ static void _read_wwid_file(const char *config_wwids_file)
stack;
log_debug("multipath wwids read %d from %s", count, config_wwids_file);
+ *entries = count;
}
int dev_mpath_init(const char *config_wwids_file)
@@ -247,6 +258,7 @@ int dev_mpath_init(const char *config_wwids_file)
struct dm_pool *mem;
struct dm_hash_table *minor_tab;
struct dm_hash_table *wwid_tab;
+ int entries = 0;
dm_list_init(&_ignored);
dm_list_init(&_ignored_exceptions);
@@ -283,10 +295,16 @@ int dev_mpath_init(const char *config_wwids_file)
_wwid_hash_tab = wwid_tab;
if (config_wwids_file) {
- _read_wwid_file(config_wwids_file);
+ _read_wwid_file(config_wwids_file, &entries);
_read_wwid_exclusions();
}
+ if (!entries) {
+ /* reading dev wwids is skipped with null wwid_hash_tab */
+ dm_hash_destroy(_wwid_hash_tab);
+ _wwid_hash_tab = NULL;
+ }
+
return 1;
}
@@ -432,10 +450,10 @@ static int _dev_is_mpath_component_udev(struct device *dev)
}
#endif
-static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev)
+static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev,
+ int primary_result, dev_t primary_dev)
{
struct dev_types *dt = cmd->dev_types;
- const char *part_name;
const char *name; /* e.g. "sda" for "/dev/sda" */
char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */
char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */
@@ -449,25 +467,15 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
int dm_dev_major;
int dm_dev_minor;
struct stat info;
- dev_t primary_dev;
int is_mpath_component = 0;
- /* multipathing is only known to exist for SCSI or NVME devices */
- if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev))
- return 0;
-
- switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
+ switch (primary_result) {
case 2: /* The dev is partition. */
- part_name = dev_name(dev); /* name of original dev for log_debug msg */
/* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path))))
return_0;
-
- log_debug_devs("%s: Device is a partition, using primary "
- "device %s for mpath component detection",
- part_name, name);
break;
case 1: /* The dev is already a primary dev. Just continue with the dev. */
@@ -589,47 +597,189 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
return is_mpath_component;
}
-static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev)
+static int _read_sys_wwid(struct cmd_context *cmd, struct device *dev,
+ char *idbuf, int idbufsize)
{
- char sysbuf[PATH_MAX] = { 0 };
- char *wwid;
- long look;
+ char idtmp[DEV_WWID_SIZE];
- if (!_wwid_hash_tab)
+ if (!read_sys_block(cmd, dev, "device/wwid", idbuf, idbufsize)) {
+ /* the wwid file is not under device for nvme devs */
+ if (!read_sys_block(cmd, dev, "wwid", idbuf, idbufsize))
+ return 0;
+ }
+ if (!idbuf[0])
return 0;
- if (!read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf)))
+ /* in t10 id, replace series of spaces with one _ like multipath */
+ if (!strncmp(idbuf, "t10.", 4) && strchr(idbuf, ' ')) {
+ if (idbufsize < DEV_WWID_SIZE)
+ return 0;
+ memcpy(idtmp, idbuf, DEV_WWID_SIZE);
+ memset(idbuf, 0, idbufsize);
+ format_t10_id((const unsigned char *)idtmp, DEV_WWID_SIZE, (unsigned char *)idbuf, idbufsize);
+ }
+ return 1;
+}
+
+#define VPD_SIZE 4096
+
+static int _read_sys_vpd_wwids(struct cmd_context *cmd, struct device *dev,
+ struct dm_list *ids)
+{
+ unsigned char vpd_data[VPD_SIZE] = { 0 };
+ int vpd_datalen = 0;
+
+ if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen))
+ return 0;
+ if (!vpd_datalen)
return 0;
- if (!sysbuf[0])
+ /* adds dev_wwid entry to dev->wwids for each id in vpd data */
+ parse_vpd_ids(vpd_data, vpd_datalen, ids);
+ return 1;
+}
+
+void free_wwids(struct dm_list *ids)
+{
+ struct dev_wwid *dw, *safe;
+
+ dm_list_iterate_items_safe(dw, safe, ids) {
+ dm_list_del(&dw->list);
+ free(dw);
+ }
+}
+
+static int _wwid_type_num(char *id)
+{
+ if (!strncmp(id, "naa.", 4))
+ return 3;
+ else if (!strncmp(id, "eui.", 4))
+ return 2;
+ else if (!strncmp(id, "t10.", 4))
+ return 1;
+ else
+ return -1;
+}
+
+/*
+ * TODO: if each of the different wwid types (naa/eui/t10) were
+ * represented by different DEV_ID_TYPE_FOO values, and used
+ * as device_id types, then we could drop struct dev_wwid and
+ * drop dev->wwids, and just use dev->ids for each of the
+ * different wwids found in vpd_pg83. This would also require
+ * the ability to handle both the original method of replacing
+ * every space in the id string with _ and the new/multipath
+ * format_t10_id replacing series of spaces with one _.
+ */
+struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids)
+{
+ struct dev_wwid *dw;
+ int len;
+
+ if (!id_type) {
+ id_type = _wwid_type_num(id);
+ if (id_type == -1)
+ log_debug("unknown wwid type %s", id);
+ }
+
+ if (!(dw = zalloc(sizeof(struct dev_wwid))))
+ return NULL;
+ len = strlen(id);
+ if (len >= DEV_WWID_SIZE)
+ len = DEV_WWID_SIZE - 1;
+ memcpy(dw->id, id, len);
+ dw->type = id_type;
+ dm_list_add(ids, &dw->list);
+ return dw;
+}
+
+/*
+ * we save ids with format: naa.<value>, eui.<value>, t10.<value>.
+ * multipath wwids file uses format: 3<value>, 2<value>, 1<value>.
+ * The values are saved in wwid_hash_tab without the type prefix.
+ */
+
+static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev,
+ int primary_result, dev_t primary_dev)
+{
+ char idbuf[DEV_WWID_SIZE] = { 0 };
+ struct dev_wwid *dw;
+ char *wwid;
+
+ if (!_wwid_hash_tab)
return 0;
/*
- * sysfs prints wwid as <typestr>.<value>
- * multipath wwid uses '3'<value>
- * does "<typestr>." always correspond to "3"?
+ * Check the primary device, not the partition.
*/
- if (!(wwid = strchr(sysbuf, '.')))
- return 0;
+ if (primary_result == 2) {
+ if (!(dev = dev_cache_get_by_devt(cmd, primary_dev))) {
+ log_debug("dev_is_mpath_component %s no primary dev", dev_name(dev));
+ return 0;
+ }
+ }
- /* skip the type and dot, just as '3' was skipped from wwids entry */
- wwid++;
-
- look = (long) dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid));
+ /*
+ * This function may be called multiple times for the same device, in
+ * particular if partitioned for each partition.
+ */
+ if (!dm_list_empty(&dev->wwids))
+ goto lookup;
- if (look) {
- log_debug_devs("dev_is_mpath_component %s multipath wwid %s", dev_name(dev), wwid);
- return 1;
+ /*
+ * Get all the ids for the device from vpd_pg83 and check if any of
+ * those are in /etc/multipath/wwids. These ids should include the
+ * value printed from the sysfs wwid file.
+ */
+ _read_sys_vpd_wwids(cmd, dev, &dev->wwids);
+ if (!dm_list_empty(&dev->wwids))
+ goto lookup;
+
+ /*
+ * This will read the sysfs wwid file, nvme devices in particular have
+ * a wwid file but not a vpd_pg83 file.
+ */
+ if (_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf)))
+ add_wwid(idbuf, 0, &dev->wwids);
+
+ lookup:
+ dm_list_iterate_items(dw, &dev->wwids) {
+ if (dw->type == 1 || dw->type == 2 || dw->type == 3)
+ wwid = &dw->id[4];
+ else
+ wwid = dw->id;
+
+ if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) {
+ log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), dw->id);
+ return 1;
+ }
}
+
return 0;
}
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev)
{
- if (_dev_is_mpath_component_sysfs(cmd, dev) == 1)
+ struct dev_types *dt = cmd->dev_types;
+ int primary_result;
+ dev_t primary_dev;
+
+ /*
+ * multipath only uses SCSI or NVME devices
+ */
+ if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev))
+ return 0;
+
+ /*
+ * primary_result 2: dev is a partition, primary_dev is the whole device
+ * primary_result 1: dev is a whole device
+ */
+ primary_result = dev_get_primary_dev(dt, dev, &primary_dev);
+
+ if (_dev_is_mpath_component_sysfs(cmd, dev, primary_result, primary_dev) == 1)
goto found;
- if (_dev_in_wwid_file(cmd, dev))
+ if (_dev_in_wwid_file(cmd, dev, primary_result, primary_dev))
goto found;
if (external_device_info_source() == DEV_EXT_UDEV) {
@@ -637,6 +787,12 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev)
goto found;
}
+ /*
+ * TODO: save the result of this function in dev->flags and use those
+ * flags on repeated calls to avoid repeating the work multiple times
+ * for the same device when there are partitions on the device.
+ */
+
return 0;
found:
return 1;
diff --git a/lib/device/device.h b/lib/device/device.h
index 572994bb9..1c85f37a9 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -59,6 +59,14 @@ struct dev_ext {
void *handle;
};
+#define DEV_WWID_SIZE 128
+
+struct dev_wwid {
+ struct dm_list list;
+ int type;
+ char id[DEV_WWID_SIZE];
+};
+
#define DEV_ID_TYPE_SYS_WWID 0x0001
#define DEV_ID_TYPE_SYS_SERIAL 0x0002
#define DEV_ID_TYPE_MPATH_UUID 0x0003
@@ -105,6 +113,7 @@ struct dev_use {
*/
struct device {
struct dm_list aliases; /* struct dm_str_list */
+ struct dm_list wwids; /* struct dev_wwid, used for multipath component detection */
struct dm_list ids; /* struct dev_id, different entries for different idtypes */
struct dev_id *id; /* points to the the ids entry being used for this dev */
dev_t dev;
@@ -206,5 +215,9 @@ void dev_destroy_file(struct device *dev);
int dev_mpath_init(const char *config_wwids_file);
void dev_mpath_exit(void);
+struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids);
+void free_wwids(struct dm_list *ids);
+int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids);
+int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes);
#endif
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 20901ab90..4d8fa5c9c 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -182,7 +182,9 @@ void free_dids(struct dm_list *ids)
}
}
-int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize)
+static int _read_sys_block(struct cmd_context *cmd, struct device *dev,
+ const char *suffix, char *sysbuf, int sysbufsize,
+ int binary, int *retlen)
{
char path[PATH_MAX];
dev_t devt = dev->dev;
@@ -196,11 +198,17 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff
return 0;
}
- get_sysfs_value(path, sysbuf, sysbufsize, 0);
+ if (binary) {
+ ret = get_sysfs_binary(path, sysbuf, sysbufsize, retlen);
+ if (ret && !*retlen)
+ ret = 0;
+ } else {
+ ret = get_sysfs_value(path, sysbuf, sysbufsize, 0);
+ if (ret && !sysbuf[0])
+ ret = 0;
+ }
- if (sysbuf[0]) {
- if (prim)
- log_debug("Using primary device_id for partition %s.", dev_name(dev));
+ if (ret) {
sysbuf[sysbufsize - 1] = '\0';
return 1;
}
@@ -220,6 +228,19 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff
return 0;
}
+int read_sys_block(struct cmd_context *cmd, struct device *dev,
+ const char *suffix, char *sysbuf, int sysbufsize)
+{
+ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 0, NULL);
+}
+
+int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
+ const char *suffix, char *sysbuf, int sysbufsize,
+ int *retlen)
+{
+ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 1, retlen);
+}
+
static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix)
{
if (!strncmp(sysbuf, prefix, strlen(prefix)))
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
index 2cd2fd7c6..e049e2333 100644
--- a/lib/device/device_id.h
+++ b/lib/device/device_id.h
@@ -55,6 +55,8 @@ void devices_file_exit(struct cmd_context *cmd);
void unlink_searched_devnames(struct cmd_context *cmd);
int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize);
+int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
+ const char *suffix, char *sysbuf, int sysbufsize, int *retlen);
int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);
diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c
new file mode 100644
index 000000000..4bafa7b9e
--- /dev/null
+++ b/lib/device/parse_vpd.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2022 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "base/memory/zalloc.h"
+#include "lib/misc/lib.h"
+#include "lib/device/device.h"
+
+#include <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/ioctl.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>
+
+/*
+ * Replace series of spaces with a single _.
+ */
+int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
+{
+ int in_space = 0;
+ int retlen = 0;
+ int j = 0;
+ int i;
+
+ for (i = 0; i < in_bytes; i++) {
+ if (!in[i])
+ break;
+ if (j >= (out_bytes - 2))
+ break;
+ /* skip leading spaces */
+ if (!retlen && (in[i] == ' '))
+ continue;
+ /* replace one or more spaces with _ */
+ if (in[i] == ' ') {
+ in_space = 1;
+ continue;
+ }
+ /* spaces are finished so insert _ */
+ if (in_space) {
+ out[j++] = '_';
+ in_space = 0;
+ retlen++;
+ }
+ out[j++] = in[i];
+ retlen++;
+ }
+ return retlen;
+}
+
+static int _to_hex(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
+{
+ int off = 0;
+ int num;
+ int i;
+
+ for (i = 0; i < in_bytes; i++) {
+ num = sprintf((char *)out + off, "%02x", in[i]);
+ if (num < 0)
+ break;
+ off += num;
+ if (off + 2 >= out_bytes)
+ break;
+ }
+ return off;
+}
+
+#define ID_BUFSIZE 1024
+
+/*
+ * based on linux kernel function
+ */
+int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids)
+{
+ char id[ID_BUFSIZE];
+ unsigned char tmp_str[ID_BUFSIZE];
+ const unsigned char *d, *cur_id_str;
+ size_t id_len = ID_BUFSIZE;
+ int id_size = -1;
+ uint8_t cur_id_size = 0;
+
+ memset(id, 0, ID_BUFSIZE);
+ for (d = vpd_data + 4;
+ d < vpd_data + vpd_datalen;
+ d += d[3] + 4) {
+ memset(tmp_str, 0, sizeof(tmp_str));
+
+ switch (d[1] & 0xf) {
+ case 0x1:
+ /* T10 Vendor ID */
+ cur_id_size = d[3];
+ if (cur_id_size + 4 > id_len)
+ cur_id_size = id_len - 4;
+ cur_id_str = d + 4;
+ format_t10_id(cur_id_str, cur_id_size, tmp_str, sizeof(tmp_str));
+ id_size = snprintf(id, ID_BUFSIZE, "t10.%s", tmp_str);
+ if (id_size < 0)
+ break;
+ if (id_size >= ID_BUFSIZE)
+ id_size = ID_BUFSIZE - 1;
+ add_wwid(id, 1, ids);
+ break;
+ case 0x2:
+ /* EUI-64 */
+ cur_id_size = d[3];
+ cur_id_str = d + 4;
+ switch (cur_id_size) {
+ case 8:
+ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str));
+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
+ break;
+ case 12:
+ _to_hex(cur_id_str, 12, tmp_str, sizeof(tmp_str));
+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
+ break;
+ case 16:
+ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str));
+ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
+ break;
+ default:
+ break;
+ }
+ if (id_size < 0)
+ break;
+ if (id_size >= ID_BUFSIZE)
+ id_size = ID_BUFSIZE - 1;
+ add_wwid(id, 2, ids);
+ break;
+ case 0x3:
+ /* NAA */
+ cur_id_size = d[3];
+ cur_id_str = d + 4;
+ switch (cur_id_size) {
+ case 8:
+ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str));
+ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str);
+ break;
+ case 16:
+ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str));
+ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str);
+ break;
+ default:
+ break;
+ }
+ if (id_size < 0)
+ break;
+ if (id_size >= ID_BUFSIZE)
+ id_size = ID_BUFSIZE - 1;
+ add_wwid(id, 3, ids);
+ break;
+ case 0x8:
+ /* SCSI name string */
+ cur_id_size = d[3];
+ cur_id_str = d + 4;
+ if (cur_id_size >= id_len)
+ cur_id_size = id_len - 1;
+ memcpy(id, cur_id_str, cur_id_size);
+ id_size = cur_id_size;
+
+ /*
+ * Not in the kernel version, copying multipath code,
+ * which checks if this string begins with naa or eui
+ * and if so does tolower() on the chars.
+ */
+ if (!strncmp(id, "naa.", 4) || !strncmp(id, "eui.", 4)) {
+ int i;
+ for (i = 0; i < id_size; i++)
+ id[i] = tolower(id[i]);
+ }
+ add_wwid(id, 8, ids);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return id_size;
+}
--
2.34.3

View File

@ -0,0 +1,29 @@
From e60d7ce8e748cb6d51552879c162d01aafa17160 Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
Date: Wed, 15 Jun 2022 11:53:51 +0200
Subject: [PATCH 54/54] build: Fix make rpm with VERSION_DM without dash
When building RPM from a branch based on a release tag the expected -git
suffix is missing breaking the script producing error like following one:
error: line 215: Unterminated rich dependency: (2021-53.ge36b180a6.el9: Requires: device-mapper-devel >= 1.02.181 (2021-53.ge36b180a6.el9
---
Makefile.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.in b/Makefile.in
index 3b7e0ecaa..f7a46269a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -110,7 +110,7 @@ rpm: dist
$(LN_S) -f $(abs_top_srcdir)/spec/build.inc $(rpmbuilddir)/SOURCES
$(LN_S) -f $(abs_top_srcdir)/spec/macros.inc $(rpmbuilddir)/SOURCES
$(LN_S) -f $(abs_top_srcdir)/spec/packages.inc $(rpmbuilddir)/SOURCES
- DM_VER=$$(cut -d- -f1 $(top_srcdir)/VERSION_DM);\
+ DM_VER=$$(cut -d' ' -f1 $(top_srcdir)/VERSION_DM | cut -d- -f1);\
GIT_VER=$$(cd $(top_srcdir); git describe | cut -d- --output-delimiter=. -f2,3 || echo 0);\
$(SED) -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \
-e "s,^\(Version:[^0-9%]*\)[0-9.]*$$,\1 $(LVM_VER)," \
--
2.34.3

View File

@ -0,0 +1,921 @@
From 13b8c209f39ab018f34b3ccd369590a89fe71a57 Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
Date: Wed, 15 Jun 2022 19:58:18 +0200
Subject: [PATCH] make: generate
---
man/lvchange.8_pregen | 20 ++++++++++++++++++--
man/lvconvert.8_pregen | 22 ++++++++++++++++++++--
man/lvcreate.8_pregen | 24 ++++++++++++++++++++++--
man/lvdisplay.8_pregen | 5 +++--
man/lvextend.8_pregen | 5 +++--
man/lvm-fullreport.8_pregen | 5 +++--
man/lvm-lvpoll.8_pregen | 5 +++--
man/lvmconfig.8_pregen | 5 +++--
man/lvmdevices.8_pregen | 8 +++++---
man/lvmdiskscan.8_pregen | 5 +++--
man/lvreduce.8_pregen | 5 +++--
man/lvremove.8_pregen | 5 +++--
man/lvrename.8_pregen | 5 +++--
man/lvresize.8_pregen | 5 +++--
man/lvs.8_pregen | 5 +++--
man/lvscan.8_pregen | 5 +++--
man/pvchange.8_pregen | 5 +++--
man/pvck.8_pregen | 5 +++--
man/pvcreate.8_pregen | 5 +++--
man/pvdisplay.8_pregen | 5 +++--
man/pvmove.8_pregen | 5 +++--
man/pvremove.8_pregen | 5 +++--
man/pvresize.8_pregen | 5 +++--
man/pvs.8_pregen | 5 +++--
man/pvscan.8_pregen | 5 +++--
man/vgcfgbackup.8_pregen | 5 +++--
man/vgcfgrestore.8_pregen | 5 +++--
man/vgchange.8_pregen | 5 +++--
man/vgck.8_pregen | 5 +++--
man/vgconvert.8_pregen | 5 +++--
man/vgcreate.8_pregen | 5 +++--
man/vgdisplay.8_pregen | 5 +++--
man/vgexport.8_pregen | 5 +++--
man/vgextend.8_pregen | 5 +++--
man/vgimport.8_pregen | 5 +++--
man/vgimportclone.8_pregen | 5 +++--
man/vgimportdevices.8_pregen | 5 +++--
man/vgmerge.8_pregen | 5 +++--
man/vgmknodes.8_pregen | 5 +++--
man/vgreduce.8_pregen | 5 +++--
man/vgremove.8_pregen | 5 +++--
man/vgrename.8_pregen | 5 +++--
man/vgs.8_pregen | 5 +++--
man/vgscan.8_pregen | 5 +++--
man/vgsplit.8_pregen | 5 +++--
45 files changed, 188 insertions(+), 91 deletions(-)
diff --git a/man/lvchange.8_pregen b/man/lvchange.8_pregen
index b559c89c9..27bee0f14 100644
--- a/man/lvchange.8_pregen
+++ b/man/lvchange.8_pregen
@@ -126,6 +126,8 @@ lvchange \(em Change the attributes of logical volume(s)
\fB--sysinit\fP
.br
\fB-t\fP|\fB--test\fP
+.br
+ \fB--vdosettings\fP \fIString\fP
.br
\fB-v\fP|\fB--verbose\fP
.br
@@ -202,6 +204,8 @@ required, after which the others are optional.
\fB--\fP[\fBraid\fP]\fBminrecoveryrate\fP \fISize\fP[k|UNIT]
.br
\fB--\fP[\fBraid\fP]\fBmaxrecoveryrate\fP \fISize\fP[k|UNIT]
+.br
+ \fB--vdosettings\fP \fIString\fP
.br
\fB--\fP[\fBraid\fP]\fBwritebehind\fP \fINumber\fP
.br
@@ -609,8 +613,9 @@ See \fBlvm.conf\fP(5) for more information about profiles.
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -927,6 +932,17 @@ error messages in multi-stage operations if a tool relies on reading
back metadata it believes has changed but hasn't.
.
.HP
+\fB--vdosettings\fP \fIString\fP
+.br
+Specifies tunable VDO options for VDO LVs.
+Use the form 'option=value' or 'option1=value option2=value', or
+repeat --vdosettings for each option being set.
+These settings override the default VDO behaviors.
+To remove vdosettings and revert to the default
+VDO behaviors, use --vdosettings 'default'.
+See \fBlvmvdo\fP(7) for more information.
+.
+.HP
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail
diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen
index 679519303..fa52da55c 100644
--- a/man/lvconvert.8_pregen
+++ b/man/lvconvert.8_pregen
@@ -155,6 +155,8 @@ lvconvert \(em Change logical volume layout
\fB--usepolicies\fP
.br
\fB--vdopool\fP \fILV\fP
+.br
+ \fB--vdosettings\fP \fIString\fP
.br
\fB-v\fP|\fB--verbose\fP
.br
@@ -742,6 +744,8 @@ Convert LV to type vdopool.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
+[ \fB--vdosettings\fP \fIString\fP ]
+.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -1131,8 +1135,9 @@ See \fBlvmvdo\fP(7) for more information about VDO usage.
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -1535,6 +1540,17 @@ The name of a VDO pool LV.
See \fBlvmvdo\fP(7) for more information about VDO usage.
.
.HP
+\fB--vdosettings\fP \fIString\fP
+.br
+Specifies tunable VDO options for VDO LVs.
+Use the form 'option=value' or 'option1=value option2=value', or
+repeat --vdosettings for each option being set.
+These settings override the default VDO behaviors.
+To remove vdosettings and revert to the default
+VDO behaviors, use --vdosettings 'default'.
+See \fBlvmvdo\fP(7) for more information.
+.
+.HP
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail
@@ -1808,6 +1824,8 @@ Convert LV to type vdopool.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
+[ \fB--vdosettings\fP \fIString\fP ]
+.br
[ COMMON_OPTIONS ]
.ad b
.RE
diff --git a/man/lvcreate.8_pregen b/man/lvcreate.8_pregen
index 2cccbbe56..0ffe92a94 100644
--- a/man/lvcreate.8_pregen
+++ b/man/lvcreate.8_pregen
@@ -157,6 +157,8 @@ lvcreate \(em Create a logical volume
\fB--vdo\fP
.br
\fB--vdopool\fP \fILV\fP
+.br
+ \fB--vdosettings\fP \fIString\fP
.br
\fB-v\fP|\fB--verbose\fP
.br
@@ -537,6 +539,8 @@ Create a LV that returns VDO when used.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
+[ \fB--vdosettings\fP \fIString\fP ]
+.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -1003,8 +1007,9 @@ See \fBlvmvdo\fP(7) for more information about VDO usage.
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -1438,6 +1443,17 @@ The name of a VDO pool LV.
See \fBlvmvdo\fP(7) for more information about VDO usage.
.
.HP
+\fB--vdosettings\fP \fIString\fP
+.br
+Specifies tunable VDO options for VDO LVs.
+Use the form 'option=value' or 'option1=value option2=value', or
+repeat --vdosettings for each option being set.
+These settings override the default VDO behaviors.
+To remove vdosettings and revert to the default
+VDO behaviors, use --vdosettings 'default'.
+See \fBlvmvdo\fP(7) for more information.
+.
+.HP
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail
@@ -1966,6 +1982,8 @@ Create a VDO LV with VDO pool.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
+[ \fB--vdosettings\fP \fIString\fP ]
+.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -1996,6 +2014,8 @@ Create a VDO LV with VDO pool.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
+[ \fB--vdosettings\fP \fIString\fP ]
+.br
[ COMMON_OPTIONS ]
.ad b
.RE
diff --git a/man/lvdisplay.8_pregen b/man/lvdisplay.8_pregen
index 04aab4c09..387a7d30d 100644
--- a/man/lvdisplay.8_pregen
+++ b/man/lvdisplay.8_pregen
@@ -186,8 +186,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvextend.8_pregen b/man/lvextend.8_pregen
index be6992e94..8a3e1ea4e 100644
--- a/man/lvextend.8_pregen
+++ b/man/lvextend.8_pregen
@@ -328,8 +328,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvm-fullreport.8_pregen b/man/lvm-fullreport.8_pregen
index 02b38ef40..edae0efe3 100644
--- a/man/lvm-fullreport.8_pregen
+++ b/man/lvm-fullreport.8_pregen
@@ -169,8 +169,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvm-lvpoll.8_pregen b/man/lvm-lvpoll.8_pregen
index 7f45f6eb3..fa8027f8e 100644
--- a/man/lvm-lvpoll.8_pregen
+++ b/man/lvm-lvpoll.8_pregen
@@ -115,8 +115,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvmconfig.8_pregen b/man/lvmconfig.8_pregen
index 51946e1ec..e6762f989 100644
--- a/man/lvmconfig.8_pregen
+++ b/man/lvmconfig.8_pregen
@@ -156,8 +156,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvmdevices.8_pregen b/man/lvmdevices.8_pregen
index d64c3a31a..a2397e50f 100644
--- a/man/lvmdevices.8_pregen
+++ b/man/lvmdevices.8_pregen
@@ -322,7 +322,8 @@ Find a device with the PVID and add the device to the devices file.
.HP
\fB--check\fP
.br
-Check the content of the devices file.
+Checks the content of the devices file.
+Reports incorrect device names or PVIDs for entries.
.
.HP
\fB--commandprofile\fP \fIString\fP
@@ -364,8 +365,9 @@ then it will override the default type that lvm would use.
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvmdiskscan.8_pregen b/man/lvmdiskscan.8_pregen
index 7fd3d941d..ac0931c88 100644
--- a/man/lvmdiskscan.8_pregen
+++ b/man/lvmdiskscan.8_pregen
@@ -102,8 +102,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvreduce.8_pregen b/man/lvreduce.8_pregen
index ea960eb53..cd2e38e5b 100644
--- a/man/lvreduce.8_pregen
+++ b/man/lvreduce.8_pregen
@@ -130,8 +130,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvremove.8_pregen b/man/lvremove.8_pregen
index 2bd7997a3..8a4afbdff 100644
--- a/man/lvremove.8_pregen
+++ b/man/lvremove.8_pregen
@@ -136,8 +136,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvrename.8_pregen b/man/lvrename.8_pregen
index d41a4c241..27ce2caeb 100644
--- a/man/lvrename.8_pregen
+++ b/man/lvrename.8_pregen
@@ -120,8 +120,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvresize.8_pregen b/man/lvresize.8_pregen
index f3ea2536c..10e7dda7c 100644
--- a/man/lvresize.8_pregen
+++ b/man/lvresize.8_pregen
@@ -286,8 +286,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvs.8_pregen b/man/lvs.8_pregen
index 2b2c5f193..94a74f9dd 100644
--- a/man/lvs.8_pregen
+++ b/man/lvs.8_pregen
@@ -172,8 +172,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/lvscan.8_pregen b/man/lvscan.8_pregen
index f459ab35b..8d79f22dd 100644
--- a/man/lvscan.8_pregen
+++ b/man/lvscan.8_pregen
@@ -119,8 +119,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvchange.8_pregen b/man/pvchange.8_pregen
index 4add9ca69..010845274 100644
--- a/man/pvchange.8_pregen
+++ b/man/pvchange.8_pregen
@@ -179,8 +179,9 @@ multiple tags at once. See \fBlvm\fP(8) for information about tags.
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvck.8_pregen b/man/pvck.8_pregen
index 88200f21e..7d6652342 100644
--- a/man/pvck.8_pregen
+++ b/man/pvck.8_pregen
@@ -351,8 +351,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvcreate.8_pregen b/man/pvcreate.8_pregen
index a74a5ec2a..6ffd596fe 100644
--- a/man/pvcreate.8_pregen
+++ b/man/pvcreate.8_pregen
@@ -229,8 +229,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen
index 2f26a8727..59628bedd 100644
--- a/man/pvdisplay.8_pregen
+++ b/man/pvdisplay.8_pregen
@@ -183,8 +183,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvmove.8_pregen b/man/pvmove.8_pregen
index 0f70497a2..f633b97d2 100644
--- a/man/pvmove.8_pregen
+++ b/man/pvmove.8_pregen
@@ -206,8 +206,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvremove.8_pregen b/man/pvremove.8_pregen
index 3d4a86c09..51c589fd7 100644
--- a/man/pvremove.8_pregen
+++ b/man/pvremove.8_pregen
@@ -103,8 +103,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvresize.8_pregen b/man/pvresize.8_pregen
index 87d87c8ce..9ce57e325 100644
--- a/man/pvresize.8_pregen
+++ b/man/pvresize.8_pregen
@@ -98,8 +98,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvs.8_pregen b/man/pvs.8_pregen
index 32c28e4d1..955b3f887 100644
--- a/man/pvs.8_pregen
+++ b/man/pvs.8_pregen
@@ -169,8 +169,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/pvscan.8_pregen b/man/pvscan.8_pregen
index 1c96d5aab..1e1cc11ab 100644
--- a/man/pvscan.8_pregen
+++ b/man/pvscan.8_pregen
@@ -369,8 +369,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgcfgbackup.8_pregen b/man/vgcfgbackup.8_pregen
index 5e658093a..cf984b04b 100644
--- a/man/vgcfgbackup.8_pregen
+++ b/man/vgcfgbackup.8_pregen
@@ -123,8 +123,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgcfgrestore.8_pregen b/man/vgcfgrestore.8_pregen
index 695e05582..6165cd36e 100644
--- a/man/vgcfgrestore.8_pregen
+++ b/man/vgcfgrestore.8_pregen
@@ -208,8 +208,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgchange.8_pregen b/man/vgchange.8_pregen
index 05c67aead..7c7030c0d 100644
--- a/man/vgchange.8_pregen
+++ b/man/vgchange.8_pregen
@@ -556,8 +556,9 @@ See \fBlvm.conf\fP(5) for more information about profiles.
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgck.8_pregen b/man/vgck.8_pregen
index a8fa33f4b..cfb828ff9 100644
--- a/man/vgck.8_pregen
+++ b/man/vgck.8_pregen
@@ -114,8 +114,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgconvert.8_pregen b/man/vgconvert.8_pregen
index 4d54c2b27..b99de39b8 100644
--- a/man/vgconvert.8_pregen
+++ b/man/vgconvert.8_pregen
@@ -124,8 +124,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgcreate.8_pregen b/man/vgcreate.8_pregen
index 9bb8d3868..d5316aa1c 100644
--- a/man/vgcreate.8_pregen
+++ b/man/vgcreate.8_pregen
@@ -206,8 +206,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgdisplay.8_pregen b/man/vgdisplay.8_pregen
index 0a12b3c39..b6cd294d5 100644
--- a/man/vgdisplay.8_pregen
+++ b/man/vgdisplay.8_pregen
@@ -180,8 +180,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgexport.8_pregen b/man/vgexport.8_pregen
index a87058946..6af64b82a 100644
--- a/man/vgexport.8_pregen
+++ b/man/vgexport.8_pregen
@@ -139,8 +139,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgextend.8_pregen b/man/vgextend.8_pregen
index 2b2650527..e55e0a110 100644
--- a/man/vgextend.8_pregen
+++ b/man/vgextend.8_pregen
@@ -147,8 +147,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgimport.8_pregen b/man/vgimport.8_pregen
index 5cd8fab84..9f8614205 100644
--- a/man/vgimport.8_pregen
+++ b/man/vgimport.8_pregen
@@ -128,8 +128,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgimportclone.8_pregen b/man/vgimportclone.8_pregen
index bf0af5841..80da5454b 100644
--- a/man/vgimportclone.8_pregen
+++ b/man/vgimportclone.8_pregen
@@ -113,8 +113,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgimportdevices.8_pregen b/man/vgimportdevices.8_pregen
index 5897e29ad..44e5fc663 100644
--- a/man/vgimportdevices.8_pregen
+++ b/man/vgimportdevices.8_pregen
@@ -132,8 +132,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgmerge.8_pregen b/man/vgmerge.8_pregen
index a36e0c7bd..dfe8e2f0f 100644
--- a/man/vgmerge.8_pregen
+++ b/man/vgmerge.8_pregen
@@ -107,8 +107,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgmknodes.8_pregen b/man/vgmknodes.8_pregen
index 0a03e1582..d7cd722a4 100644
--- a/man/vgmknodes.8_pregen
+++ b/man/vgmknodes.8_pregen
@@ -108,8 +108,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgreduce.8_pregen b/man/vgreduce.8_pregen
index f3178a618..63b0a20f3 100644
--- a/man/vgreduce.8_pregen
+++ b/man/vgreduce.8_pregen
@@ -199,8 +199,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgremove.8_pregen b/man/vgremove.8_pregen
index 779c0f13e..661ada673 100644
--- a/man/vgremove.8_pregen
+++ b/man/vgremove.8_pregen
@@ -109,8 +109,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgrename.8_pregen b/man/vgrename.8_pregen
index d3e776ca4..2b849d180 100644
--- a/man/vgrename.8_pregen
+++ b/man/vgrename.8_pregen
@@ -133,8 +133,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgs.8_pregen b/man/vgs.8_pregen
index ee5083a93..2ca98b0b0 100644
--- a/man/vgs.8_pregen
+++ b/man/vgs.8_pregen
@@ -166,8 +166,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgscan.8_pregen b/man/vgscan.8_pregen
index 824e7f673..a8da70d99 100644
--- a/man/vgscan.8_pregen
+++ b/man/vgscan.8_pregen
@@ -101,8 +101,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
diff --git a/man/vgsplit.8_pregen b/man/vgsplit.8_pregen
index 065c8b52a..99938a4e3 100644
--- a/man/vgsplit.8_pregen
+++ b/man/vgsplit.8_pregen
@@ -175,8 +175,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
-Devices that the command can use. This option can be repeated
-or accepts a comma separated list of devices. This overrides
+Restricts the devices that are visible and accessible to the command.
+Devices not listed will appear to be missing. This option can be
+repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
--
2.34.3

View File

@ -0,0 +1,246 @@
From 73b9a2805ca2f2c70f6f631b405f8fea3f72f23b Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 5 Jul 2022 17:08:00 -0500
Subject: [PATCH] exit with error when --devicesfile name doesn't exist
---
lib/cache/lvmcache.c | 3 ++-
lib/label/label.c | 4 ++--
test/shell/devicesfile-basic.sh | 1 +
tools/pvcreate.c | 3 ++-
tools/pvremove.c | 3 ++-
tools/pvscan.c | 3 ++-
tools/toollib.c | 27 +++++++++++++++++++++------
tools/vgcfgrestore.c | 5 ++++-
tools/vgcreate.c | 5 ++++-
tools/vgextend.c | 3 ++-
tools/vgmerge.c | 3 ++-
tools/vgsplit.c | 3 ++-
12 files changed, 46 insertions(+), 17 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 0e62cd267..61a2fee6d 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1600,7 +1600,8 @@ int lvmcache_label_scan(struct cmd_context *cmd)
* with infos/vginfos based on reading headers from
* each device, and a vg summary from each mda.
*/
- label_scan(cmd);
+ if (!label_scan(cmd))
+ return_0;
/*
* When devnames are used as device ids (which is dispreferred),
diff --git a/lib/label/label.c b/lib/label/label.c
index 06958b502..00ede2b76 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -800,7 +800,7 @@ static int _setup_bcache(void)
}
if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) {
- log_error("Failed to create bcache with %d cache blocks.", cache_blocks);
+ log_error("Failed to set up io layer with %d blocks.", cache_blocks);
return 0;
}
@@ -1015,7 +1015,7 @@ int label_scan(struct cmd_context *cmd)
* data to invalidate.)
*/
if (!(iter = dev_iter_create(NULL, 0))) {
- log_error("Scanning failed to get devices.");
+ log_error("Failed to get device list.");
return 0;
}
while ((dev = dev_iter_get(cmd, iter))) {
diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh
index d1cfb6a35..2d197a73a 100644
--- a/test/shell/devicesfile-basic.sh
+++ b/test/shell/devicesfile-basic.sh
@@ -107,6 +107,7 @@ not vgs --devicesfile test.devices $vg2
# misspelled override name fails
not vgs --devicesfile doesnotexist $vg1
not vgs --devicesfile doesnotexist $vg2
+not vgs --devicesfile doesnotexist
# devicesfile and devices cannot be used together
not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1
diff --git a/tools/pvcreate.c b/tools/pvcreate.c
index 71eb060a3..a1ef0e9e1 100644
--- a/tools/pvcreate.c
+++ b/tools/pvcreate.c
@@ -144,7 +144,8 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
cmd->create_edit_devices_file = 1;
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd))
+ return_ECMD_FAILED;
if (!(handle = init_processing_handle(cmd, NULL))) {
log_error("Failed to initialize processing handle.");
diff --git a/tools/pvremove.c b/tools/pvremove.c
index 2dfdbd016..5c39ee0c7 100644
--- a/tools/pvremove.c
+++ b/tools/pvremove.c
@@ -45,7 +45,8 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv)
clear_hint_file(cmd);
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd))
+ return_ECMD_FAILED;
/* When forcibly clearing a PV we don't care about a VG lock. */
if (pp.force == DONT_PROMPT_OVERRIDE)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 50d46051a..bce1fbb40 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -1626,7 +1626,8 @@ static int _pvscan_cache_all(struct cmd_context *cmd, int argc, char **argv,
* which we want 'pvscan --cache' to do, and that uses
* info from lvmcache, e.g. duplicate pv info.
*/
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd))
+ return_0;
cmd->pvscan_recreate_hints = 0;
cmd->use_hints = 0;
diff --git a/tools/toollib.c b/tools/toollib.c
index 01ba03658..210b3dca5 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1601,7 +1601,10 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv,
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LABEL);
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd)) {
+ ret_max = ECMD_FAILED;
+ goto_out;
+ }
if (argc) {
for (; opt < argc; opt++) {
@@ -2381,8 +2384,13 @@ int process_each_vg(struct cmd_context *cmd,
* Scan all devices to populate lvmcache with initial
* list of PVs and VGs.
*/
- if (!(read_flags & PROCESS_SKIP_SCAN))
- lvmcache_label_scan(cmd);
+ if (!(read_flags & PROCESS_SKIP_SCAN)) {
+ if (!lvmcache_label_scan(cmd)) {
+ ret_max = ECMD_FAILED;
+ goto_out;
+ }
+ }
+
/*
* A list of all VGs on the system is needed when:
@@ -3932,7 +3940,10 @@ int process_each_lv(struct cmd_context *cmd,
* Scan all devices to populate lvmcache with initial
* list of PVs and VGs.
*/
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd)) {
+ ret_max = ECMD_FAILED;
+ goto_out;
+ }
/*
* A list of all VGs on the system is needed when:
@@ -4568,8 +4579,12 @@ int process_each_pv(struct cmd_context *cmd,
goto_out;
}
- if (!(read_flags & PROCESS_SKIP_SCAN))
- lvmcache_label_scan(cmd);
+ if (!(read_flags & PROCESS_SKIP_SCAN)) {
+ if (!lvmcache_label_scan(cmd)) {
+ ret_max = ECMD_FAILED;
+ goto_out;
+ }
+ }
if (!lvmcache_get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) {
ret_max = ret;
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c
index e49313d14..9fcba89d4 100644
--- a/tools/vgcfgrestore.c
+++ b/tools/vgcfgrestore.c
@@ -132,7 +132,10 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
clear_hint_file(cmd);
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd)) {
+ unlock_vg(cmd, NULL, vg_name);
+ return_ECMD_FAILED;
+ }
cmd->handles_unknown_segments = 1;
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index dde3f1eac..14608777f 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -84,7 +84,10 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
cmd->create_edit_devices_file = 1;
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd)) {
+ unlock_vg(cmd, NULL, vp_new.vg_name);
+ return_ECMD_FAILED;
+ }
if (lvmcache_vginfo_from_vgname(vp_new.vg_name, NULL)) {
unlock_vg(cmd, NULL, vp_new.vg_name);
diff --git a/tools/vgextend.c b/tools/vgextend.c
index 0856b4c78..fecd6bdd5 100644
--- a/tools/vgextend.c
+++ b/tools/vgextend.c
@@ -160,7 +160,8 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
cmd->edit_devices_file = 1;
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd))
+ return_ECMD_FAILED;
if (!(handle = init_processing_handle(cmd, NULL))) {
log_error("Failed to initialize processing handle.");
diff --git a/tools/vgmerge.c b/tools/vgmerge.c
index 08615cd62..4ed4a8f0b 100644
--- a/tools/vgmerge.c
+++ b/tools/vgmerge.c
@@ -72,7 +72,8 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
return ECMD_FAILED;
}
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd))
+ return_ECMD_FAILED;
if (strcmp(vg_name_to, vg_name_from) > 0)
lock_vg_from_first = 1;
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index a085ac2ba..9d6534e89 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -559,7 +559,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
- lvmcache_label_scan(cmd);
+ if (!lvmcache_label_scan(cmd))
+ return_ECMD_FAILED;
if (!(vginfo_to = lvmcache_vginfo_from_vgname(vg_name_to, NULL))) {
if (!validate_name(vg_name_to)) {
--
2.34.3

View File

@ -0,0 +1,55 @@
From 3f297c1b3bebcb8812db882f369fbb4c43f4ceb3 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 25 Jul 2022 13:50:43 -0500
Subject: [PATCH] apply multipath_component_detection=0 to duplicate PV
handling
multipath_component_detection=0 has always applied to the filter-based
component detection. Also apply this setting to the duplicate-PV
handling which also eliminates multipath components (based on duplicate
PVs having the same wwid.)
(cherry picked from commit 99ce09ae778c2cc4aa2611e425bba5287b8b9513)
---
lib/cache/lvmcache.c | 3 +++
test/shell/duplicate-pvs-multipath.sh | 10 +++++++---
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 61a2fee6d..04e9f0605 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -640,6 +640,9 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
*dev_mpath = NULL;
+ if (!find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL))
+ return 0;
+
/* This function only makes sense with more than one dev. */
if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) {
log_debug("Skip multipath component checks with single device for PVID %s", pvid);
diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh
index 59c15b0d4..bc98d2d5a 100644
--- a/test/shell/duplicate-pvs-multipath.sh
+++ b/test/shell/duplicate-pvs-multipath.sh
@@ -24,9 +24,13 @@ modprobe --dry-run scsi_debug || skip
multipath -l || skip
multipath -l | grep scsi_debug && skip
-# Turn off multipath_component_detection so that the duplicate
-# resolution of mpath components is used.
-aux lvmconf 'devices/multipath_component_detection = 0'
+# FIXME: setting multipath_component_detection=0 now also disables
+# the wwid-based mpath component detection, so this test will need
+# to find another way to disable only the filter-mpath code (using
+# sysfs and multipath/wwids) while keeping the code enabled that
+# eliminates duplicates based on their matching wwids which this
+# tries to test.
+
# Prevent wwids from being used for filtering.
aux lvmconf 'devices/multipath_wwids_file = "/dev/null"'
# Need to use /dev/mapper/mpath
--
2.37.1

View File

@ -68,7 +68,7 @@ Version: 2.03.14
%if 0%{?from_snapshot}
Release: 0.1.20210426git%{shortcommit}%{?dist}%{?rel_suffix}
%else
Release: 3%{?dist}%{?rel_suffix}
Release: 6%{?dist}%{?rel_suffix}
%endif
License: GPLv2
URL: http://sourceware.org/lvm2
@ -103,6 +103,41 @@ Patch22: 0021-man-add-section-about-static-autoactivation.patch
Patch23: 0022-lvcreate-include-recent-options.patch
Patch24: 0023-man-lvmautoactivation-replace-systemctl-with-journal.patch
Patch25: 0024-make-generate.patch
Patch26: 0025-pvcreate-overwrite-partition-header-with-f.patch
Patch27: 0026-lvmdevices-check-error-exit-if-update-is-needed.patch
Patch28: 0027-Revert-pvcreate-overwrite-partition-header-with-f.patch
Patch29: 0028-devices-exclude-multipath-components-based-on-matchi.patch
Patch30: 0029-devices-exclude-md-components-when-duplicate-pvs-are.patch
Patch31: 0030-lvmdevices-fix-checks-when-adding-entries.patch
Patch32: 0031-lvmdevices-make-deldev-work-for-missing-device.patch
Patch33: 0032-devices-file-do-not-clear-PVID-of-unread-devices.patch
Patch34: 0033-man-lvmcache-mention-writecache-memory-usage.patch
Patch35: 0034-writecache-display-block-size-from-lvs.patch
Patch36: 0035-devices-simplify-dev_cache_get_by_devt.patch
Patch37: 0036-devices-drop-incorrect-paths-from-aliases-list.patch
Patch38: 0037-devices-initial-use-of-existing-option.patch
Patch39: 0038-devices-fix-dev_name-assumptions.patch
Patch40: 0039-devices-use-dev-cache-aliases-handling-from-label-sc.patch
Patch41: 0040-writecache-check-memory-usage.patch
Patch42: 0041-change-messages-about-filtered-devices.patch
Patch43: 0042-vgimportdevices-fix-incorrect-deviceidtype-usage.patch
Patch44: 0043-lvmlockd-return-error-from-vgcreate-init_vg_sanlock.patch
Patch45: 0044-devices-file-remove-extraneous-unlock-in-vgchange-u.patch
Patch46: 0045-filter-mpath-use-multipath-blacklist.patch
Patch47: 0046-improve-description-of-devices-option.patch
Patch48: 0047-vdo-support-vdosettings.patch
Patch49: 0048-toollib-fix-segfault-when-handling-selection-with-hi.patch
Patch50: 0049-devices-file-move-clean-up-after-command-is-run.patch
Patch51: 0050-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch
Patch52: 0051-filter-mpath-handle-other-wwid-types-in-blacklist.patch
Patch53: 0052-vdo-fix-conversion-of-vdo_slab_size_mb.patch
Patch54: 0053-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch
Patch55: 0054-build-Fix-make-rpm-with-VERSION_DM-without-dash.patch
Patch56: 0055-make-generate.patch
# BZ 2090949:
Patch57: 0056-exit-with-error-when-devicesfile-name-doesn-t-exist.patch
# BZ 2111137:
Patch58: 0057-apply-multipath_component_detection-0-to-duplicate-P.patch
BuildRequires: gcc
%if %{enable_testsuite}
@ -188,6 +223,39 @@ or more physical volumes and creating one or more logical volumes
%patch23 -p1 -b .backup23
%patch24 -p1 -b .backup24
%patch25 -p1 -b .backup25
%patch26 -p1 -b .backup26
%patch27 -p1 -b .backup27
%patch28 -p1 -b .backup28
%patch29 -p1 -b .backup29
%patch30 -p1 -b .backup30
%patch31 -p1 -b .backup31
%patch32 -p1 -b .backup32
%patch33 -p1 -b .backup33
%patch34 -p1 -b .backup34
%patch35 -p1 -b .backup35
%patch36 -p1 -b .backup36
%patch37 -p1 -b .backup37
%patch38 -p1 -b .backup38
%patch39 -p1 -b .backup39
%patch40 -p1 -b .backup40
%patch41 -p1 -b .backup41
%patch42 -p1 -b .backup42
%patch43 -p1 -b .backup43
%patch44 -p1 -b .backup44
%patch45 -p1 -b .backup45
%patch46 -p1 -b .backup46
%patch47 -p1 -b .backup47
%patch48 -p1 -b .backup48
%patch49 -p1 -b .backup49
%patch50 -p1 -b .backup50
%patch51 -p1 -b .backup51
%patch52 -p1 -b .backup52
%patch53 -p1 -b .backup53
%patch54 -p1 -b .backup54
%patch55 -p1 -b .backup55
%patch56 -p1 -b .backup56
%patch57 -p1 -b .backup57
%patch58 -p1 -b .backup58
%build
%global _default_pid_dir /run
@ -806,6 +874,15 @@ An extensive functional testsuite for LVM2.
%endif
%changelog
* Fri Jul 29 2022 Marian Csontos <mcsontos@redhat.com> - 2.03.14-6
- Fix effect of setting multipath_component_detection to 0.
* Thu Jul 14 2022 Marian Csontos <mcsontos@redhat.com> - 2.03.14-5
- Exit with error when --devicesfile used does not exist.
* Wed Jun 15 2022 Marian Csontos <mcsontos@redhat.com> - 2.03.14-4
- Additional important fixes from upstream up to commit 3b0f9ce.
* Tue Jan 04 2022 Marian Csontos <mcsontos@redhat.com> - 2.03.14-3
- Fix devices file and autoactivation related issues.