import CS lvm2-2.03.21-3.el9

c9-beta imports/c9-beta/lvm2-2.03.21-3.el9
eabdullin 2023-09-21 19:24:34 +00:00
parent 4277844893
commit 5291febd18
27 changed files with 2194 additions and 940 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/LVM2.2.03.17.tgz
SOURCES/LVM2.2.03.21.tgz

View File

@ -1 +1 @@
8a0043a552c17be61234989c02ef501eda971fd1 SOURCES/LVM2.2.03.17.tgz
b6d4a84bf1f0306f43f447c7531021d5c126edbf SOURCES/LVM2.2.03.21.tgz

View File

@ -1,133 +0,0 @@
From b01433cdc841133500a0ed4041b9b35838d45e87 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 2 Dec 2022 11:59:09 -0600
Subject: [PATCH] device_id: fix segfault verifying serial for non-pv
The recent change that verifies sys_serial system.devices entries
using the PVID did not exclude non-PV devices from being checked.
The verification code would attempt to use du->pvid which was null
for the non-PVs causing a segfault.
(cherry picked from commit 6613a61d3b5ce4d12a6fef79195eac34f30ef4da)
---
lib/device/device_id.c | 6 ++-
test/shell/devicesfile-serial.sh | 79 ++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+), 2 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index aae875776..96726a448 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -2237,8 +2237,8 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
* number is correct, since serial numbers may not be unique.
* Search for the PVID on other devs in device_ids_check_serial.
*/
- if ((du->idtype == DEV_ID_TYPE_SYS_SERIAL) &&
- (!du->pvid || memcmp(dev->pvid, du->pvid, ID_LEN))) {
+ if ((du->idtype == DEV_ID_TYPE_SYS_SERIAL) && du->pvid &&
+ memcmp(dev->pvid, du->pvid, ID_LEN)) {
log_debug("suspect device id serial %s for %s", du->idname, dev_name(dev));
str_list_add(cmd->mem, &cmd->device_ids_check_serial, dm_pool_strdup(cmd->mem, du->idname));
*device_ids_invalid = 1;
@@ -2570,6 +2570,8 @@ void device_ids_check_serial(struct cmd_context *cmd, struct dm_list *scan_devs,
dm_list_iterate_items(dul, &dus_check) {
if (!dul->du->dev)
continue;
+ if (!dul->du->pvid)
+ continue;
/* save previously matched devs so they can be dropped from
lvmcache at the end if they are no longer used */
if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil))))
diff --git a/test/shell/devicesfile-serial.sh b/test/shell/devicesfile-serial.sh
index b7bfce29e..a88c1906a 100644
--- a/test/shell/devicesfile-serial.sh
+++ b/test/shell/devicesfile-serial.sh
@@ -772,6 +772,85 @@ grep $SERIAL1 out2
grep $dev3 out3
grep $SERIAL3 out3
+# non-PV devices
+
+aux wipefs_a $dev1
+aux wipefs_a $dev2
+aux wipefs_a $dev3
+aux wipefs_a $dev4
+
+echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
+echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
+echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
+echo $SERIAL4 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
+
+rm $DF
+touch $DF
+vgcreate $vg4 $dev4
+lvmdevices --adddev "$dev1"
+lvmdevices --adddev "$dev2"
+lvmdevices --adddev "$dev3"
+cat $DF
+
+grep $dev1 $DF |tee out1
+grep $dev2 $DF |tee out2
+grep $dev3 $DF |tee out3
+grep $dev4 $DF |tee out4
+
+grep $SERIAL1 out1
+grep $SERIAL2 out2
+grep $SERIAL2 out3
+grep $SERIAL4 out4
+
+pvs |tee out
+grep $dev4 out
+not grep $dev1 out
+not grep $dev2 out
+not grep $dev3 out
+
+pvcreate $dev1
+pvs |tee out
+grep $dev1 out
+grep $dev4 out
+not grep $dev2 out
+not grep $dev3 out
+
+pvcreate $dev2
+pvs |tee out
+grep $dev1 out
+grep $dev4 out
+grep $dev2 out
+not grep $dev3 out
+
+pvcreate $dev3
+pvs |tee out
+grep $dev1 out
+grep $dev4 out
+grep $dev2 out
+grep $dev3 out
+
+PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
+PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
+PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
+PVID4=`pvs "$dev4" --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}'`
+OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
+OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
+
+grep $dev1 $DF |tee out1
+grep $dev2 $DF |tee out2
+grep $dev3 $DF |tee out3
+grep $dev4 $DF |tee out4
+
+grep $PVID1 out1
+grep $PVID2 out2
+grep $PVID3 out3
+grep $PVID4 out4
+
+vgcreate $vg2 $dev2 $dev3
+vgs | grep $vg2
+
remove_base
rmmod brd
--
2.38.1

