Accepting request 1000764 from home:hmzhao:branches:Base:System

- Update lvm2 from LVM2.2.03.15 to LVM2.2.03.16
  *** WHATS_NEW for 2.03.16 ***
  Version 2.03.16 - 18th May 2022
  ===============================
    Fix segfault when handling selection with historical LVs.
    Add support --vdosettings with lvcreate, lvconvert, lvchange.
    Filtering multipath devices respects blacklist setting from multipath configuration.
    lvmdevices support for removing by device id using --deviceidtype and --deldev.
    Display writecache block size with lvs -o writecache_block_size.
    Improve cachesettings description in man lvmcache.
    Fix lossing of delete message on thin-pool extension.
- Drop patches that have been merged into upstream
  - 0001-post-release.patch
  - 0002-asan-fix-some-reports-from-libasan.patch
  - 0003-make-generate.patch
  - 0004-tests-udev-pvscan-vgchange-fix-service-wait.patch
  - 0005-devices-file-do-not-clear-PVID-of-unread-devices.patch
  - 0006-tests-skip-vgchange-pvs-online.sh-on-rhel5.patch
  - 0007-dev_manager-fix-dm_task_get_device_list.patch
  - 0008-dev_manager-failing-status-is-not-internal-error.patch
  - 0009-clang-add-extra-check.patch
  - 0010-clang-possible-better-compilation-with-musl-c.patch
  - 0011-dev_manager-do-not-query-for-open_count.patch
  - 0012-dev_manager-use-list-info-for-preset-devs.patch
  - 0013-man-lvmcache-add-more-writecache-cachesettings-info.patch
  - 0014-man-update-cachesettings-option-description.patch
  - 0015-man-lvmcache-mention-writecache-memory-usage.patch
  - 0016-writecache-display-block-size-from-lvs.patch
  - 0017-devices-simplify-dev_cache_get_by_devt.patch
  - 0018-devices-drop-incorrect-paths-from-aliases-list.patch
  - 0019-devices-initial-use-of-existing-option.patch
  - 0020-devices-fix-dev_name-assumptions.patch
  - 0021-devices-use-dev-cache-aliases-handling-from-label-sc.patch
  - 0022-devices-only-close-PVs-on-LVs-when-scan_lvs-is-enabl.patch
  - 0023-writecache-check-memory-usage.patch
  - 0024-pvscan-don-t-use-udev-for-external-device-info.patch
  - 0025-vgchange-monitor-don-t-use-udev-info.patch
- Add upstream patch
  - 0001-devices-file-move-clean-up-after-command-is-run.patch
  - 0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch
  - 0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch
  - 0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch
  - 0005-pvdisplay-restore-reportformat-option.patch
  - 0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch
  - 0007-report-fix-pe_start-column-type-from-NUM-to-SIZ.patch
  - 0008-_vg_read_raw_area-fix-segfault-caused-by-using-null-.patch
  - 0009-mm-remove-libaio-from-being-skipped.patch
  - 0010-dmsetup-check-also-for-ouf-of-range-value.patch
  - 0011-devices-drop-double-from-sysfs-path.patch
  - 0012-devices-file-fix-pvcreate-uuid-matching-pvid-entry-w.patch
  - 0013-vgimportdevices-change-result-when-devices-are-not-a.patch
  - 0014-vgimportdevices-fix-locking-when-creating-devices-fi.patch
- update lvm2.spec
  - indent some lines for easy read
  - remove config item '--enable-cmirrord'
  - add new man lvm_import_vdo.8
  - add new man dmfilemapd.8

OBS-URL: https://build.opensuse.org/request/show/1000764
OBS-URL: https://build.opensuse.org/package/show/Base:System/lvm2?expand=0&rev=312
This commit is contained in:
heming zhao 2022-09-01 23:48:48 +00:00 committed by Git OBS Bridge
parent a1b7bcac16
commit 819badda28
45 changed files with 2191 additions and 2819 deletions

View File

@ -0,0 +1,47 @@
From 9dfa6f38793f6b5f7de2a4148ab2f7790e3c39da Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 27 May 2022 12:38:43 -0500
Subject: [PATCH] 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 | 2 --
tools/lvmcmdline.c | 1 +
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 4cb81bf94279..2666d7b42be6 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1905,7 +1905,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);
@@ -2034,7 +2033,6 @@ void destroy_toolcontext(struct cmd_context *cmd)
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
_destroy_filters(cmd);
- devices_file_exit(cmd);
dev_cache_exit();
_destroy_dev_types(cmd);
_destroy_tags(cmd);
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 1e3547ed72f3..b052d698fed7 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -3305,6 +3305,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.26.2

View File

@ -1,51 +0,0 @@
From 8dccc2314e2482370bc6e5cf007eb210994abdef Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
Date: Mon, 7 Feb 2022 18:02:07 +0100
Subject: post-release
---
VERSION | 2 +-
VERSION_DM | 2 +-
WHATS_NEW | 3 +++
WHATS_NEW_DM | 3 +++
4 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/VERSION b/VERSION
index 0e6ab70a9c50..fba090956ba1 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.03.15(2) (2022-02-07)
+2.03.16(2)-git (2022-02-07)
diff --git a/VERSION_DM b/VERSION_DM
index d6704212f283..d122183b2c63 100644
--- a/VERSION_DM
+++ b/VERSION_DM
@@ -1 +1 @@
-1.02.183 (2022-02-07)
+1.02.185-git (2022-02-07)
diff --git a/WHATS_NEW b/WHATS_NEW
index dda9954fe52f..006d0acb141c 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,3 +1,6 @@
+Version 2.03.16 -
+====================================
+
Version 2.03.15 - 07th February 2022
====================================
Remove service based autoactivation. global/event_activation = 0 is NOOP.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 77843726211c..c634362217a5 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,3 +1,6 @@
+Version 1.02.185 -
+=====================================
+
Version 1.02.183 - 07th February 2022
=====================================
Unmangle UUIDs for DM_DEVICE_LIST ioctl.
--
2.34.1

View File

