Compare commits
No commits in common. 'c9' and 'c10-beta' have entirely different histories.
@ -1 +1 @@
|
|||||||
SOURCES/LVM2.2.03.21.tgz
|
SOURCES/LVM2.2.03.24.tgz
|
||||||
|
@ -1 +1 @@
|
|||||||
b6d4a84bf1f0306f43f447c7531021d5c126edbf SOURCES/LVM2.2.03.21.tgz
|
7c2dcac585dc89dbd0070216262a3a8446e7f222 SOURCES/LVM2.2.03.24.tgz
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
From 37195813dc68a794e6bece25b8e56479f18602ca Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marian Csontos <mcsontos@redhat.com>
|
||||||
|
Date: Thu, 16 May 2024 12:12:06 +0200
|
||||||
|
Subject: [PATCH 1/9] RHEL9
|
||||||
|
|
||||||
|
---
|
||||||
|
VERSION | 2 +-
|
||||||
|
VERSION_DM | 2 +-
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
WHATS_NEW_DM | 4 ++++
|
||||||
|
doc/release-notes/2.03.24.mdwn | 8 ++------
|
||||||
|
5 files changed, 12 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/VERSION b/VERSION
|
||||||
|
index c41928e80..95824e0e2 100644
|
||||||
|
--- a/VERSION
|
||||||
|
+++ b/VERSION
|
||||||
|
@@ -1 +1 @@
|
||||||
|
-2.03.24(2) (2024-05-16)
|
||||||
|
+2.03.24(2)-RHEL10 (2024-08-15)
|
||||||
|
diff --git a/VERSION_DM b/VERSION_DM
|
||||||
|
index 63629f72c..b7c564189 100644
|
||||||
|
--- a/VERSION_DM
|
||||||
|
+++ b/VERSION_DM
|
||||||
|
@@ -1 +1 @@
|
||||||
|
-1.02.198 (2024-05-16)
|
||||||
|
+1.02.198-RHEL10 (2024-08-15)
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 1c5f4b223..c7de3914a 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,6 @@
|
||||||
|
+Version 2.03.25 -
|
||||||
|
+==================
|
||||||
|
+
|
||||||
|
Version 2.03.24 - 16th May 2024
|
||||||
|
===============================
|
||||||
|
Lvconvert supports VDO options for thin-pool with vdo conversion.
|
||||||
|
@@ -5450,3 +5453,4 @@ Display output. Some metadata information cannot yet be displayed.
|
||||||
|
Recovery tools to salvage "lost" metadata directly from the disks:
|
||||||
|
but we hope the new format will mean such tools are hardly ever needed!
|
||||||
|
|
||||||
|
+
|
||||||
|
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
||||||
|
index b1508f08f..a2277c53b 100644
|
||||||
|
--- a/WHATS_NEW_DM
|
||||||
|
+++ b/WHATS_NEW_DM
|
||||||
|
@@ -1,3 +1,6 @@
|
||||||
|
+Version 1.02.199 -
|
||||||
|
+===================
|
||||||
|
+
|
||||||
|
Version 1.02.198 - 16th May 2024
|
||||||
|
================================
|
||||||
|
Fix static only compilation of libdevmapper.a and dmsetup tool.
|
||||||
|
@@ -1554,3 +1557,4 @@ Version 1.00.08 - 27 Feb 2004
|
||||||
|
Updated README/INSTALL to reflect move to sources.redhat.com.
|
||||||
|
Updated autoconf files to 2003-06-17.
|
||||||
|
|
||||||
|
+
|
||||||
|
diff --git a/doc/release-notes/2.03.24.mdwn b/doc/release-notes/2.03.24.mdwn
|
||||||
|
index 71aa8add7..4d2c57497 100644
|
||||||
|
--- a/doc/release-notes/2.03.24.mdwn
|
||||||
|
+++ b/doc/release-notes/2.03.24.mdwn
|
||||||
|
@@ -72,9 +72,5 @@ Also few more minor improvements:
|
||||||
|
|
||||||
|
"""]]
|
||||||
|
|
||||||
|
-<!-- remove the pending tag on release, remove draft tag once editing is complete -->
|
||||||
|
-[[!tag draft pending]]
|
||||||
|
-<!--
|
||||||
|
-For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
|
||||||
|
-\[[!meta date="Tue Nov 21 14:26:07 2023 +0100"]]
|
||||||
|
--->
|
||||||
|
+[[!tag]]
|
||||||
|
+[[meta date="Thu May 16 12:12:06 2024 +0200"]]
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -1,84 +0,0 @@
|
|||||||
From ecea7b14c453a58831f2dda5a0aa869ee4601dff Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Mon, 24 Apr 2023 15:47:45 -0500
|
|
||||||
Subject: [PATCH 1/2] fix dev_name use in add_areas_line
|
|
||||||
|
|
||||||
This function was relying on dev_name() returning NULL
|
|
||||||
to indicate no device, but dev_name never returns NULL.
|
|
||||||
|
|
||||||
(cherry picked from commit 31cfcf7ce9aab5dd16ba15e48bfe33be849fad4c)
|
|
||||||
---
|
|
||||||
lib/activate/dev_manager.c | 45 ++++++++++++++++++++++++--------------
|
|
||||||
1 file changed, 29 insertions(+), 16 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
|
|
||||||
index 07d58733e..ac3f01718 100644
|
|
||||||
--- a/lib/activate/dev_manager.c
|
|
||||||
+++ b/lib/activate/dev_manager.c
|
|
||||||
@@ -3000,34 +3000,47 @@ static int _add_error_area(struct dev_manager *dm, struct dm_tree_node *node,
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int _bad_pv_area(struct lv_segment *seg, uint32_t s)
|
|
||||||
+{
|
|
||||||
+ struct stat info;
|
|
||||||
+ const char *name;
|
|
||||||
+ struct device *dev;
|
|
||||||
+
|
|
||||||
+ if (!seg_pvseg(seg, s))
|
|
||||||
+ return 1;
|
|
||||||
+ if (!seg_pv(seg, s))
|
|
||||||
+ return 1;
|
|
||||||
+ if (!(dev = seg_dev(seg, s)))
|
|
||||||
+ return 1;
|
|
||||||
+ if (dm_list_empty(&dev->aliases))
|
|
||||||
+ return 1;
|
|
||||||
+ /* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
|
|
||||||
+ name = dev_name(dev);
|
|
||||||
+ if (stat(name, &info) < 0)
|
|
||||||
+ return 1;
|
|
||||||
+ if (!S_ISBLK(info.st_mode))
|
|
||||||
+ return 1;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
|
||||||
struct dm_tree_node *node, uint32_t start_area,
|
|
||||||
uint32_t areas)
|
|
||||||
{
|
|
||||||
+ struct cmd_context *cmd = seg->lv->vg->cmd;
|
|
||||||
uint64_t extent_size = seg->lv->vg->extent_size;
|
|
||||||
uint32_t s;
|
|
||||||
char *dlid;
|
|
||||||
- struct stat info;
|
|
||||||
const char *name;
|
|
||||||
unsigned num_error_areas = 0;
|
|
||||||
unsigned num_existing_areas = 0;
|
|
||||||
|
|
||||||
- /* 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 ||
|
|
||||||
- stat(name, &info) < 0 || !S_ISBLK(info.st_mode))) ||
|
|
||||||
- (seg_type(seg, s) == AREA_LV && !seg_lv(seg, s))) {
|
|
||||||
- if (!seg->lv->vg->cmd->partial_activation) {
|
|
||||||
- if (!seg->lv->vg->cmd->degraded_activation ||
|
|
||||||
- !lv_is_raid_type(seg->lv)) {
|
|
||||||
- log_error("Aborting. LV %s is now incomplete "
|
|
||||||
- "and '--activationmode partial' was not specified.",
|
|
||||||
+ if (((seg_type(seg, s) == AREA_PV) && _bad_pv_area(seg, s)) ||
|
|
||||||
+ ((seg_type(seg, s) == AREA_LV) && !seg_lv(seg, s))) {
|
|
||||||
+ if (!cmd->partial_activation) {
|
|
||||||
+ if (!cmd->degraded_activation || !lv_is_raid_type(seg->lv)) {
|
|
||||||
+ log_error("Aborting. LV %s is incomplete and --activationmode partial was not specified.",
|
|
||||||
display_lvname(seg->lv));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.40.1
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
From c6982874d57e2debc0d33c50b74572bacc91b424 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marian Csontos <mcsontos@redhat.com>
|
||||||
|
Date: Thu, 16 May 2024 15:34:28 +0200
|
||||||
|
Subject: [PATCH 2/9] WHATS_NEW: update
|
||||||
|
|
||||||
|
---
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
WHATS_NEW_DM | 4 ++++
|
||||||
|
2 files changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index c7de3914a..1d56f8675 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.03.25 -
|
||||||
|
==================
|
||||||
|
+ Revert Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it.
|
||||||
|
|
||||||
|
Version 2.03.24 - 16th May 2024
|
||||||
|
===============================
|
||||||
|
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
||||||
|
index a2277c53b..da8df6914 100644
|
||||||
|
--- a/WHATS_NEW_DM
|
||||||
|
+++ b/WHATS_NEW_DM
|
||||||
|
@@ -1,5 +1,9 @@
|
||||||
|
Version 1.02.199 -
|
||||||
|
===================
|
||||||
|
+ Revert Increase DM_UDEV_RULES_VSN to 3 to indicate changed udev rules.
|
||||||
|
+ Revert Rename DM_NOSCAN to .DM_NOSCAN so it's not stored in udev db.
|
||||||
|
+ Revert Rename DM_SUSPENDED to .DM_SUSPENDED so it's not stored in udev db.
|
||||||
|
+ Revert Do not import DM_UDEV_DISABLE_OTHER_RULES_FLAG from db in 10-dm-disk.rules.
|
||||||
|
|
||||||
|
Version 1.02.198 - 16th May 2024
|
||||||
|
================================
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -1,510 +0,0 @@
|
|||||||
From fb1e53f229f4bcde07df4b562927e213bd7f8d17 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Wed, 22 Mar 2023 13:05:43 -0500
|
|
||||||
Subject: [PATCH 2/2] raidintegrity: allow snapshots
|
|
||||||
|
|
||||||
(cherry picked from commit fd6e113bba5fed5ee41152cde33220294c24ce2b)
|
|
||||||
---
|
|
||||||
lib/activate/dev_manager.c | 6 +-
|
|
||||||
lib/metadata/integrity_manip.c | 5 -
|
|
||||||
lib/metadata/snapshot_manip.c | 2 -
|
|
||||||
test/shell/snapshot-raid.sh | 441 +++++++++++++++++++++++++++++++++
|
|
||||||
4 files changed, 446 insertions(+), 8 deletions(-)
|
|
||||||
create mode 100644 test/shell/snapshot-raid.sh
|
|
||||||
|
|
||||||
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
|
|
||||||
index ac3f01718..1f4d7c98b 100644
|
|
||||||
--- a/lib/activate/dev_manager.c
|
|
||||||
+++ b/lib/activate/dev_manager.c
|
|
||||||
@@ -3039,7 +3039,11 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
|
||||||
if (((seg_type(seg, s) == AREA_PV) && _bad_pv_area(seg, s)) ||
|
|
||||||
((seg_type(seg, s) == AREA_LV) && !seg_lv(seg, s))) {
|
|
||||||
if (!cmd->partial_activation) {
|
|
||||||
- if (!cmd->degraded_activation || !lv_is_raid_type(seg->lv)) {
|
|
||||||
+ if (!cmd->degraded_activation ||
|
|
||||||
+ (!lv_is_raid_type(seg->lv) &&
|
|
||||||
+ !lv_is_integrity(seg->lv) &&
|
|
||||||
+ !lv_is_integrity_metadata(seg->lv) &&
|
|
||||||
+ !lv_is_integrity_origin(seg->lv))) {
|
|
||||||
log_error("Aborting. LV %s is incomplete and --activationmode partial was not specified.",
|
|
||||||
display_lvname(seg->lv));
|
|
||||||
return 0;
|
|
||||||
diff --git a/lib/metadata/integrity_manip.c b/lib/metadata/integrity_manip.c
|
|
||||||
index 456795532..506b9f06b 100644
|
|
||||||
--- a/lib/metadata/integrity_manip.c
|
|
||||||
+++ b/lib/metadata/integrity_manip.c
|
|
||||||
@@ -508,11 +508,6 @@ int lv_add_integrity_to_raid(struct logical_volume *lv, struct integrity_setting
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (lv_is_origin(lv)) {
|
|
||||||
- log_error("Integrity cannot be added to snapshot origins.");
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
seg_top = first_seg(lv);
|
|
||||||
area_count = seg_top->area_count;
|
|
||||||
|
|
||||||
diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c
|
|
||||||
index 822b8da77..b34079d08 100644
|
|
||||||
--- a/lib/metadata/snapshot_manip.c
|
|
||||||
+++ b/lib/metadata/snapshot_manip.c
|
|
||||||
@@ -423,8 +423,6 @@ int validate_snapshot_origin(const struct logical_volume *origin_lv)
|
|
||||||
}
|
|
||||||
} else if (lv_is_raid_type(origin_lv) && !lv_is_raid(origin_lv)) {
|
|
||||||
err = "raid subvolumes";
|
|
||||||
- } else if (lv_is_raid(origin_lv) && lv_raid_has_integrity((struct logical_volume *)origin_lv)) {
|
|
||||||
- err = "raid with integrity";
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
diff --git a/test/shell/snapshot-raid.sh b/test/shell/snapshot-raid.sh
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..757bf911e
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/shell/snapshot-raid.sh
|
|
||||||
@@ -0,0 +1,441 @@
|
|
||||||
+#!/usr/bin/env bash
|
|
||||||
+
|
|
||||||
+# Copyright (C) 2018 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 snapshots of raid
|
|
||||||
+
|
|
||||||
+SKIP_WITH_LVMPOLLD=1
|
|
||||||
+
|
|
||||||
+. lib/inittest
|
|
||||||
+
|
|
||||||
+which mkfs.ext4 || skip
|
|
||||||
+
|
|
||||||
+mount_dir="mnt"
|
|
||||||
+mkdir -p "$mount_dir"
|
|
||||||
+
|
|
||||||
+snap_dir="mnt_snap"
|
|
||||||
+mkdir -p "$snap_dir"
|
|
||||||
+
|
|
||||||
+_sync_percent() {
|
|
||||||
+ local checklv=$1
|
|
||||||
+ get lv_field "$checklv" sync_percent | cut -d. -f1
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+_wait_sync() {
|
|
||||||
+ local checklv=$1
|
|
||||||
+
|
|
||||||
+ for i in $(seq 1 10) ; do
|
|
||||||
+ sync=$(_sync_percent "$checklv")
|
|
||||||
+ echo "sync_percent is $sync"
|
|
||||||
+
|
|
||||||
+ if test "$sync" = "100"; then
|
|
||||||
+ return
|
|
||||||
+ fi
|
|
||||||
+
|
|
||||||
+ sleep 1
|
|
||||||
+ done
|
|
||||||
+ echo "timeout waiting for recalc"
|
|
||||||
+ dmsetup status "$DM_DEV_DIR/mapper/${checklv/\//-}"
|
|
||||||
+ return 1
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+# add and remove a snapshot
|
|
||||||
+
|
|
||||||
+test_add_del_snap() {
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B"
|
|
||||||
+ not ls "$snap_dir/B"
|
|
||||||
+ touch "$snap_dir/C"
|
|
||||||
+ not ls "$mount_dir/C"
|
|
||||||
+ ls "$mount_dir/A"
|
|
||||||
+ ls "$snap_dir/A"
|
|
||||||
+
|
|
||||||
+ umount "$snap_dir"
|
|
||||||
+ lvremove -y $vg/snap
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+# add and remove snapshot while origin has a missing raid image
|
|
||||||
+
|
|
||||||
+test_snap_with_missing_image() {
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ aux disable_dev "$dev1"
|
|
||||||
+ lvs -a -o+devices $vg
|
|
||||||
+
|
|
||||||
+ not lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+
|
|
||||||
+ aux enable_dev "$dev1"
|
|
||||||
+ _wait_sync $vg/$lv1
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+
|
|
||||||
+ aux disable_dev "$dev1"
|
|
||||||
+ lvs -a -o+devices $vg
|
|
||||||
+
|
|
||||||
+ lvremove -y $vg/snap
|
|
||||||
+
|
|
||||||
+ aux enable_dev "$dev1"
|
|
||||||
+ vgextend --restoremissing $vg "$dev1"
|
|
||||||
+ lvs -a -o+devices $vg
|
|
||||||
+ _wait_sync $vg/$lv1
|
|
||||||
+
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+# raid image is lost and restored while a snapshot exists
|
|
||||||
+
|
|
||||||
+test_missing_image_with_snap() {
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+ aux disable_dev "$dev1"
|
|
||||||
+ lvs -a -o+devices $vg
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B"
|
|
||||||
+ not ls "$snap_dir/B"
|
|
||||||
+ touch "$snap_dir/C"
|
|
||||||
+ not ls "$mount_dir/C"
|
|
||||||
+ ls "$mount_dir/A"
|
|
||||||
+ ls "$snap_dir/A"
|
|
||||||
+
|
|
||||||
+ aux enable_dev "$dev1"
|
|
||||||
+ _wait_sync $vg/$lv1
|
|
||||||
+
|
|
||||||
+ ls "$mount_dir/B"
|
|
||||||
+ ls "$snap_dir/C"
|
|
||||||
+
|
|
||||||
+ umount "$snap_dir"
|
|
||||||
+ lvremove -y $vg/snap
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+# add and remove raid image while snapshot exists
|
|
||||||
+
|
|
||||||
+test_add_del_image_with_snap() {
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B"
|
|
||||||
+ touch "$snap_dir/C"
|
|
||||||
+
|
|
||||||
+ lvconvert -y -m+1 $vg/$lv1 "$dev4"
|
|
||||||
+ _wait_sync $vg/$lv1
|
|
||||||
+
|
|
||||||
+ ls "$mount_dir/B"
|
|
||||||
+ ls "$snap_dir/C"
|
|
||||||
+ ls "$mount_dir/A"
|
|
||||||
+ ls "$snap_dir/A"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B2"
|
|
||||||
+ touch "$snap_dir/C2"
|
|
||||||
+
|
|
||||||
+ lvconvert -y -m-1 $vg/$lv1 "$dev4"
|
|
||||||
+
|
|
||||||
+ ls "$mount_dir/B"
|
|
||||||
+ ls "$snap_dir/C"
|
|
||||||
+ ls "$mount_dir/A"
|
|
||||||
+ ls "$snap_dir/A"
|
|
||||||
+ ls "$mount_dir/B2"
|
|
||||||
+ ls "$snap_dir/C2"
|
|
||||||
+ umount "$snap_dir"
|
|
||||||
+ lvremove -y $vg/snap
|
|
||||||
+
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+test_replace_image_with_snap() {
|
|
||||||
+ # add an image to replace
|
|
||||||
+ lvconvert -y -m+1 $vg/$lv1 "$dev4"
|
|
||||||
+ _wait_sync $vg/$lv1
|
|
||||||
+
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B"
|
|
||||||
+ touch "$snap_dir/C"
|
|
||||||
+
|
|
||||||
+ lvconvert -y --replace "$dev4" $vg/$lv1 "$dev5"
|
|
||||||
+ _wait_sync $vg/$lv1
|
|
||||||
+
|
|
||||||
+ ls "$mount_dir/B"
|
|
||||||
+ ls "$snap_dir/C"
|
|
||||||
+ ls "$mount_dir/A"
|
|
||||||
+ ls "$snap_dir/A"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B2"
|
|
||||||
+ touch "$snap_dir/C2"
|
|
||||||
+
|
|
||||||
+ umount "$snap_dir"
|
|
||||||
+ lvremove -y $vg/snap
|
|
||||||
+
|
|
||||||
+ # put lv1 back to original state with images on dev1 and dev2
|
|
||||||
+ lvconvert -y -m-1 $vg/$lv1 "$dev5"
|
|
||||||
+
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+test_repair_image_with_snap() {
|
|
||||||
+ # add an image to repair
|
|
||||||
+ lvconvert -y -m+1 $vg/$lv1 "$dev4"
|
|
||||||
+ _wait_sync $vg/$lv1
|
|
||||||
+
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B"
|
|
||||||
+ touch "$snap_dir/C"
|
|
||||||
+
|
|
||||||
+ aux disable_dev "$dev4"
|
|
||||||
+ lvs -a -o+devices $vg
|
|
||||||
+
|
|
||||||
+ lvconvert -y --repair $vg/$lv1 "$dev5"
|
|
||||||
+ _wait_sync $vg/$lv1
|
|
||||||
+
|
|
||||||
+ ls "$mount_dir/B"
|
|
||||||
+ ls "$snap_dir/C"
|
|
||||||
+ ls "$mount_dir/A"
|
|
||||||
+ ls "$snap_dir/A"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B2"
|
|
||||||
+ touch "$snap_dir/C2"
|
|
||||||
+
|
|
||||||
+ umount "$snap_dir"
|
|
||||||
+ lvremove -y $vg/snap
|
|
||||||
+
|
|
||||||
+ aux enable_dev "$dev4"
|
|
||||||
+ lvs -a -o+devices $vg
|
|
||||||
+ vgck --updatemetadata $vg
|
|
||||||
+
|
|
||||||
+ # put lv1 back to original state with images on dev1 and dev2
|
|
||||||
+ lvconvert -y -m-1 $vg/$lv1 "$dev5"
|
|
||||||
+
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+test_merge_snap()
|
|
||||||
+{
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B"
|
|
||||||
+ touch "$snap_dir/C"
|
|
||||||
+
|
|
||||||
+ umount "$snap_dir"
|
|
||||||
+
|
|
||||||
+ lvconvert --merge $vg/snap
|
|
||||||
+
|
|
||||||
+ # the merge will begin once the origin is not in use
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+
|
|
||||||
+ lvs -a $vg
|
|
||||||
+ lvchange -an $vg/$lv1
|
|
||||||
+ lvchange -ay $vg/$lv1
|
|
||||||
+ lvs -a $vg
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ ls "$mount_dir/A"
|
|
||||||
+ ls "$mount_dir/C"
|
|
||||||
+ not ls "$mount_dir/B"
|
|
||||||
+
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+test_extend_snap()
|
|
||||||
+{
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L8M $vg/$lv1 "$dev3"
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+ touch "$mount_dir/B"
|
|
||||||
+ touch "$snap_dir/C"
|
|
||||||
+
|
|
||||||
+ lvextend -L+8M $vg/snap
|
|
||||||
+
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+ umount "$snap_dir"
|
|
||||||
+ lvremove -y $vg/snap
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+test_fill_snap()
|
|
||||||
+{
|
|
||||||
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+ touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+ lvcreate -s -n snap -L4M $vg/$lv1 "$dev3"
|
|
||||||
+
|
|
||||||
+ lvs -a $vg
|
|
||||||
+ get lv_field $vg/snap lv_attr | grep "swi-a-s---"
|
|
||||||
+
|
|
||||||
+ dd if=/dev/zero of="$mount_dir/1" bs=1M count=1 oflag=sync
|
|
||||||
+ dd if=/dev/zero of="$mount_dir/2" bs=1M count=1 oflag=sync
|
|
||||||
+ dd if=/dev/zero of="$mount_dir/3" bs=1M count=1 oflag=sync
|
|
||||||
+ dd if=/dev/zero of="$mount_dir/4" bs=1M count=1 oflag=sync
|
|
||||||
+ dd if=/dev/zero of="$mount_dir/5" bs=1M count=1 oflag=sync
|
|
||||||
+
|
|
||||||
+ lvs -a $vg
|
|
||||||
+ get lv_field $vg/snap lv_attr | grep "swi-I-s---"
|
|
||||||
+ check lv_field $vg/snap data_percent "100.00"
|
|
||||||
+
|
|
||||||
+ umount "$mount_dir"
|
|
||||||
+ lvremove -y $vg/snap
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+aux prepare_devs 5 200
|
|
||||||
+
|
|
||||||
+vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
|
|
||||||
+
|
|
||||||
+lvcreate --type raid1 -m1 -n $lv1 -L128M $vg "$dev1" "$dev2"
|
|
||||||
+_wait_sync $vg/$lv1
|
|
||||||
+test_add_del_snap
|
|
||||||
+test_snap_with_missing_image
|
|
||||||
+test_missing_image_with_snap
|
|
||||||
+test_add_del_image_with_snap
|
|
||||||
+test_replace_image_with_snap
|
|
||||||
+test_repair_image_with_snap
|
|
||||||
+test_merge_snap
|
|
||||||
+test_extend_snap
|
|
||||||
+test_fill_snap
|
|
||||||
+lvremove -y $vg/$lv1
|
|
||||||
+
|
|
||||||
+lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -L128M $vg "$dev1" "$dev2"
|
|
||||||
+_wait_sync $vg/${lv1}_rimage_0
|
|
||||||
+_wait_sync $vg/${lv1}_rimage_1
|
|
||||||
+_wait_sync $vg/$lv1
|
|
||||||
+test_add_del_snap
|
|
||||||
+test_snap_with_missing_image
|
|
||||||
+test_missing_image_with_snap
|
|
||||||
+test_add_del_image_with_snap
|
|
||||||
+test_replace_image_with_snap
|
|
||||||
+test_repair_image_with_snap
|
|
||||||
+test_merge_snap
|
|
||||||
+test_extend_snap
|
|
||||||
+test_fill_snap
|
|
||||||
+lvremove -y $vg/$lv1
|
|
||||||
+
|
|
||||||
+# Repeat above with cache|writecache on the raid image?
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Add/remove integrity while a snapshot exists
|
|
||||||
+#
|
|
||||||
+
|
|
||||||
+lvcreate --type raid1 -m1 -n $lv1 -L128M $vg "$dev1" "$dev2"
|
|
||||||
+_wait_sync $vg/$lv1
|
|
||||||
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+touch "$mount_dir/B"
|
|
||||||
+touch "$snap_dir/C"
|
|
||||||
+
|
|
||||||
+lvconvert --raidintegrity y $vg/$lv1
|
|
||||||
+_wait_sync $vg/${lv1}_rimage_0
|
|
||||||
+_wait_sync $vg/${lv1}_rimage_1
|
|
||||||
+
|
|
||||||
+ls "$mount_dir/B"
|
|
||||||
+ls "$snap_dir/C"
|
|
||||||
+ls "$mount_dir/A"
|
|
||||||
+ls "$snap_dir/A"
|
|
||||||
+
|
|
||||||
+touch "$mount_dir/B2"
|
|
||||||
+touch "$snap_dir/C2"
|
|
||||||
+
|
|
||||||
+lvconvert --raidintegrity n $vg/$lv1
|
|
||||||
+
|
|
||||||
+ls "$mount_dir/B"
|
|
||||||
+ls "$snap_dir/C"
|
|
||||||
+ls "$mount_dir/A"
|
|
||||||
+ls "$snap_dir/A"
|
|
||||||
+ls "$mount_dir/B2"
|
|
||||||
+ls "$snap_dir/C2"
|
|
||||||
+umount "$snap_dir"
|
|
||||||
+umount "$mount_dir"
|
|
||||||
+lvremove -y $vg/snap
|
|
||||||
+lvremove -y $vg/$lv1
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Add integrity not allowed with missing image and snapshot exists
|
|
||||||
+#
|
|
||||||
+
|
|
||||||
+lvcreate --type raid1 -m1 -n $lv1 -L128M $vg "$dev1" "$dev2"
|
|
||||||
+_wait_sync $vg/$lv1
|
|
||||||
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
+
|
|
||||||
+mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
|
|
||||||
+touch "$mount_dir/A"
|
|
||||||
+
|
|
||||||
+lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
|
|
||||||
+mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
|
|
||||||
+
|
|
||||||
+touch "$mount_dir/B"
|
|
||||||
+touch "$snap_dir/C"
|
|
||||||
+
|
|
||||||
+aux disable_dev "$dev1"
|
|
||||||
+lvs -a $vg
|
|
||||||
+
|
|
||||||
+not lvconvert --raidintegrity y $vg/$lv1
|
|
||||||
+
|
|
||||||
+aux enable_dev "$dev1"
|
|
||||||
+lvs -a $vg
|
|
||||||
+
|
|
||||||
+umount "$snap_dir"
|
|
||||||
+umount "$mount_dir"
|
|
||||||
+lvremove -y $vg/snap
|
|
||||||
+lvremove -y $vg/$lv1
|
|
||||||
+
|
|
||||||
+vgremove -ff $vg
|
|
||||||
+
|
|
||||||
--
|
|
||||||
2.40.1
|
|
||||||
|
|
@ -0,0 +1,578 @@
|
|||||||
|
From 64c243930b4f7073962cd7464c7c7d2cba08a041 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Tue, 23 Apr 2024 17:08:26 -0500
|
||||||
|
Subject: [PATCH 3/9] Allow system.devices to be automatically created on first
|
||||||
|
boot
|
||||||
|
|
||||||
|
An OS installer can create system.devices for the system and
|
||||||
|
disks, but an OS image cannot create the system-specific
|
||||||
|
system.devices. The OS image can instead configure the
|
||||||
|
image so that lvm will create system.devices on first boot.
|
||||||
|
|
||||||
|
Image preparation steps to enable auto creation of system.devices:
|
||||||
|
- create empty file /etc/lvm/devices/auto-import-rootvg
|
||||||
|
- remove any existing /etc/lvm/devices/system.devices
|
||||||
|
- enable lvm-devices-import.path
|
||||||
|
- enable lvm-devices-import.service
|
||||||
|
|
||||||
|
On first boot of the prepared image:
|
||||||
|
- udev triggers vgchange -aay --autoactivation event <rootvg>
|
||||||
|
- vgchange activates LVs in the root VG
|
||||||
|
- vgchange finds the file /etc/lvm/devices/auto-import-rootvg,
|
||||||
|
and no /etc/lvm/devices/system.devices, so it creates
|
||||||
|
/run/lvm/lvm-devices-import
|
||||||
|
- lvm-devices-import.path is run when /run/lvm/lvm-devices-import
|
||||||
|
appears, and triggers lvm-devices-import.service
|
||||||
|
- lvm-devices-import.service runs vgimportdevices --rootvg --auto
|
||||||
|
- vgimportdevices finds /etc/lvm/devices/auto-import-rootvg,
|
||||||
|
and no system.devices, so it creates system.devices containing
|
||||||
|
PVs in the root VG, and removes /etc/lvm/devices/auto-import-rootvg
|
||||||
|
and /run/lvm/lvm-devices-import
|
||||||
|
|
||||||
|
Run directly, vgimportdevices --rootvg (without --auto), will create
|
||||||
|
a new system.devices for the root VG, or will add devices for the
|
||||||
|
root VG to an existing system.devices.
|
||||||
|
|
||||||
|
(cherry picked from commit c609dedc2f035f770b5f645c4695924abf15c2ca)
|
||||||
|
(cherry picked from commit 3321a669d8f2df99df9d6dcd4ebb2b4d30731c7a)
|
||||||
|
---
|
||||||
|
lib/commands/toolcontext.h | 1 +
|
||||||
|
lib/config/defaults.h | 2 +
|
||||||
|
lib/device/device_id.c | 5 +-
|
||||||
|
scripts/lvm-devices-import.path | 12 +++
|
||||||
|
scripts/lvm-devices-import.service | 12 +++
|
||||||
|
tools/args.h | 11 ++
|
||||||
|
tools/command-lines.in | 5 +
|
||||||
|
tools/pvscan.c | 4 +-
|
||||||
|
tools/tools.h | 2 +-
|
||||||
|
tools/vgchange.c | 155 ++++++++++++++++++++++++++++-
|
||||||
|
tools/vgimportdevices.c | 114 ++++++++++++++++++++-
|
||||||
|
11 files changed, 315 insertions(+), 8 deletions(-)
|
||||||
|
create mode 100644 scripts/lvm-devices-import.path
|
||||||
|
create mode 100644 scripts/lvm-devices-import.service
|
||||||
|
|
||||||
|
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
|
||||||
|
index fec0a52cf..043afbf76 100644
|
||||||
|
--- a/lib/commands/toolcontext.h
|
||||||
|
+++ b/lib/commands/toolcontext.h
|
||||||
|
@@ -217,6 +217,7 @@ struct cmd_context {
|
||||||
|
unsigned device_ids_check_hostname:1;
|
||||||
|
unsigned device_ids_refresh_trigger:1;
|
||||||
|
unsigned device_ids_invalid:1;
|
||||||
|
+ unsigned device_ids_auto_import:1;
|
||||||
|
unsigned get_vgname_from_options:1; /* used by lvconvert */
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
|
||||||
|
index ed0c4f404..efe36d1fa 100644
|
||||||
|
--- a/lib/config/defaults.h
|
||||||
|
+++ b/lib/config/defaults.h
|
||||||
|
@@ -337,6 +337,8 @@
|
||||||
|
#define VGS_ONLINE_DIR DEFAULT_RUN_DIR "/vgs_online"
|
||||||
|
#define PVS_LOOKUP_DIR DEFAULT_RUN_DIR "/pvs_lookup"
|
||||||
|
|
||||||
|
+#define DEVICES_IMPORT_PATH DEFAULT_RUN_DIR "/lvm-devices-import"
|
||||||
|
+
|
||||||
|
#define DEFAULT_DEVICE_ID_SYSFS_DIR "/sys/" /* trailing / to match dm_sysfs_dir() */
|
||||||
|
|
||||||
|
#define DEFAULT_DEVICESFILE_BACKUP_LIMIT 50
|
||||||
|
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||||
|
index 2b183810a..1ce7927ed 100644
|
||||||
|
--- a/lib/device/device_id.c
|
||||||
|
+++ b/lib/device/device_id.c
|
||||||
|
@@ -1726,9 +1726,10 @@ int device_ids_write(struct cmd_context *cmd)
|
||||||
|
|
||||||
|
if ((fc_bytes = snprintf(fc, sizeof(fc),
|
||||||
|
"# LVM uses devices listed in this file.\n" \
|
||||||
|
- "# Created by LVM command %s pid %d at %s" \
|
||||||
|
+ "# Created by LVM command %s%s pid %d at %s" \
|
||||||
|
"# HASH=%u\n",
|
||||||
|
- cmd->name, getpid(), ctime(&t), hash)) < 0) {
|
||||||
|
+ cmd->name, cmd->device_ids_auto_import ? " (auto)" : "",
|
||||||
|
+ getpid(), ctime(&t), hash)) < 0) {
|
||||||
|
log_error("Failed to write buffer for devices file content.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
diff --git a/scripts/lvm-devices-import.path b/scripts/lvm-devices-import.path
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..bcf0dcd4c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/scripts/lvm-devices-import.path
|
||||||
|
@@ -0,0 +1,12 @@
|
||||||
|
+[Unit]
|
||||||
|
+Description=lvm-devices-import to create system.devices
|
||||||
|
+
|
||||||
|
+# /run/lvm/lvm-devices-import created by vgchange -aay <rootvg>
|
||||||
|
+
|
||||||
|
+[Path]
|
||||||
|
+PathExists=/run/lvm/lvm-devices-import
|
||||||
|
+Unit=lvm-devices-import.service
|
||||||
|
+ConditionPathExists=!/etc/lvm/devices/system.devices
|
||||||
|
+
|
||||||
|
+[Install]
|
||||||
|
+WantedBy=multi-user.target
|
||||||
|
diff --git a/scripts/lvm-devices-import.service b/scripts/lvm-devices-import.service
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..9d3bda2ee
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/scripts/lvm-devices-import.service
|
||||||
|
@@ -0,0 +1,12 @@
|
||||||
|
+[Unit]
|
||||||
|
+Description=Create lvm system.devices
|
||||||
|
+
|
||||||
|
+[Service]
|
||||||
|
+Type=oneshot
|
||||||
|
+RemainAfterExit=no
|
||||||
|
+ExecStart=/usr/sbin/vgimportdevices --rootvg --auto
|
||||||
|
+ConditionPathExists=!/etc/lvm/devices/system.devices
|
||||||
|
+
|
||||||
|
+[Install]
|
||||||
|
+WantedBy=multi-user.target
|
||||||
|
+
|
||||||
|
diff --git a/tools/args.h b/tools/args.h
|
||||||
|
index 09b2ad551..ed0fb9620 100644
|
||||||
|
--- a/tools/args.h
|
||||||
|
+++ b/tools/args.h
|
||||||
|
@@ -94,6 +94,14 @@ arg(atversion_ARG, '\0', "atversion", string_VAL, 0, 0,
|
||||||
|
"which does not contain any newer settings for which LVM would\n"
|
||||||
|
"issue a warning message when checking the configuration.\n")
|
||||||
|
|
||||||
|
+arg(auto_ARG, '\0', "auto", 0, 0, 0,
|
||||||
|
+ "This option is used when automatically importing devices for the root VG.\n"
|
||||||
|
+ "The auto import is intended to be done once, on first boot, to create an\n"
|
||||||
|
+ "initial system.devices file for the root VG.\n"
|
||||||
|
+ "When this option is used, the vgimportdevices --rootvg command does nothing\n"
|
||||||
|
+ "if system.devices exists, or the file auto-import-rootvg does not exist\n"
|
||||||
|
+ "(both in the /etc/lvm/devices/ directory.)\n")
|
||||||
|
+
|
||||||
|
arg(autoactivation_ARG, '\0', "autoactivation", string_VAL, 0, 0,
|
||||||
|
"Specify if autoactivation is being used from an event.\n"
|
||||||
|
"This allows the command to apply settings that are specific\n"
|
||||||
|
@@ -754,6 +762,9 @@ arg(resync_ARG, '\0', "resync", 0, 0, 0,
|
||||||
|
"which the LV is without a complete redundant copy of the data.\n"
|
||||||
|
"See \\fBlvmraid\\fP(7) for more information.\n")
|
||||||
|
|
||||||
|
+arg(rootvg_ARG, '\0', "rootvg", 0, 0, 0,
|
||||||
|
+ "Import devices used for the root VG.\n")
|
||||||
|
+
|
||||||
|
arg(rows_ARG, '\0', "rows", 0, 0, 0,
|
||||||
|
"Output columns as rows.\n")
|
||||||
|
|
||||||
|
diff --git a/tools/command-lines.in b/tools/command-lines.in
|
||||||
|
index 1c728afa0..3ad5d3c46 100644
|
||||||
|
--- a/tools/command-lines.in
|
||||||
|
+++ b/tools/command-lines.in
|
||||||
|
@@ -1911,6 +1911,11 @@ OO: --foreign, --reportformat ReportFmt
|
||||||
|
ID: vgimportdevices_all
|
||||||
|
DESC: Add devices from all accessible VGs to the devices file.
|
||||||
|
|
||||||
|
+vgimportdevices --rootvg
|
||||||
|
+OO: --auto, --reportformat ReportFmt
|
||||||
|
+ID: vgimportdevices_root
|
||||||
|
+DESC: Add devices from root VG to the devices file.
|
||||||
|
+
|
||||||
|
---
|
||||||
|
|
||||||
|
vgmerge VG VG
|
||||||
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
||||||
|
index f88e1b751..0a9cb59df 100644
|
||||||
|
--- a/tools/pvscan.c
|
||||||
|
+++ b/tools/pvscan.c
|
||||||
|
@@ -495,7 +495,7 @@ static int _pvscan_aa_single(struct cmd_context *cmd, const char *vg_name,
|
||||||
|
|
||||||
|
log_debug("pvscan autoactivating VG %s.", vg_name);
|
||||||
|
|
||||||
|
- if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1)) {
|
||||||
|
+ if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1, NULL)) {
|
||||||
|
log_error_pvscan(cmd, "%s: autoactivation failed.", vg->name);
|
||||||
|
pp->activate_errors++;
|
||||||
|
}
|
||||||
|
@@ -755,7 +755,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
|
||||||
|
|
||||||
|
log_debug("pvscan autoactivating VG %s.", vgname);
|
||||||
|
|
||||||
|
- if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1)) {
|
||||||
|
+ if (!vgchange_activate(cmd, vg, CHANGE_AAY, 1, NULL)) {
|
||||||
|
log_error_pvscan(cmd, "%s: autoactivation failed.", vg->name);
|
||||||
|
pp->activate_errors++;
|
||||||
|
}
|
||||||
|
diff --git a/tools/tools.h b/tools/tools.h
|
||||||
|
index f4a0c94d7..58708c695 100644
|
||||||
|
--- a/tools/tools.h
|
||||||
|
+++ b/tools/tools.h
|
||||||
|
@@ -164,7 +164,7 @@ int mirror_remove_missing(struct cmd_context *cmd,
|
||||||
|
|
||||||
|
|
||||||
|
int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
- activation_change_t activate, int vg_complete_to_activate);
|
||||||
|
+ activation_change_t activate, int vg_complete_to_activate, char *root_dm_uuid);
|
||||||
|
|
||||||
|
int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg);
|
||||||
|
|
||||||
|
diff --git a/tools/vgchange.c b/tools/vgchange.c
|
||||||
|
index 378ded16e..2004d6e92 100644
|
||||||
|
--- a/tools/vgchange.c
|
||||||
|
+++ b/tools/vgchange.c
|
||||||
|
@@ -16,11 +16,14 @@
|
||||||
|
#include "tools.h"
|
||||||
|
#include "lib/device/device_id.h"
|
||||||
|
#include "lib/label/hints.h"
|
||||||
|
+#include "device_mapper/misc/dm-ioctl.h"
|
||||||
|
+#include <mntent.h>
|
||||||
|
|
||||||
|
struct vgchange_params {
|
||||||
|
int lock_start_count;
|
||||||
|
unsigned int lock_start_sanlock : 1;
|
||||||
|
unsigned int vg_complete_to_activate : 1;
|
||||||
|
+ char *root_dm_uuid; /* dm uuid of LV under root fs */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -197,7 +200,7 @@ int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg
|
||||||
|
}
|
||||||
|
|
||||||
|
int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
- activation_change_t activate, int vg_complete_to_activate)
|
||||||
|
+ activation_change_t activate, int vg_complete_to_activate, char *root_dm_uuid)
|
||||||
|
{
|
||||||
|
int lv_open, active, monitored = 0, r = 1;
|
||||||
|
const struct lv_list *lvl;
|
||||||
|
@@ -279,6 +282,43 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Possibly trigger auto-generation of system.devices:
|
||||||
|
+ * - if root_dm_uuid contains vg->id, and
|
||||||
|
+ * - /etc/lvm/devices/auto-import-rootvg exists, and
|
||||||
|
+ * - /etc/lvm/devices/system.devices does not exist, then
|
||||||
|
+ * - create /run/lvm/lvm-devices-import to
|
||||||
|
+ * trigger lvm-devices-import.path and .service
|
||||||
|
+ * - lvm-devices-import will run vgimportdevices --rootvg
|
||||||
|
+ * to create system.devices
|
||||||
|
+ */
|
||||||
|
+ if (root_dm_uuid) {
|
||||||
|
+ char path[PATH_MAX];
|
||||||
|
+ struct stat info;
|
||||||
|
+ FILE *fp;
|
||||||
|
+
|
||||||
|
+ if (memcmp(root_dm_uuid + 4, &vg->id, ID_LEN))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ if (cmd->enable_devices_file || devices_file_exists(cmd))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ if (stat(path, &info) < 0)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ log_debug("Found %s creating %s", path, DEVICES_IMPORT_PATH);
|
||||||
|
+
|
||||||
|
+ if (!(fp = fopen(DEVICES_IMPORT_PATH, "w"))) {
|
||||||
|
+ log_debug("failed to create %s", DEVICES_IMPORT_PATH);
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ if (fclose(fp))
|
||||||
|
+ stack;
|
||||||
|
+ }
|
||||||
|
+out:
|
||||||
|
/* Print message only if there was not found a missing VG */
|
||||||
|
log_print_unless_silent("%d logical volume(s) in volume group \"%s\" now active",
|
||||||
|
lvs_in_vg_activated(vg), vg->name);
|
||||||
|
@@ -714,7 +754,7 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
||||||
|
|
||||||
|
if (arg_is_set(cmd, activate_ARG)) {
|
||||||
|
activate = (activation_change_t) arg_uint_value(cmd, activate_ARG, 0);
|
||||||
|
- if (!vgchange_activate(cmd, vg, activate, vp->vg_complete_to_activate))
|
||||||
|
+ if (!vgchange_activate(cmd, vg, activate, vp->vg_complete_to_activate, vp->root_dm_uuid))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
} else if (arg_is_set(cmd, refresh_ARG)) {
|
||||||
|
/* refreshes the visible LVs (which starts polling) */
|
||||||
|
@@ -735,6 +775,115 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Automatic creation of system.devices for root VG on first boot
|
||||||
|
+ * is useful for OS images where the OS installer is not used to
|
||||||
|
+ * customize the OS for system.
|
||||||
|
+ *
|
||||||
|
+ * - OS image prep:
|
||||||
|
+ * . rm /etc/lvm/devices/system.devices (if it exists)
|
||||||
|
+ * . touch /etc/lvm/devices/auto-import-rootvg
|
||||||
|
+ * . enable lvm-devices-import.path
|
||||||
|
+ * . enable lvm-devices-import.service
|
||||||
|
+ *
|
||||||
|
+ * - lvchange -ay <rootvg>/<rootlv>
|
||||||
|
+ * . run by initrd so root fs can be mounted
|
||||||
|
+ * . does not use system.devices
|
||||||
|
+ * . named <rootvg>/<rootlv> comes from kernel command line rd.lvm
|
||||||
|
+ * . uses first device that appears containing the named root LV
|
||||||
|
+ *
|
||||||
|
+ * - vgchange -aay <rootvg>
|
||||||
|
+ * . triggered by udev when all PVs from root VG are online
|
||||||
|
+ * . activate LVs in root VG (in addition to the already active root LV)
|
||||||
|
+ * . check for /etc/lvm/devices/auto-import-rootvg (found)
|
||||||
|
+ * . check for /etc/lvm/devices/system.devices (not found)
|
||||||
|
+ * . create /run/lvm/lvm-devices-import because
|
||||||
|
+ * auto-import-rootvg was found and system.devices was not found
|
||||||
|
+ *
|
||||||
|
+ * - lvm-devices-import.path
|
||||||
|
+ * . triggered by /run/lvm/lvm-devices-import
|
||||||
|
+ * . start lvm-devices-import.service
|
||||||
|
+ *
|
||||||
|
+ * - lvm-devices-import.service
|
||||||
|
+ * . check for /etc/lvm/devices/system.devices, do nothing if found
|
||||||
|
+ * . run vgimportdevices --rootvg --auto
|
||||||
|
+ *
|
||||||
|
+ * - vgimportdevices --rootvg --auto
|
||||||
|
+ * . check for /etc/lvm/devices/auto-import-rootvg (found)
|
||||||
|
+ * . check for /etc/lvm/devices/system.devices (not found)
|
||||||
|
+ * . creates /etc/lvm/devices/system.devices for PVs in root VG
|
||||||
|
+ * . removes /etc/lvm/devices/auto-import-rootvg
|
||||||
|
+ * . removes /run/lvm/lvm-devices-import
|
||||||
|
+ *
|
||||||
|
+ * On future startup, /etc/lvm/devices/system.devices will exist,
|
||||||
|
+ * and /etc/lvm/devices/auto-import-rootvg will not exist, so
|
||||||
|
+ * vgchange -aay <rootvg> will not create /run/lvm/lvm-devices-import,
|
||||||
|
+ * and lvm-devices-import.path and lvm-device-import.service will not run.
|
||||||
|
+ *
|
||||||
|
+ * lvm-devices-import.path:
|
||||||
|
+ * [Path]
|
||||||
|
+ * PathExists=/run/lvm/lvm-devices-import
|
||||||
|
+ * Unit=lvm-devices-import.service
|
||||||
|
+ * ConditionPathExists=!/etc/lvm/devices/system.devices
|
||||||
|
+ *
|
||||||
|
+ * lvm-devices-import.service:
|
||||||
|
+ * [Service]
|
||||||
|
+ * Type=oneshot
|
||||||
|
+ * RemainAfterExit=no
|
||||||
|
+ * ExecStart=/usr/sbin/vgimportdevices --rootvg --auto
|
||||||
|
+ * ConditionPathExists=!/etc/lvm/devices/system.devices
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static void _get_rootvg_dev(struct cmd_context *cmd, char **dm_uuid_out)
|
||||||
|
+{
|
||||||
|
+ char path[PATH_MAX];
|
||||||
|
+ char dm_uuid[DM_UUID_LEN];
|
||||||
|
+ struct stat info;
|
||||||
|
+ FILE *fme = NULL;
|
||||||
|
+ struct mntent *me;
|
||||||
|
+ int found = 0;
|
||||||
|
+
|
||||||
|
+ if (cmd->enable_devices_file || devices_file_exists(cmd))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (stat(path, &info) < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (!(fme = setmntent("/etc/mtab", "r")))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ while ((me = getmntent(fme))) {
|
||||||
|
+ if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) {
|
||||||
|
+ found = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ endmntent(fme);
|
||||||
|
+
|
||||||
|
+ if (!found)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (stat(me->mnt_dir, &info) < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), (int)MAJOR(info.st_dev), (int)MINOR(info.st_dev)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ log_debug("Found root dm_uuid %s", dm_uuid);
|
||||||
|
+
|
||||||
|
+ /* UUID_PREFIX = "LVM-" */
|
||||||
|
+ if (strncmp(dm_uuid, UUID_PREFIX, 4))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (strlen(dm_uuid) < 4 + ID_LEN)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
|
||||||
|
struct vgchange_params *vp,
|
||||||
|
int *skip_command,
|
||||||
|
@@ -778,6 +927,8 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
|
||||||
|
|
||||||
|
get_single_vgname_cmd_arg(cmd, NULL, &vgname);
|
||||||
|
|
||||||
|
+ _get_rootvg_dev(cmd, &vp->root_dm_uuid);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Lock the VG before scanning the PVs so _vg_read can avoid the normal
|
||||||
|
* lock_vol+rescan (READ_WITHOUT_LOCK avoids the normal lock_vol and
|
||||||
|
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
|
||||||
|
index bccd94f61..70d12e500 100644
|
||||||
|
--- a/tools/vgimportdevices.c
|
||||||
|
+++ b/tools/vgimportdevices.c
|
||||||
|
@@ -15,11 +15,16 @@
|
||||||
|
#include "tools.h"
|
||||||
|
#include "lib/cache/lvmcache.h"
|
||||||
|
#include "lib/device/device_id.h"
|
||||||
|
+#include "device_mapper/misc/dm-ioctl.h"
|
||||||
|
/* coverity[unnecessary_header] needed for MuslC */
|
||||||
|
#include <sys/file.h>
|
||||||
|
+#include <mntent.h>
|
||||||
|
|
||||||
|
struct vgimportdevices_params {
|
||||||
|
uint32_t added_devices;
|
||||||
|
+ int root_vg_found;
|
||||||
|
+ char *root_dm_uuid;
|
||||||
|
+ char *root_vg_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _vgimportdevices_single(struct cmd_context *cmd,
|
||||||
|
@@ -35,6 +40,13 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
|
||||||
|
int updated_pvs = 0;
|
||||||
|
const char *idtypestr = NULL; /* deviceidtype_ARG ? */
|
||||||
|
|
||||||
|
+ if (vp->root_dm_uuid) {
|
||||||
|
+ if (memcmp(vp->root_dm_uuid + 4, &vg->id, ID_LEN))
|
||||||
|
+ return ECMD_PROCESSED;
|
||||||
|
+ vp->root_vg_found = 1;
|
||||||
|
+ vp->root_vg_name = dm_pool_strdup(cmd->mem, vg_name);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
|
if (is_missing_pv(pvl->pv) || !pvl->pv->dev) {
|
||||||
|
memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
|
||||||
|
@@ -86,6 +98,87 @@ static int _vgimportdevices_single(struct cmd_context *cmd,
|
||||||
|
return ECMD_PROCESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _get_rootvg_dev(struct cmd_context *cmd, char **dm_uuid_out, int *skip)
|
||||||
|
+{
|
||||||
|
+ char path[PATH_MAX];
|
||||||
|
+ char dm_uuid[DM_UUID_LEN];
|
||||||
|
+ struct stat info;
|
||||||
|
+ FILE *fme = NULL;
|
||||||
|
+ struct mntent *me;
|
||||||
|
+ int found = 0;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * When --auto is set, the command does nothing
|
||||||
|
+ * if /etc/lvm/devices/system.devices exists, or
|
||||||
|
+ * if /etc/lvm/devices/auto-import-rootvg does not exist.
|
||||||
|
+ */
|
||||||
|
+ if (arg_is_set(cmd, auto_ARG)) {
|
||||||
|
+ if (devices_file_exists(cmd)) {
|
||||||
|
+ *skip = 1;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0)
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (stat(path, &info) < 0) {
|
||||||
|
+ *skip = 1;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * This flag is just used in device_ids_write to enable
|
||||||
|
+ * an extra comment in system.devices indicating that
|
||||||
|
+ * the file was auto generated for the root vg.
|
||||||
|
+ */
|
||||||
|
+ cmd->device_ids_auto_import = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(fme = setmntent("/etc/mtab", "r")))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ while ((me = getmntent(fme))) {
|
||||||
|
+ if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) {
|
||||||
|
+ found = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ endmntent(fme);
|
||||||
|
+
|
||||||
|
+ if (!found)
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (stat(me->mnt_dir, &info) < 0)
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), (int)MAJOR(info.st_dev), (int)MINOR(info.st_dev)))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ /* UUID_PREFIX = "LVM-" */
|
||||||
|
+ if (strncmp(dm_uuid, UUID_PREFIX, 4))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (strlen(dm_uuid) < 4 + ID_LEN)
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid);
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void _clear_rootvg_auto(struct cmd_context *cmd)
|
||||||
|
+{
|
||||||
|
+ char path[PATH_MAX];
|
||||||
|
+
|
||||||
|
+ if (dm_snprintf(path, sizeof(path), "%s/devices/auto-import-rootvg", cmd->system_dir) < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (unlink(path) < 0)
|
||||||
|
+ log_debug("Failed to unlink %s", path);
|
||||||
|
+
|
||||||
|
+ if (unlink(DEVICES_IMPORT_PATH) < 0)
|
||||||
|
+ log_debug("Failed to unlink %s", DEVICES_IMPORT_PATH);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* This command always scans all devices on the system,
|
||||||
|
* any pre-existing devices_file does not limit the scope.
|
||||||
|
@@ -130,6 +223,19 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
/* So that we can warn about this. */
|
||||||
|
cmd->handles_missing_pvs = 1;
|
||||||
|
|
||||||
|
+ /* Import devices for the root VG. */
|
||||||
|
+ if (arg_is_set(cmd, rootvg_ARG)) {
|
||||||
|
+ int skip = 0;
|
||||||
|
+ if (!_get_rootvg_dev(cmd, &vp.root_dm_uuid, &skip)) {
|
||||||
|
+ log_error("Failed to find root VG.");
|
||||||
|
+ return ECMD_FAILED;
|
||||||
|
+ }
|
||||||
|
+ if (skip) {
|
||||||
|
+ log_print("Root VG auto import is not enabled.");
|
||||||
|
+ return ECMD_PROCESSED;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!lock_global(cmd, "ex"))
|
||||||
|
return ECMD_FAILED;
|
||||||
|
|
||||||
|
@@ -230,7 +336,13 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- log_print("Added %u devices to devices file.", vp.added_devices);
|
||||||
|
+ if (vp.root_vg_found)
|
||||||
|
+ log_print("Added %u devices to devices file for root VG %s.", vp.added_devices, vp.root_vg_name);
|
||||||
|
+ else
|
||||||
|
+ log_print("Added %u devices to devices file.", vp.added_devices);
|
||||||
|
+
|
||||||
|
+ if (vp.root_vg_found && arg_is_set(cmd, auto_ARG))
|
||||||
|
+ _clear_rootvg_auto(cmd);
|
||||||
|
out:
|
||||||
|
if ((ret == ECMD_FAILED) && created_file)
|
||||||
|
if (unlink(cmd->devices_file_path) < 0)
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
From 1835574e39e9417b3800469fe80ce47d2210b9a7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
|
||||||
Date: Sun, 23 Apr 2023 12:49:37 +0200
|
|
||||||
Subject: [PATCH 3/8] lvmdbus: preserve PATH envvar
|
|
||||||
|
|
||||||
(cherry picked from commit afc02ae6e7234e1190cedf5c74ca3d6367efd7d1)
|
|
||||||
---
|
|
||||||
daemons/lvmdbusd/lvm_shell_proxy.py.in | 2 ++
|
|
||||||
1 file changed, 2 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
|
|
||||||
index b8c8fa565..02a776e1d 100755
|
|
||||||
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
|
|
||||||
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
|
|
||||||
@@ -154,6 +154,8 @@ class LVMShellProxy(object):
|
|
||||||
|
|
||||||
# If any env variables contain LVM we will propagate them too
|
|
||||||
for k, v in os.environ.items():
|
|
||||||
+ if "PATH" in k:
|
|
||||||
+ local_env[k] = v
|
|
||||||
if "LVM" in k:
|
|
||||||
local_env[k] = v
|
|
||||||
|
|
||||||
--
|
|
||||||
2.40.1
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 9881bf7c27c5acd6e3a13d258cf347ec167957b5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Fri, 24 May 2024 19:49:08 +0200
|
||||||
|
Subject: [PATCH 4/9] lvm: fix shell completion
|
||||||
|
|
||||||
|
Previous commit 82617852a4d3c89b09124eddedcc2c1859b9d50e
|
||||||
|
introduce bug in complession - as the rl_completion_matches()
|
||||||
|
needs to always advance to next element where the index
|
||||||
|
is held in static variable.
|
||||||
|
|
||||||
|
Add comment about this usage.
|
||||||
|
|
||||||
|
(cherry picked from commit 73298635b9db2c2a11bc4cc291b15d0f21907598)
|
||||||
|
(cherry picked from commit c33b0e11878a52aeaa42b4ebfd0692e5da7f5e07)
|
||||||
|
---
|
||||||
|
tools/lvm.c | 13 ++++++++-----
|
||||||
|
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/lvm.c b/tools/lvm.c
|
||||||
|
index 116b707b2..3a7e6dc6c 100644
|
||||||
|
--- a/tools/lvm.c
|
||||||
|
+++ b/tools/lvm.c
|
||||||
|
@@ -52,7 +52,8 @@ static char *_list_cmds(const char *text, int state)
|
||||||
|
|
||||||
|
for (;i < _cmdline->num_command_names;++i)
|
||||||
|
if (!strncmp(text, _cmdline->command_names[i].name, len))
|
||||||
|
- return strdup(_cmdline->command_names[i].name);
|
||||||
|
+ /* increase position for next iteration */
|
||||||
|
+ return strdup(_cmdline->command_names[i++].name);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -102,9 +103,10 @@ static char *_list_args(const char *text, int state)
|
||||||
|
|
||||||
|
/* Short form arguments */
|
||||||
|
if (len < 3) {
|
||||||
|
- for (;match_no < cna->num_args; ++match_no) {
|
||||||
|
+ while (match_no < cna->num_args) {
|
||||||
|
char s[3];
|
||||||
|
- char c = (_cmdline->opt_names + cna->valid_args[match_no])->short_opt;
|
||||||
|
+ /* increase position for next iteration */
|
||||||
|
+ char c = _cmdline->opt_names[cna->valid_args[match_no++]].short_opt;
|
||||||
|
if (c) {
|
||||||
|
sprintf(s, "-%c", c);
|
||||||
|
if (!strncmp(text, s, len))
|
||||||
|
@@ -117,8 +119,9 @@ static char *_list_args(const char *text, int state)
|
||||||
|
if (match_no < cna->num_args)
|
||||||
|
match_no = cna->num_args;
|
||||||
|
|
||||||
|
- for (;match_no - cna->num_args < cna->num_args; ++match_no) {
|
||||||
|
- const char *l = (_cmdline->opt_names + cna->valid_args[match_no - cna->num_args])->long_opt;
|
||||||
|
+ while ((match_no - cna->num_args) < cna->num_args) {
|
||||||
|
+ /* increase position for next iteration */
|
||||||
|
+ const char *l = _cmdline->opt_names[cna->valid_args[match_no++ - cna->num_args]].long_opt;
|
||||||
|
if (*(l + 2) && !strncmp(text, l, len))
|
||||||
|
return strdup(l);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
From 80b73e2901d470fd3d1f45664626980167091f02 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Tue, 25 Apr 2023 14:46:36 -0500
|
|
||||||
Subject: [PATCH 4/8] lvmcache: fix valgrind error when dropping md duplicate
|
|
||||||
|
|
||||||
When lvmcache info is dropped because it's an md component,
|
|
||||||
then the lvmcache vginfo can also be dropped, but the list
|
|
||||||
iterator was still using the list head in vginfo, so break
|
|
||||||
from the loop earlier to avoid it.
|
|
||||||
|
|
||||||
(cherry picked from commit 6d262eaf640dead7861c1a7716e216b9bcea75e5)
|
|
||||||
---
|
|
||||||
lib/cache/lvmcache.c | 7 +++++++
|
|
||||||
1 file changed, 7 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
|
|
||||||
index b8a9eac25..127d29229 100644
|
|
||||||
--- a/lib/cache/lvmcache.c
|
|
||||||
+++ b/lib/cache/lvmcache.c
|
|
||||||
@@ -1503,6 +1503,9 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
|
|
||||||
*/
|
|
||||||
|
|
||||||
dm_list_iterate_items_safe(vginfo, vginfo2, &_vginfos) {
|
|
||||||
+ char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
|
||||||
+ memcpy(vgid, vginfo->vgid, ID_LEN);
|
|
||||||
+
|
|
||||||
dm_list_iterate_items_safe(info, info2, &vginfo->infos) {
|
|
||||||
dev = info->dev;
|
|
||||||
device_hint = _get_pvsummary_device_hint(dev->pvid);
|
|
||||||
@@ -1557,6 +1560,10 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
|
|
||||||
/* lvmcache_del will also delete vginfo if info was last one */
|
|
||||||
lvmcache_del(info);
|
|
||||||
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
|
|
||||||
+
|
|
||||||
+ /* If vginfo was deleted don't continue using vginfo->infos */
|
|
||||||
+ if (!_search_vginfos_list(NULL, vgid))
|
|
||||||
+ break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.40.1
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From 0a9228807d0b3901be4ccf29311a955efba4877e Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Fri, 28 Apr 2023 13:31:39 -0500
|
|
||||||
Subject: [PATCH 5/8] pvck: improve error for write to existing file
|
|
||||||
|
|
||||||
(cherry picked from commit c4440b5b495a2d11ff541dd7e7791e2a83c83609)
|
|
||||||
---
|
|
||||||
tools/pvck.c | 5 +++++
|
|
||||||
1 file changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/tools/pvck.c b/tools/pvck.c
|
|
||||||
index 879810b76..0998caaf5 100644
|
|
||||||
--- a/tools/pvck.c
|
|
||||||
+++ b/tools/pvck.c
|
|
||||||
@@ -1444,8 +1444,13 @@ static int _dump_metadata(struct cmd_context *cmd, const char *dump, struct sett
|
|
||||||
int bad = 0;
|
|
||||||
|
|
||||||
if (arg_is_set(cmd, file_ARG)) {
|
|
||||||
+ struct stat sb;
|
|
||||||
if (!(tofile = arg_str_value(cmd, file_ARG, NULL)))
|
|
||||||
return 0;
|
|
||||||
+ if (!stat(tofile, &sb)) {
|
|
||||||
+ log_error("File already exists.");
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set->mda_num)
|
|
||||||
--
|
|
||||||
2.40.1
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From 21601348504f709483286ea0e39a4310192fab96 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 30 May 2024 14:51:22 -0500
|
||||||
|
Subject: [PATCH 5/9] vgimportdevices: skip global lockd locking
|
||||||
|
|
||||||
|
Fix commit b65a2c3f3a767 "vgimportdevices: skip lvmlockd locking"
|
||||||
|
which intended to disable lvmlockd locking, but the lockd_gl_disable
|
||||||
|
flag was mistakenly set after lock_global() so it wasn't effective.
|
||||||
|
This caused vgimportdevices to fail unless locking was started.
|
||||||
|
|
||||||
|
(cherry picked from commit a8b8e1f074598d080bfb34e1fd04fe36ec122f93)
|
||||||
|
---
|
||||||
|
tools/vgimportdevices.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c
|
||||||
|
index 70d12e500..2217fdad6 100644
|
||||||
|
--- a/tools/vgimportdevices.c
|
||||||
|
+++ b/tools/vgimportdevices.c
|
||||||
|
@@ -236,7 +236,7 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!lock_global(cmd, "ex"))
|
||||||
|
+ if (!lockf_global(cmd, "ex"))
|
||||||
|
return ECMD_FAILED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -1,87 +0,0 @@
|
|||||||
From 7702262444a5af924d0fc94ff956663aab3505df Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Tue, 2 May 2023 16:12:23 -0500
|
|
||||||
Subject: [PATCH 6/8] lvreduce: make _lvseg_get_stripes handle integrity layer
|
|
||||||
|
|
||||||
lvreduce uses _lvseg_get_stripes() which was unable to get raid stripe
|
|
||||||
info with an integrity layer present. This caused lvreduce on a
|
|
||||||
raid+integrity LV to fail prematurely when checking stripe parameters.
|
|
||||||
An unhelpful error message about stripe size would be printed.
|
|
||||||
|
|
||||||
(cherry picked from commit 368381fd4022dc99ffe551b30ed75c3ddbc5c5c8)
|
|
||||||
---
|
|
||||||
lib/metadata/lv_manip.c | 35 ++++++++++++++++++++++++++---------
|
|
||||||
1 file changed, 26 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
|
||||||
index 2a4e0e88a..add9512ff 100644
|
|
||||||
--- a/lib/metadata/lv_manip.c
|
|
||||||
+++ b/lib/metadata/lv_manip.c
|
|
||||||
@@ -5144,22 +5144,39 @@ int lv_extend_policy_calculate_percent(struct logical_volume *lv,
|
|
||||||
|
|
||||||
static uint32_t _lvseg_get_stripes(struct lv_segment *seg, uint32_t *stripesize)
|
|
||||||
{
|
|
||||||
- uint32_t s;
|
|
||||||
- struct lv_segment *seg_mirr;
|
|
||||||
+ uint32_t s, a;
|
|
||||||
+ struct lv_segment *seg_get, *seg_image, *seg_iorig;
|
|
||||||
+ struct logical_volume *lv_image, *lv_iorig;
|
|
||||||
|
|
||||||
/* If segment mirrored, check if images are striped */
|
|
||||||
- if (seg_is_mirrored(seg))
|
|
||||||
+ if (seg_is_mirrored(seg)) {
|
|
||||||
for (s = 0; s < seg->area_count; s++) {
|
|
||||||
if (seg_type(seg, s) != AREA_LV)
|
|
||||||
continue;
|
|
||||||
- seg_mirr = first_seg(seg_lv(seg, s));
|
|
||||||
|
|
||||||
- if (seg_is_striped(seg_mirr)) {
|
|
||||||
- seg = seg_mirr;
|
|
||||||
+ lv_image = seg_lv(seg, s);
|
|
||||||
+ seg_image = first_seg(lv_image);
|
|
||||||
+ seg_get = NULL;
|
|
||||||
+
|
|
||||||
+ if (seg_is_integrity(seg_image)) {
|
|
||||||
+ /* Get stripe values from the iorig layer. */
|
|
||||||
+ for (a = 0; a < seg_image->area_count; a++) {
|
|
||||||
+ lv_iorig = seg_lv(seg_image, a);
|
|
||||||
+ seg_iorig = first_seg(lv_iorig);
|
|
||||||
+ seg_get = seg_iorig;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ /* Get stripe values from the image layer. */
|
|
||||||
+ seg_get = seg_image;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (seg_get && seg_is_striped(seg_get)) {
|
|
||||||
+ seg = seg_get;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (seg_is_striped(seg)) {
|
|
||||||
*stripesize = seg->stripe_size;
|
|
||||||
@@ -5168,7 +5185,7 @@ static uint32_t _lvseg_get_stripes(struct lv_segment *seg, uint32_t *stripesize)
|
|
||||||
|
|
||||||
if (seg_is_raid(seg)) {
|
|
||||||
*stripesize = seg->stripe_size;
|
|
||||||
- return _raid_stripes_count(seg);
|
|
||||||
+ return _raid_stripes_count(seg);
|
|
||||||
}
|
|
||||||
|
|
||||||
*stripesize = 0;
|
|
||||||
@@ -5593,7 +5610,7 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
|
|
||||||
seg_size /= seg_mirrors;
|
|
||||||
lp->extents = logical_extents_used + seg_size;
|
|
||||||
break;
|
|
||||||
- }
|
|
||||||
+ }
|
|
||||||
} else if (new_extents <= logical_extents_used + seg_logical_extents) {
|
|
||||||
seg_size = new_extents - logical_extents_used;
|
|
||||||
lp->extents = new_extents;
|
|
||||||
--
|
|
||||||
2.40.1
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
From aeb32f844d2b3edfbb2454fe43b29b3d045c8ad6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marian Csontos <mcsontos@redhat.com>
|
||||||
|
Date: Wed, 26 Jun 2024 14:37:17 +0200
|
||||||
|
Subject: [PATCH 6/9] scripts: Install services for devices file init
|
||||||
|
|
||||||
|
Services introduced in commit c609dedc2f035f770b5f645c4695924abf15c2ca
|
||||||
|
need installing.
|
||||||
|
|
||||||
|
(cherry picked from commit 1b9bf5007bbfba5bcd622f039a099e6f7e0a8162)
|
||||||
|
---
|
||||||
|
scripts/Makefile.in | 2 ++
|
||||||
|
spec/packages.inc | 2 ++
|
||||||
|
2 files changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
|
||||||
|
index a79edbd4d..f683b7ab1 100644
|
||||||
|
--- a/scripts/Makefile.in
|
||||||
|
+++ b/scripts/Makefile.in
|
||||||
|
@@ -108,6 +108,8 @@ endif
|
||||||
|
ifeq ("@BUILD_LVMDBUSD@", "yes")
|
||||||
|
$(Q) $(INSTALL_DATA) lvm2_lvmdbusd_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmdbusd.service
|
||||||
|
endif
|
||||||
|
+ $(Q) $(INSTALL_DATA) lvm-devices-import.path $(systemd_unit_dir)/lvm-devices-import.path
|
||||||
|
+ $(Q) $(INSTALL_DATA) lvm-devices-import.service $(systemd_unit_dir)/lvm-devices-import.service
|
||||||
|
|
||||||
|
ifeq ("@BUILD_LVMDBUSD@", "yes")
|
||||||
|
install_dbus_service:
|
||||||
|
diff --git a/spec/packages.inc b/spec/packages.inc
|
||||||
|
index 05733e0df..ee67af590 100644
|
||||||
|
--- a/spec/packages.inc
|
||||||
|
+++ b/spec/packages.inc
|
||||||
|
@@ -193,6 +193,8 @@ fi
|
||||||
|
%{_unitdir}/lvm2-lvmpolld.service
|
||||||
|
%{_unitdir}/lvm2-lvmpolld.socket
|
||||||
|
%endif
|
||||||
|
+ %{_unitdir}/lvm-devices-import.service
|
||||||
|
+ %{_unitdir}/lvm-devices-import.path
|
||||||
|
%else
|
||||||
|
%{_sysconfdir}/rc.d/init.d/blk-availability
|
||||||
|
%{_sysconfdir}/rc.d/init.d/lvm2-monitor
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -0,0 +1,330 @@
|
|||||||
|
From 04aeea691fc9f509d9f73f2fcffca8669abe1906 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Wed, 12 Jun 2024 15:36:45 -0500
|
||||||
|
Subject: [PATCH 7/9] lvmlockd: avoid lockd_vg for local VGs
|
||||||
|
|
||||||
|
Previously, a command would call lockd_vg() for a local VG,
|
||||||
|
which would go to lvmlockd, which would send back ENOLS,
|
||||||
|
and the command would not care when it saw the VG was local.
|
||||||
|
The pointless back-and-forth to lvmlockd for local VGs can
|
||||||
|
be avoided by checking the VG lock_type in lvmcache (which
|
||||||
|
label_scan now saves there; this wasn't the case back when
|
||||||
|
the original lockd_vg logic was added.) If the lock_type
|
||||||
|
saved during label_scan indicates a local VG, then the
|
||||||
|
lockd_vg step is skipped.
|
||||||
|
|
||||||
|
(cherry picked from commit bf60cb4da23cac2f6b721170dd0d8bfd38b16466)
|
||||||
|
---
|
||||||
|
lib/cache/lvmcache.c | 10 +++++++++
|
||||||
|
lib/cache/lvmcache.h | 2 ++
|
||||||
|
lib/locking/lvmlockd.c | 12 ++++++++---
|
||||||
|
tools/lvconvert.c | 8 ++++---
|
||||||
|
tools/polldaemon.c | 9 +++++---
|
||||||
|
tools/toollib.c | 47 +++++++++++++++++++++++++++++++++++-------
|
||||||
|
6 files changed, 71 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
|
||||||
|
index 711a97fec..1ea4cb7db 100644
|
||||||
|
--- a/lib/cache/lvmcache.c
|
||||||
|
+++ b/lib/cache/lvmcache.c
|
||||||
|
@@ -3002,6 +3002,16 @@ int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const ch
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int lvmcache_vg_is_lockd_type(struct cmd_context *cmd, const char *vgname, const char *vgid)
|
||||||
|
+{
|
||||||
|
+ struct lvmcache_vginfo *vginfo;
|
||||||
|
+
|
||||||
|
+ if ((vginfo = lvmcache_vginfo_from_vgname(vgname, vgid)))
|
||||||
|
+ return is_lockd_type(vginfo->lock_type);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Example of reading four devs in sequence from the same VG:
|
||||||
|
*
|
||||||
|
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
|
||||||
|
index eccf29eb2..760ff6ba1 100644
|
||||||
|
--- a/lib/cache/lvmcache.h
|
||||||
|
+++ b/lib/cache/lvmcache.h
|
||||||
|
@@ -179,6 +179,8 @@ void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
|
||||||
|
|
||||||
|
int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||||
|
|
||||||
|
+int lvmcache_vg_is_lockd_type(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||||
|
+
|
||||||
|
bool lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||||
|
|
||||||
|
int lvmcache_vginfo_has_pvid(struct lvmcache_vginfo *vginfo, const char *pvid_arg);
|
||||||
|
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
|
||||||
|
index 9c24b619f..33150cb48 100644
|
||||||
|
--- a/lib/locking/lvmlockd.c
|
||||||
|
+++ b/lib/locking/lvmlockd.c
|
||||||
|
@@ -2014,9 +2014,15 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
||||||
|
* this result is passed into vg_read(). After vg_read() reads the VG,
|
||||||
|
* it checks if the VG lock_type (sanlock or dlm) requires a lock to be
|
||||||
|
* held, and if so, it verifies that the lock was correctly acquired by
|
||||||
|
- * looking at lockd_state. If vg_read() sees that the VG is a local VG,
|
||||||
|
- * i.e. lock_type is not sanlock or dlm, then no lock is required, and it
|
||||||
|
- * ignores lockd_state (which would indicate no lock was found.)
|
||||||
|
+ * looking at lockd_state.
|
||||||
|
+ *
|
||||||
|
+ * If vg_read() sees that the VG is a local VG, i.e. lock_type is not
|
||||||
|
+ * sanlock or dlm, then no lock is required, and it ignores lockd_state,
|
||||||
|
+ * which would indicate no lock was found.... although a newer
|
||||||
|
+ * optimization avoids calling lockd_vg() at all for local VGs
|
||||||
|
+ * by checking the lock_type in lvmcache saved by label_scan. In extremely
|
||||||
|
+ * rare case where the lock_type changes between label_scan and vg_read,
|
||||||
|
+ * the caller will go back and repeat lockd_vg()+vg_read().
|
||||||
|
*/
|
||||||
|
|
||||||
|
int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||||
|
index dd40ef4f5..4e551a949 100644
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ b/tools/lvconvert.c
|
||||||
|
@@ -5788,10 +5788,12 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
|
||||||
|
struct logical_volume *lv_fast;
|
||||||
|
uint32_t lockd_state, error_flags;
|
||||||
|
uint64_t dirty;
|
||||||
|
+ int is_lockd;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
idl = dm_list_item(dm_list_first(&lr->poll_idls), struct convert_poll_id_list);
|
||||||
|
id = idl->id;
|
||||||
|
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, id->vg_name, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: we should be able to save info about the dm device for this LV
|
||||||
|
@@ -5806,7 +5808,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
|
||||||
|
lockd_state = 0;
|
||||||
|
error_flags = 0;
|
||||||
|
|
||||||
|
- if (!lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) {
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) {
|
||||||
|
log_error("Detaching writecache interrupted - locking VG failed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -5843,7 +5845,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
|
||||||
|
if (!lv_writecache_is_clean(cmd, lv, &dirty)) {
|
||||||
|
unlock_and_release_vg(cmd, vg, vg->name);
|
||||||
|
|
||||||
|
- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
||||||
|
stack;
|
||||||
|
|
||||||
|
log_print_unless_silent("Detaching writecache cleaning %llu blocks", (unsigned long long)dirty);
|
||||||
|
@@ -5896,7 +5898,7 @@ out_release:
|
||||||
|
unlock_and_release_vg(cmd, vg, vg->name);
|
||||||
|
|
||||||
|
out_lockd:
|
||||||
|
- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
||||||
|
stack;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
diff --git a/tools/polldaemon.c b/tools/polldaemon.c
|
||||||
|
index 730dfbcbb..3a9211768 100644
|
||||||
|
--- a/tools/polldaemon.c
|
||||||
|
+++ b/tools/polldaemon.c
|
||||||
|
@@ -156,6 +156,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
|
||||||
|
int finished = 0;
|
||||||
|
uint32_t lockd_state = 0;
|
||||||
|
uint32_t error_flags = 0;
|
||||||
|
+ int is_lockd;
|
||||||
|
int ret;
|
||||||
|
unsigned wait_before_testing = parms->wait_before_testing;
|
||||||
|
|
||||||
|
@@ -171,11 +172,13 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, id->vg_name, NULL);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* An ex VG lock is needed because the check can call finish_copy
|
||||||
|
* which writes the VG.
|
||||||
|
*/
|
||||||
|
- if (!lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) {
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "ex", 0, &lockd_state)) {
|
||||||
|
log_error("ABORTING: Can't lock VG for %s.", id->display_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -229,7 +232,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
|
||||||
|
|
||||||
|
unlock_and_release_vg(cmd, vg, vg->name);
|
||||||
|
|
||||||
|
- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
||||||
|
stack;
|
||||||
|
|
||||||
|
wait_before_testing = 1;
|
||||||
|
@@ -240,7 +243,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
|
||||||
|
out:
|
||||||
|
if (vg)
|
||||||
|
unlock_and_release_vg(cmd, vg, vg->name);
|
||||||
|
- if (!lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, id->vg_name, "un", 0, &lockd_state))
|
||||||
|
stack;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index 080ee5429..686a5423c 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -2176,6 +2176,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
int ret;
|
||||||
|
int skip;
|
||||||
|
int notfound;
|
||||||
|
+ int is_lockd;
|
||||||
|
int process_all = 0;
|
||||||
|
int do_report_ret_code = 1;
|
||||||
|
|
||||||
|
@@ -2195,6 +2196,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
vg_uuid = vgnl->vgid;
|
||||||
|
skip = 0;
|
||||||
|
notfound = 0;
|
||||||
|
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
|
||||||
|
|
||||||
|
uuid[0] = '\0';
|
||||||
|
if (is_orphan_vg(vg_name)) {
|
||||||
|
@@ -2212,8 +2214,8 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
}
|
||||||
|
|
||||||
|
log_very_verbose("Processing VG %s %s", vg_name, uuid);
|
||||||
|
-
|
||||||
|
- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
||||||
|
+do_lockd:
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
||||||
|
stack;
|
||||||
|
ret_max = ECMD_FAILED;
|
||||||
|
report_log_ret_code(ret_max);
|
||||||
|
@@ -2235,6 +2237,14 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
if (skip || notfound)
|
||||||
|
goto endvg;
|
||||||
|
|
||||||
|
+ if (!is_lockd && vg_is_shared(vg)) {
|
||||||
|
+ /* The lock_type changed since label_scan, won't really occur in practice. */
|
||||||
|
+ log_debug("Repeat lock and read for local to shared vg");
|
||||||
|
+ unlock_and_release_vg(cmd, vg, vg_name);
|
||||||
|
+ is_lockd = 1;
|
||||||
|
+ goto do_lockd;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Process this VG? */
|
||||||
|
if ((process_all ||
|
||||||
|
(!dm_list_empty(arg_vgnames) && str_list_match_item(arg_vgnames, vg_name)) ||
|
||||||
|
@@ -2255,7 +2265,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
unlock_vg(cmd, vg, vg_name);
|
||||||
|
endvg:
|
||||||
|
release_vg(vg);
|
||||||
|
- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
||||||
|
stack;
|
||||||
|
|
||||||
|
log_set_report_object_name_and_id(NULL, NULL);
|
||||||
|
@@ -3873,6 +3883,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
||||||
|
int ret;
|
||||||
|
int skip;
|
||||||
|
int notfound;
|
||||||
|
+ int is_lockd;
|
||||||
|
int do_report_ret_code = 1;
|
||||||
|
|
||||||
|
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
|
||||||
|
@@ -3882,6 +3893,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
||||||
|
vg_uuid = vgnl->vgid;
|
||||||
|
skip = 0;
|
||||||
|
notfound = 0;
|
||||||
|
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
|
||||||
|
|
||||||
|
uuid[0] = '\0';
|
||||||
|
if (vg_uuid && !id_write_format((const struct id*)vg_uuid, uuid, sizeof(uuid)))
|
||||||
|
@@ -3927,7 +3939,8 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
||||||
|
|
||||||
|
log_very_verbose("Processing VG %s %s", vg_name, vg_uuid ? uuid : "");
|
||||||
|
|
||||||
|
- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
||||||
|
+do_lockd:
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
||||||
|
ret_max = ECMD_FAILED;
|
||||||
|
report_log_ret_code(ret_max);
|
||||||
|
continue;
|
||||||
|
@@ -3948,6 +3961,14 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
||||||
|
if (skip || notfound)
|
||||||
|
goto endvg;
|
||||||
|
|
||||||
|
+ if (!is_lockd && vg_is_shared(vg)) {
|
||||||
|
+ /* The lock_type changed since label_scan, won't really occur in practice. */
|
||||||
|
+ log_debug("Repeat lock and read for local to shared vg");
|
||||||
|
+ unlock_and_release_vg(cmd, vg, vg_name);
|
||||||
|
+ is_lockd = 1;
|
||||||
|
+ goto do_lockd;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ret = process_each_lv_in_vg(cmd, vg, &lvnames, tags_arg, 0,
|
||||||
|
handle, check_single_lv, process_single_lv);
|
||||||
|
if (ret != ECMD_PROCESSED)
|
||||||
|
@@ -3959,7 +3980,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
|
||||||
|
unlock_vg(cmd, vg, vg_name);
|
||||||
|
endvg:
|
||||||
|
release_vg(vg);
|
||||||
|
- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
||||||
|
stack;
|
||||||
|
log_set_report_object_name_and_id(NULL, NULL);
|
||||||
|
}
|
||||||
|
@@ -4513,6 +4534,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
int ret;
|
||||||
|
int skip;
|
||||||
|
int notfound;
|
||||||
|
+ int is_lockd;
|
||||||
|
int do_report_ret_code = 1;
|
||||||
|
|
||||||
|
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
|
||||||
|
@@ -4522,6 +4544,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
vg_uuid = vgnl->vgid;
|
||||||
|
skip = 0;
|
||||||
|
notfound = 0;
|
||||||
|
+ is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
|
||||||
|
|
||||||
|
uuid[0] = '\0';
|
||||||
|
if (is_orphan_vg(vg_name)) {
|
||||||
|
@@ -4537,8 +4560,8 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
ret_max = ECMD_FAILED;
|
||||||
|
goto_out;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
||||||
|
+do_lockd:
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
|
||||||
|
ret_max = ECMD_FAILED;
|
||||||
|
report_log_ret_code(ret_max);
|
||||||
|
continue;
|
||||||
|
@@ -4561,6 +4584,14 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
|
||||||
|
if (notfound)
|
||||||
|
goto endvg;
|
||||||
|
|
||||||
|
+ if (vg && !is_lockd && vg_is_shared(vg)) {
|
||||||
|
+ /* The lock_type changed since label_scan, won't really occur in practice. */
|
||||||
|
+ log_debug("Repeat lock and read for local to shared vg");
|
||||||
|
+ unlock_and_release_vg(cmd, vg, vg_name);
|
||||||
|
+ is_lockd = 1;
|
||||||
|
+ goto do_lockd;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Don't call "continue" when skip is set, because we need to remove
|
||||||
|
* error_vg->pvs entries from devices list.
|
||||||
|
@@ -4583,7 +4614,7 @@ endvg:
|
||||||
|
if (error_vg)
|
||||||
|
unlock_and_release_vg(cmd, error_vg, vg_name);
|
||||||
|
release_vg(vg);
|
||||||
|
- if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
||||||
|
+ if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
|
||||||
|
stack;
|
||||||
|
|
||||||
|
/* Quit early when possible. */
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -0,0 +1,86 @@
|
|||||||
|
From 7470dbb82e011a797d2c60d6ce025930ef71ddd8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 13 Jun 2024 13:34:23 -0500
|
||||||
|
Subject: [PATCH 8/9] lvmlockd: allow forced vgchange locktype from none
|
||||||
|
|
||||||
|
vgchange --locktype sanlock|dlm --lockopt force <vgname>
|
||||||
|
can be used to change the lock type without lvmlockd or
|
||||||
|
the lock manager involved.
|
||||||
|
|
||||||
|
(cherry picked from commit 4dc009c87227a137c8be50686b1104cebb9a88e2)
|
||||||
|
---
|
||||||
|
man/lvmlockd.8_main | 5 +++++
|
||||||
|
tools/vgchange.c | 17 +++++++++--------
|
||||||
|
2 files changed, 14 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/lvmlockd.8_main b/man/lvmlockd.8_main
|
||||||
|
index ea967d73d..38f9d958d 100644
|
||||||
|
--- a/man/lvmlockd.8_main
|
||||||
|
+++ b/man/lvmlockd.8_main
|
||||||
|
@@ -729,6 +729,11 @@ vgchange --locktype sanlock|dlm <vgname>
|
||||||
|
Start the VG on hosts to use it:
|
||||||
|
.br
|
||||||
|
vgchange --lockstart <vgname>
|
||||||
|
+.P
|
||||||
|
+If lvmlockd or the cluster manager are not available, the lock type can
|
||||||
|
+be forcibly changed with:
|
||||||
|
+.br
|
||||||
|
+vgchange --locktype sanlock|dlm \-\-lockopt force <vgname>
|
||||||
|
.
|
||||||
|
.SS Changing a shared VG to a local VG
|
||||||
|
.
|
||||||
|
diff --git a/tools/vgchange.c b/tools/vgchange.c
|
||||||
|
index 2004d6e92..94c1feb8f 100644
|
||||||
|
--- a/tools/vgchange.c
|
||||||
|
+++ b/tools/vgchange.c
|
||||||
|
@@ -1176,7 +1176,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
|
||||||
|
+static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg, int *no_change)
|
||||||
|
{
|
||||||
|
const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
|
||||||
|
const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
|
||||||
|
@@ -1206,6 +1206,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
|
||||||
|
if (lock_type && !strcmp(vg->lock_type, lock_type)) {
|
||||||
|
log_warn("WARNING: New lock type %s matches the current lock type %s.",
|
||||||
|
lock_type, vg->lock_type);
|
||||||
|
+ *no_change = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1344,9 +1345,14 @@ static int _vgchange_locktype_single(struct cmd_context *cmd, const char *vg_nam
|
||||||
|
struct volume_group *vg,
|
||||||
|
struct processing_handle *handle)
|
||||||
|
{
|
||||||
|
- if (!_vgchange_locktype(cmd, vg))
|
||||||
|
+ int no_change = 0;
|
||||||
|
+
|
||||||
|
+ if (!_vgchange_locktype(cmd, vg, &no_change))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
|
+ if (no_change)
|
||||||
|
+ return ECMD_PROCESSED;
|
||||||
|
+
|
||||||
|
if (!vg_write(vg) || !vg_commit(vg))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
|
@@ -1402,13 +1408,8 @@ int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
* just return success when they see the disable flag set.
|
||||||
|
*/
|
||||||
|
if (lockopt && !strcmp(lockopt, "force")) {
|
||||||
|
- if (lock_type && strcmp(lock_type, "none")) {
|
||||||
|
- log_error("Lock type can only be forced to \"none\" for recovery.");
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (!arg_is_set(cmd, yes_ARG) &&
|
||||||
|
- yes_no_prompt("Forcibly change VG lock type to none? [y/n]: ") == 'n') {
|
||||||
|
+ yes_no_prompt("Forcibly change VG lock type to %s? [y/n]: ", lock_type) == 'n') {
|
||||||
|
log_error("VG lock type not changed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
From 41d16e42f88997fda991f86d598bffc19fcd937f Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Wed, 17 May 2023 11:10:45 -0500
|
|
||||||
Subject: [PATCH 8/8] tests: integrity: snapshots now work on raid+integrity
|
|
||||||
|
|
||||||
(cherry picked from commit 3a757047560d75a28d7e4c7d9a5253a72d786544)
|
|
||||||
---
|
|
||||||
test/shell/integrity.sh | 8 --------
|
|
||||||
1 file changed, 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/test/shell/integrity.sh b/test/shell/integrity.sh
|
|
||||||
index a7dd5b565..d1683a08e 100644
|
|
||||||
--- a/test/shell/integrity.sh
|
|
||||||
+++ b/test/shell/integrity.sh
|
|
||||||
@@ -626,7 +626,6 @@ not lvconvert --splitmirrors 1 -n tmp -y $vg/$lv1
|
|
||||||
not lvconvert --splitmirrors 1 --trackchanges -y $vg/$lv1
|
|
||||||
not lvchange --syncaction repair $vg/$lv1
|
|
||||||
not lvreduce -L4M $vg/$lv1
|
|
||||||
-not lvcreate -s -n snap -L4M $vg/$lv1
|
|
||||||
not pvmove -n $vg/$lv1 "$dev1"
|
|
||||||
not pvmove "$dev1"
|
|
||||||
_verify_data_on_mnt
|
|
||||||
@@ -810,11 +809,4 @@ not lvconvert --raidintegrity y $vg/${lv2}_cpool_cdata
|
|
||||||
not lvconvert --raidintegrity y $vg/${lv2}_cpool_cmeta
|
|
||||||
lvremove -y $vg/$lv1
|
|
||||||
|
|
||||||
-# cannot add integrity to raid that has a snapshot
|
|
||||||
-
|
|
||||||
-lvcreate --type raid1 -m1 -n $lv1 -l 8 $vg
|
|
||||||
-lvcreate -s -n $lv2 -l 8 $vg/$lv1
|
|
||||||
-not lvconvert --raidintegrity y $vg/$lv1
|
|
||||||
-lvremove -y $vg/$lv1
|
|
||||||
-
|
|
||||||
vgremove -ff $vg
|
|
||||||
--
|
|
||||||
2.40.1
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 39d672d5f90a8a46d20b5674fc092ec5a38d6991 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Heinz Mauelshagen <heinzm@redhat.com>
|
||||||
|
Date: Wed, 17 Jul 2024 17:08:20 +0200
|
||||||
|
Subject: [PATCH 9/9] lv_manip: avoid unreleased memory pool(s) message on RAID
|
||||||
|
extend
|
||||||
|
|
||||||
|
In case of different PV sizes in a VG, the lvm2 allocator falls short
|
||||||
|
to define extended segments resiliently asked for 100%FREE RaidLV extension
|
||||||
|
and a RAID distinct allocation check fails. Fix is to release a memory pool
|
||||||
|
on the resulting error path.
|
||||||
|
|
||||||
|
Until the lvm2 allocator gets enhanced (WIP) to do such complex (and other)
|
||||||
|
allocations proper, a workaround is to extend a RaidLV to any free space on
|
||||||
|
its already allocated PVs by defining those PVs on the lvextend command line
|
||||||
|
then iteratively run further such lvextend commands to extend it to its
|
||||||
|
final intended size. Mind, this may be a non-trivial extension interation.
|
||||||
|
|
||||||
|
(cherry picked from commit 557b2850cef7fa49e2cbacd36e77f679181f09ae)
|
||||||
|
---
|
||||||
|
WHATS_NEW | 5 +++++
|
||||||
|
lib/metadata/lv_manip.c | 3 ++-
|
||||||
|
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 1d56f8675..8647a8f87 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+Version 2.03.26 -
|
||||||
|
+==================
|
||||||
|
+ Fix unreleased memory pools on RAID's lvextend.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
Version 2.03.25 -
|
||||||
|
==================
|
||||||
|
Revert Don't import DM_UDEV_DISABLE_OTHER_RULES_FLAG in LVM rules, DM rules cover it.
|
||||||
|
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
||||||
|
index bec363ef8..871d3bec9 100644
|
||||||
|
--- a/lib/metadata/lv_manip.c
|
||||||
|
+++ b/lib/metadata/lv_manip.c
|
||||||
|
@@ -4415,6 +4415,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
|
||||||
|
log_error("Failed to remove LV");
|
||||||
|
else if (!vg_write(vg) || !vg_commit(vg))
|
||||||
|
log_error("Failed to commit VG %s", vg->name);
|
||||||
|
+ dm_pool_free(vg->vgmem, lvl);
|
||||||
|
return_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4571,7 +4572,7 @@ int lv_extend(struct logical_volume *lv,
|
||||||
|
alloc != ALLOC_ANYWHERE &&
|
||||||
|
!(r = _lv_raid_redundant_allocation(lv, allocatable_pvs))) {
|
||||||
|
log_error("Insufficient suitable allocatable extents for logical volume %s", display_lvname(lv));
|
||||||
|
- if (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg))
|
||||||
|
+ if (!old_extents && (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg)))
|
||||||
|
return_0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.46.0
|
||||||
|
|
@ -1,102 +0,0 @@
|
|||||||
From e96cdaca1d2fec1d225ff09ef81f66edd7df7513 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Fri, 16 Jun 2023 12:06:40 -0500
|
|
||||||
Subject: [PATCH 09/14] lvresize: fix multiple mounts
|
|
||||||
|
|
||||||
which was mistaken as a mounted LV that had been renamed.
|
|
||||||
|
|
||||||
(cherry picked from commit 7c3eca833ff7878d6d32198ed76380c91fdc15fc)
|
|
||||||
---
|
|
||||||
lib/device/filesystem.c | 47 +++++++++++++++++++++--------------------
|
|
||||||
1 file changed, 24 insertions(+), 23 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
|
|
||||||
index 2163276ed..bca29747a 100644
|
|
||||||
--- a/lib/device/filesystem.c
|
|
||||||
+++ b/lib/device/filesystem.c
|
|
||||||
@@ -243,8 +243,6 @@ int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *l
|
|
||||||
FILE *fme = NULL;
|
|
||||||
struct mntent *me;
|
|
||||||
int renamed = 0;
|
|
||||||
- int found_dir = 0;
|
|
||||||
- int found_dev = 0;
|
|
||||||
int dev_match, dir_match;
|
|
||||||
|
|
||||||
if (stat(lv_path, &st_lv) < 0) {
|
|
||||||
@@ -281,6 +279,9 @@ int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *l
|
|
||||||
}
|
|
||||||
endmntent(fme);
|
|
||||||
|
|
||||||
+ if (mtab_mntpath[0])
|
|
||||||
+ log_debug("%s mtab mntpath %s", display_lvname(lv), mtab_mntpath);
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* In mtab dir path, replace each ascii space character with the
|
|
||||||
* four characters \040 which is how /proc/mounts represents spaces.
|
|
||||||
@@ -319,15 +320,31 @@ int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *l
|
|
||||||
if (strcmp(fstype, proc_fstype))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * When an LV is mounted on two dirs, it appears in /proc/mounts twice as
|
|
||||||
+ * /dev/mapper/vg-lvol0 on /foo type xfs ...
|
|
||||||
+ * /dev/mapper/vg-lvol0 on /bar type xfs ...
|
|
||||||
+ * All entries match dm_devpath, one entry matches mntpath,
|
|
||||||
+ * and other entries don't match mntpath.
|
|
||||||
+ *
|
|
||||||
+ * When an LV is mounted on one dir, and is renamed from lvol0 to lvol1,
|
|
||||||
+ * it appears in /proc/mounts once as
|
|
||||||
+ * /dev/mapper/vg-lvol0 on /foo type xfs ...
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
dir_match = !strcmp(mtab_mntpath, proc_mntpath);
|
|
||||||
dev_match = !strcmp(dm_devpath, proc_devpath);
|
|
||||||
|
|
||||||
- if (dir_match)
|
|
||||||
- found_dir++;
|
|
||||||
- if (dev_match)
|
|
||||||
- found_dev++;
|
|
||||||
+ if (!dir_match && !dev_match)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (dev_match && !dir_match) {
|
|
||||||
+ log_debug("LV %s mounted at %s also mounted at %s.",
|
|
||||||
+ dm_devpath, mtab_mntpath, proc_mntpath);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if (dir_match != dev_match) {
|
|
||||||
+ if (!dev_match && dir_match) {
|
|
||||||
log_error("LV %s mounted at %s may have been renamed (from %s).",
|
|
||||||
dm_devpath, proc_mntpath, proc_devpath);
|
|
||||||
renamed = 1;
|
|
||||||
@@ -337,26 +354,10 @@ int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *l
|
|
||||||
if (fclose(fp))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Don't try resizing if:
|
|
||||||
- * - different device names apppear for the mount point
|
|
||||||
- * (LVs probably renamed while mounted), or
|
|
||||||
- * - the mount point for the LV appears multiple times, or
|
|
||||||
- * - the LV device is listed for multiple mounts.
|
|
||||||
- */
|
|
||||||
if (renamed) {
|
|
||||||
log_error("File system resizing not supported: fs utilities do not support renamed devices.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
- /* These two are likely detected as renamed, but include checks in case. */
|
|
||||||
- if (found_dir > 1) {
|
|
||||||
- log_error("File system resizing not supported: %s appears more than once in /proc/mounts.", mtab_mntpath);
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- if (found_dev > 1) {
|
|
||||||
- log_error("File system resizing not supported: %s appears more than once in /proc/mounts.", dm_devpath);
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.41.0
|
|
||||||
|
|
@ -1,247 +0,0 @@
|
|||||||
From 9e35daea0212e12ea556c04830a91db08a7f3505 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Fri, 19 May 2023 12:52:48 -0500
|
|
||||||
Subject: [PATCH 10/14] device_id: ignore trailing underscores in t10 wwid from
|
|
||||||
devices file
|
|
||||||
|
|
||||||
In previous lvm versions, trailing spaces at the end of a t10 wwid would
|
|
||||||
be replaced with underscores, so the IDNAME string in system.devices
|
|
||||||
would look something like "t10.123_". Current versions of lvm ignore
|
|
||||||
trailing spaces in a t10 wwid, so the IDNAME string used would be
|
|
||||||
"t10.123". The different values would cause lvm to not recognize a
|
|
||||||
device in system.devices with the trailing _. Fix this by ignoring
|
|
||||||
trailing underscores in the IDNAME string from system.devices.
|
|
||||||
|
|
||||||
(cherry picked from commit 4cdb178968b44125c41dee6dd28997283c0afefa)
|
|
||||||
---
|
|
||||||
lib/device/device_id.c | 46 ++++++++++--
|
|
||||||
test/shell/devicesfile-vpd-ids.sh | 113 ++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 152 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
|
||||||
index 79da12884..7db6c9b86 100644
|
|
||||||
--- a/lib/device/device_id.c
|
|
||||||
+++ b/lib/device/device_id.c
|
|
||||||
@@ -1728,7 +1728,8 @@ static int _match_dm_devnames(struct cmd_context *cmd, struct device *dev,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void _reduce_underscores(char *in, int in_len, char *out, int out_size)
|
|
||||||
+/* More than one _ in a row is replaced with one _ */
|
|
||||||
+static void _reduce_repeating_underscores(char *in, int in_len, char *out, int out_size)
|
|
||||||
{
|
|
||||||
int us = 0, i, j = 0;
|
|
||||||
|
|
||||||
@@ -1750,6 +1751,17 @@ static void _reduce_underscores(char *in, int in_len, char *out, int out_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* Remove any _ at the end of the string. */
|
|
||||||
+static void _remove_trailing_underscores(char *buf)
|
|
||||||
+{
|
|
||||||
+ char *end;
|
|
||||||
+
|
|
||||||
+ end = buf + strlen(buf) - 1;
|
|
||||||
+ while ((end > buf) && (*end == '_'))
|
|
||||||
+ end--;
|
|
||||||
+ end[1] = '\0';
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* du is a devices file entry. dev is any device on the system.
|
|
||||||
* check if du is for dev by comparing the device's ids to du->idname.
|
|
||||||
@@ -1764,6 +1776,7 @@ static void _reduce_underscores(char *in, int in_len, char *out, int out_size)
|
|
||||||
static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct device *dev)
|
|
||||||
{
|
|
||||||
char du_t10[DEV_WWID_SIZE] = { 0 };
|
|
||||||
+ char id_t10[DEV_WWID_SIZE];
|
|
||||||
struct dev_id *id;
|
|
||||||
const char *idname;
|
|
||||||
int part;
|
|
||||||
@@ -1818,10 +1831,17 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
|
||||||
* for IDNAME were saved in the past with each space replaced
|
|
||||||
* by one _. Now we convert multiple spaces to a single _.
|
|
||||||
* So, convert a df entry with the old style to the new shorter
|
|
||||||
- * style to compare.
|
|
||||||
+ * style to compare. Also, in past versions, trailing spaces
|
|
||||||
+ * in the wwid would be replaced by _, but now trailing spaces
|
|
||||||
+ * are ignored. This means devices file entries created by
|
|
||||||
+ * past versions may have _ at the end of the IDNAME string.
|
|
||||||
+ * So, exclude trailing underscores when comparing a t10 wwid
|
|
||||||
+ * from a device with a t10 wwid in the devices file.
|
|
||||||
*/
|
|
||||||
- if (du->idtype == DEV_ID_TYPE_SYS_WWID && !strncmp(du->idname, "t10", 3) && strstr(du->idname, "__"))
|
|
||||||
- _reduce_underscores(du->idname, strlen(du->idname), du_t10, sizeof(du_t10) - 1);
|
|
||||||
+ if (du->idtype == DEV_ID_TYPE_SYS_WWID && !strncmp(du->idname, "t10", 3) && strchr(du->idname, '_')) {
|
|
||||||
+ _reduce_repeating_underscores(du->idname, strlen(du->idname), du_t10, sizeof(du_t10) - 1);
|
|
||||||
+ _remove_trailing_underscores(du_t10);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to match du with ids that have already been read for the dev
|
|
||||||
@@ -1829,6 +1849,20 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
|
||||||
*/
|
|
||||||
dm_list_iterate_items(id, &dev->ids) {
|
|
||||||
if (id->idtype == du->idtype) {
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * For t10 wwids, remove actual trailing underscores from the dev wwid
|
|
||||||
+ * (in id->idname), because all trailing underscores were removed from
|
|
||||||
+ * the du->idname read from the devices file. i.e. no trailing _ are
|
|
||||||
+ * used in t10 wwid comparisons.
|
|
||||||
+ */
|
|
||||||
+ if ((id->idtype == DEV_ID_TYPE_SYS_WWID) &&
|
|
||||||
+ id->idname && !strncmp(id->idname, "t10", 3) && du_t10[0]) {
|
|
||||||
+ memset(id_t10, 0, sizeof(id_t10));
|
|
||||||
+ strncpy(id_t10, id->idname, DEV_WWID_SIZE-1);
|
|
||||||
+ _remove_trailing_underscores(id_t10);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if ((id->idtype == DEV_ID_TYPE_DEVNAME) && _match_dm_devnames(cmd, dev, id, du)) {
|
|
||||||
/* dm devs can have differing names that we know still match */
|
|
||||||
du->dev = dev;
|
|
||||||
@@ -1846,9 +1880,7 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
|
||||||
idtype_to_str(du->idtype), du->idname, dev_name(dev));
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
- } else if ((id->idtype == DEV_ID_TYPE_SYS_WWID) && id->idname &&
|
|
||||||
- !strncmp(id->idname, "t10", 3) && du_t10[0] && !strcmp(id->idname, du_t10)) {
|
|
||||||
- /* Compare the shorter form du t10 wwid to the dev t10 wwid. */
|
|
||||||
+ } else if ((id->idtype == DEV_ID_TYPE_SYS_WWID) && du_t10[0] && id_t10[0] && !strcmp(id_t10, du_t10)) {
|
|
||||||
du->dev = dev;
|
|
||||||
dev->id = id;
|
|
||||||
dev->flags |= DEV_MATCHED_USE_ID;
|
|
||||||
diff --git a/test/shell/devicesfile-vpd-ids.sh b/test/shell/devicesfile-vpd-ids.sh
|
|
||||||
index b2042fb9a..52805737b 100644
|
|
||||||
--- a/test/shell/devicesfile-vpd-ids.sh
|
|
||||||
+++ b/test/shell/devicesfile-vpd-ids.sh
|
|
||||||
@@ -80,6 +80,7 @@ echo $DEV1
|
|
||||||
DFDIR="$LVM_SYSTEM_DIR/devices"
|
|
||||||
mkdir -p "$DFDIR" || true
|
|
||||||
DF="$DFDIR/system.devices"
|
|
||||||
+DFTMP="$DFDIR/system.devices_tmp"
|
|
||||||
touch $DF
|
|
||||||
|
|
||||||
pvcreate "$DEV1"
|
|
||||||
@@ -243,6 +244,118 @@ vgremove $vg
|
|
||||||
rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
cleanup_sysfs
|
|
||||||
|
|
||||||
+# Test t10 wwid with trailing space and line feed at the end
|
|
||||||
+rm $DF
|
|
||||||
+aux wipefs_a "$DEV1"
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/
|
|
||||||
+echo -n "7431 302e 4154 4120 2020 2020 5642 4f58 \
|
|
||||||
+2048 4152 4444 4953 4b20 2020 2020 2020 \
|
|
||||||
+2020 2020 2020 2020 2020 2020 2020 2020 \
|
|
||||||
+2020 2020 5642 3963 3130 6433 3138 2d31 \
|
|
||||||
+3838 6439 6562 6320 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+lvmdevices --adddev "$DEV1"
|
|
||||||
+cat $DF
|
|
||||||
+vgcreate $vg "$DEV1"
|
|
||||||
+lvcreate -l1 -an $vg
|
|
||||||
+cat $DF
|
|
||||||
+# check wwid string in metadata output
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1" |tee out
|
|
||||||
+grep sys_wwid out
|
|
||||||
+# check wwid string in system.devices
|
|
||||||
+grep sys_wwid $DF
|
|
||||||
+lvremove -y $vg
|
|
||||||
+vgremove $vg
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+cleanup_sysfs
|
|
||||||
+
|
|
||||||
+# Test t10 wwid with trailing space at the end that was created by 9.0/9.1
|
|
||||||
+rm $DF
|
|
||||||
+aux wipefs_a "$DEV1"
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/
|
|
||||||
+echo -n "7431 302e 4154 4120 2020 2020 5642 4f58 \
|
|
||||||
+2048 4152 4444 4953 4b20 2020 2020 2020 \
|
|
||||||
+2020 2020 2020 2020 2020 2020 2020 2020 \
|
|
||||||
+2020 2020 5642 3963 3130 6433 3138 2d31 \
|
|
||||||
+3838 6439 6562 6320 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+lvmdevices --adddev "$DEV1"
|
|
||||||
+cat $DF
|
|
||||||
+vgcreate $vg "$DEV1"
|
|
||||||
+PVID1=`pvs "$DEV1" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
||||||
+T10_WWID_RHEL91="t10.ATA_____VBOX_HARDDISK___________________________VB9c10d318-188d9ebc_"
|
|
||||||
+lvcreate -l1 -an $vg
|
|
||||||
+cat $DF
|
|
||||||
+# check wwid string in metadata output
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1" |tee out
|
|
||||||
+grep sys_wwid out
|
|
||||||
+# check wwid string in system.devices
|
|
||||||
+grep sys_wwid $DF
|
|
||||||
+# Replace IDNAME with the IDNAME that 9.0/9.1 created from this wwid
|
|
||||||
+cat $DF | grep -v IDNAME > $DFTMP
|
|
||||||
+cat $DFTMP
|
|
||||||
+echo "IDTYPE=sys_wwid IDNAME=t10.ATA_____VBOX_HARDDISK___________________________VB9c10d318-188d9ebc_ DEVNAME=${DEV1} PVID=${PVID1}" >> $DFTMP
|
|
||||||
+cp $DFTMP $DF
|
|
||||||
+cat $DF
|
|
||||||
+vgs
|
|
||||||
+pvs
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1"
|
|
||||||
+# Removing the trailing _ which should then work
|
|
||||||
+cat $DF | grep -v IDNAME > $DFTMP
|
|
||||||
+cat $DFTMP
|
|
||||||
+echo "IDTYPE=sys_wwid IDNAME=t10.ATA_____VBOX_HARDDISK___________________________VB9c10d318-188d9ebc DEVNAME=${DEV1} PVID=${PVID1}" >> $DFTMP
|
|
||||||
+cp $DFTMP $DF
|
|
||||||
+cat $DF
|
|
||||||
+vgs
|
|
||||||
+pvs
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1"
|
|
||||||
+lvremove -y $vg
|
|
||||||
+vgremove $vg
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+cleanup_sysfs
|
|
||||||
+
|
|
||||||
+# test a t10 wwid that has actual trailing underscore which
|
|
||||||
+# is followed by a trailing space.
|
|
||||||
+rm $DF
|
|
||||||
+aux wipefs_a "$DEV1"
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/
|
|
||||||
+echo -n "7431 302e 4154 4120 2020 2020 5642 4f58 \
|
|
||||||
+2048 4152 4444 4953 4b20 2020 2020 2020 \
|
|
||||||
+2020 2020 2020 2020 2020 2020 2020 2020 \
|
|
||||||
+2020 2020 5642 3963 3130 6433 3138 2d31 \
|
|
||||||
+3838 6439 6562 5f20 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+# The wwid has an actual underscore char (5f) followed by a space char (20)
|
|
||||||
+# 9.1 converts the trailing space to an underscore
|
|
||||||
+T10_WWID_RHEL91="t10.ATA_____VBOX_HARDDISK___________________________VB9c10d318-188d9eb__"
|
|
||||||
+# 9.2 ignores the trailing space
|
|
||||||
+T10_WWID_RHEL92="t10.ATA_____VBOX_HARDDISK___________________________VB9c10d318-188d9eb_"
|
|
||||||
+lvmdevices --adddev "$DEV1"
|
|
||||||
+cat $DF
|
|
||||||
+vgcreate $vg "$DEV1"
|
|
||||||
+PVID1=`pvs "$DEV1" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
||||||
+lvcreate -l1 -an $vg
|
|
||||||
+cat $DF
|
|
||||||
+# check wwid string in metadata output
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1" |tee out
|
|
||||||
+grep sys_wwid out
|
|
||||||
+# check wwid string in system.devices
|
|
||||||
+grep sys_wwid $DF
|
|
||||||
+# Replace IDNAME with the IDNAME that 9.0/9.1 created from this wwid
|
|
||||||
+cat $DF | grep -v IDNAME > $DFTMP
|
|
||||||
+cat $DFTMP
|
|
||||||
+echo "IDTYPE=sys_wwid IDNAME=${T10_WWID_RHEL91} DEVNAME=${DEV1} PVID=${PVID1}" >> $DFTMP
|
|
||||||
+cp $DFTMP $DF
|
|
||||||
+cat $DF
|
|
||||||
+vgs
|
|
||||||
+pvs
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1"
|
|
||||||
+lvremove -y $vg
|
|
||||||
+vgremove $vg
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+cleanup_sysfs
|
|
||||||
+
|
|
||||||
+
|
|
||||||
# TODO: lvmdevices --adddev <dev> --deviceidtype <type> --deviceid <val>
|
|
||||||
# This would let the user specify the second naa wwid.
|
|
||||||
|
|
||||||
--
|
|
||||||
2.41.0
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
|||||||
From 499fd37ff0c2bae1c492c3883f063a332e12ac3d Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Thu, 8 Jun 2023 12:24:05 -0500
|
|
||||||
Subject: [PATCH 11/14] device_id: fix handling of non-PV with duplicate serial
|
|
||||||
number
|
|
||||||
|
|
||||||
Fix in the code that matches devices to system.devices entries when
|
|
||||||
the devices have the same serial number. A non-PV device in
|
|
||||||
system.devices has no pvid value, and the code was segfaulting
|
|
||||||
when checking the null pvid value.
|
|
||||||
|
|
||||||
(cherry picked from commit 74feebdab723c1ea46d4316f8a581750c1d8cda3)
|
|
||||||
---
|
|
||||||
lib/device/device_id.c | 2 ++
|
|
||||||
test/shell/devicesfile-serial.sh | 38 ++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 40 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
|
||||||
index 7db6c9b86..e3d622ecc 100644
|
|
||||||
--- a/lib/device/device_id.c
|
|
||||||
+++ b/lib/device/device_id.c
|
|
||||||
@@ -2625,6 +2625,8 @@ void device_ids_check_serial(struct cmd_context *cmd, struct dm_list *scan_devs,
|
|
||||||
* Match du to a dev based on PVID.
|
|
||||||
*/
|
|
||||||
dm_list_iterate_items(dul, &dus_check) {
|
|
||||||
+ if (!dul->du->pvid)
|
|
||||||
+ continue;
|
|
||||||
log_debug("Matching suspect serial device id %s PVID %s prev %s",
|
|
||||||
dul->du->idname, dul->du->pvid, dul->du->devname);
|
|
||||||
found = 0;
|
|
||||||
diff --git a/test/shell/devicesfile-serial.sh b/test/shell/devicesfile-serial.sh
|
|
||||||
index a88c1906a..a4cbd5cb2 100644
|
|
||||||
--- a/test/shell/devicesfile-serial.sh
|
|
||||||
+++ b/test/shell/devicesfile-serial.sh
|
|
||||||
@@ -851,6 +851,44 @@ grep $PVID4 out4
|
|
||||||
vgcreate $vg2 $dev2 $dev3
|
|
||||||
vgs | grep $vg2
|
|
||||||
|
|
||||||
+# 3 devs with duplicate serial, 2 pvs with stale devnames, 1 non-pv device
|
|
||||||
+
|
|
||||||
+aux wipefs_a $dev1
|
|
||||||
+aux wipefs_a $dev2
|
|
||||||
+aux wipefs_a $dev3
|
|
||||||
+
|
|
||||||
+echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
|
|
||||||
+echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
|
|
||||||
+echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
|
|
||||||
+
|
|
||||||
+rm $DF
|
|
||||||
+touch $DF
|
|
||||||
+vgcreate $vg1 $dev1 $dev2
|
|
||||||
+lvmdevices --adddev $dev3
|
|
||||||
+cat $DF
|
|
||||||
+cp $DF $ORIG
|
|
||||||
+
|
|
||||||
+PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
||||||
+PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
||||||
+OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
|
|
||||||
+OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
|
|
||||||
+
|
|
||||||
+pvs -o+uuid,deviceid
|
|
||||||
+
|
|
||||||
+sed -e "s|DEVNAME=$dev1|DEVNAME=tmp|" $ORIG > tmp1
|
|
||||||
+sed -e "s|DEVNAME=$dev2|DEVNAME=$dev1|" tmp1 > tmp2
|
|
||||||
+sed -e "s|DEVNAME=tmp|DEVNAME=$dev2|" tmp2 > $DF
|
|
||||||
+cat $DF
|
|
||||||
+
|
|
||||||
+# pvs should report the correct info and fix the DF
|
|
||||||
+pvs -o+uuid,deviceid |tee out
|
|
||||||
+grep $dev1 out |tee out1
|
|
||||||
+grep $dev2 out |tee out2
|
|
||||||
+grep $OPVID1 out1
|
|
||||||
+grep $OPVID2 out2
|
|
||||||
+grep $SERIAL1 out1
|
|
||||||
+grep $SERIAL1 out2
|
|
||||||
+
|
|
||||||
remove_base
|
|
||||||
rmmod brd
|
|
||||||
|
|
||||||
--
|
|
||||||
2.41.0
|
|
||||||
|
|
@ -1,693 +0,0 @@
|
|||||||
From 894ae888233ff5026c981500623f4f829d358405 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Thu, 15 Jun 2023 13:58:48 -0500
|
|
||||||
Subject: [PATCH 12/14] device_id: ignore leading and trailing spaces for
|
|
||||||
sys_wwid and sys_serial
|
|
||||||
|
|
||||||
Leading and trailing underscores are also ignored to handle device ids
|
|
||||||
written by previous versions which replaced all spaces with underscores.
|
|
||||||
|
|
||||||
(cherry picked from commit 228a8e8c1fd8e82a2e31a6060614dc3dd2f8bc51)
|
|
||||||
---
|
|
||||||
lib/device/device.h | 1 +
|
|
||||||
lib/device/device_id.c | 278 +++++++++++++++++++-----------
|
|
||||||
lib/device/parse_vpd.c | 50 ++++++
|
|
||||||
test/shell/devicesfile-vpd-ids.sh | 101 +++++++++--
|
|
||||||
4 files changed, 312 insertions(+), 118 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/device/device.h b/lib/device/device.h
|
|
||||||
index 446104218..84d87232b 100644
|
|
||||||
--- a/lib/device/device.h
|
|
||||||
+++ b/lib/device/device.h
|
|
||||||
@@ -239,6 +239,7 @@ int dev_mpath_init(const char *config_wwids_file);
|
|
||||||
void dev_mpath_exit(void);
|
|
||||||
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);
|
|
||||||
+int format_general_id(const char *in, int in_bytes, unsigned char *out, int out_bytes);
|
|
||||||
int parse_vpd_serial(const unsigned char *in, char *out, int outsize);
|
|
||||||
|
|
||||||
/* dev_util */
|
|
||||||
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
|
||||||
index e3d622ecc..a6fc4a26d 100644
|
|
||||||
--- a/lib/device/device_id.c
|
|
||||||
+++ b/lib/device/device_id.c
|
|
||||||
@@ -185,6 +185,71 @@ void free_dids(struct dm_list *ids)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* More than one _ in a row is replaced with one _ */
|
|
||||||
+static void _reduce_repeating_underscores(char *buf, int bufsize)
|
|
||||||
+{
|
|
||||||
+ char *tmpbuf;
|
|
||||||
+ int us = 0, i, j = 0;
|
|
||||||
+
|
|
||||||
+ if (!(tmpbuf = strndup(buf, bufsize-1)))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ memset(buf, 0, bufsize);
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < strlen(tmpbuf); i++) {
|
|
||||||
+ if (tmpbuf[i] == '_')
|
|
||||||
+ us++;
|
|
||||||
+ else
|
|
||||||
+ us = 0;
|
|
||||||
+
|
|
||||||
+ if (us == 1)
|
|
||||||
+ buf[j++] = '_';
|
|
||||||
+ else if (us > 1)
|
|
||||||
+ continue;
|
|
||||||
+ else
|
|
||||||
+ buf[j++] = tmpbuf[i];
|
|
||||||
+
|
|
||||||
+ if (j == bufsize)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ buf[bufsize-1] = '\0';
|
|
||||||
+ free(tmpbuf);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void _remove_leading_underscores(char *buf, int bufsize)
|
|
||||||
+{
|
|
||||||
+ char *tmpbuf;
|
|
||||||
+ int i, j = 0;
|
|
||||||
+
|
|
||||||
+ if (buf[0] != '_')
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (!(tmpbuf = strndup(buf, bufsize-1)))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ memset(buf, 0, bufsize);
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < strlen(tmpbuf); i++) {
|
|
||||||
+ if (!j && tmpbuf[i] == '_')
|
|
||||||
+ continue;
|
|
||||||
+ buf[j++] = tmpbuf[i];
|
|
||||||
+
|
|
||||||
+ if (j == bufsize)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ free(tmpbuf);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void _remove_trailing_underscores(char *buf, int bufsize)
|
|
||||||
+{
|
|
||||||
+ char *end;
|
|
||||||
+
|
|
||||||
+ end = buf + strlen(buf) - 1;
|
|
||||||
+ while ((end > buf) && (*end == '_'))
|
|
||||||
+ end--;
|
|
||||||
+ end[1] = '\0';
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int _read_sys_block(struct cmd_context *cmd, struct device *dev,
|
|
||||||
const char *suffix, char *sysbuf, int sysbufsize,
|
|
||||||
int binary, int *retlen)
|
|
||||||
@@ -406,7 +471,7 @@ struct dev_wwid *dev_add_wwid(char *id, int id_type, struct dm_list *ids)
|
|
||||||
|
|
||||||
int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev)
|
|
||||||
{
|
|
||||||
- unsigned char vpd_data[VPD_SIZE] = { 0 };
|
|
||||||
+ char vpd_data[VPD_SIZE] = { 0 };
|
|
||||||
int vpd_datalen = 0;
|
|
||||||
|
|
||||||
dev->flags |= DEV_ADDED_VPD_WWIDS;
|
|
||||||
@@ -417,36 +482,47 @@ int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* adds dev_wwid entry to dev->wwids for each id in vpd data */
|
|
||||||
- parse_vpd_ids(vpd_data, vpd_datalen, &dev->wwids);
|
|
||||||
+ parse_vpd_ids((const unsigned char *)vpd_data, vpd_datalen, &dev->wwids);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev,
|
|
||||||
- char *buf, int bufsize, struct dev_wwid **dw_out)
|
|
||||||
+ char *outbuf, int outbufsize, struct dev_wwid **dw_out)
|
|
||||||
{
|
|
||||||
- char tmpbuf[DEV_WWID_SIZE];
|
|
||||||
+ char buf[DEV_WWID_SIZE] = { 0 };
|
|
||||||
struct dev_wwid *dw;
|
|
||||||
- int ret;
|
|
||||||
+ int is_t10 = 0;
|
|
||||||
+ int i, ret;
|
|
||||||
|
|
||||||
dev->flags |= DEV_ADDED_SYS_WWID;
|
|
||||||
|
|
||||||
- ret = read_sys_block(cmd, dev, "device/wwid", buf, bufsize);
|
|
||||||
+ ret = read_sys_block(cmd, dev, "device/wwid", buf, sizeof(buf));
|
|
||||||
if (!ret || !buf[0]) {
|
|
||||||
/* the wwid file is not under device for nvme devs */
|
|
||||||
- ret = read_sys_block(cmd, dev, "wwid", buf, bufsize);
|
|
||||||
+ ret = read_sys_block(cmd, dev, "wwid", buf, sizeof(buf));
|
|
||||||
}
|
|
||||||
if (!ret || !buf[0])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- /* in t10 id, replace characters like space and quote */
|
|
||||||
- if (!strncmp(buf, "t10.", 4)) {
|
|
||||||
- if (bufsize < DEV_WWID_SIZE)
|
|
||||||
- return 0;
|
|
||||||
- memcpy(tmpbuf, buf, DEV_WWID_SIZE);
|
|
||||||
- memset(buf, 0, bufsize);
|
|
||||||
- format_t10_id((const unsigned char *)tmpbuf, DEV_WWID_SIZE, (unsigned char *)buf, bufsize);
|
|
||||||
+ for (i = 0; i < sizeof(buf) - 4; i++) {
|
|
||||||
+ if (buf[i] == ' ')
|
|
||||||
+ continue;
|
|
||||||
+ if (!strncmp(&buf[i], "t10", 3))
|
|
||||||
+ is_t10 = 1;
|
|
||||||
+ break;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Remove leading and trailing spaces.
|
|
||||||
+ * Replace internal spaces with underscores.
|
|
||||||
+ * t10 wwids have multiple sequential spaces
|
|
||||||
+ * replaced by a single underscore.
|
|
||||||
+ */
|
|
||||||
+ if (is_t10)
|
|
||||||
+ format_t10_id((const unsigned char *)buf, sizeof(buf), (unsigned char *)outbuf, outbufsize);
|
|
||||||
+ else
|
|
||||||
+ format_general_id((const char *)buf, sizeof(buf), (unsigned char *)outbuf, outbufsize);
|
|
||||||
+
|
|
||||||
/* Note, if wwids are also read from vpd, this same wwid will be added again. */
|
|
||||||
|
|
||||||
if (!(dw = dev_add_wwid(buf, 0, &dev->wwids)))
|
|
||||||
@@ -457,9 +533,9 @@ int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev,
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _dev_read_sys_serial(struct cmd_context *cmd, struct device *dev,
|
|
||||||
- char *buf, int bufsize)
|
|
||||||
+ char *outbuf, int outbufsize)
|
|
||||||
{
|
|
||||||
- unsigned char vpd_data[VPD_SIZE] = { 0 };
|
|
||||||
+ char buf[VPD_SIZE] = { 0 };
|
|
||||||
const char *devname;
|
|
||||||
int vpd_datalen = 0;
|
|
||||||
|
|
||||||
@@ -471,13 +547,16 @@ static int _dev_read_sys_serial(struct cmd_context *cmd, struct device *dev,
|
|
||||||
* (Only virtio disks /dev/vdx are known to use /sys/class/block/vdx/serial.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
- read_sys_block(cmd, dev, "device/serial", buf, bufsize);
|
|
||||||
- if (buf[0])
|
|
||||||
- return 1;
|
|
||||||
+ read_sys_block(cmd, dev, "device/serial", buf, sizeof(buf));
|
|
||||||
+ if (buf[0]) {
|
|
||||||
+ format_general_id((const char *)buf, sizeof(buf), (unsigned char *)outbuf, outbufsize);
|
|
||||||
+ if (outbuf[0])
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if (read_sys_block_binary(cmd, dev, "device/vpd_pg80", (char *)vpd_data, VPD_SIZE, &vpd_datalen) && vpd_datalen) {
|
|
||||||
- parse_vpd_serial(vpd_data, buf, bufsize);
|
|
||||||
- if (buf[0])
|
|
||||||
+ if (read_sys_block_binary(cmd, dev, "device/vpd_pg80", buf, VPD_SIZE, &vpd_datalen) && vpd_datalen) {
|
|
||||||
+ parse_vpd_serial((const unsigned char *)buf, outbuf, outbufsize);
|
|
||||||
+ if (outbuf[0])
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -505,12 +584,13 @@ static int _dev_read_sys_serial(struct cmd_context *cmd, struct device *dev,
|
|
||||||
if (dm_snprintf(path, sizeof(path), "%s/class/block/%s/serial", sysfs_dir, vdx) < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- ret = get_sysfs_value(path, buf, bufsize, 0);
|
|
||||||
+ ret = get_sysfs_value(path, buf, sizeof(buf), 0);
|
|
||||||
if (ret && !buf[0])
|
|
||||||
ret = 0;
|
|
||||||
if (ret) {
|
|
||||||
- buf[bufsize - 1] = '\0';
|
|
||||||
- return 1;
|
|
||||||
+ format_general_id((const char *)buf, sizeof(buf), (unsigned char *)outbuf, outbufsize);
|
|
||||||
+ if (buf[0])
|
|
||||||
+ return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -520,6 +600,7 @@ static int _dev_read_sys_serial(struct cmd_context *cmd, struct device *dev,
|
|
||||||
const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_t idtype)
|
|
||||||
{
|
|
||||||
char sysbuf[PATH_MAX] = { 0 };
|
|
||||||
+ char sysbuf2[PATH_MAX] = { 0 };
|
|
||||||
const char *idname = NULL;
|
|
||||||
struct dev_wwid *dw;
|
|
||||||
int i;
|
|
||||||
@@ -584,16 +665,45 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* wwids are already munged if needed */
|
|
||||||
- if (idtype != DEV_ID_TYPE_SYS_WWID) {
|
|
||||||
+ /*
|
|
||||||
+ * Replace all spaces, quotes, control chars with underscores.
|
|
||||||
+ * sys_wwid, sys_serial, and wwid_* have already been handled,
|
|
||||||
+ * and with slightly different replacement (see format_t10_id,
|
|
||||||
+ * format_general_id.)
|
|
||||||
+ */
|
|
||||||
+ if ((idtype != DEV_ID_TYPE_SYS_WWID) &&
|
|
||||||
+ (idtype != DEV_ID_TYPE_SYS_SERIAL) &&
|
|
||||||
+ (idtype != DEV_ID_TYPE_WWID_NAA) &&
|
|
||||||
+ (idtype != DEV_ID_TYPE_WWID_EUI) &&
|
|
||||||
+ (idtype != DEV_ID_TYPE_WWID_T10)) {
|
|
||||||
for (i = 0; i < strlen(sysbuf); i++) {
|
|
||||||
- if (sysbuf[i] == '"')
|
|
||||||
- continue;
|
|
||||||
- if (isblank(sysbuf[i]) || isspace(sysbuf[i]) || iscntrl(sysbuf[i]))
|
|
||||||
+ if ((sysbuf[i] == '"') ||
|
|
||||||
+ isblank(sysbuf[i]) ||
|
|
||||||
+ isspace(sysbuf[i]) ||
|
|
||||||
+ iscntrl(sysbuf[i]))
|
|
||||||
sysbuf[i] = '_';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Reduce actual leading and trailing underscores for sys_wwid
|
|
||||||
+ * and sys_serial, since underscores were previously used as
|
|
||||||
+ * replacements for leading/trailing spaces which are now ignored.
|
|
||||||
+ * Also reduce any actual repeated underscores in t10 wwid since
|
|
||||||
+ * multiple repeated spaces were also once replaced by underscores.
|
|
||||||
+ */
|
|
||||||
+ if ((idtype == DEV_ID_TYPE_SYS_WWID) ||
|
|
||||||
+ (idtype == DEV_ID_TYPE_SYS_SERIAL)) {
|
|
||||||
+ memcpy(sysbuf2, sysbuf, sizeof(sysbuf2));
|
|
||||||
+ _remove_leading_underscores(sysbuf2, sizeof(sysbuf2));
|
|
||||||
+ _remove_trailing_underscores(sysbuf2, sizeof(sysbuf2));
|
|
||||||
+ if (idtype == DEV_ID_TYPE_SYS_WWID && !strncmp(sysbuf2, "t10", 3) && strstr(sysbuf2, "__"))
|
|
||||||
+ _reduce_repeating_underscores(sysbuf2, sizeof(sysbuf2));
|
|
||||||
+ if (memcmp(sysbuf, sysbuf2, sizeof(sysbuf)))
|
|
||||||
+ log_debug("device_id_system_read reduced underscores %s to %s", sysbuf, sysbuf2);
|
|
||||||
+ memcpy(sysbuf, sysbuf2, sizeof(sysbuf));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (!sysbuf[0])
|
|
||||||
goto bad;
|
|
||||||
|
|
||||||
@@ -1728,40 +1838,6 @@ static int _match_dm_devnames(struct cmd_context *cmd, struct device *dev,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* More than one _ in a row is replaced with one _ */
|
|
||||||
-static void _reduce_repeating_underscores(char *in, int in_len, char *out, int out_size)
|
|
||||||
-{
|
|
||||||
- int us = 0, i, j = 0;
|
|
||||||
-
|
|
||||||
- for (i = 0; i < in_len; i++) {
|
|
||||||
- if (in[i] == '_')
|
|
||||||
- us++;
|
|
||||||
- else
|
|
||||||
- us = 0;
|
|
||||||
-
|
|
||||||
- if (us == 1)
|
|
||||||
- out[j++] = '_';
|
|
||||||
- else if (us > 1)
|
|
||||||
- continue;
|
|
||||||
- else
|
|
||||||
- out[j++] = in[i];
|
|
||||||
-
|
|
||||||
- if (j == out_size)
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/* Remove any _ at the end of the string. */
|
|
||||||
-static void _remove_trailing_underscores(char *buf)
|
|
||||||
-{
|
|
||||||
- char *end;
|
|
||||||
-
|
|
||||||
- end = buf + strlen(buf) - 1;
|
|
||||||
- while ((end > buf) && (*end == '_'))
|
|
||||||
- end--;
|
|
||||||
- end[1] = '\0';
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* du is a devices file entry. dev is any device on the system.
|
|
||||||
* check if du is for dev by comparing the device's ids to du->idname.
|
|
||||||
@@ -1775,8 +1851,7 @@ static void _remove_trailing_underscores(char *buf)
|
|
||||||
|
|
||||||
static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct device *dev)
|
|
||||||
{
|
|
||||||
- char du_t10[DEV_WWID_SIZE] = { 0 };
|
|
||||||
- char id_t10[DEV_WWID_SIZE];
|
|
||||||
+ char du_idname[PATH_MAX];
|
|
||||||
struct dev_id *id;
|
|
||||||
const char *idname;
|
|
||||||
int part;
|
|
||||||
@@ -1827,20 +1902,30 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Devices file entries with IDTYPE=sys_wwid and a T10 WWID
|
|
||||||
- * for IDNAME were saved in the past with each space replaced
|
|
||||||
- * by one _. Now we convert multiple spaces to a single _.
|
|
||||||
- * So, convert a df entry with the old style to the new shorter
|
|
||||||
- * style to compare. Also, in past versions, trailing spaces
|
|
||||||
- * in the wwid would be replaced by _, but now trailing spaces
|
|
||||||
- * are ignored. This means devices file entries created by
|
|
||||||
- * past versions may have _ at the end of the IDNAME string.
|
|
||||||
- * So, exclude trailing underscores when comparing a t10 wwid
|
|
||||||
- * from a device with a t10 wwid in the devices file.
|
|
||||||
+ * sys_wwid and sys_serial were saved in the past with leading and
|
|
||||||
+ * trailing spaces replaced with underscores, and t10 wwids also had
|
|
||||||
+ * repeated internal spaces replaced with one underscore each. Now we
|
|
||||||
+ * ignore leading and trailing spaces and replace multiple repeated
|
|
||||||
+ * spaces with one underscore in t10 wwids. In order to handle
|
|
||||||
+ * system.devices entries created by older versions, modify the IDNAME
|
|
||||||
+ * value that's read (du->idname) to remove leading and trailing
|
|
||||||
+ * underscores, and reduce repeated underscores to one in t10 wwids.
|
|
||||||
+ *
|
|
||||||
+ * Example: wwid is reported as " t10.123 456 " (without quotes)
|
|
||||||
+ * Previous versions would save this in system.devices as: __t10.123__456__
|
|
||||||
+ * Current versions will save this in system.devices as: t10.123_456
|
|
||||||
+ * device_id_system_read() now returns: t10.123_456
|
|
||||||
+ * When this code reads __t10.123__456__ from system.devices, that
|
|
||||||
+ * string is modified to t10.123_456 so that it will match the value
|
|
||||||
+ * returned from device_id_system_read().
|
|
||||||
*/
|
|
||||||
- if (du->idtype == DEV_ID_TYPE_SYS_WWID && !strncmp(du->idname, "t10", 3) && strchr(du->idname, '_')) {
|
|
||||||
- _reduce_repeating_underscores(du->idname, strlen(du->idname), du_t10, sizeof(du_t10) - 1);
|
|
||||||
- _remove_trailing_underscores(du_t10);
|
|
||||||
+ strncpy(du_idname, du->idname, PATH_MAX-1);
|
|
||||||
+ if (((du->idtype == DEV_ID_TYPE_SYS_WWID) || (du->idtype == DEV_ID_TYPE_SYS_SERIAL)) &&
|
|
||||||
+ strchr(du_idname, '_')) {
|
|
||||||
+ _remove_leading_underscores(du_idname, sizeof(du_idname));
|
|
||||||
+ _remove_trailing_underscores(du_idname, sizeof(du_idname));
|
|
||||||
+ if (du->idtype == DEV_ID_TYPE_SYS_WWID && !strncmp(du_idname, "t10", 3) && strstr(du_idname, "__"))
|
|
||||||
+ _reduce_repeating_underscores(du_idname, sizeof(du_idname));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -1848,21 +1933,14 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
|
||||||
* (and saved on dev->ids to avoid rereading.)
|
|
||||||
*/
|
|
||||||
dm_list_iterate_items(id, &dev->ids) {
|
|
||||||
- if (id->idtype == du->idtype) {
|
|
||||||
+ if (!id->idname)
|
|
||||||
+ continue;
|
|
||||||
|
|
||||||
+ if (id->idtype == du->idtype) {
|
|
||||||
/*
|
|
||||||
- * For t10 wwids, remove actual trailing underscores from the dev wwid
|
|
||||||
- * (in id->idname), because all trailing underscores were removed from
|
|
||||||
- * the du->idname read from the devices file. i.e. no trailing _ are
|
|
||||||
- * used in t10 wwid comparisons.
|
|
||||||
+ * dm names can have different forms, so matching names
|
|
||||||
+ * is not always a direct comparison.
|
|
||||||
*/
|
|
||||||
- if ((id->idtype == DEV_ID_TYPE_SYS_WWID) &&
|
|
||||||
- id->idname && !strncmp(id->idname, "t10", 3) && du_t10[0]) {
|
|
||||||
- memset(id_t10, 0, sizeof(id_t10));
|
|
||||||
- strncpy(id_t10, id->idname, DEV_WWID_SIZE-1);
|
|
||||||
- _remove_trailing_underscores(id_t10);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if ((id->idtype == DEV_ID_TYPE_DEVNAME) && _match_dm_devnames(cmd, dev, id, du)) {
|
|
||||||
/* dm devs can have differing names that we know still match */
|
|
||||||
du->dev = dev;
|
|
||||||
@@ -1871,22 +1949,16 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
|
||||||
log_debug("Match device_id %s %s to %s: dm names",
|
|
||||||
idtype_to_str(du->idtype), du->idname, dev_name(dev));
|
|
||||||
return 1;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- } else if (id->idname && !strcmp(id->idname, du->idname)) {
|
|
||||||
+ if (!strcmp(id->idname, du_idname)) {
|
|
||||||
du->dev = dev;
|
|
||||||
dev->id = id;
|
|
||||||
dev->flags |= DEV_MATCHED_USE_ID;
|
|
||||||
log_debug("Match device_id %s %s to %s",
|
|
||||||
- idtype_to_str(du->idtype), du->idname, dev_name(dev));
|
|
||||||
+ idtype_to_str(du->idtype), du_idname, dev_name(dev));
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
- } else if ((id->idtype == DEV_ID_TYPE_SYS_WWID) && du_t10[0] && id_t10[0] && !strcmp(id_t10, du_t10)) {
|
|
||||||
- du->dev = dev;
|
|
||||||
- dev->id = id;
|
|
||||||
- dev->flags |= DEV_MATCHED_USE_ID;
|
|
||||||
- log_debug("Match device_id %s %s to %s",
|
|
||||||
- idtype_to_str(du->idtype), du->idname, dev_name(dev));
|
|
||||||
- return 1;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
log_debug("Mismatch device_id %s %s to %s: idname %s",
|
|
||||||
@@ -1913,12 +1985,12 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
|
||||||
id->dev = dev;
|
|
||||||
dm_list_add(&dev->ids, &id->list);
|
|
||||||
|
|
||||||
- if (idname && !strcmp(idname, du->idname)) {
|
|
||||||
+ if (idname && !strcmp(idname, du_idname)) {
|
|
||||||
du->dev = dev;
|
|
||||||
dev->id = id;
|
|
||||||
dev->flags |= DEV_MATCHED_USE_ID;
|
|
||||||
log_debug("Match device_id %s %s to %s",
|
|
||||||
- idtype_to_str(du->idtype), du->idname, dev_name(dev));
|
|
||||||
+ idtype_to_str(du->idtype), idname, dev_name(dev));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1944,7 +2016,7 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
|
|
||||||
dev_read_vpd_wwids(cmd, dev);
|
|
||||||
|
|
||||||
dm_list_iterate_items(dw, &dev->wwids) {
|
|
||||||
- if (!strcmp(dw->id, du->idname)) {
|
|
||||||
+ if (!strcmp(dw->id, du_idname)) {
|
|
||||||
if (!(id = zalloc(sizeof(struct dev_id))))
|
|
||||||
return_0;
|
|
||||||
/* wwid types are 1,2,3 and idtypes are DEV_ID_TYPE_ */
|
|
||||||
diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c
|
|
||||||
index c1ac974fd..938277e38 100644
|
|
||||||
--- a/lib/device/parse_vpd.c
|
|
||||||
+++ b/lib/device/parse_vpd.c
|
|
||||||
@@ -36,7 +36,57 @@
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
+ * Remove leading spaces.
|
|
||||||
+ * Remove trailing spaces.
|
|
||||||
+ * Replace each space with underscore.
|
|
||||||
+ * Skip quotes, non-ascii, non-printable.
|
|
||||||
+ */
|
|
||||||
+int format_general_id(const char *in, int in_bytes, unsigned char *out, int out_bytes)
|
|
||||||
+{
|
|
||||||
+ const char *end;
|
|
||||||
+ int end_bytes = strlen(in);
|
|
||||||
+ int retlen = 0;
|
|
||||||
+ int j = 0;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ if (!end_bytes)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ end = in + end_bytes - 1;
|
|
||||||
+ while ((end > in) && (*end == ' ')) {
|
|
||||||
+ end--;
|
|
||||||
+ end_bytes--;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < end_bytes; i++) {
|
|
||||||
+ if (!in[i])
|
|
||||||
+ break;
|
|
||||||
+ if (j >= (out_bytes - 2))
|
|
||||||
+ break;
|
|
||||||
+ /* skip leading spaces */
|
|
||||||
+ if (!retlen && (in[i] == ' '))
|
|
||||||
+ continue;
|
|
||||||
+ /* skip non-ascii non-printable characters */
|
|
||||||
+ if (!isascii(in[i]) || !isprint(in[i]))
|
|
||||||
+ continue;
|
|
||||||
+ /* skip quote */
|
|
||||||
+ if (in[i] == '"')
|
|
||||||
+ continue;
|
|
||||||
+ /* replace each space with _ */
|
|
||||||
+ if (in[i] == ' ')
|
|
||||||
+ out[j++] = '_';
|
|
||||||
+ else
|
|
||||||
+ out[j++] = in[i];
|
|
||||||
+ retlen++;
|
|
||||||
+ }
|
|
||||||
+ return retlen;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Remove leading spaces.
|
|
||||||
+ * Remove trailing spaces.
|
|
||||||
* Replace series of spaces with a single _.
|
|
||||||
+ * Skip quotes, non-ascii, non-printable.
|
|
||||||
*/
|
|
||||||
int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
|
|
||||||
{
|
|
||||||
diff --git a/test/shell/devicesfile-vpd-ids.sh b/test/shell/devicesfile-vpd-ids.sh
|
|
||||||
index 52805737b..04dbae7d0 100644
|
|
||||||
--- a/test/shell/devicesfile-vpd-ids.sh
|
|
||||||
+++ b/test/shell/devicesfile-vpd-ids.sh
|
|
||||||
@@ -223,8 +223,8 @@ cleanup_sysfs
|
|
||||||
# Test t10 wwid containing quote
|
|
||||||
rm $DF
|
|
||||||
aux wipefs_a "$DEV1"
|
|
||||||
-mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/
|
|
||||||
-echo "t10.ATA_2.5\"_SATA_SSD_1112-A___111111111111" > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device
|
|
||||||
+echo "t10.ATA_2.5\"_SATA_SSD_1112-A___111111111111" > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
lvmdevices --adddev "$DEV1"
|
|
||||||
cat $DF
|
|
||||||
vgcreate $vg "$DEV1"
|
|
||||||
@@ -241,19 +241,19 @@ grep sys_wwid $DF
|
|
||||||
grep 2.5_SATA_SSD $DF
|
|
||||||
lvremove -y $vg
|
|
||||||
vgremove $vg
|
|
||||||
-rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
cleanup_sysfs
|
|
||||||
|
|
||||||
# Test t10 wwid with trailing space and line feed at the end
|
|
||||||
rm $DF
|
|
||||||
aux wipefs_a "$DEV1"
|
|
||||||
-mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device
|
|
||||||
echo -n "7431 302e 4154 4120 2020 2020 5642 4f58 \
|
|
||||||
2048 4152 4444 4953 4b20 2020 2020 2020 \
|
|
||||||
2020 2020 2020 2020 2020 2020 2020 2020 \
|
|
||||||
2020 2020 5642 3963 3130 6433 3138 2d31 \
|
|
||||||
-3838 6439 6562 6320 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
-cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+3838 6439 6562 6320 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
+cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
lvmdevices --adddev "$DEV1"
|
|
||||||
cat $DF
|
|
||||||
vgcreate $vg "$DEV1"
|
|
||||||
@@ -266,19 +266,19 @@ grep sys_wwid out
|
|
||||||
grep sys_wwid $DF
|
|
||||||
lvremove -y $vg
|
|
||||||
vgremove $vg
|
|
||||||
-rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
cleanup_sysfs
|
|
||||||
|
|
||||||
# Test t10 wwid with trailing space at the end that was created by 9.0/9.1
|
|
||||||
rm $DF
|
|
||||||
aux wipefs_a "$DEV1"
|
|
||||||
-mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device
|
|
||||||
echo -n "7431 302e 4154 4120 2020 2020 5642 4f58 \
|
|
||||||
2048 4152 4444 4953 4b20 2020 2020 2020 \
|
|
||||||
2020 2020 2020 2020 2020 2020 2020 2020 \
|
|
||||||
2020 2020 5642 3963 3130 6433 3138 2d31 \
|
|
||||||
-3838 6439 6562 6320 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
-cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+3838 6439 6562 6320 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
+cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
lvmdevices --adddev "$DEV1"
|
|
||||||
cat $DF
|
|
||||||
vgcreate $vg "$DEV1"
|
|
||||||
@@ -311,20 +311,20 @@ pvs
|
|
||||||
pvs -o+deviceidtype,deviceid "$DEV1"
|
|
||||||
lvremove -y $vg
|
|
||||||
vgremove $vg
|
|
||||||
-rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
cleanup_sysfs
|
|
||||||
|
|
||||||
# test a t10 wwid that has actual trailing underscore which
|
|
||||||
# is followed by a trailing space.
|
|
||||||
rm $DF
|
|
||||||
aux wipefs_a "$DEV1"
|
|
||||||
-mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device
|
|
||||||
echo -n "7431 302e 4154 4120 2020 2020 5642 4f58 \
|
|
||||||
2048 4152 4444 4953 4b20 2020 2020 2020 \
|
|
||||||
2020 2020 2020 2020 2020 2020 2020 2020 \
|
|
||||||
2020 2020 5642 3963 3130 6433 3138 2d31 \
|
|
||||||
-3838 6439 6562 5f20 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
-cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+3838 6439 6562 5f20 0a" | xxd -r -p > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
+cat $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
# The wwid has an actual underscore char (5f) followed by a space char (20)
|
|
||||||
# 9.1 converts the trailing space to an underscore
|
|
||||||
T10_WWID_RHEL91="t10.ATA_____VBOX_HARDDISK___________________________VB9c10d318-188d9eb__"
|
|
||||||
@@ -352,9 +352,80 @@ pvs
|
|
||||||
pvs -o+deviceidtype,deviceid "$DEV1"
|
|
||||||
lvremove -y $vg
|
|
||||||
vgremove $vg
|
|
||||||
-rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/wwid
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
+cleanup_sysfs
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Test trailing/leading/center spaces in sys_wwid and sys_serial device
|
|
||||||
+# ids, and that old system.devices files that have trailing/leading
|
|
||||||
+# underscores are understood.
|
|
||||||
+#
|
|
||||||
+
|
|
||||||
+rm $DF
|
|
||||||
+aux wipefs_a "$DEV1"
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device
|
|
||||||
+echo -n " s123 456 " > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
|
|
||||||
+lvmdevices --adddev "$DEV1"
|
|
||||||
+cat $DF
|
|
||||||
+grep "IDNAME=s123__456 DEVNAME" $DF
|
|
||||||
+vgcreate $vg "$DEV1"
|
|
||||||
+PVID1=`pvs "$DEV1" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
||||||
+cat $DF | grep -v IDNAME > $DFTMP
|
|
||||||
+cat $DFTMP
|
|
||||||
+echo "IDTYPE=sys_serial IDNAME=__s123__456__ DEVNAME=${DEV1} PVID=${PVID1}" >> $DFTMP
|
|
||||||
+cp $DFTMP $DF
|
|
||||||
+cat $DF
|
|
||||||
+vgs
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1"
|
|
||||||
+lvremove -y $vg
|
|
||||||
+vgremove $vg
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
|
|
||||||
cleanup_sysfs
|
|
||||||
|
|
||||||
+rm $DF
|
|
||||||
+aux wipefs_a "$DEV1"
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device
|
|
||||||
+echo -n " t10.123 456 " > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
+lvmdevices --adddev "$DEV1"
|
|
||||||
+cat $DF
|
|
||||||
+grep "IDNAME=t10.123_456 DEVNAME" $DF
|
|
||||||
+vgcreate $vg "$DEV1"
|
|
||||||
+PVID1=`pvs "$DEV1" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
||||||
+cat $DF | grep -v IDNAME > $DFTMP
|
|
||||||
+cat $DFTMP
|
|
||||||
+echo "IDTYPE=sys_wwid IDNAME=__t10.123__456__ DEVNAME=${DEV1} PVID=${PVID1}" >> $DFTMP
|
|
||||||
+cp $DFTMP $DF
|
|
||||||
+cat $DF
|
|
||||||
+vgs
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1"
|
|
||||||
+lvremove -y $vg
|
|
||||||
+vgremove $vg
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
+cleanup_sysfs
|
|
||||||
+
|
|
||||||
+rm $DF
|
|
||||||
+aux wipefs_a "$DEV1"
|
|
||||||
+mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device
|
|
||||||
+echo -n " naa.123 456 " > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
+lvmdevices --adddev "$DEV1"
|
|
||||||
+cat $DF
|
|
||||||
+grep "IDNAME=naa.123__456 DEVNAME" $DF
|
|
||||||
+vgcreate $vg "$DEV1"
|
|
||||||
+PVID1=`pvs "$DEV1" --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
||||||
+cat $DF | grep -v IDNAME > $DFTMP
|
|
||||||
+cat $DFTMP
|
|
||||||
+echo "IDTYPE=sys_wwid IDNAME=__naa.123__456__ DEVNAME=${DEV1} PVID=${PVID1}" >> $DFTMP
|
|
||||||
+cp $DFTMP $DF
|
|
||||||
+cat $DF
|
|
||||||
+vgs
|
|
||||||
+pvs -o+deviceidtype,deviceid "$DEV1"
|
|
||||||
+lvremove -y $vg
|
|
||||||
+vgremove $vg
|
|
||||||
+rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid
|
|
||||||
+cleanup_sysfs
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
|
|
||||||
# TODO: lvmdevices --adddev <dev> --deviceidtype <type> --deviceid <val>
|
|
||||||
# This would let the user specify the second naa wwid.
|
|
||||||
--
|
|
||||||
2.41.0
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
|||||||
From 14cb9d915270634c364d89918f824c538b28dc80 Mon Sep 17 00:00:00 2001
|
|
||||||
From: heinzm <heinzm@redhat.com>
|
|
||||||
Date: Wed, 10 May 2023 18:22:11 +0200
|
|
||||||
Subject: [PATCH 13/14] Fix "multisegment RAID1, allocator uses one disk for
|
|
||||||
both legs"
|
|
||||||
|
|
||||||
In case of e.g. 3 PVs, creating or extending a RaidLV causes SubLV
|
|
||||||
collocation thus putting segments of diffent rimage (and potentially
|
|
||||||
larger rmeta) SubLVs onto the same PV. For redundant RaidLVs this'll
|
|
||||||
compromise redundancy. Fix by detecting such bogus allocation on
|
|
||||||
lvcreate/lvextend and reject the request.
|
|
||||||
|
|
||||||
(cherry picked from commit 05c2b10c5d0a99993430ffbcef684a099ba810ad)
|
|
||||||
---
|
|
||||||
lib/metadata/lv_manip.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 41 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
|
||||||
index add9512ff..e4799e082 100644
|
|
||||||
--- a/lib/metadata/lv_manip.c
|
|
||||||
+++ b/lib/metadata/lv_manip.c
|
|
||||||
@@ -4455,6 +4455,38 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* Check either RAID images and metas are being allocated redundantly. */
|
|
||||||
+static int _lv_raid_redundant(struct logical_volume *lv,
|
|
||||||
+ struct dm_list *allocatable_pvs, int meta)
|
|
||||||
+{
|
|
||||||
+ uint32_t nlvs, s;
|
|
||||||
+ struct lv_segment *seg = first_seg(lv);
|
|
||||||
+ struct pv_list *pvl;
|
|
||||||
+
|
|
||||||
+ if (meta && !seg->meta_areas)
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
+ dm_list_iterate_items(pvl, allocatable_pvs) {
|
|
||||||
+ nlvs = 0;
|
|
||||||
+
|
|
||||||
+ for (s = 0; s < seg->area_count; s++) {
|
|
||||||
+ struct logical_volume *slv = meta ? seg_metalv(seg, s) : seg_lv(seg, s);
|
|
||||||
+
|
|
||||||
+ if (slv && lv_is_on_pv(slv, pvl->pv) && nlvs++)
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* Check both RAID images and metas are being allocated redundantly. */
|
|
||||||
+static int _lv_raid_redundant_allocation(struct logical_volume *lv, struct dm_list *allocatable_pvs)
|
|
||||||
+{
|
|
||||||
+ return _lv_raid_redundant(lv, allocatable_pvs, 0) &&
|
|
||||||
+ _lv_raid_redundant(lv, allocatable_pvs, 1);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Entry point for single-step LV allocation + extension.
|
|
||||||
* Extents is the number of logical extents to append to the LV unless
|
|
||||||
@@ -4557,6 +4589,15 @@ int lv_extend(struct logical_volume *lv,
|
|
||||||
mirrors, stripes, stripe_size)))
|
|
||||||
goto_out;
|
|
||||||
|
|
||||||
+ if (segtype_is_raid(segtype) &&
|
|
||||||
+ alloc != ALLOC_ANYWHERE &&
|
|
||||||
+ !(r = _lv_raid_redundant_allocation(lv, allocatable_pvs))) {
|
|
||||||
+ log_error("Insufficient suitable allocatable extents for logical volume %s", display_lvname(lv));
|
|
||||||
+ if (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg))
|
|
||||||
+ return_0;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (lv_raid_has_integrity(lv)) {
|
|
||||||
if (!lv_extend_integrity_in_raid(lv, allocatable_pvs)) {
|
|
||||||
r = 0;
|
|
||||||
--
|
|
||||||
2.41.0
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
|||||||
From 4e28d22cc152fd9c753e5584a5ae99e7a5d1ac96 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Teigland <teigland@redhat.com>
|
|
||||||
Date: Wed, 17 May 2023 14:15:25 -0500
|
|
||||||
Subject: [PATCH 14/14] tests: integrity-caching: ensure raid redundancy
|
|
||||||
|
|
||||||
The recent fix 05c2b10c5d0a9 ensures that raid LV images are not
|
|
||||||
using the same devices. This was happening in the lvextend commands
|
|
||||||
used by this test, so fix the test to use more devices to ensue
|
|
||||||
redundancy.
|
|
||||||
|
|
||||||
(cherry picked from commit 24e4b6df1182d0d41763176c175e98e5fa6153ab)
|
|
||||||
---
|
|
||||||
lib/metadata/lv_manip.c | 5 ++++-
|
|
||||||
test/shell/integrity-caching.sh | 27 ++++++++++++++++++---------
|
|
||||||
2 files changed, 22 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
|
||||||
index e4799e082..70c969de5 100644
|
|
||||||
--- a/lib/metadata/lv_manip.c
|
|
||||||
+++ b/lib/metadata/lv_manip.c
|
|
||||||
@@ -4472,8 +4472,11 @@ static int _lv_raid_redundant(struct logical_volume *lv,
|
|
||||||
for (s = 0; s < seg->area_count; s++) {
|
|
||||||
struct logical_volume *slv = meta ? seg_metalv(seg, s) : seg_lv(seg, s);
|
|
||||||
|
|
||||||
- if (slv && lv_is_on_pv(slv, pvl->pv) && nlvs++)
|
|
||||||
+ if (slv && lv_is_on_pv(slv, pvl->pv) && nlvs++) {
|
|
||||||
+ log_error("LV %s using PV %s is not redundant.",
|
|
||||||
+ display_lvname(slv), dev_name(pvl->pv->dev));
|
|
||||||
return 0;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/test/shell/integrity-caching.sh b/test/shell/integrity-caching.sh
|
|
||||||
index 5539ac575..06fc04928 100644
|
|
||||||
--- a/test/shell/integrity-caching.sh
|
|
||||||
+++ b/test/shell/integrity-caching.sh
|
|
||||||
@@ -23,7 +23,7 @@ aux kernel_at_least 5 10 || export LVM_TEST_PREFER_BRD=0
|
|
||||||
mnt="mnt"
|
|
||||||
mkdir -p $mnt
|
|
||||||
|
|
||||||
-aux prepare_devs 6 80
|
|
||||||
+aux prepare_devs 9 80
|
|
||||||
|
|
||||||
# Use awk instead of anoyingly long log out from printf
|
|
||||||
#printf "%0.sA" {1..16384} >> fileA
|
|
||||||
@@ -319,7 +319,7 @@ vgremove -ff $vg
|
|
||||||
# Test lvextend while inactive
|
|
||||||
|
|
||||||
_prepare_vg
|
|
||||||
-lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -l 8 $vg
|
|
||||||
+lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -l 8 $vg "$dev1" "$dev2"
|
|
||||||
_wait_recalc $vg/${lv1}_rimage_0
|
|
||||||
_wait_recalc $vg/${lv1}_rimage_1
|
|
||||||
_wait_recalc $vg/$lv1
|
|
||||||
@@ -329,7 +329,11 @@ lvs -a -o name,size,segtype,devices,sync_percent $vg
|
|
||||||
_add_new_data_to_mnt
|
|
||||||
umount $mnt
|
|
||||||
lvchange -an $vg/$lv1
|
|
||||||
-lvextend -l 16 $vg/$lv1
|
|
||||||
+# use two new devs for raid extend to ensure redundancy
|
|
||||||
+vgextend $vg "$dev7" "$dev8"
|
|
||||||
+lvs -a -o name,segtype,devices $vg
|
|
||||||
+lvextend -l 16 $vg/$lv1 "$dev7" "$dev8"
|
|
||||||
+lvs -a -o name,segtype,devices $vg
|
|
||||||
lvchange -ay $vg/$lv1
|
|
||||||
mount "$DM_DEV_DIR/$vg/$lv1" $mnt
|
|
||||||
xfs_growfs $mnt
|
|
||||||
@@ -346,16 +350,19 @@ vgremove -ff $vg
|
|
||||||
# Test lvextend while active
|
|
||||||
|
|
||||||
_prepare_vg
|
|
||||||
-lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -l 8 $vg
|
|
||||||
+lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -l 8 $vg "$dev1" "$dev2"
|
|
||||||
_wait_recalc $vg/${lv1}_rimage_0
|
|
||||||
_wait_recalc $vg/${lv1}_rimage_1
|
|
||||||
_wait_recalc $vg/$lv1
|
|
||||||
lvcreate --type $create_type -n fast -l 4 -an $vg "$dev6"
|
|
||||||
lvconvert -y --type $convert_type $convert_option fast $vg/$lv1
|
|
||||||
+# use two new devs for raid extend to ensure redundancy
|
|
||||||
+vgextend $vg "$dev7" "$dev8"
|
|
||||||
lvs -a -o name,size,segtype,devices,sync_percent $vg
|
|
||||||
_add_new_data_to_mnt
|
|
||||||
-lvextend -l 16 $vg/$lv1
|
|
||||||
-xfs_growfs $mnt
|
|
||||||
+lvextend -l 16 $vg/$lv1 "$dev7" "$dev8"
|
|
||||||
+lvs -a -o name,size,segtype,devices,sync_percent $vg
|
|
||||||
+resize2fs "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
_wait_recalc $vg/${lv1}_${suffix}_rimage_0
|
|
||||||
_wait_recalc $vg/${lv1}_${suffix}_rimage_1
|
|
||||||
_add_more_data_to_mnt
|
|
||||||
@@ -367,17 +374,19 @@ lvremove $vg/$lv1
|
|
||||||
vgremove -ff $vg
|
|
||||||
|
|
||||||
_prepare_vg
|
|
||||||
-lvcreate --type raid5 --raidintegrity y -n $lv1 -l 8 $vg
|
|
||||||
+lvcreate --type raid5 --raidintegrity y -n $lv1 -I4 -l 8 $vg "$dev1" "$dev2" "$dev3"
|
|
||||||
_wait_recalc $vg/${lv1}_rimage_0
|
|
||||||
_wait_recalc $vg/${lv1}_rimage_1
|
|
||||||
_wait_recalc $vg/${lv1}_rimage_2
|
|
||||||
_wait_recalc $vg/$lv1
|
|
||||||
lvcreate --type $create_type -n fast -l 4 -an $vg "$dev6"
|
|
||||||
lvconvert -y --type $convert_type $convert_option fast $vg/$lv1
|
|
||||||
+vgextend $vg "$dev7" "$dev8" "$dev9"
|
|
||||||
lvs -a -o name,size,segtype,devices,sync_percent $vg
|
|
||||||
_add_new_data_to_mnt
|
|
||||||
-lvextend -l 16 $vg/$lv1
|
|
||||||
-xfs_growfs $mnt
|
|
||||||
+lvextend -l 16 $vg/$lv1 "$dev7" "$dev8" "$dev9"
|
|
||||||
+lvs -a -o name,size,segtype,devices,sync_percent $vg
|
|
||||||
+resize2fs "$DM_DEV_DIR/$vg/$lv1"
|
|
||||||
_wait_recalc $vg/${lv1}_${suffix}_rimage_0
|
|
||||||
_wait_recalc $vg/${lv1}_${suffix}_rimage_1
|
|
||||||
_add_more_data_to_mnt
|
|
||||||
--
|
|
||||||
2.41.0
|
|
||||||
|
|
Loading…
Reference in new issue