View File

@ -0,0 +1,84 @@
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

View File

@ -1,36 +0,0 @@
From 20c6961e37bf6f5010f9d2035dbc1ce03f9b0223 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 15 Dec 2022 09:57:04 -0600
Subject: [PATCH] lvextend: fix overprovisioning check for thin lvs
18722dfdf4d3 lvresize: restructure code
mistakenly changed the overprovisioning check from applying
to all lv_is_thin_type lvs to only lv_is_thin_pool lvs, so
it no longer applied when extending thin lvs. The result
was missing warning messages when extending thin lvs.
(cherry picked from commit 4baef0f93f608403b6f2db445e7bf1e80f8f3ee6)
---
lib/metadata/lv_manip.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 4cdbc19a0..f8eae0447 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7007,9 +7007,10 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_thin_pool(lv_top)) {
if (!update_thin_pool_lv(lv_top, 1))
goto_out;
- if (is_extend)
- thin_pool_check_overprovisioning(lv_top);
}
+ if (lv_is_thin_type(lv_top) && is_extend)
+ thin_pool_check_overprovisioning(lv_top);
+
if (lv_main && lv_is_cow_covering_origin(lv_main)) {
if (!monitor_dev_for_events(cmd, lv_main, 0, 0))
stack;
--
2.38.1

View File

@ -0,0 +1,510 @@
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

View File

@ -0,0 +1,26 @@
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

View File

@ -1,32 +0,0 @@
From db067b9054d87ada6aa133394e65e3af9d75fc08 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 3 Jan 2023 11:38:33 -0600
Subject: [PATCH] lvresize: fix cryptsetup resize in helper
typo used "cryptresize" as command name
this affects cases where the file system is resized
independently, and then the lvresize command is used
which only needs to resize the crypt device and the LV.
(cherry picked from commit 81acde7ffdf9fbe522ada16f89e429d9f729dc0c)
---
scripts/lvresize_fs_helper.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/lvresize_fs_helper.sh b/scripts/lvresize_fs_helper.sh
index 031b8453b..f531dd447 100755
--- a/scripts/lvresize_fs_helper.sh
+++ b/scripts/lvresize_fs_helper.sh
@@ -224,7 +224,7 @@ fsreduce() {
cryptresize() {
NEWSIZESECTORS=$(($NEWSIZEBYTES/512))
logmsg "cryptsetup resize ${NEWSIZESECTORS} sectors ${DEVPATH}"
- cryptresize resize --size "$NEWSIZESECTORS" "$DEVPATH"
+ cryptsetup resize --size "$NEWSIZESECTORS" "$DEVPATH"
if [ $? -eq 0 ]; then
logmsg "cryptsetup done"
else
--
2.39.0

View File

@ -0,0 +1,43 @@
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

View File

@ -1,48 +0,0 @@
From 8f7b4456ad93c3907a82fd03d0feceb9785e3bfc Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 5 Jan 2023 14:28:31 -0600
Subject: [PATCH 1/3] vgimportclone: fix importing PV without metadata
If one of the PVs in the VG does not hold metadata, then the
command would fail, thinking that PV was from a different VG.
Also add missing free on that error path.
(cherry picked from commit c4b898a53eec39bc28b5451e7fde87945303a644)
---
tools/vgimportclone.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index 60ef20762..93fa3b18d 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -203,7 +203,7 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
struct device *dev;
struct device_list *devl;
struct dm_list other_devs;
- struct volume_group *vg, *error_vg;
+ struct volume_group *vg, *error_vg = NULL;
const char *vgname;
char base_vgname[NAME_LEN] = { 0 };
char tmp_vgname[NAME_LEN] = { 0 };
@@ -322,7 +322,7 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
goto out;
}
- if (!(vgname = lvmcache_vgname_from_info(info))) {
+ if (!(vgname = lvmcache_vgname_from_info(info)) || is_orphan_vg(vgname)) {
/* The PV may not have metadata, this will be resolved in
the process_each_vg/vg_read at the end. */
continue;
@@ -503,6 +503,8 @@ retry_name:
}
ret = ECMD_PROCESSED;
out:
+ if (error_vg)
+ release_vg(error_vg);
unlock_devices_file(cmd);
return ret;
}
--
2.39.1

View File

@ -1,89 +0,0 @@
From 4e34edd6e4e52328dd77b6a55aeadd9b0454c743 Mon Sep 17 00:00:00 2001
From: Tony Asleson <tasleson@redhat.com>
Date: Tue, 29 Nov 2022 10:00:39 -0600
Subject: [PATCH 2/3] lvmdbusd: Move get_error_msg to utils
Moving this so we can re-use outside of lvm_shell_proxy.
(cherry picked from commit 8f60c494515ddccb20e4afb804edb6b9599e65c0)
---
daemons/lvmdbusd/lvm_shell_proxy.py.in | 23 +++--------------------
daemons/lvmdbusd/utils.py | 17 +++++++++++++++++
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
index ac6d51e65..37d73218b 100755
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
@@ -28,7 +28,7 @@ except ImportError:
import lvmdbusd.cfg as cfg
from lvmdbusd.utils import log_debug, log_error, add_no_notify, make_non_block,\
- read_decoded, extract_stack_trace, LvmBug
+ read_decoded, extract_stack_trace, LvmBug, get_error_msg
SHELL_PROMPT = "lvm> "
@@ -191,24 +191,7 @@ class LVMShellProxy(object):
def get_last_log(self):
self._write_cmd('lastlog\n')
report_json = self._read_response()[1]
- return LVMShellProxy.get_error_msg(report_json)
-
- @staticmethod
- def get_error_msg(report_json):
- # Get the error message from the returned JSON
- if 'log' in report_json:
- error_msg = ""
- # Walk the entire log array and build an error string
- for log_entry in report_json['log']:
- if log_entry['log_type'] == "error":
- if error_msg:
- error_msg += ', ' + log_entry['log_message']
- else:
- error_msg = log_entry['log_message']
-
- return error_msg
-
- return None
+ return get_error_msg(report_json)
def call_lvm(self, argv, debug=False):
rc = 1
@@ -245,7 +228,7 @@ class LVMShellProxy(object):
# report json too.
error_msg = self.get_last_log()
if error_msg is None:
- error_msg = LVMShellProxy.get_error_msg(report_json)
+ error_msg = get_error_msg(report_json)
if error_msg is None:
error_msg = 'No error reason provided! (missing "log" section)'
diff --git a/daemons/lvmdbusd/utils.py b/daemons/lvmdbusd/utils.py
index 5aecb1fff..0b81591b2 100644
--- a/daemons/lvmdbusd/utils.py
+++ b/daemons/lvmdbusd/utils.py
@@ -859,3 +859,20 @@ class LvmDebugData:
self._close_fd()
# In case lvm_complete doesn't get called.
self._remove_file()
+
+
+def get_error_msg(report_json):
+ # Get the error message from the returned JSON
+ if 'log' in report_json:
+ error_msg = ""
+ # Walk the entire log array and build an error string
+ for log_entry in report_json['log']:
+ if log_entry['log_type'] == "error":
+ if error_msg:
+ error_msg += ', ' + log_entry['log_message']
+ else:
+ error_msg = log_entry['log_message']
+
+ return error_msg
+
+ return None
--
2.39.1

View File

@ -0,0 +1,31 @@
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

View File

@ -1,79 +0,0 @@
From 0441d340e752427d0d355a85e5e5e465e911a102 Mon Sep 17 00:00:00 2001
From: Tony Asleson <tasleson@redhat.com>
Date: Tue, 29 Nov 2022 10:04:17 -0600
Subject: [PATCH 3/3] lvmdbusd: Add command_log_selection to command line
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2145114
(cherry picked from commit e63b0c7262f50ab43fcde1c50b6d880acab68407)
---
daemons/lvmdbusd/cmdhandler.py | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 0c7bd8528..9a76db4c9 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -17,7 +17,7 @@ import os
from lvmdbusd import cfg
from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error, add_no_notify,\
- make_non_block, read_decoded, extract_stack_trace, LvmBug, add_config_option
+ make_non_block, read_decoded, extract_stack_trace, LvmBug, add_config_option, get_error_msg
from lvmdbusd.lvm_shell_proxy import LVMShellProxy
try:
@@ -121,6 +121,9 @@ def call_lvm(command, debug=False, line_cb=None,
command.insert(0, cfg.LVM_CMD)
command = add_no_notify(command)
+ # Ensure we get an error message when we fork & exec the lvm command line
+ command = add_config_option(command, "--config", 'log/command_log_selection="log_context!=''"')
+
process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=True,
env=os.environ)
@@ -167,7 +170,17 @@ def call_lvm(command, debug=False, line_cb=None,
if debug or (process.returncode != 0 and (process.returncode != 5 and "fullreport" in command)):
_debug_c(command, process.returncode, (stdout_text, stderr_text))
- return process.returncode, stdout_text, stderr_text
+ try:
+ report_json = json.loads(stdout_text)
+ except json.decoder.JSONDecodeError:
+ # Some lvm commands don't return json even though we are asking for it to do so.
+ return process.returncode, stdout_text, stderr_text
+
+ error_msg = get_error_msg(report_json)
+ if error_msg:
+ stderr_text += error_msg
+
+ return process.returncode, report_json, stderr_text
else:
if cfg.run.value == 0:
raise SystemExit
@@ -619,20 +632,8 @@ def lvm_full_report_json():
rc, out, err = call(cmd)
# When we have an exported vg the exit code of lvs or fullreport will be 5
if rc == 0 or rc == 5:
- # If the 'call' implementation is lvmshell, the out is a dictionary as lvmshell has to
- # parse the output to get the exit value. When doing fork & exec, out is a string
- # representing the JSON. TODO: Make this consistent between implementations.
- if cfg.SHELL_IN_USE:
- assert(type(out) == dict)
- return out
- else:
- try:
- return json.loads(out)
- except json.decoder.JSONDecodeError as joe:
- log_error("JSONDecodeError %s, \n JSON=\n%s\n" %
- (str(joe), out))
- raise LvmBug("'fullreport' returned invalid JSON")
-
+ assert(type(out) == dict)
+ return out
raise LvmBug("'fullreport' exited with code '%d'" % rc)
--
2.39.1

View File

@ -0,0 +1,87 @@
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

View File

@ -1,49 +0,0 @@
From 380e3855fbc661eed490665cf1e3d05e985da189 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 3 Jan 2023 14:35:26 -0600
Subject: [PATCH 1/4] tests: lvresize-fs-crypt using helper only for crypt dev
(cherry picked from commit 2580f007f0aaa3bf22c43295caa2c60c6142494f)
---
test/shell/lvresize-fs-crypt.sh | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/test/shell/lvresize-fs-crypt.sh b/test/shell/lvresize-fs-crypt.sh
index e7b8b9426..61a6de022 100644
--- a/test/shell/lvresize-fs-crypt.sh
+++ b/test/shell/lvresize-fs-crypt.sh
@@ -135,6 +135,31 @@ cryptsetup close $cr
lvchange -an $vg/$lv
lvremove $vg/$lv
+# lvresize uses helper only for crypt dev resize
+# because the fs was resized separately beforehand
+lvcreate -n $lv -L 456M $vg
+echo 93R4P4pIqAH8 | cryptsetup luksFormat -i1 --type luks1 "$DM_DEV_DIR/$vg/$lv"
+echo 93R4P4pIqAH8 | cryptsetup luksOpen "$DM_DEV_DIR/$vg/$lv" $cr
+mkfs.ext4 /dev/mapper/$cr
+mount /dev/mapper/$cr "$mount_dir"
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=100 conv=fdatasync
+df --output=size "$mount_dir" |tee df1
+# resize only the fs (to 256M), not the crypt dev or LV
+umount "$mount_dir"
+resize2fs /dev/mapper/$cr 262144k
+mount /dev/mapper/$cr "$mount_dir"
+# this lvresize will not resize the fs (which is already reduced
+# to smaller than the requested LV size), but lvresize will use
+# the helper to resize the crypt dev before resizing the LV.
+lvresize -L-100M $vg/$lv
+check lv_field $vg/$lv lv_size "356.00m"
+df --output=size "$mount_dir" |tee df2
+not diff df1 df2
+umount "$mount_dir"
+cryptsetup close $cr
+lvchange -an $vg/$lv
+lvremove $vg/$lv
+
# test with LUKS2?
vgremove -ff $vg
--
2.39.1

View File

@ -1,114 +0,0 @@
From 7e0c2e1581225a916269edc8f04fb10e4ef5e952 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 19 Jan 2023 11:36:51 -0600
Subject: [PATCH 2/4] lvresize: only resize crypt when fs resize is enabled
There were a couple of cases where lvresize, without --fs resize,
was resizing the crypt layer above the LV. Resizing the crypt
layer should only be done when fs resizing is enabled (even if the
fs is already small enough due to being independently reduced.)
Also, check the size of the crypt device to see if it's already
been reduced independently, and skip the cryptsetup resize if
it's not needed.
(cherry picked from commit 3bb55765286dc8e4f0000957d85a6b8ee2752852)
---
lib/device/filesystem.c | 12 ++++++++++++
lib/device/filesystem.h | 1 +
lib/metadata/lv_manip.c | 18 +++++++++++++++++-
test/shell/lvresize-fs-crypt.sh | 7 ++++++-
4 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
index bdc230175..b4c43a626 100644
--- a/lib/device/filesystem.c
+++ b/lib/device/filesystem.c
@@ -106,6 +106,7 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
struct fs_info info;
FILE *fme = NULL;
struct mntent *me;
+ int fd;
int ret;
if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", lv->vg->cmd->dev_dir,
@@ -151,6 +152,17 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
log_print("File system found on crypt device %s on LV %s.",
crypt_path, display_lvname(lv));
+ if ((fd = open(crypt_path, O_RDONLY)) < 0) {
+ log_error("Failed to open crypt path %s", crypt_path);
+ return 0;
+ }
+ if (ioctl(fd, BLKGETSIZE64, &info.crypt_dev_size_bytes) < 0) {
+ log_error("Failed to get crypt device size %s", crypt_path);
+ close(fd);
+ return 0;
+ }
+ close(fd);
+
if (!fs_get_blkid(crypt_path, &info)) {
log_error("No file system info from blkid for dm-crypt device %s on LV %s.",
crypt_path, display_lvname(lv));
diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h
index 7a34d2ae0..fd1af0416 100644
--- a/lib/device/filesystem.h
+++ b/lib/device/filesystem.h
@@ -25,6 +25,7 @@ struct fs_info {
uint64_t fs_last_byte; /* last byte on the device used by the fs */
uint32_t crypt_offset_bytes; /* offset in bytes of crypt data on LV */
dev_t crypt_devt; /* dm-crypt device between the LV and FS */
+ uint64_t crypt_dev_size_bytes;
unsigned nofs:1;
unsigned unmounted:1;
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index f8eae0447..a2e9db2c9 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6397,7 +6397,23 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
* but the crypt dev over the LV should be shrunk to correspond with
* the LV size, so that the FS does not see an incorrect device size.
*/
- if (!fsinfo.needs_reduce && fsinfo.needs_crypt && !test_mode()) {
+ if (!fsinfo.needs_reduce && fsinfo.needs_crypt) {
+ /* Check if the crypt device is already sufficiently reduced. */
+ if (fsinfo.crypt_dev_size_bytes <= newsize_bytes_fs) {
+ log_print("crypt device is already reduced to %llu bytes.",
+ (unsigned long long)fsinfo.crypt_dev_size_bytes);
+ ret = 1;
+ goto out;
+ }
+ if (!strcmp(lp->fsopt, "checksize")) {
+ log_error("crypt reduce is required (see --resizefs or cryptsetup resize.)");
+ ret = 0;
+ goto out;
+ }
+ if (test_mode()) {
+ ret = 1;
+ goto_out;
+ }
ret = crypt_resize_script(cmd, lv, &fsinfo, newsize_bytes_fs);
goto out;
}
diff --git a/test/shell/lvresize-fs-crypt.sh b/test/shell/lvresize-fs-crypt.sh
index 61a6de022..4bef771dc 100644
--- a/test/shell/lvresize-fs-crypt.sh
+++ b/test/shell/lvresize-fs-crypt.sh
@@ -151,7 +151,12 @@ mount /dev/mapper/$cr "$mount_dir"
# this lvresize will not resize the fs (which is already reduced
# to smaller than the requested LV size), but lvresize will use
# the helper to resize the crypt dev before resizing the LV.
-lvresize -L-100M $vg/$lv
+# Using --fs resize is required to allow lvresize to look above
+# the lv at crypt&fs layers for potential resizing. Without
+# --fs resize, lvresize fails because it sees that crypt resize
+# is needed and --fs resize is needed to enable that.
+not lvresize -L-100 $vg/$lv
+lvresize -L-100M --fs resize $vg/$lv
check lv_field $vg/$lv lv_size "356.00m"
df --output=size "$mount_dir" |tee df2
not diff df1 df2
--
2.39.1

View File

@ -0,0 +1,37 @@
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

View File

@ -1,188 +0,0 @@
From fba3614c3ed596b99d8adf2fe6c60886db10b2c0 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 26 Jan 2023 14:00:00 -0600
Subject: [PATCH 3/4] lvresize: fail early if mounted LV was renamed
If a mounted LV is renamed, then fs resizing utilities will fail,
so detect this condition and fail the command before any changes
are made.
(cherry picked from commit 5374a44c57127cdd832a675545c1d2bbf0b3751a)
---
lib/device/filesystem.c | 110 ++++++++++++++++++++++++++++++++++++++
lib/device/filesystem.h | 2 +
lib/metadata/lv_manip.c | 3 ++
test/shell/lvresize-fs.sh | 11 ++++
4 files changed, 126 insertions(+)
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
index b4c43a626..db507bdda 100644
--- a/lib/device/filesystem.c
+++ b/lib/device/filesystem.c
@@ -214,6 +214,116 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
return ret;
}
+int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *lv, char *lv_path, char *fstype)
+{
+ FILE *fp;
+ char proc_line[PATH_MAX];
+ char proc_fstype[FSTYPE_MAX];
+ char proc_devpath[1024];
+ char proc_mntpath[1024];
+ char lv_mapper_path[1024];
+ char mntent_mount_dir[1024];
+ char *dm_name;
+ struct stat st_lv;
+ struct stat stme;
+ 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) {
+ log_error("Failed to get LV path %s", lv_path);
+ return 0;
+ }
+
+ /*
+ * If LVs have been renamed while their file systems were mounted, then
+ * inconsistencies appear in the device path and mount point info
+ * provided by getmntent and /proc/mounts. If there's any
+ * inconsistency or duplication of info for the LV name or the mount
+ * point, then give up and don't try fs resize which is likely to fail
+ * due to kernel problems where mounts reference old device names
+ * causing fs resizing tools to fail.
+ */
+
+ if (!(fme = setmntent("/etc/mtab", "r")))
+ return_0;
+
+ while ((me = getmntent(fme))) {
+ if (strcmp(me->mnt_type, fstype))
+ continue;
+ if (me->mnt_dir[0] != '/')
+ continue;
+ if (me->mnt_fsname[0] != '/')
+ continue;
+ if (stat(me->mnt_dir, &stme) < 0)
+ continue;
+ if (stme.st_dev != st_lv.st_rdev)
+ continue;
+ strncpy(mntent_mount_dir, me->mnt_dir, PATH_MAX-1);
+ }
+ endmntent(fme);
+
+ if (!(dm_name = dm_build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL)))
+ return_0;
+
+ if ((dm_snprintf(lv_mapper_path, 1024, "%s/%s", dm_dir(), dm_name) < 0))
+ return_0;
+
+ if (!(fp = fopen("/proc/mounts", "r")))
+ return_0;
+
+ while (fgets(proc_line, sizeof(proc_line), fp)) {
+ if (proc_line[0] != '/')
+ continue;
+ if (sscanf(proc_line, "%s %s %s", proc_devpath, proc_mntpath, proc_fstype) != 3)
+ continue;
+ if (strcmp(fstype, proc_fstype))
+ continue;
+
+ dir_match = !strcmp(mntent_mount_dir, proc_mntpath);
+ dev_match = !strcmp(lv_mapper_path, proc_devpath);
+
+ if (dir_match)
+ found_dir++;
+ if (dev_match)
+ found_dev++;
+
+ if (dir_match != dev_match) {
+ log_error("LV %s mounted at %s may have been renamed (from %s).",
+ lv_mapper_path, proc_mntpath, proc_devpath);
+ renamed = 1;
+ }
+ }
+
+ 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.", mntent_mount_dir);
+ return 1;
+ }
+ if (found_dev > 1) {
+ log_error("File system resizing not supported: %s appears more than once in /proc/mounts.", lv_mapper_path);
+ return 1;
+ }
+ return 0;
+}
+
#define FS_CMD_MAX_ARGS 16
int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h
index fd1af0416..77eac34d0 100644
--- a/lib/device/filesystem.h
+++ b/lib/device/filesystem.h
@@ -48,4 +48,6 @@ int fs_reduce_script(struct cmd_context *cmd, struct logical_volume *lv, struct
uint64_t newsize_bytes, char *fsmode);
int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
uint64_t newsize_bytes_fs);
+
+int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *lv, char *lv_path, char *fstype);
#endif
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index a2e9db2c9..25e16d41d 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6928,6 +6928,9 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
log_error("File system not found for --resizefs or --fs options.");
goto out;
}
+ /* FS utils will fail if LVs were renamed while mounted. */
+ if (fs_mount_state_is_misnamed(cmd, lv_top, lv_path, fstype))
+ goto_out;
}
/*
diff --git a/test/shell/lvresize-fs.sh b/test/shell/lvresize-fs.sh
index 0be6911a0..f437652d6 100644
--- a/test/shell/lvresize-fs.sh
+++ b/test/shell/lvresize-fs.sh
@@ -262,6 +262,17 @@ umount "$mount_dir"
lvchange -an $vg/$lv
lvremove $vg/$lv
+# lvextend|lvreduce, ext4, active, mounted, --fs resize, renamed LV
+lvcreate -n $lv -L 256M $vg
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
+lvrename $vg/$lv $vg/$lv2
+not lvextend --fs resize -L+32M $vg/$lv2
+not lvreduce --fs resize -L-32M $vg/$lv2
+umount "$mount_dir"
+lvchange -an $vg/$lv2
+lvremove $vg/$lv2
+
#
# lvextend, xfs
--
2.39.1

View File

@ -0,0 +1,102 @@
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

View File

@ -0,0 +1,247 @@
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