@ -1,144 +0,0 @@
From f83b3962c10bf4e196fec0e3e735820ba908661f Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Mon, 7 Feb 2022 19:58:04 +0100
Subject: asan: fix some reports from libasan
When compiled and used with:
CFLAGS="-fsanitize=address -g -O0"
ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
we have few reported issue - they where not normally spotted, since
we were still accessing our own memory - but ouf of buffer-range.
TODO: there is still something to enhance with handling of #orphan vgids
---
lib/config/config.c | 4 +++-
lib/format_text/format-text.c | 2 +-
lib/format_text/text_label.c | 6 ++++--
lib/metadata/metadata-exported.h | 2 +-
lib/uuid/uuid.c | 5 +++++
tools/Makefile.in | 4 ++--
tools/command.c | 2 +-
7 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/lib/config/config.c b/lib/config/config.c
index c8dab5683a20..f9614779a743 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -522,7 +522,9 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
if (!(dev->flags & DEV_REGULAR) || size2)
use_plain_read = 0;
- if (!(buf = zalloc(size + size2))) {
+ /* Ensure there is extra '\0' after end of buffer since we pass
+ * buffer to funtions like strtoll() */
+ if (!(buf = zalloc(size + size2 + 1))) {
log_error("Failed to allocate circular buffer.");
return 0;
}
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 00443faa12f7..07aaa0b28880 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -2601,7 +2601,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
fmt->ops = &_text_handler;
fmt->name = FMT_TEXT_NAME;
fmt->alias = FMT_TEXT_ALIAS;
- fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME);
+ strncpy(fmt->orphan_vg_name, ORPHAN_VG_NAME(FMT_TEXT_NAME), sizeof(fmt->orphan_vg_name));
fmt->features = FMT_SEGMENTS | FMT_TAGS | FMT_PRECOMMIT |
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
FMT_UNLIMITED_STRIPESIZE | FMT_CONFIG_PROFILE |
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 29b470271170..324c86e44978 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -410,6 +410,7 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
{
struct lvmcache_vgsummary vgsummary;
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
+ char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
struct lvmcache_info *info;
const struct format_type *fmt = labeller->fmt;
struct label_header *lh = (struct label_header *) label_buf;
@@ -433,6 +434,7 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
pvhdr = (struct pv_header *) ((char *) label_buf + xlate32(lh->offset_xl));
memcpy(pvid, &pvhdr->pv_uuid, ID_LEN);
+ strncpy(vgid, FMT_TEXT_ORPHAN_VG_NAME, ID_LEN);
/*
* FIXME: stop adding the device to lvmcache initially as an orphan
@@ -449,8 +451,8 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
* Other reasons for lvmcache_add to return NULL are internal errors.
*/
if (!(info = lvmcache_add(cmd, labeller, pvid, dev, label_sector,
- FMT_TEXT_ORPHAN_VG_NAME,
- FMT_TEXT_ORPHAN_VG_NAME, 0, is_duplicate)))
+ vgid,
+ vgid, 0, is_duplicate)))
return_0;
lvmcache_set_device_size(info, xlate64(pvhdr->device_size_xl));
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 7bac5b900343..fd370d4b261a 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -371,7 +371,7 @@ struct format_type {
struct labeller *labeller;
const char *name;
const char *alias;
- const char *orphan_vg_name;
+ char orphan_vg_name[ID_LEN];
struct volume_group *orphan_vg; /* Only one ever exists. */
uint32_t features;
void *library;
diff --git a/lib/uuid/uuid.c b/lib/uuid/uuid.c
index be4cbc3ec194..d8b72422bc0f 100644
--- a/lib/uuid/uuid.c
+++ b/lib/uuid/uuid.c
@@ -168,6 +168,11 @@ int id_write_format(const struct id *id, char *buffer, size_t size)
assert(ID_LEN == 32);
+ if (id->uuid[0] == '#') {
+ (void) dm_strncpy(buffer, (char*)id->uuid, size);
+ return 1;
+ }
+
/* split into groups separated by dashes */
if (size < (32 + 6 + 1)) {
if (size > 0)
diff --git a/tools/Makefile.in b/tools/Makefile.in
index e0e180474789..25fe3b6b36d8 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -190,9 +190,9 @@ command-lines-input.h: $(srcdir)/command-lines.in Makefile
$(Q) set -o pipefail && \
( cat $(srcdir)/license.inc && \
echo "/* Do not edit. This file is generated by the Makefile. */" && \
- echo -en "const char _command_input[] =\n\n\"" && \
+ echo -en "static const char _command_input[] =\n\n\"" && \
$(EGREP) -v '^#|\-\-\-|^$$' $(srcdir)/command-lines.in | $(AWK) 'BEGIN {ORS = "\\n\"\n\""} //' && \
- echo "\\n\";" \
+ echo "\\n\\n\";" \
) > $@
$(SOURCES:%.c=%.d) $(SOURCES2:%.c=%.d): command-lines-input.h command-count.h cmds.h
diff --git a/tools/command.c b/tools/command.c
index 18ffd64ed986..8de8825e4cbd 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -2549,7 +2549,7 @@ static const char *_man_long_opt_name(const char *cmdname, int opt_enum)
}
if (strchr(long_opt, '[')) {
- for (i = 0; i < sizeof(long_opt_name) - 1; ++long_opt, ++i) {
+ for (i = 0; *long_opt && i < sizeof(long_opt_name) - 1; ++long_opt, ++i) {
if (i < (sizeof(long_opt_name) - 8))
switch(*long_opt) {
case '[':
--
2.34.1

View File

@ -0,0 +1,52 @@
From bfe072e4388b530cbf5369be8a8f1305220198bf Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 27 May 2022 14:27:03 -0500
Subject: [PATCH] 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 3aaf6a2e55b8..ed9c726c9748 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1863,6 +1863,15 @@ int setup_devices(struct cmd_context *cmd)
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 9c3455c7678e..77fe265a0c54 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.26.2

View File

@ -0,0 +1,52 @@
From c302903dbab1d5fd05b344c654bed83c9ecb69f8 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 6 Jun 2022 11:39:02 -0500
Subject: [PATCH] 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 270366ad7cfe..846f6c8bab13 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.26.2

View File

@ -1,318 +0,0 @@
From 13122bcc3329f3c1aee0a1cc478eda8906cd96df Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Sun, 6 Feb 2022 20:05:54 +0100
Subject: make: generate
---
conf/example.conf.in | 15 +++-----
man/lvdisplay.8_pregen | 12 -------
man/lvmdevices.8_pregen | 3 +-
man/pvdisplay.8_pregen | 12 -------
man/pvscan.8_pregen | 77 ++++++++++++++++++++++-------------------
man/vgchange.8_pregen | 12 +++++++
man/vgdisplay.8_pregen | 12 -------
7 files changed, 60 insertions(+), 83 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index a78ed7333310..94f7a23fdb11 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1151,16 +1151,11 @@ global {
# lvdisplay_shows_full_device_path = 0
# Configuration option global/event_activation.
- # Activate LVs based on system-generated device events.
- # When a PV appears on the system, a system-generated uevent triggers
- # the lvm2-pvscan service which runs the pvscan --cache -aay command.
- # If the new PV completes a VG, pvscan autoactivates LVs in the VG.
- # When event_activation is disabled, the lvm2-activation services are
- # generated and run at fixed points during system startup. These
- # services run vgchange -aay to autoactivate LVs in VGs that happen
- # to be present at that point in time.
- # See the --setautoactivation option or the auto_activation_volume_list
- # setting to configure autoactivation for specific VGs or LVs.
+ # Disable event based autoactivation commands.
+ # WARNING: setting this to zero may cause machine startup to fail.
+ # Previously, setting this to zero would enable static autoactivation
+ # services (via the lvm2-activation-generator), but the autoactivation
+ # services and generator have been removed.
# This configuration option has an automatic default value.
# event_activation = 1
diff --git a/man/lvdisplay.8_pregen b/man/lvdisplay.8_pregen
index a1740ebed152..04aab4c0970c 100644
--- a/man/lvdisplay.8_pregen
+++ b/man/lvdisplay.8_pregen
@@ -61,8 +61,6 @@ and more, using a more compact and configurable output format.
.br
[ \fB--readonly\fP ]
.br
-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
-.br
[ \fB--segments\fP ]
.br
[ \fB--separator\fP \fIString\fP ]
@@ -332,16 +330,6 @@ device-mapper kernel driver, so this option is unable to report whether
or not LVs are actually in use.
.
.HP
-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
-.br
-Overrides current output format for reports which is defined globally by
-the report/output_format setting in \fBlvm.conf\fP(5).
-\fBbasic\fP is the original format with columns and rows.
-If there is more than one report per command, each report is prefixed
-with the report name for identification. \fBjson\fP produces report
-output in JSON format. See \fBlvmreport\fP(7) for more information.
-.
-.HP
\fB--segments\fP
.br
.
diff --git a/man/lvmdevices.8_pregen b/man/lvmdevices.8_pregen
index d64c3a31abe7..a2391a62bb3e 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
diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen
index 22a0992b52bb..2f26a8727d43 100644
--- a/man/pvdisplay.8_pregen
+++ b/man/pvdisplay.8_pregen
@@ -61,8 +61,6 @@ and more, using a more compact and configurable output format.
.br
[ \fB--readonly\fP ]
.br
-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
-.br
[ \fB--separator\fP \fIString\fP ]
.br
[ \fB--shared\fP ]
@@ -320,16 +318,6 @@ device-mapper kernel driver, so this option is unable to report whether
or not LVs are actually in use.
.
.HP
-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
-.br
-Overrides current output format for reports which is defined globally by
-the report/output_format setting in \fBlvm.conf\fP(5).
-\fBbasic\fP is the original format with columns and rows.
-If there is more than one report per command, each report is prefixed
-with the report name for identification. \fBjson\fP produces report
-output in JSON format. See \fBlvmreport\fP(7) for more information.
-.
-.HP
\fB-S\fP|\fB--select\fP \fIString\fP
.br
Select objects for processing and reporting based on specified criteria.
diff --git a/man/pvscan.8_pregen b/man/pvscan.8_pregen
index 9eb6b5bf96be..4622e145e564 100644
--- a/man/pvscan.8_pregen
+++ b/man/pvscan.8_pregen
@@ -15,6 +15,8 @@ pvscan \(em List all physical volumes
.P
.ad l
\fB-a\fP|\fB--activate\fP \fBy\fP|\fBn\fP|\fBay\fP
+.br
+ \fB--autoactivation\fP \fIString\fP
.br
\fB--cache\fP
.br
@@ -91,59 +93,50 @@ like
or
.BR pvdisplay (8).
.P
-When the --cache and -aay options are used, pvscan records which PVs are
-available on the system, and activates LVs in completed VGs. A VG is
-complete when pvscan sees that the final PV in the VG has appeared. This
-is used by event-based system startup (systemd, udev) to activate LVs.
-.P
-The four main variations of this are:
+When --cache is used, pvscan updates runtime lvm state on the system, or
+with -aay performs autoactivation.
.P
.B pvscan --cache
.I device
.P
-If device is present, lvm adds a record that the PV on device is online.
+If device is present, lvm records that the PV on device is online.
If device is not present, lvm removes the online record for the PV.
-In most cases, the pvscan will only read the named devices.
+pvscan only reads the named device.
.P
-.B pvscan --cache -aay
-.IR device ...
+.B pvscan --cache
.P
-This begins by performing the same steps as above. Afterward, if the VG
-for the specified PV is complete, then pvscan will activate LVs in the VG
-(the same as vgchange -aay vgname would do.)
+Updates the runtime state for all lvm devices.
.P
-.B pvscan --cache
+.B pvscan --cache -aay
+.I device
.P
-This first clears all existing PV online records, then scans all devices
-on the system, adding PV online records for any PVs that are found.
+Performs the --cache steps for the device, then checks if the VG using the
+device is complete. If so, LVs in the VG are autoactivated, the same as
+vgchange -aay vgname would do. (A device name may be replaced with major
+and minor numbers.)
.P
.B pvscan --cache -aay
.P
-This begins by performing the same steps as pvscan --cache. Afterward, it
-activates LVs in any complete VGs.
+Performs the --cache steps for all devices, then autoactivates any complete VGs.
.P
-To prevent devices from being scanned by pvscan --cache, add them
-to
-.BR lvm.conf (5)
-.B devices/global_filter.
-For more information, see:
-.br
-.B lvmconfig --withcomments devices/global_filter
+.B pvscan --cache --listvg|--listlvs
+.I device
.P
-Auto-activation of VGs or LVs can be enabled/disabled using:
-.br
+Performs the --cache steps for the device, then prints the name of the VG
+using the device, or the names of LVs using the device. --checkcomplete
+is usually included to check if all PVs for the VG or LVs are online.
+When this command is called by a udev rule, the output must conform to
+udev rule specifications (see --udevoutput.) The udev rule will use the
+results to perform autoactivation.
+.P
+Autoactivation of VGs or LVs can be enabled/disabled using vgchange or
+lvchange with --setautoactivation y|n, or by adding names to
.BR lvm.conf (5)
.B activation/auto_activation_volume_list
.P
-For more information, see:
-.br
-.B lvmconfig --withcomments activation/auto_activation_volume_list
-.P
-To disable auto-activation, explicitly set this list to an empty list,
-i.e. auto_activation_volume_list = [ ].
-.P
-When this setting is undefined (e.g. commented), then all LVs are
-auto-activated.
+See
+.BR lvmautoactivation (7)
+for more information about how pvscan is used for autoactivation.
.
.SH USAGE
.
@@ -215,6 +208,8 @@ Record that a PV is online and autoactivate the VG if complete.
.br
[ \fB--noudevsync\fP ]
.br
+[ \fB--autoactivation\fP \fIString\fP ]
+.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -239,6 +234,8 @@ Record that a PV is online and list the VG using the PV.
.br
[ \fB--udevoutput\fP ]
.br
+[ \fB--autoactivation\fP \fIString\fP ]
+.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -342,6 +339,14 @@ Auto-activate LVs in a VG when the PVs scanned have completed the VG.
(Only \fBay\fP is applicable.)
.
.HP
+\fB--autoactivation\fP \fIString\fP
+.br
+Specify if autoactivation is being used from an event.
+This allows the command to apply settings that are specific
+to event activation, such as device scanning optimizations
+using pvs_online files created by event-based pvscans.
+.
+.HP
\fB--cache\fP
.br
Scan one or more devices and record that they are online.
diff --git a/man/vgchange.8_pregen b/man/vgchange.8_pregen
index 05c67aeada56..9dbad3faad87 100644
--- a/man/vgchange.8_pregen
+++ b/man/vgchange.8_pregen
@@ -24,6 +24,8 @@ vgchange \(em Change volume group attributes
.nh
\%\fBcontiguous\fP|\:\fBcling\fP|\:\fBcling_by_tags\fP|\:\fBnormal\fP|\:\fBanywhere\fP|\:\fBinherit\fP
.hy
+.br
+ \fB--autoactivation\fP \fIString\fP
.br
\fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP
.br
@@ -286,6 +288,8 @@ Activate or deactivate LVs.
.br
[ \fB--poll\fP \fBy\fP|\fBn\fP ]
.br
+[ \fB--autoactivation\fP \fIString\fP ]
+.br
[ \fB--ignoremonitoring\fP ]
.br
[ \fB--noudevsync\fP ]
@@ -516,6 +520,14 @@ which PVs the command will use for allocation.
See \fBlvm\fP(8) for more information about allocation.
.
.HP
+\fB--autoactivation\fP \fIString\fP
+.br
+Specify if autoactivation is being used from an event.
+This allows the command to apply settings that are specific
+to event activation, such as device scanning optimizations
+using pvs_online files created by event-based pvscans.
+.
+.HP
\fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP
.br
Specifies if metadata should be backed up automatically after a change.
diff --git a/man/vgdisplay.8_pregen b/man/vgdisplay.8_pregen
index 9c694921dee8..0a12b3c395bb 100644
--- a/man/vgdisplay.8_pregen
+++ b/man/vgdisplay.8_pregen
@@ -58,8 +58,6 @@ and more, using a more compact and configurable output format.
.br
[ \fB--readonly\fP ]
.br
-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
-.br
[ \fB--shared\fP ]
.br
[ \fB--separator\fP \fIString\fP ]
@@ -312,16 +310,6 @@ device-mapper kernel driver, so this option is unable to report whether
or not LVs are actually in use.
.
.HP
-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
-.br
-Overrides current output format for reports which is defined globally by
-the report/output_format setting in \fBlvm.conf\fP(5).
-\fBbasic\fP is the original format with columns and rows.
-If there is more than one report per command, each report is prefixed
-with the report name for identification. \fBjson\fP produces report
-output in JSON format. See \fBlvmreport\fP(7) for more information.
-.
-.HP
\fB-S\fP|\fB--select\fP \fIString\fP
.br
Select objects for processing and reporting based on specified criteria.
--
2.34.1

View File

@ -0,0 +1,741 @@
From 3b0f9cec7e999c33f17714358d2b469bda6967d2 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 6 Jun 2022 14:04:20 -0500
Subject: [PATCH] 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 22b96134b58a..3ab5cb2f1d53 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -41,6 +41,7 @@ SOURCES =\
device/dev-dasd.c \
device/dev-lvm1-pool.c \
device/online.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 ed9c726c9748..193eb7585f45 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 46b1da72c1ad..7ffe01152510 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 846f6c8bab13..27b0f41a6a8a 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;
}
@@ -434,10 +452,10 @@ static int _dev_is_mpath_component_udev(struct device *dev)
/* mpath_devno is major:minor of the dm multipath device currently using the component dev. */
-static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev, dev_t *mpath_devno)
+static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev,
+ int primary_result, dev_t primary_dev, dev_t *mpath_devno)
{
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/" */
@@ -451,25 +469,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. */
@@ -593,47 +601,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, dev_t *holder_devno)
{
- if (_dev_is_mpath_component_sysfs(cmd, dev, holder_devno) == 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, holder_devno) == 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) {
@@ -641,6 +791,12 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *h
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 d0d670ec3708..06440f44b3fa 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 f1928347c127..9dec9f884da4 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 94773a65e588..9b9c9ce03c65 100644
--- a/lib/device/device_id.h
+++ b/lib/device/device_id.h
@@ -58,6 +58,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 000000000000..4bafa7b9eff6
--- /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.26.2

View File

@ -1,63 +0,0 @@
From 61f23fe15e0c6e5b7882263e0d527f363535da4d Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 7 Feb 2022 16:44:57 -0600
Subject: tests: udev-pvscan-vgchange fix service wait
As a result of removing -r from systemd-run in
commit fbd8b0cf43dc67f51f86f060dce748f446985855
this test needs to change how it handles the
transient services.
---
test/shell/udev-pvscan-vgchange.sh | 15 +--------------
1 file changed, 1 insertion(+), 14 deletions(-)
diff --git a/test/shell/udev-pvscan-vgchange.sh b/test/shell/udev-pvscan-vgchange.sh
index a209dc048cce..eb698407881f 100644
--- a/test/shell/udev-pvscan-vgchange.sh
+++ b/test/shell/udev-pvscan-vgchange.sh
@@ -75,7 +75,7 @@ wait_lvm_activate() {
local vgw=$1
local wait=0
- while systemctl status lvm-activate-$vgw | grep "active (running)" && test "$wait" -le 30; do
+ while systemctl status lvm-activate-$vgw > /dev/null && test "$wait" -le 30; do
sleep .2
wait=$(( wait + 1 ))
done
@@ -382,7 +382,6 @@ lvcreate -l1 -an -n $lv1 $vg9
lvcreate -l1 -an -n $lv2 $vg9
mdadm --stop "$mddev"
-systemctl stop lvm-activate-$vg9 || true
_clear_online_files
mdadm --assemble "$mddev" "$dev1" "$dev2"
@@ -405,17 +404,6 @@ mdadm --stop "$mddev"
aux udev_wait
wipe_all
-systemctl stop lvm-activate-$vg1
-systemctl stop lvm-activate-$vg2
-systemctl stop lvm-activate-$vg3
-systemctl stop lvm-activate-$vg4
-systemctl stop lvm-activate-$vg5
-systemctl stop lvm-activate-$vg6
-systemctl stop lvm-activate-$vg7
-systemctl stop lvm-activate-$vg8
-systemctl stop lvm-activate-$vg9
-
-
# no devices file, filter with symlink of PV
# the pvscan needs to look at all dev names to
# match the symlink in the filter with the
@@ -439,7 +427,6 @@ udevadm trigger --settle -c add /sys/block/$BDEV1
ls /dev/disk/by-id/lvm-pv-uuid-$OPVID1
vgchange -an $vg10
-systemctl stop lvm-activate-$vg10
_clear_online_files
aux lvmconf "devices/filter = [ \"a|/dev/disk/by-id/lvm-pv-uuid-$OPVID1|\", \"r|.*|\" ]"
--
2.34.1

View File

@ -1,144 +0,0 @@
From d59382c772483d3c09b4fcff90c01d81742feac6 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 10 Feb 2022 14:00:25 -0600
Subject: 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 9e471a9b514a..8c3a8c30e086 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 4618247ba1f2..003f10a96641 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1746,6 +1746,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.
@@ -1828,6 +1835,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 93dfdd5c1d9a..35ae7f5cc8df 100644
--- a/lib/label/hints.c
+++ b/lib/label/hints.c
@@ -236,6 +236,7 @@ static int _touch_newhints(void)
return_0;
if (fclose(fp))
stack;
+ log_debug("newhints created");
return 1;
}
@@ -506,6 +507,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 8676b9e4a642..fe2bc8fec743 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -687,6 +687,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
@@ -702,6 +704,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;
}
}
@@ -725,6 +728,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);
@@ -1389,6 +1393,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.1

View File

@ -0,0 +1,34 @@
From db5277c97155632ce83e1125e348eda97c871968 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 24 Jun 2022 10:40:54 -0500
Subject: [PATCH] pvdisplay: restore --reportformat option
Fixes commit b8f4ec846 "display: ignore --reportformat"
by restoring the --reportformat option to pvdisplay.
Adding -C to pvdisplay turns the command into a reporting
command (like pvs, vgs, lvs) in which --reportformat can
be useful.
---
tools/command-lines.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/command-lines.in b/tools/command-lines.in
index b64fd0dda232..b6a03d158daa 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -1593,10 +1593,10 @@ pvdisplay
OO: --aligned, --all, --binary, --colon, --columns, --configreport ConfigReport,
--foreign, --ignorelockingfailure,
--logonly, --maps, --noheadings, --nosuffix, --options String,
---readonly, --select String, --separator String, --shared,
+--readonly, --reportformat ReportFmt, --select String, --separator String, --shared,
--short, --sort String, --unbuffered, --units Units
OP: PV|Tag ...
-IO: --ignoreskippedcluster, --reportformat ReportFmt
+IO: --ignoreskippedcluster
ID: pvdisplay_general
---
--
2.26.2

View File

@ -0,0 +1,246 @@
From 92b4fcf57f3c6d212d06b72b097e1a06e6efb84b 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 22edcfd849e3..a1c4a61c82fa 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1612,7 +1612,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 711edb6f4085..f845abb9640f 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -801,7 +801,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;
}
@@ -1292,7 +1292,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 77fe265a0c54..715c579b394c 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 71eb060a37ae..a1ef0e9e1941 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 2dfdbd016826..5c39ee0c7904 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 1e47d754ab7e..72c3279c3179 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -1407,7 +1407,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 d77092d894d2..544791808f6c 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1655,7 +1655,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++) {
@@ -2435,8 +2438,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:
@@ -3987,7 +3995,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:
@@ -4623,8 +4634,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 e49313d144e8..9fcba89d44d5 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 dde3f1eac279..14608777fd59 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 0856b4c78d25..fecd6bdd5b4f 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 08615cd62305..4ed4a8f0b752 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 5f113b3635e2..c7f4b8af4db1 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.26.2

View File

@ -1,27 +0,0 @@
From 6626adb46789e329a53242822dc6e9d233320adb Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 15 Feb 2022 15:56:01 -0600
Subject: tests: skip vgchange-pvs-online.sh on rhel5
the /dev/mapper/ paths to test devices don't seem to work there
---
test/shell/vgchange-pvs-online.sh | 3 +++
1 file changed, 3 insertions(+)
diff --git a/test/shell/vgchange-pvs-online.sh b/test/shell/vgchange-pvs-online.sh
index ced03f4daef7..9bcf70e4b245 100644
--- a/test/shell/vgchange-pvs-online.sh
+++ b/test/shell/vgchange-pvs-online.sh
@@ -19,6 +19,9 @@ _clear_online_files() {
aux prepare_devs 4
+# skip rhel5 which doesn't seem to have /dev/mapper/LVMTESTpv1
+aux driver_at_least 4 15 || skip
+
DFDIR="$LVM_SYSTEM_DIR/devices"
mkdir -p "$DFDIR" || true
DF="$DFDIR/system.devices"
--
2.34.1

View File

@ -1,44 +0,0 @@
From 6ffb150f3075da69597e6f3e84d7533f2d8a36fa Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Wed, 16 Feb 2022 00:33:25 +0100
Subject: dev_manager: fix dm_task_get_device_list
With very old version of DM target driver we have to avoid
trying to use newuuid setting - otherwise we get error
during ioctl preparation phase.
Patch is fixing regression from commit:
988ea0e94c79a496f2619eab878fd9db6168711d
---
lib/activate/dev_manager.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 6cf4c718c389..3fd6aaff76a9 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -107,6 +107,8 @@ static struct dm_task *_setup_task_run(int task, struct dm_info *info,
int with_flush,
int query_inactive)
{
+ char vsn[80];
+ unsigned maj, min;
struct dm_task *dmt;
if (!(dmt = dm_task_create(task)))
@@ -142,7 +144,11 @@ static struct dm_task *_setup_task_run(int task, struct dm_info *info,
case DM_DEVICE_TARGET_MSG:
return dmt; /* TARGET_MSG needs more local tweaking before task_run() */
case DM_DEVICE_LIST:
- if (!dm_task_set_newuuid(dmt, " ")) // new uuid has no meaning here
+ /* Use 'newuuid' only with DM version that supports it */
+ if (driver_version(vsn, sizeof(vsn)) &&
+ (sscanf(vsn, "%u.%u", &maj, &min) == 2) &&
+ (maj == 4 ? min >= 19 : maj > 4) &&
+ !dm_task_set_newuuid(dmt, " ")) // new uuid has no meaning here
log_warn("WARNING: Failed to query uuid with LIST.");
break;
default:
--
2.34.1

View File

@ -0,0 +1,38 @@
From fc8fda641781d0978ff22ad0a59d5a19b5e450e1 Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
Date: Fri, 5 Aug 2022 11:02:25 +0200
Subject: [PATCH] report: fix pe_start column type from NUM to SIZ
The 'pe_start' column was incorrectly marked as being of type NUM.
This was not correct as pe_start is actually of type SIZ, which means
it can have a size suffix and hence it's not a pure numeric value.
Proper column type is important for selection to work correctly, so we
can also do comparisons while using suffixes.
This is also important for new "json_std" output format which does not
put double quotes around pure numeric values. With pe_start incorrectly
marked as NUM instead of SIZ, this produced invalid JSON output
like '"pe_start" = 1.00m' because it contained the 'm' (or other)
size suffix. If properly marked as SIZ, this is then put in double
quotes like '"pe_start" = "1.00m"'.
---
lib/report/columns.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 7e450dacef66..d702635d2f15 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -191,7 +191,7 @@ FIELD(LABEL, label, NUM, "PExtVsn", type, 0, pvextvsn, pv_ext_vsn, "PV header ex
/*
* PVS type fields
*/
-FIELD(PVS, pv, NUM, "1st PE", pe_start, 7, size64, pe_start, "Offset to the start of data on the underlying device.", 0)
+FIELD(PVS, pv, SIZ, "1st PE", pe_start, 7, size64, pe_start, "Offset to the start of data on the underlying device.", 0)
FIELD(PVS, pv, SIZ, "PSize", id, 0, pvsize, pv_size, "Size of PV in current units.", 0)
FIELD(PVS, pv, SIZ, "PFree", id, 0, pvfree, pv_free, "Total amount of unallocated space in current units.", 0)
FIELD(PVS, pv, SIZ, "Used", id, 0, pvused, pv_used, "Total amount of allocated space in current units.", 0)
--
2.26.2

View File

@ -0,0 +1,35 @@
From ce58e9d5b37c3e408f2b41c8095980490a87f2a4 Mon Sep 17 00:00:00 2001
From: Wu Guanghao <wuguanghao3@huawei.com>
Date: Mon, 15 Aug 2022 09:39:02 -0500
Subject: [PATCH] _vg_read_raw_area: fix segfault caused by using null pointer
When we tested lvm2, the kernel injected various random faults.
(gdb) bt
...
(gdb) p vg
$1 = (struct volume_group *) 0x0
(gdb) p use_previous_vg
$2 = (unsigned int *) 0x0
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
---
lib/format_text/format-text.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 07aaa0b28880..c1ccdb0316d8 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -428,7 +428,7 @@ static struct volume_group *_vg_read_raw_area(struct cmd_context *cmd,
rlocn->checksum,
&when, &desc);
- if (!vg && !*use_previous_vg) {
+ if (!vg && (!use_previous_vg || !*use_previous_vg)) {
log_warn("WARNING: Failed to read metadata text at %llu off %llu size %llu VG %s on %s",
(unsigned long long)(area->start + rlocn->offset),
(unsigned long long)rlocn->offset,
--
2.26.2

View File

@ -1,29 +0,0 @@
From c2679f76e5c1733451361b593fa45ba9545250b1 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Tue, 15 Feb 2022 21:16:10 +0100
Subject: dev_manager: failing status is not internal error
Different target type for LV it's not an internal error.
i.e. when target type is replaced with 'error' type - it should be
reported as regular warning and not cause interruption of command with
internall error.
---
lib/activate/dev_manager.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 3fd6aaff76a9..4d18d9838736 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -204,7 +204,7 @@ static int _get_segment_status_from_target_params(const char *target_name,
/* If kernel's type isn't an exact match is it compatible? */
(!segtype->ops->target_status_compatible ||
!segtype->ops->target_status_compatible(target_name))) {
- log_warn(INTERNAL_ERROR "WARNING: Segment type %s found does not match expected type %s for %s.",
+ log_warn("WARNING: Detected %s segment type does not match expected type %s for %s.",
target_name, segtype->name, display_lvname(seg_status->seg->lv));
return 0;
}
--
2.34.1

View File

@ -1,26 +0,0 @@
From d2e7a05573f54750d13c1154036ae2c67478539b Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Tue, 8 Feb 2022 19:17:30 +0100
Subject: clang: add extra check
Make clang happier.
---
lib/metadata/metadata.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index db0e511ec8ea..1cda1888f356 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2197,7 +2197,7 @@ static int _validate_lock_args_chars(const char *lock_args)
static int _validate_vg_lock_args(struct volume_group *vg)
{
- if (!_validate_lock_args_chars(vg->lock_args)) {
+ if (!vg->lock_args || !_validate_lock_args_chars(vg->lock_args)) {
log_error(INTERNAL_ERROR "VG %s has invalid lock_args chars", vg->name);
return 0;
}
--
2.34.1

View File

@ -0,0 +1,26 @@
From a3eb6ba425773224076c41aabc3c490a6a016ee6 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Thu, 18 Aug 2022 14:31:27 +0200
Subject: [PATCH] mm: remove libaio from being skipped
Since libaio is now used also in critical section,
keep the libaio locked in memory.
---
lib/mm/memlock.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/mm/memlock.c b/lib/mm/memlock.c
index 3d1a3927ceb4..f43bacdcdf27 100644
--- a/lib/mm/memlock.c
+++ b/lib/mm/memlock.c
@@ -105,7 +105,6 @@ static const char * const _blacklist_maps[] = {
"/LC_MESSAGES/",
"gconv/gconv-modules.cache",
"/ld-2.", /* not using dlopen,dlsym during mlock */
- "/libaio.so.", /* not using aio during mlock */
"/libattr.so.", /* not using during mlock (udev) */
"/libblkid.so.", /* not using blkid during mlock (udev) */
"/libbz2.so.", /* not using during mlock (udev) */
--
2.26.2

View File

@ -1,27 +0,0 @@
From 4fd76de4b69f8e5e6d5afa03d54cb4b8986c4bcc Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Wed, 16 Feb 2022 00:48:49 +0100
Subject: clang: possible better compilation with musl c
Try to help resolving reported compilation problem with
clang & musl C.
https://github.com/lvmteam/lvm2/issues/61
---
libdaemon/server/daemon-server.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 88905a7ddd5a..96cfc392e22b 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -18,6 +18,7 @@
#include <dlfcn.h>
#include <errno.h>
+#include <fcntl.h> /* help musl C */
#include <pthread.h>
#include <sys/file.h>
#include <sys/stat.h>
--
2.34.1

View File

@ -0,0 +1,28 @@
From 718e38d5faf3a3ca23690d2f4203df1df65eba77 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Thu, 18 Aug 2022 13:56:03 +0200
Subject: [PATCH] dmsetup: check also for ouf of range value
Check errno result from strtoull().
---
libdm/dm-tools/dmsetup.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libdm/dm-tools/dmsetup.c b/libdm/dm-tools/dmsetup.c
index 8502d9adc170..42eeead68f4d 100644
--- a/libdm/dm-tools/dmsetup.c
+++ b/libdm/dm-tools/dmsetup.c
@@ -5106,8 +5106,9 @@ static int _size_from_string(char *argptr, uint64_t *size, const char *name)
if (!argptr)
return_0;
+ errno = 0;
*size = strtoull(argptr, &endptr, 10);
- if (endptr == argptr) {
+ if (errno || endptr == argptr) {
*size = 0;
log_error("Invalid %s argument: \"%s\"",
name, (*argptr) ? argptr : "");
--
2.26.2

View File

@ -1,26 +0,0 @@
From fa7b67eeebfc28bce355991eebe1b5f21f075e9a Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Fri, 11 Feb 2022 23:55:08 +0100
Subject: dev_manager: do not query for open_count
Oepn count is not used along this code path.
---
lib/activate/dev_manager.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 4d18d9838736..feea06a47e53 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2268,7 +2268,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
return 1;
}
- if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL))
+ if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL))
return_0;
/*
--
2.34.1

View File

@ -0,0 +1,90 @@
From 1a981e9b6efb0bbc0881f5ed1f17900e9c669f48 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Wed, 10 Aug 2022 15:09:34 +0200
Subject: [PATCH] devices: drop double // from sysfs path
dm_sysfs_dir() comes internally as /sys/.
---
lib/device/dev-mpath.c | 4 ++--
lib/device/dev-type.c | 8 ++++----
lib/metadata/vdo_manip.c | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
index 27b0f41a6a8a..2040edac3bb8 100644
--- a/lib/device/dev-mpath.c
+++ b/lib/device/dev-mpath.c
@@ -815,7 +815,7 @@ const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev
/* /sys/dev/block/253:7/slaves/sda/device/wwid */
- if (dm_snprintf(slaves_path, sizeof(slaves_path), "%s/dev/block/%d:%d/slaves",
+ if (dm_snprintf(slaves_path, sizeof(slaves_path), "%sdev/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;
@@ -845,7 +845,7 @@ const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev
/* read /sys/block/sda/device/wwid */
- if (dm_snprintf(wwid_path, sizeof(wwid_path), "%s/block/%s/device/wwid",
+ if (dm_snprintf(wwid_path, sizeof(wwid_path), "%sblock/%s/device/wwid",
dm_sysfs_dir(), slave_name) < 0) {
log_warn("Failed to create sysfs wwid path for %s", slave_name);
continue;
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index 939eb4aeb514..1dc895b54216 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -548,7 +548,7 @@ static int _has_sys_partition(struct device *dev)
int minor = (int) MINOR(dev->dev);
/* check if dev is a partition */
- if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
+ if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/partition",
dm_sysfs_dir(), major, minor) < 0) {
log_warn("WARNING: %s: partition path is too long.", dev_name(dev));
return 0;
@@ -775,7 +775,7 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
* - basename ../../block/md0/md0 = md0
* Parent's 'dev' sysfs attribute = /sys/block/md0/dev
*/
- if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d",
+ if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d",
dm_sysfs_dir(), major, minor) < 0) {
log_warn("WARNING: %s: major:minor sysfs path is too long.", dev_name(dev));
return 0;
@@ -787,7 +787,7 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
temp_path[size] = '\0';
- if (dm_snprintf(path, sizeof(path), "%s/block/%s/dev",
+ if (dm_snprintf(path, sizeof(path), "%sblock/%s/dev",
dm_sysfs_dir(), basename(dirname(temp_path))) < 0) {
log_warn("WARNING: sysfs path for %s is too long.",
basename(dirname(temp_path)));
@@ -1095,7 +1095,7 @@ int wipe_known_signatures(struct cmd_context *cmd, struct device *dev,
static int _snprintf_attr(char *buf, size_t buf_size, const char *sysfs_dir,
const char *attribute, dev_t dev)
{
- if (dm_snprintf(buf, buf_size, "%s/dev/block/%d:%d/%s", sysfs_dir,
+ if (dm_snprintf(buf, buf_size, "%sdev/block/%d:%d/%s", sysfs_dir,
(int)MAJOR(dev), (int)MINOR(dev),
attribute) < 0) {
log_warn("WARNING: sysfs path for %s attribute is too long.", attribute);
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
index 0db401537d7c..779883d03bc3 100644
--- a/lib/metadata/vdo_manip.c
+++ b/lib/metadata/vdo_manip.c
@@ -148,7 +148,7 @@ static int _sysfs_get_kvdo_value(const char *dm_name, const struct dm_info *dmin
char temp[64];
int fd, size, r = 0;
- if (dm_snprintf(path, sizeof(path), "%s/block/dm-%d/vdo/%s",
+ if (dm_snprintf(path, sizeof(path), "%sblock/dm-%d/vdo/%s",
dm_sysfs_dir(), dminfo->minor, vdo_param) < 0) {
log_debug("Failed to build kvdo path.");
return 0;
--
2.26.2

View File

@ -1,55 +0,0 @@
From d4a0816a5824dc375d662e76823ee8ed77bb9983 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Wed, 16 Feb 2022 00:33:32 +0100
Subject: dev_manager: use list info for preset devs
In some cases we can also use cached info obtained from DM_DEVICE_LIST
also to avoid extra ioctl check for present devices.
---
lib/activate/dev_manager.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index feea06a47e53..63bfd9b74b90 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2254,6 +2254,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
{
char *dlid, *name;
struct dm_info info, info2;
+ const struct dm_active_device *dev;
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
return_0;
@@ -2262,15 +2263,20 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
return_0;
if (!dm->cmd->disable_dm_devs &&
- dm->cmd->cache_dm_devs &&
- !dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, NULL)) {
- log_debug("Cached as not present %s.", name);
- return 1;
- }
-
- if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL))
+ dm->cmd->cache_dm_devs) {
+ if (!dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, &dev)) {
+ log_debug("Cached as not present %s.", name);
+ return 1;
+ }
+ info = (struct dm_info) {
+ .exists = 1,
+ .major = dev->major,
+ .minor = dev->minor,
+ };
+ log_debug("Cached as present %s %s (%d:%d).",
+ name, dlid, info.major, info.minor);
+ } else if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL))
return_0;
-
/*
* For top level volumes verify that existing device match
* requested major/minor and that major/minor pair is available for use
--
2.34.1

View File

@ -0,0 +1,66 @@
From 8c3cfc75c72696ae8b620555fcc4f815b0c1d6b6 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 19 Aug 2022 13:31:22 -0500
Subject: [PATCH] devices file: fix pvcreate --uuid matching pvid entry with no
device id
pvcreate with --uuid would segfault if a devices file entry matched
the specified pvid, but the devices file entry had no device_id, which
could happen if the entry has a devname idtype.
---
lib/device/device_id.c | 7 ++++---
test/shell/devicesfile-devname.sh | 13 +++++++++++++
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 9dec9f884da4..6c70f110c820 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1168,8 +1168,9 @@ id_done:
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");
+ log_warn("WARNING: adding device %s with PVID %s which is already used for %s device_id %s.",
+ dev_name(dev), pvid, du_pvid->dev ? dev_name(du_pvid->dev) : "missing device",
+ du_pvid->idname ?: "none");
if (du_devid && (du_devid->dev != dev)) {
if (!du_devid->dev) {
@@ -1215,7 +1216,7 @@ id_done:
else
check_idname = device_id_system_read(cmd, dev, du_pvid->idtype);
- if (check_idname && !strcmp(check_idname, du_pvid->idname)) {
+ if (!du_pvid->idname || (check_idname && !strcmp(check_idname, du_pvid->idname))) {
update_du = du_pvid;
dm_list_del(&update_du->list);
update_matching_kind = "PVID";
diff --git a/test/shell/devicesfile-devname.sh b/test/shell/devicesfile-devname.sh
index 338637275ec5..211f4dbed36b 100644
--- a/test/shell/devicesfile-devname.sh
+++ b/test/shell/devicesfile-devname.sh
@@ -550,6 +550,19 @@ vgchange -an $vg2
vgremove -ff $vg1
vgremove -ff $vg2
+# bz 2119473
+
+aux lvmconf "devices/search_for_devnames = \"none\""
+sed -e "s|DEVNAME=$dev1|DEVNAME=.|" "$ORIG" > tmp1.devices
+sed -e "s|IDNAME=$dev1|IDNAME=.|" tmp1.devices > "$DF"
+pvs
+lvmdevices
+pvcreate -ff --yes --uuid "$PVID1" --norestorefile $dev1
+grep "$PVID1" "$DF" |tee out
+grep "DEVNAME=$dev1" out
+grep "IDNAME=$dev1" out
+aux lvmconf "devices/search_for_devnames = \"auto\""
+
# devnames change so the new devname now refers to a filtered device,
# e.g. an mpath or md component, which is not scanned
--
2.26.2

View File

@ -1,95 +0,0 @@
From ec2119beddde9e38681cb096b93048ee25034c1e Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 16 Feb 2022 15:21:09 -0600
Subject: man lvmcache: add more writecache cachesettings info
---
man/lvmcache.7_main | 51 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 39 insertions(+), 12 deletions(-)
diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main
index 8d7d3d17b766..dddd33cfa02c 100644
--- a/man/lvmcache.7_main
+++ b/man/lvmcache.7_main
@@ -243,15 +243,40 @@ can be used.
.
.SS dm-writecache settings
.
-Tunable parameters can be passed to the dm-writecache kernel module using
-the --cachesettings option when caching is started, e.g.
+To specify dm-writecache tunable settings on the command line, use:
+.br
+--cachesettings 'option=N' or
+.br
+--cachesettings 'option1=N option2=N ...'
+.P
+For example, --cachesettings 'high_watermark=90 writeback_jobs=4'.
+.P
+To include settings when caching is started, run:
.P
.nf
# lvconvert --type writecache --cachevol fast \\
- --cachesettings 'high_watermark=N writeback_jobs=N' vg/main
+ --cachesettings 'option=N' vg/main
+.fi
+.P
+To change settings for an existing writecache, run:
+.P
+.nf
+# lvchange --cachesettings 'option=N' vg/main
+.fi
+.P
+To clear all settings that have been applied, run:
+.P
+.nf
+# lvchange --cachesettings '' vg/main
+.fi
+.P
+To view the settings that are applied to a writecache LV, run:
+.P
+.nf
+# lvs -o cachesettings vg/main
.fi
.P
-Tunable options are:
+Tunable settings are:
.
.TP
high_watermark = <percent>
@@ -301,11 +326,14 @@ writecache. Adding cleaner=0 to the splitcache command will skip the
cleaner mode, and any required flushing is performed in device suspend.
.SS dm-writecache using metadata profiles
-
-Writecache allows to set a variety of options. Lots of these settings
-can be specified in lvm.conf or profile settings. You can prepare
-a number of different profiles in the \fI#DEFAULT_SYS_DIR#/profile\fP directory
-and just specify the metadata profile file name when writecaching LV.
+.
+In addition to specifying writecache settings on the command line, they
+can also be set in lvm.conf, or in a profile file, using the
+allocation/cache_settings/writecache config structure shown below.
+.P
+It's possible to prepare a number of different profile files in the
+\fI#DEFAULT_SYS_DIR#/profile\fP directory and specify the file name
+of the profile when starting writecache.
.P
.I Example
.nf
@@ -327,11 +355,10 @@ writeback_jobs=1024
EOF
.P
-# lvcreate -an -L10G --name wcache vg /dev/fast_ssd
-# lvcreate --type writecache -L10G --name main --cachevol wcache \\
+# lvcreate -an -L10G --name fast vg /dev/fast_ssd
+# lvcreate --type writecache -L10G --name main --cachevol fast \\
--metadataprofile cache_writecache vg /dev/slow_hdd
.fi
-
.
.SS dm-cache with separate data and metadata LVs
.
--
2.34.1

View File

@ -0,0 +1,442 @@
From 3c49a2e43ccfbad720a3134484c7870a14b1135b Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 29 Aug 2022 15:17:36 -0500
Subject: [PATCH] vgimportdevices: change result when devices are not added
When using --all, if one VG is skipped, continue adding
other VGs, and do not return an error from the command
if some VGs are added. (A VG is skipped if it's missing PVs.)
If the command fails during devices file setup or device
scanning, then remove the devices file if it has been
newly created by the command, and exit with an error.
If devices from a named VG are not imported (e.g. the
VG is missing devices), then remove the devices file if
it has been newly created by the command, and exit with
an error.
If --all VGs are being imported, and no devices are found
to include in the devices file, then remove the devices
file if it has been newly created by the command, and
exit with an error.
---
test/shell/vgimportdevices.sh | 308 ++++++++++++++++++++++++++++++++++
tools/vgimportdevices.c | 41 +++--
2 files changed, 336 insertions(+), 13 deletions(-)
create mode 100644 test/shell/vgimportdevices.sh
diff --git a/test/shell/vgimportdevices.sh b/test/shell/vgimportdevices.sh
new file mode 100644
index 000000000000..47363cec350a
--- /dev/null
+++ b/test/shell/vgimportdevices.sh
@@ -0,0 +1,308 @@
+
+#!/usr/bin/env bash
+
+# Copyright (C) 2020 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='vgimportdevices'
+
+. lib/inittest
+
+aux prepare_devs 5
+
+DFDIR="$LVM_SYSTEM_DIR/devices"
+mkdir "$DFDIR" || true
+DF="$DFDIR/system.devices"
+
+aux lvmconf 'devices/use_devicesfile = 1'
+
+not ls "$DF"
+pvcreate "$dev1"
+ls "$DF"
+grep "$dev1" "$DF"
+rm -f "$DF"
+dd if=/dev/zero of="$dev1" bs=1M count=1
+
+#
+# vgimportdevices -a with no prev df
+#
+
+# no devs found
+not vgimportdevices -a
+not ls "$DF"
+
+# one orphan pv, no vgs
+pvcreate "$dev1"
+rm -f "$DF"
+not vgimportdevices -a
+not ls "$DF"
+
+# one complete vg
+vgcreate $vg1 "$dev1"
+rm -f "$DF"
+vgimportdevices -a
+ls "$DF"
+grep "$dev1" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+rm -f "$DF"
+
+# two complete vgs
+vgcreate $vg1 "$dev1"
+vgcreate $vg2 "$dev2"
+rm -f "$DF"
+vgimportdevices -a
+ls "$DF"
+grep "$dev1" "$DF"
+grep "$dev2" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+rm -f "$DF"
+
+# one incomplete vg
+vgcreate $vg1 "$dev1" "$dev2"
+lvcreate -l1 -an $vg1
+rm -f "$DF"
+dd if=/dev/zero of="$dev1" bs=1M count=1
+not vgimportdevices -a
+not ls "$DF"
+vgs $vg1
+pvs "$dev2"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+rm -f "$DF"
+
+# three complete, one incomplete vg
+vgcreate $vg1 "$dev1"
+vgcreate $vg2 "$dev2"
+vgcreate $vg3 "$dev3"
+vgcreate $vg4 "$dev4" "$dev5"
+rm -f "$DF"
+dd if=/dev/zero of="$dev5" bs=1M count=1
+vgimportdevices -a
+ls "$DF"
+grep "$dev1" "$DF"
+grep "$dev2" "$DF"
+grep "$dev3" "$DF"
+not grep "$dev4" "$DF"
+not grep "$dev5" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+dd if=/dev/zero of="$dev3" bs=1M count=1
+dd if=/dev/zero of="$dev4" bs=1M count=1
+rm -f "$DF"
+
+
+#
+# vgimportdevices -a with existing df
+#
+
+# no devs found
+vgcreate $vg1 "$dev1"
+grep "$dev1" "$DF"
+dd if=/dev/zero of="$dev1" bs=1M count=1
+not vgimportdevices -a
+ls "$DF"
+
+# one complete vg
+vgcreate $vg1 "$dev1"
+vgimportdevices -a
+grep "$dev1" "$DF"
+vgcreate --devicesfile "" $vg2 "$dev2"
+not grep "$dev2" "$DF"
+vgimportdevices -a
+grep "$dev1" "$DF"
+grep "$dev2" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+rm -f "$DF"
+
+# two complete vgs
+vgcreate --devicesfile "" $vg1 "$dev1"
+vgcreate --devicesfile "" $vg2 "$dev2"
+rm -f "$DF"
+vgimportdevices -a
+ls "$DF"
+grep "$dev1" "$DF"
+grep "$dev2" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+rm -f "$DF"
+
+# one incomplete vg
+vgcreate $vg1 "$dev1"
+vgimportdevices -a
+grep "$dev1" "$DF"
+dd if=/dev/zero of="$dev1" bs=1M count=1
+vgcreate --devicesfile "" $vg2 "$dev2" "$dev3"
+not grep "$dev2" "$DF"
+not grep "$dev3" "$DF"
+dd if=/dev/zero of="$dev2" bs=1M count=1
+not vgimportdevices -a
+ls "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+dd if=/dev/zero of="$dev3" bs=1M count=1
+rm -f "$DF"
+
+# import the same vg again
+vgcreate --devicesfile "" $vg1 "$dev1"
+not ls "$DF"
+vgimportdevices -a
+ls "$DF"
+grep "$dev1" "$DF"
+vgimportdevices -a
+ls "$DF"
+grep "$dev1" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+rm -f "$DF"
+
+# import a series of vgs
+vgcreate --devicesfile "" $vg1 "$dev1"
+vgimportdevices -a
+grep "$dev1" "$DF"
+vgcreate --devicesfile "" $vg2 "$dev2"
+vgimportdevices -a
+grep "$dev1" "$DF"
+grep "$dev2" "$DF"
+vgcreate --devicesfile "" $vg3 "$dev3"
+vgimportdevices -a
+grep "$dev1" "$DF"
+grep "$dev2" "$DF"
+grep "$dev3" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+dd if=/dev/zero of="$dev3" bs=1M count=1
+rm -f "$DF"
+
+#
+# vgimportdevices vg with no prev df
+#
+
+# no devs found
+not vgimportdevices $vg1
+not ls "$DF"
+
+# one complete vg
+vgcreate $vg1 "$dev1"
+rm -f "$DF"
+vgimportdevices $vg1
+ls "$DF"
+grep "$dev1" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+rm -f "$DF"
+
+# two complete vgs
+vgcreate $vg1 "$dev1"
+vgcreate $vg2 "$dev2"
+rm -f "$DF"
+vgimportdevices $vg1
+ls "$DF"
+grep "$dev1" "$DF"
+vgimportdevices $vg2
+ls "$DF"
+grep "$dev2" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+rm -f "$DF"
+
+# one incomplete vg
+vgcreate $vg1 "$dev1" "$dev2"
+lvcreate -l1 -an $vg1
+rm -f "$DF"
+dd if=/dev/zero of="$dev1" bs=1M count=1
+not vgimportdevices $vg1
+not ls "$DF"
+vgs $vg1
+pvs "$dev2"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+rm -f "$DF"
+
+# three complete, one incomplete vg
+vgcreate $vg1 "$dev1"
+vgcreate $vg2 "$dev2"
+vgcreate $vg3 "$dev3"
+vgcreate $vg4 "$dev4" "$dev5"
+rm -f "$DF"
+dd if=/dev/zero of="$dev5" bs=1M count=1
+not vgimportdevices $vg4
+not ls "$DF"
+vgimportdevices $vg3
+ls "$DF"
+grep "$dev3" "$DF"
+not grep "$dev1" "$DF"
+not grep "$dev2" "$DF"
+not grep "$dev4" "$DF"
+not grep "$dev5" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+dd if=/dev/zero of="$dev3" bs=1M count=1
+dd if=/dev/zero of="$dev4" bs=1M count=1
+rm -f "$DF"
+
+#
+# vgimportdevices vg with existing df
+#
+
+# vg not found
+vgcreate $vg1 "$dev1"
+vgimportdevices -a
+grep "$dev1" "$DF"
+not vgimportdevices $vg2
+grep "$dev1" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+rm -f "$DF"
+
+# vg incomplete
+vgcreate $vg1 "$dev1"
+vgimportdevices -a
+grep "$dev1" "$DF"
+vgcreate --devicesfile "" $vg2 "$dev2" "$dev3"
+dd if=/dev/zero of="$dev2" bs=1M count=1
+not vgimportdevices $vg2
+grep "$dev1" "$DF"
+not grep "$dev2" "$DF"
+not grep "$dev3" "$DF"
+
+# reset
+dd if=/dev/zero of="$dev1" bs=1M count=1
+dd if=/dev/zero of="$dev2" bs=1M count=1
+dd if=/dev/zero of="$dev3" bs=1M count=1
+dd if=/dev/zero of="$dev4" bs=1M count=1
+rm -f "$DF"
+
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
index ea205d941073..9ade1b9e4b21 100644
--- a/tools/vgimportdevices.c
+++ b/tools/vgimportdevices.c
@@ -36,9 +36,9 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
dm_list_iterate_items(pvl, &vg->pvs) {
if (is_missing_pv(pvl->pv) || !pvl->pv->dev) {
memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
- log_error("Not importing devices for VG %s with missing PV %s.",
- vg->name, pvid);
- goto bad;
+ log_print("Not importing devices for VG %s with missing PV %s.",
+ vg->name, pvid);
+ return ECMD_PROCESSED;
}
}
@@ -71,14 +71,17 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
updated_pvs++;
}
+ /*
+ * Writes the device_id of each PV into the vg metadata.
+ * This is not a critial step and should not influence
+ * the result of the command.
+ */
if (updated_pvs) {
if (!vg_write(vg) || !vg_commit(vg))
- goto_bad;
+ log_print("Failed to write device ids in VG metadata.");
}
return ECMD_PROCESSED;
-bad:
- return ECMD_FAILED;
}
/*
@@ -114,6 +117,7 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
{
struct vgimportdevices_params vp = { 0 };
struct processing_handle *handle;
+ int created_file = 0;
int ret = ECMD_FAILED;
if (arg_is_set(cmd, foreign_ARG))
@@ -139,9 +143,12 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
log_error("Devices file not enabled.");
return ECMD_FAILED;
}
- if (!devices_file_exists(cmd) && !devices_file_touch(cmd)) {
- log_error("Failed to create devices file.");
- return ECMD_FAILED;
+ if (!devices_file_exists(cmd)) {
+ if (!devices_file_touch(cmd)) {
+ log_error("Failed to create devices file.");
+ return ECMD_FAILED;
+ }
+ created_file = 1;
}
/*
@@ -195,22 +202,30 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
*/
ret = process_each_vg(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE,
0, handle, _vgimportdevices_single);
- if (ret == ECMD_FAILED)
- goto out;
+ if (ret == ECMD_FAILED) {
+ /*
+ * Error from setting up devices file or label_scan,
+ * _vgimportdevices_single does not return an error.
+ */
+ goto_out;
+ }
if (!vp.added_devices) {
- log_print("No devices to add.");
+ log_error("No devices to add.");
+ ret = ECMD_FAILED;
goto out;
}
if (!device_ids_write(cmd)) {
- log_print("Failed to update devices file.");
+ log_error("Failed to write the devices file.");
ret = ECMD_FAILED;
goto out;
}
log_print("Added %u devices to devices file.", vp.added_devices);
out:
+ if ((ret == ECMD_FAILED) && created_file)
+ unlink(cmd->devices_file_path);
destroy_processing_handle(cmd, handle);
return ret;
}
--
2.26.2

View File

@ -1,37 +0,0 @@
From 96c99d647ef783abcd26a1f3f63f12e033195633 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 16 Feb 2022 15:36:44 -0600
Subject: man: update cachesettings option description
to be more consistent with man page description
---
tools/args.h | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/tools/args.h b/tools/args.h
index 3f4580b8d9eb..56669645d2a1 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -862,12 +862,13 @@ arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0,
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0,
- "Specifies tunable values for a cache LV in \"Key = Value\" form.\n"
- "Repeat this option to specify multiple values.\n"
- "(The default values should usually be adequate.)\n"
- "The special string value \\fBdefault\\fP switches\n"
- "settings back to their default kernel values and removes\n"
- "them from the list of settings stored in LVM metadata.\n"
+ "Specifies tunable kernel options for dm-cache or dm-writecache LVs.\n"
+ "Use the form 'option=value' or 'option1=value option2=value', or\n"
+ "repeat --cachesettings for each option being set.\n"
+ "These settings override the default kernel behaviors which are\n"
+ "usually adequate. To remove cachesettings and revert to the default\n"
+ "kernel behaviors, use --cachesettings 'default' for dm-cache or\n"
+ "an empty string --cachesettings '' for dm-writecache.\n"
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0,
--
2.34.1

View File

@ -0,0 +1,76 @@
From 0eebd9d7802c724ee71b6ebb80940ea6007f9c7a Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 30 Aug 2022 14:40:48 -0500
Subject: [PATCH] vgimportdevices: fix locking when creating devices file
Take the devices file lock before creating a new devices file.
(Was missed by the change to preemptively create the devices
file prior to setup_devices(), which was done to improve the
error path.)
---
lib/device/dev-cache.c | 7 +++----
lib/device/device_id.c | 1 +
tools/vgimportdevices.c | 10 ++++++++--
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 193eb7585f45..85f9b499af4d 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1937,10 +1937,9 @@ int setup_devices(struct cmd_context *cmd)
if (!file_exists) {
/*
- * pvcreate/vgcreate/vgimportdevices/lvmdevices-add create
- * a new devices file here if it doesn't exist.
- * They have the create_edit_devices_file flag set.
- * First they create/lock-ex the devices file lockfile.
+ * pvcreate/vgcreate create a new devices file here if it
+ * doesn't exist. They have create_edit_devices_file=1.
+ * First create/lock-ex the devices file lockfile.
* Other commands will not use a devices file if none exists.
*/
lock_mode = LOCK_EX;
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 6c70f110c820..a0a6265336ed 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -2468,6 +2468,7 @@ static int _lock_devices_file(struct cmd_context *cmd, int mode, int nonblock, i
if (_devices_file_locked == mode) {
/* can happen when a command holds an ex lock and does an update in device_ids_validate */
+ /* can happen when vgimportdevices calls this directly, followed later by setup_devices */
if (held)
*held = 1;
return 1;
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
index 9ade1b9e4b21..23c2718ffe0f 100644
--- a/tools/vgimportdevices.c
+++ b/tools/vgimportdevices.c
@@ -132,8 +132,10 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
/*
- * Prepare devices file preemptively because the error path for this
- * case from process_each is not as clean.
+ * Prepare/create devices file preemptively because the error path for
+ * this case from process_each/setup_devices is not as clean.
+ * This means that when setup_devices is called, it the devices
+ * file steps will be redundant, and need to handle being repeated.
*/
if (!setup_devices_file(cmd)) {
log_error("Failed to set up devices file.");
@@ -143,6 +145,10 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
log_error("Devices file not enabled.");
return ECMD_FAILED;
}
+ if (!lock_devices_file(cmd, LOCK_EX)) {
+ log_error("Failed to lock the devices file.");
+ return ECMD_FAILED;
+ }
if (!devices_file_exists(cmd)) {
if (!devices_file_touch(cmd)) {
log_error("Failed to create devices file.");
--
2.26.2

View File

@ -1,35 +0,0 @@
From 6144dac897728a4857294d70645df8ed7a5ff11f Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 21 Feb 2022 11:35:58 -0600
Subject: 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 dddd33cfa02c..ce440bf49983 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.1

View File

@ -1,102 +0,0 @@
From ac1f4bbbfd4c5f1387c3e0607f7d556409e7a4b4 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 21 Feb 2022 16:09:57 -0600
Subject: 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 12b78b766f15..7e450dacef66 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 12ea890f4b09..6f302360f5d0 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 60df417a40f5..c06b22674f21 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 ce440bf49983..8b8289c74ac7 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 2579ef7b7bac..4e17effe5f1f 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.1

View File

@ -1,134 +0,0 @@
From 1126be8f8dbce482e82d8f98a7e7f4b7cd2cac34 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 24 Feb 2022 15:57:29 -0600
Subject: 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 | 6 ++---
3 files changed, 9 insertions(+), 59 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index d3fae494869d..1777628a81a0 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 449bfeb7511c..a88e3c282207 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 fe2bc8fec743..66d6e7db7a6e 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1134,7 +1134,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
dm_list_iterate_items(po, &pvs_online) {
if (po->dev)
continue;
- if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno, NULL, NULL))) {
+ if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno))) {
log_error("No device found for %d:%d PVID %s",
(int)MAJOR(po->devno), (int)MINOR(po->devno), po->pvid);
goto bad;
@@ -1722,7 +1722,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);
}
}
@@ -1742,7 +1742,7 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
if (dm_dev->uuid &&
strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) {
devt = MKDEV(dm_dev->major, dm_dev->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);
}
/* ATM no further caching for any lvconvert command
--
2.34.1

View File

@ -1,467 +0,0 @@
From 7e70041e324e1a4d49134a93323072e1b6ec661f Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 24 Feb 2022 16:03:21 -0600
Subject: 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 1777628a81a0..8db28bd84a01 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 a88e3c282207..622335982a10 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 b4f1930b1605..811ad897851b 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 8c3a8c30e086..572994bb9f14 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.1

View File

@ -1,70 +0,0 @@
From 00c3069872ab488f66f14c8c2727bd080affc05e Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 24 Feb 2022 16:10:37 -0600
Subject: 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 003f10a96641..c8df47345e72 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1577,7 +1577,7 @@ void device_ids_match_device_list(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? */
@@ -1625,7 +1625,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 b08c044fab7c..897adec347ae 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1488,7 +1488,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;
@@ -3925,7 +3925,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 {
@@ -5261,7 +5261,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.1

View File

@ -1,291 +0,0 @@
From 4eb04c8c05e52776891f62863375ceacf866de77 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 22 Feb 2022 15:03:11 -0600
Subject: 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 | 23 ++++++++++++++++++++++-
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, 75 insertions(+), 8 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 63bfd9b74b90..2cae3bed1fde 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2947,6 +2947,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 ||
@@ -2965,7 +2969,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 0e77a009d072..c67a86fa33f6 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 c8df47345e72..7ce955b11c8d 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;
@@ -955,6 +957,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
@@ -1842,6 +1848,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));
@@ -2225,14 +2234,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 35ae7f5cc8df..edce6f517133 100644
--- a/lib/label/hints.c
+++ b/lib/label/hints.c
@@ -500,6 +500,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 66d6e7db7a6e..ffb39389188a 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1130,6 +1130,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
* sure to find the device.
*/
if (try_dev_scan) {
+ log_debug("Repeat dev cache scan to translate devnos.");
dev_cache_scan(cmd);
dm_list_iterate_items(po, &pvs_online) {
if (po->dev)
@@ -1736,6 +1737,12 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
struct lv_list *lvl;
dev_t devt;
+ /*
+ * FIXME: this is all unnecessary unless there are PVs stacked on LVs,
+ * so we can skip all of this if scan_lvs=0.
+ */
+ log_debug("invalidating devs for any pvs on lvs");
+
if (get_device_list(NULL, &devs, &devs_features)) {
if (devs_features & DM_DEVICE_LIST_HAS_UUID) {
dm_list_iterate_items(dm_dev, devs)
@@ -1879,10 +1886,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 */
@@ -1912,7 +1933,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 b598df3d6b79..60c80f1b1e5c 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 e2bf191a1ef0..46da57948f00 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 813e8e525052..fc3667db0a9a 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 85482552aefe..adc954babe67 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 99f552ad1268..670568945953 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.1

View File

@ -1,272 +0,0 @@
From 7b1a857d5ac480b789af07d85e55bc87c6a76934 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 28 Feb 2022 17:37:12 -0600
Subject: [PATCH 1/3] 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 8db28bd84a01..5607beefc40f 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 622335982a10..46b1da72c1ad 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 ffb39389188a..c208638757af 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -459,7 +459,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;
@@ -479,14 +478,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);
@@ -514,50 +522,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;
@@ -605,37 +597,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)
@@ -663,10 +624,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;
@@ -677,7 +636,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));
@@ -701,9 +659,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;
}
@@ -787,41 +745,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.1

View File

@ -1,31 +0,0 @@
From cc73d99886dfd6e0da3c6ca685669f77fac3c1cd Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 1 Mar 2022 12:22:46 -0600
Subject: [PATCH 2/3] devices: only close PVs on LVs when scan_lvs is enabled
This code is only needed when lvm scans PVs that are stacked on LVs.
---
lib/label/label.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/label/label.c b/lib/label/label.c
index c208638757af..e6bc791a78ff 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1661,9 +1661,11 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
dev_t devt;
/*
- * FIXME: this is all unnecessary unless there are PVs stacked on LVs,
- * so we can skip all of this if scan_lvs=0.
+ * This is only needed when the command sees PVs stacked on LVs which
+ * will only happen with scan_lvs=1.
*/
+ if (!cmd->scan_lvs)
+ return;
log_debug("invalidating devs for any pvs on lvs");
if (get_device_list(NULL, &devs, &devs_features)) {
--
2.34.1

View File

@ -1,101 +0,0 @@
From bef1363c0064f42e8063571143a428ad163d1bd9 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 1 Mar 2022 14:31:39 -0600
Subject: [PATCH 3/3] 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 a3eb60b20006..1c4351e9d481 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -6070,6 +6070,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)
@@ -6158,6 +6221,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.1

View File

@ -1,35 +0,0 @@
From c7a5b5cca067496f5912bf992dcfedb6771dd083 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 9 Mar 2022 11:54:59 -0600
Subject: [PATCH] pvscan: don't use udev for external device info
pvscan is used to populate udev info, so it can't expect
to use that udev info.
---
tools/pvscan.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index dcf183a464d9..db6709a5a23a 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -1710,13 +1710,11 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
}
/*
- * If obtain_device_list_from_udev was set to 1, force it to 0.
- * Don't ask udev for info since pvscan is running from udev.
- * If a pvscan attempts to get dev info from udev, udev can
- * repeatedly return errors about the dev not being initialized
- * which will stall the pvscan.
+ * Do not use udev for device listing or device info because pvscan
+ * is used to populate udev info.
*/
init_obtain_device_list_from_udev(0);
+ init_external_device_info_source(DEV_EXT_NONE);
if (arg_is_set(cmd, major_ARG) + arg_is_set(cmd, minor_ARG))
devno_args = 1;
--
2.34.1

View File

@ -1,36 +0,0 @@
From 72f0b637d239c893ca49b05b83e2ebddc327e900 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 25 Mar 2022 14:13:56 -0500
Subject: [PATCH] vgchange monitor: don't use udev info
vgchange --monitor y is run during startup when udev is being
initialized and is not yet ready to be used.
---
tools/vgchange.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tools/vgchange.c b/tools/vgchange.c
index fc076c1d56ba..09ade96a60e6 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -992,6 +992,17 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
return ECMD_PROCESSED;
}
+ /*
+ * Do not use udev for device listing or device info because
+ * vgchange --monitor y is called during boot when udev is being
+ * initialized and is not yet ready to be used.
+ */
+ if (arg_is_set(cmd, monitor_ARG) &&
+ arg_int_value(cmd, monitor_ARG, DEFAULT_DMEVENTD_MONITOR)) {
+ init_obtain_device_list_from_udev(0);
+ init_external_device_info_source(DEV_EXT_NONE);
+ }
+
if (update)
flags |= READ_FOR_UPDATE;
else if (arg_is_set(cmd, activate_ARG))
--
2.34.1

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:935283a51ee17abd752a545a0ed1cf4edc993359265bc9e562edf81500edc99e
size 2651598

View File

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE1QGkeEQK4v0TChvouREkMeUJA58FAmIBUeQACgkQuREkMeUJ
A58DthAA16VW+k8lVVAkX+PfcpqVgvO9M4Rhj4qPAcmwKX2z8wMo5hYnrsG3cQDg
NIbtlD05FZuFFMA7GFBdV+LtHCRF6lCe2LbuSsRWmbxz8Z8yn/h801d4Fp/SaZpm
2Itq0Ve6HLysNqA9P6Yl6YE7U6hWnR6PxoS4jl1C5ttpOlmgDHcIM5xl8Dn3PQbZ
S6ujlWl4OX+E0bG5Qg5iwpUcfZMboJ7VGGCKmXzO0Z/7ABw4Os9dgApHGFlHEsKm
XBmeKT77AQxgozPefiqve1CHFNZG8HmSyMhhstUFNl1qMvxGD3CAObdHIiGT1uQL
z6HrxANZ+5EU+sGgCtJtSBfxzPP3s8RPhUiN0WD3rgkJdshc2qBXsOfkNEUKycnq
wCZtJdh6CPsSEfRv83TrGKTKiNT4DyIzPLBh+goV5SpMc/e1kijv6uUMRwEFGb5Y
LZsMRrO8GmwhkkdIDWhdvhGtzJVhd6n80fNPuQTDm7Rp+1+fhgnV6teRNXxO9aWC
eKeZkpaj0/fjpbDc9o+y5DGpvXdbY4KfNx6nGUGEPsqnTYBnq3Ud/V1fZuaOC2AV
iZK4bXXVQoFVkLGnl3sHx2SQInuui0nDo4i2nIwI2rqIMNClb59hAotDEYdlCQc7
GlAnvWBqrJFjPhVYj8x933lbOyie5GO4qSTI7n0O72c80f8dcbY=
=EPS0
-----END PGP SIGNATURE-----

3
LVM2.2.03.16.tgz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e661ece15b5d88d8abe39a4c1e1db2f43e1896f019948bb98b0e15d777680786
size 2658805

16
LVM2.2.03.16.tgz.asc Normal file
View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE1QGkeEQK4v0TChvouREkMeUJA58FAmKFHcYACgkQuREkMeUJ
A58CdQ//UthHUyGSHS2LiNKPhpr4vKuxstwlOclxHjvardZ1QW7ry5Ype5Elrnfb
GVot/9oZPzoYzuHaMp6E8rRTfdsmiuSU9mQ3sTDAzPcuB9QbiZUW9oTCLfACTRqK
bP8XdKVE/sJgllUFz93kQke69GntBuvrvXFzUF4yMSSRwvWMtZ4jTs2KSfCdFJUB
3r4d9ynxTdcskexYQ0fnXubl5FRokKlmi7k5G0n2BnI/eqMMMsJg8lGYiw7kmkPc
7cqE9FJzVhzEv3rLYz0+gc7/6JymAJAJcUD5jaToI3eyA6KhqauH03HZhc5JDtxL
nthpURhCETDp/St/DsXWffVCKXBKq5TIa44Hh/n1TgFKVvgshEwOCWMmsh4P1MKI
ilvwkjmpzGbVOAgFUIJnMPOpg5aQ8jatFDbzcFwUXpIXdfSS+0ghMyc4Vihh1sa0
wAM7hYSvzjYAXPb+UjRrwRunmU36SgvUpg8ZI8ZxvFgLw57IAxqlx41MbQjtPg4B
3hI/ibtiWckVwROmga1daeLe696h4lrXjRCjj85EG8FsAuZpUikuSf1ym/3uF0aP
142Dd8lvWjfjl9nXDU8cl3Ke7JFfEtQUplswaaIpwKXv37dlwyfaCrgR/laLTs4V
xLh50C5Hxr1RPQwt1qPzM6tNYS+R3O8B56iWzcF8WIBiOOG5XWc=
=HIKn
-----END PGP SIGNATURE-----

View File

@ -1,3 +1,69 @@
-------------------------------------------------------------------
Thu Sep 1 02:50:00 UTC 2022 - Heming Zhao <heming.zhao@suse.com>
- Update lvm2 from LVM2.2.03.15 to LVM2.2.03.16
*** WHATS_NEW for 2.03.16 ***
Version 2.03.16 - 18th May 2022
===============================
Fix segfault when handling selection with historical LVs.
Add support --vdosettings with lvcreate, lvconvert, lvchange.
Filtering multipath devices respects blacklist setting from multipath configuration.
lvmdevices support for removing by device id using --deviceidtype and --deldev.
Display writecache block size with lvs -o writecache_block_size.
Improve cachesettings description in man lvmcache.
Fix lossing of delete message on thin-pool extension.
- Drop patches that have been merged into upstream
- 0001-post-release.patch
- 0002-asan-fix-some-reports-from-libasan.patch
- 0003-make-generate.patch
- 0004-tests-udev-pvscan-vgchange-fix-service-wait.patch
- 0005-devices-file-do-not-clear-PVID-of-unread-devices.patch
- 0006-tests-skip-vgchange-pvs-online.sh-on-rhel5.patch
- 0007-dev_manager-fix-dm_task_get_device_list.patch
- 0008-dev_manager-failing-status-is-not-internal-error.patch
- 0009-clang-add-extra-check.patch
- 0010-clang-possible-better-compilation-with-musl-c.patch
- 0011-dev_manager-do-not-query-for-open_count.patch
- 0012-dev_manager-use-list-info-for-preset-devs.patch
- 0013-man-lvmcache-add-more-writecache-cachesettings-info.patch
- 0014-man-update-cachesettings-option-description.patch
- 0015-man-lvmcache-mention-writecache-memory-usage.patch
- 0016-writecache-display-block-size-from-lvs.patch
- 0017-devices-simplify-dev_cache_get_by_devt.patch
- 0018-devices-drop-incorrect-paths-from-aliases-list.patch
- 0019-devices-initial-use-of-existing-option.patch
- 0020-devices-fix-dev_name-assumptions.patch
- 0021-devices-use-dev-cache-aliases-handling-from-label-sc.patch
- 0022-devices-only-close-PVs-on-LVs-when-scan_lvs-is-enabl.patch
- 0023-writecache-check-memory-usage.patch
- 0024-pvscan-don-t-use-udev-for-external-device-info.patch
- 0025-vgchange-monitor-don-t-use-udev-info.patch
- Add upstream patch
- 0001-devices-file-move-clean-up-after-command-is-run.patch
- 0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch
- 0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch
- 0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch
- 0005-pvdisplay-restore-reportformat-option.patch
- 0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch
- 0007-report-fix-pe_start-column-type-from-NUM-to-SIZ.patch
- 0008-_vg_read_raw_area-fix-segfault-caused-by-using-null-.patch
- 0009-mm-remove-libaio-from-being-skipped.patch
- 0010-dmsetup-check-also-for-ouf-of-range-value.patch
- 0011-devices-drop-double-from-sysfs-path.patch
- 0012-devices-file-fix-pvcreate-uuid-matching-pvid-entry-w.patch
- 0013-vgimportdevices-change-result-when-devices-are-not-a.patch
- 0014-vgimportdevices-fix-locking-when-creating-devices-fi.patch
- update lvm2.spec
- indent some lines for easy read
- remove config item '--enable-cmirrord'
- add new man lvm_import_vdo.8
- add new man dmfilemapd.8
-------------------------------------------------------------------
Wed Mar 30 10:11:00 UTC 2022 - Heming Zhao <heming.zhao@suse.com>

273
lvm2.spec
View File

@ -21,7 +21,7 @@
%define libname_event libdevmapper-event1_03
%define _udevdir %(pkg-config --variable=udevdir udev)
%define cmdlib liblvm2cmd2_03
%define lvm2_version 2.03.15
%define lvm2_version 2.03.16
%define device_mapper_version 1.02.185
%define thin_provisioning_version 0.7.0
%define _supportsanlock 0
@ -32,23 +32,28 @@
%define lvm2_cmirrord_version 2.03
%define liblvm2app2_2_version 2.03
%define liblvm2cmd2_02_version 2.03
%if 0%{_supportsanlock} == 1
%define sanlock_version 3.3.0
%define sanlock_version 3.3.0
%endif
%global flavor @BUILD_FLAVOR@%{nil}
%define psuffix %{nil}
%if "%{flavor}" == "devicemapper"
%define psuffix -device-mapper
%bcond_without devicemapper
%define psuffix -device-mapper
%bcond_without devicemapper
%else
%bcond_with devicemapper
%bcond_with devicemapper
%endif
%if "%{flavor}" == "lockd"
%define psuffix -lvmlockd
%bcond_without lockd
%define psuffix -lvmlockd
%bcond_without lockd
%else
%bcond_with lockd
%bcond_with lockd
%endif
Name: lvm2%{psuffix}
Version: %{lvm2_version}
Release: 0
@ -63,31 +68,20 @@ Source42: ftp://sourceware.org/pub/lvm2/LVM2.%{version}.tgz.asc
Source99: baselibs.conf
# Upstream patches
Patch0001: 0001-post-release.patch
Patch0002: 0002-asan-fix-some-reports-from-libasan.patch
Patch0003: 0003-make-generate.patch
Patch0004: 0004-tests-udev-pvscan-vgchange-fix-service-wait.patch
Patch0005: 0005-devices-file-do-not-clear-PVID-of-unread-devices.patch
Patch0006: 0006-tests-skip-vgchange-pvs-online.sh-on-rhel5.patch
Patch0007: 0007-dev_manager-fix-dm_task_get_device_list.patch
Patch0008: 0008-dev_manager-failing-status-is-not-internal-error.patch
Patch0009: 0009-clang-add-extra-check.patch
Patch0010: 0010-clang-possible-better-compilation-with-musl-c.patch
Patch0011: 0011-dev_manager-do-not-query-for-open_count.patch
Patch0012: 0012-dev_manager-use-list-info-for-preset-devs.patch
Patch0013: 0013-man-lvmcache-add-more-writecache-cachesettings-info.patch
Patch0014: 0014-man-update-cachesettings-option-description.patch
Patch0015: 0015-man-lvmcache-mention-writecache-memory-usage.patch
Patch0016: 0016-writecache-display-block-size-from-lvs.patch
Patch0017: 0017-devices-simplify-dev_cache_get_by_devt.patch
Patch0018: 0018-devices-drop-incorrect-paths-from-aliases-list.patch
Patch0019: 0019-devices-initial-use-of-existing-option.patch
Patch0020: 0020-devices-fix-dev_name-assumptions.patch
Patch0021: 0021-devices-use-dev-cache-aliases-handling-from-label-sc.patch
Patch0022: 0022-devices-only-close-PVs-on-LVs-when-scan_lvs-is-enabl.patch
Patch0023: 0023-writecache-check-memory-usage.patch
Patch0024: 0024-pvscan-don-t-use-udev-for-external-device-info.patch
Patch0025: 0025-vgchange-monitor-don-t-use-udev-info.patch
Patch0001: 0001-devices-file-move-clean-up-after-command-is-run.patch
Patch0002: 0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch
Patch0003: 0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch
Patch0004: 0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch
Patch0005: 0005-pvdisplay-restore-reportformat-option.patch
Patch0006: 0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch
Patch0007: 0007-report-fix-pe_start-column-type-from-NUM-to-SIZ.patch
Patch0008: 0008-_vg_read_raw_area-fix-segfault-caused-by-using-null-.patch
Patch0009: 0009-mm-remove-libaio-from-being-skipped.patch
Patch0010: 0010-dmsetup-check-also-for-ouf-of-range-value.patch
Patch0011: 0011-devices-drop-double-from-sysfs-path.patch
Patch0012: 0012-devices-file-fix-pvcreate-uuid-matching-pvid-entry-w.patch
Patch0013: 0013-vgimportdevices-change-result-when-devices-are-not-a.patch
Patch0014: 0014-vgimportdevices-fix-locking-when-creating-devices-fi.patch
# SUSE patches: 1000+ for LVM
# Never upstream
Patch1001: cmirrord_remove_date_time_from_compilation.patch
@ -117,6 +111,7 @@ Requires(postun):coreutils
Provides: lvm = %{version}
Obsoletes: lvm2-cmirrord <= %{lvm2_cmirrord_version}
%{?systemd_requires}
%if %{with devicemapper}
BuildRequires: gcc-c++
BuildRequires: suse-module-tools
@ -161,17 +156,6 @@ Volume Manager.
%patch0012 -p1
%patch0013 -p1
%patch0014 -p1
%patch0015 -p1
%patch0016 -p1
%patch0017 -p1
%patch0018 -p1
%patch0019 -p1
%patch0020 -p1
%patch0021 -p1
%patch0022 -p1
%patch0023 -p1
%patch0024 -p1
%patch0025 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
@ -197,13 +181,13 @@ extra_opts="
--with-default-locking-dir=/run/lock/lvm
--with-default-pid-dir=/run
--with-default-run-dir=/run/lvm
--enable-cmirrord
--enable-fsadm
--enable-write_install
--with-vdo=internal
--with-vdo-format=%{_bindir}/vdoformat
"
%endif
%if %{with lockd}
extra_opts="
--enable-blkid_wiping
@ -246,120 +230,128 @@ sed -ie "s/%{device_mapper_version}/1.03.01/g" VERSION_DM
--with-thin-dump=%{_sbindir}/thin_dump \
--with-thin-repair=%{_sbindir}/thin_repair \
--with-integrity=internal \
--disable-silent-rules \
$extra_opts
### COMMON-CONFIG-END ###
%if %{with devicemapper}
%make_build device-mapper
%make_build device-mapper
%else
%make_build
%make_build
%endif
%install
%if %{with devicemapper}
make DESTDIR=%{buildroot} \
install_device-mapper \
install_systemd_units
make DESTDIR=%{buildroot} \
install_device-mapper \
install_systemd_units
ln -s service %{buildroot}/%{_sbindir}/rcdm-event
ln -s service %{buildroot}/%{_sbindir}/rcdm-event
# provide 1.02 compat links for the shared libraries
# this is needed for various binary packages
ln -s libdevmapper.so.1.03 %{buildroot}/%{_libdir}/libdevmapper.so.1.02
ln -s libdevmapper-event.so.1.03 %{buildroot}/%{_libdir}/libdevmapper-event.so.1.02
# provide 1.02 compat links for the shared libraries
# this is needed for various binary packages
ln -s libdevmapper.so.1.03 %{buildroot}/%{_libdir}/libdevmapper.so.1.02
ln -s libdevmapper-event.so.1.03 %{buildroot}/%{_libdir}/libdevmapper-event.so.1.02
# remove blkd, will be in lvm2 proper
# without force on purpose to detect changes and fail if it happens
rm %{buildroot}%{_sbindir}/blkdeactivate
rm %{buildroot}%{_unitdir}/blk-availability.service
rm %{buildroot}%{_unitdir}/lvm2-monitor.service
rm %{buildroot}%{_mandir}/man8/blkdeactivate.8
# remove blkd, will be in lvm2 proper
# without force on purpose to detect changes and fail if it happens
rm %{buildroot}%{_sbindir}/blkdeactivate
rm %{buildroot}%{_unitdir}/blk-availability.service
rm %{buildroot}%{_unitdir}/lvm2-monitor.service
rm %{buildroot}%{_mandir}/man8/blkdeactivate.8
# remove files, which will be in lvm2 & lockd packages
rm %{buildroot}%{_unitdir}/lvm2-lvmpolld.service
rm %{buildroot}%{_unitdir}/lvm2-lvmpolld.socket
rm %{buildroot}%{_unitdir}/lvmlockd.service
rm %{buildroot}%{_unitdir}/lvmlocks.service
# compat symlinks in /sbin remove with Leap 43
%if !0%{?usrmerged}
mkdir -p %{buildroot}/sbin
ln -s %{_sbindir}/dmsetup %{buildroot}/sbin/dmsetup
%endif
# compat symlinks in /sbin remove with Leap 43
%if !0%{?usrmerged}
mkdir -p %{buildroot}/sbin
ln -s %{_sbindir}/dmsetup %{buildroot}/sbin/dmsetup
%endif
%else
%if %{with lockd}
make DESTDIR=%{buildroot} \
install_systemd_units install_systemd_generators
make DESTDIR=%{buildroot} install -C daemons/lvmlockd
# lvmlockd does not have separate target install the mans by hand for now
install -m0644 -D man/lvmlockd.8 %{buildroot}%{_mandir}/man8/lvmlockd.8
install -m0644 -D man/lvmlockctl.8 %{buildroot}%{_mandir}/man8/lvmlockctl.8
%if %{with lockd}
make DESTDIR=%{buildroot} \
install_systemd_units install_systemd_generators
make DESTDIR=%{buildroot} install -C daemons/lvmlockd
# rc services symlinks
ln -s service %{buildroot}%{_sbindir}/rclvm2-lvmlockd
ln -s service %{buildroot}%{_sbindir}/rclvm2-lvmlocking
# lvmlockd does not have separate target install the mans by hand for now
install -m0644 -D man/lvmlockd.8 %{buildroot}%{_mandir}/man8/lvmlockd.8
install -m0644 -D man/lvmlockctl.8 %{buildroot}%{_mandir}/man8/lvmlockctl.8
# remove files from lvm2 split due to systemd_generators picking them up
rm %{buildroot}%{_unitdir}/blk-availability.service
rm %{buildroot}%{_unitdir}/dm-event.service
rm %{buildroot}%{_unitdir}/dm-event.socket
rm %{buildroot}%{_unitdir}/lvm2-monitor.service
rm %{buildroot}%{_unitdir}/lvm2-lvmpolld.service
rm %{buildroot}%{_unitdir}/lvm2-lvmpolld.socket
%else
%make_install
make install_system_dirs DESTDIR=%{buildroot}
make install_systemd_units DESTDIR=%{buildroot}
make install_systemd_generators DESTDIR=%{buildroot}
make install_tmpfiles_configuration DESTDIR=%{buildroot}
# Install configuration file
install -m 644 %{SOURCE1} "%{buildroot}/%{_sysconfdir}/lvm/"
# Install testsuite
make -C test install DESTDIR=%{buildroot}
# rc services symlinks
ln -s service %{buildroot}%{_sbindir}/rclvm2-lvmlockd
ln -s service %{buildroot}%{_sbindir}/rclvm2-lvmlocking
pushd "%{buildroot}/%{_libdir}"
ln -sf liblvm2cmd.so.2.03 liblvm2cmd.so
for i in libdevmapper-event-lvm2{mirror,raid,snapshot,thin}; do
ln -sf "device-mapper/$i.so" "$i.so"
ln -sf "device-mapper/$i.so" "$i.so.2.03"
done
popd
# remove files from lvm2 split due to systemd_generators picking them up
rm %{buildroot}%{_unitdir}/blk-availability.service
rm %{buildroot}%{_unitdir}/dm-event.service
rm %{buildroot}%{_unitdir}/dm-event.socket
rm %{buildroot}%{_unitdir}/lvm2-monitor.service
rm %{buildroot}%{_unitdir}/lvm2-lvmpolld.service
rm %{buildroot}%{_unitdir}/lvm2-lvmpolld.socket
%else
%make_install
make install_system_dirs DESTDIR=%{buildroot}
make install_systemd_units DESTDIR=%{buildroot}
make install_systemd_generators DESTDIR=%{buildroot}
make install_tmpfiles_configuration DESTDIR=%{buildroot}
# Install configuration file
install -m 644 %{SOURCE1} "%{buildroot}/%{_sysconfdir}/lvm/"
# Install testsuite
make -C test install DESTDIR=%{buildroot}
#rc compat symlinks
ln -s service %{buildroot}%{_sbindir}/rcblk-availability
ln -s service %{buildroot}%{_sbindir}/rclvm2-monitor
ln -s service %{buildroot}%{_sbindir}/rclvm2-lvmpolld
pushd "%{buildroot}/%{_libdir}"
ln -sf liblvm2cmd.so.2.03 liblvm2cmd.so
for i in libdevmapper-event-lvm2{mirror,raid,snapshot,thin}; do
ln -sf "device-mapper/$i.so" "$i.so"
ln -sf "device-mapper/$i.so" "$i.so.2.03"
done
popd
# Remove devicemapper binaries, plain rm so we fail if something change
rm %{buildroot}%{_sbindir}/dmsetup
rm %{buildroot}%{_sbindir}/dmeventd
rm %{buildroot}%{_sbindir}/dmstats
rm %{buildroot}%{_udevrulesdir}/10-dm.rules
rm %{buildroot}%{_udevrulesdir}/13-dm-disk.rules
rm %{buildroot}%{_udevrulesdir}/95-dm-notify.rules
rm %{buildroot}%{_unitdir}/dm-event.socket
rm %{buildroot}%{_unitdir}/dm-event.service
# See bsc#1037309 for more info
rm %{buildroot}%{_unitdir}/lvmlockd.service
rm %{buildroot}%{_unitdir}/lvmlocks.service
rm %{buildroot}%{_includedir}/libdevmapper*.h
rm %{buildroot}%{_libdir}/libdevmapper.so.*
rm %{buildroot}%{_libdir}/libdevmapper-event.so.*
rm %{buildroot}%{_libdir}/libdevmapper.so
rm %{buildroot}%{_libdir}/libdevmapper-event.so
rm %{buildroot}%{_libdir}/pkgconfig/devmapper*.pc
rm %{buildroot}%{_mandir}/man8/lvmlockctl.8
rm %{buildroot}%{_mandir}/man8/lvmlockd.8
rm %{buildroot}%{_mandir}/man8/dmstats.8
rm %{buildroot}%{_mandir}/man8/dmsetup.8
rm %{buildroot}%{_mandir}/man8/dmeventd.8
#rc compat symlinks
ln -s service %{buildroot}%{_sbindir}/rcblk-availability
ln -s service %{buildroot}%{_sbindir}/rclvm2-monitor
ln -s service %{buildroot}%{_sbindir}/rclvm2-lvmpolld
%if !0%{?usrmerged}
# compat symlinks in /sbin remove with Leap 43
mkdir -p %{buildroot}/sbin
pushd %{buildroot}/%{_sbindir}
for i in {vg,pv,lv}*; do
ln -s %{_sbindir}/$i %{buildroot}/sbin/$i
done
popd
%endif
%endif
# Remove devicemapper binaries, plain rm so we fail if something change
rm %{buildroot}%{_sbindir}/dmsetup
rm %{buildroot}%{_sbindir}/dmeventd
rm %{buildroot}%{_sbindir}/dmstats
rm %{buildroot}%{_udevrulesdir}/10-dm.rules
rm %{buildroot}%{_udevrulesdir}/13-dm-disk.rules
rm %{buildroot}%{_udevrulesdir}/95-dm-notify.rules
rm %{buildroot}%{_unitdir}/dm-event.socket
rm %{buildroot}%{_unitdir}/dm-event.service
# See bsc#1037309 for more info
rm %{buildroot}%{_unitdir}/lvmlockd.service
rm %{buildroot}%{_unitdir}/lvmlocks.service
rm %{buildroot}%{_includedir}/libdevmapper*.h
rm %{buildroot}%{_libdir}/libdevmapper.so.*
rm %{buildroot}%{_libdir}/libdevmapper-event.so.*
rm %{buildroot}%{_libdir}/libdevmapper.so
rm %{buildroot}%{_libdir}/libdevmapper-event.so
rm %{buildroot}%{_libdir}/pkgconfig/devmapper*.pc
rm %{buildroot}%{_mandir}/man8/lvmlockctl.8
rm %{buildroot}%{_mandir}/man8/lvmlockd.8
rm %{buildroot}%{_mandir}/man8/dmstats.8
rm %{buildroot}%{_mandir}/man8/dmsetup.8
rm %{buildroot}%{_mandir}/man8/dmeventd.8
%if !0%{?usrmerged}
# compat symlinks in /sbin remove with Leap 43
mkdir -p %{buildroot}/sbin
pushd %{buildroot}/%{_sbindir}
for i in {vg,pv,lv}*; do
ln -s %{_sbindir}/$i %{buildroot}/sbin/$i
done
popd
%endif
%endif
%endif
%if %{with devicemapper}
@ -404,6 +396,7 @@ Programs and man pages for configuring and using the device mapper.
%{_mandir}/man8/dmstats.8%{?ext_man}
%{_mandir}/man8/dmsetup.8%{?ext_man}
%{_mandir}/man8/dmeventd.8%{?ext_man}
%{_mandir}/man8/dmfilemapd.8%{?ext_man}
%{_udevrulesdir}/10-dm.rules
%{_udevrulesdir}/13-dm-disk.rules
%{_udevrulesdir}/95-dm-notify.rules
@ -557,7 +550,6 @@ LVM commands use lvmlockd to coordinate access to shared storage.
%{_sbindir}/lvmdump
%{_sbindir}/lvmpolld
%{_sbindir}/lvm_import_vdo
# Other files
%{_sbindir}/lvchange
%{_sbindir}/lvconvert
%{_sbindir}/lvcreate
@ -607,11 +599,11 @@ LVM commands use lvmlockd to coordinate access to shared storage.
# compat symlinks in /sbin
%if !0%{?usrmerged}
/sbin/lvm
/sbin/lvm_import_vdo
/sbin/lvmconfig
/sbin/lvmdevices
/sbin/lvmdump
/sbin/lvmpolld
/sbin/lvm_import_vdo
/sbin/lvchange
/sbin/lvconvert
/sbin/lvcreate
@ -718,6 +710,7 @@ LVM commands use lvmlockd to coordinate access to shared storage.
%{_mandir}/man8/blkdeactivate.8%{?ext_man}
%{_mandir}/man8/lvmpolld.8%{?ext_man}
%{_mandir}/man8/lvm-lvpoll.8%{?ext_man}
%{_mandir}/man8/lvm_import_vdo.8%{?ext_man}
%{_udevdir}/rules.d/11-dm-lvm.rules
%{_udevdir}/rules.d/69-dm-lvm.rules
%dir %{_sysconfdir}/lvm