From bdbd4e73632f9c65ddab89602d0de9fd9d0cc372 Mon Sep 17 00:00:00 2001 From: Marian Csontos Date: Wed, 17 May 2023 15:42:08 +0200 Subject: [PATCH] Additional patches for 9.3.0 lvm2 Resolves: #2179430 --- 0001-fix-dev_name-use-in-add_areas_line.patch | 84 +++ 0002-raidintegrity-allow-snapshots.patch | 510 ++++++++++++++++++ lvm2.spec | 10 +- 3 files changed, 601 insertions(+), 3 deletions(-) create mode 100644 0001-fix-dev_name-use-in-add_areas_line.patch create mode 100644 0002-raidintegrity-allow-snapshots.patch diff --git a/0001-fix-dev_name-use-in-add_areas_line.patch b/0001-fix-dev_name-use-in-add_areas_line.patch new file mode 100644 index 0000000..0b55391 --- /dev/null +++ b/0001-fix-dev_name-use-in-add_areas_line.patch @@ -0,0 +1,84 @@ +From ecea7b14c453a58831f2dda5a0aa869ee4601dff Mon Sep 17 00:00:00 2001 +From: David Teigland +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 + diff --git a/0002-raidintegrity-allow-snapshots.patch b/0002-raidintegrity-allow-snapshots.patch new file mode 100644 index 0000000..ae92f75 --- /dev/null +++ b/0002-raidintegrity-allow-snapshots.patch @@ -0,0 +1,510 @@ +From fb1e53f229f4bcde07df4b562927e213bd7f8d17 Mon Sep 17 00:00:00 2001 +From: David Teigland +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 + diff --git a/lvm2.spec b/lvm2.spec index 4e479dd..46a9e59 100644 --- a/lvm2.spec +++ b/lvm2.spec @@ -54,7 +54,7 @@ Version: 2.03.21 %if 0%{?from_snapshot} Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix} %else -Release: 1%{?dist}%{?rel_suffix} +Release: 2%{?dist}%{?rel_suffix} %endif License: GPLv2 URL: http://sourceware.org/lvm2 @@ -63,8 +63,9 @@ Source0: lvm2-%{shortcommit}.tgz %else Source0: ftp://sourceware.org/pub/lvm2/releases/LVM2.%{version}.tgz %endif -# BZ: -#Patch1: 0001- +# BZ 2179430: +Patch1: 0001-fix-dev_name-use-in-add_areas_line.patch +Patch2: 0002-raidintegrity-allow-snapshots.patch BuildRequires: make BuildRequires: gcc @@ -692,6 +693,9 @@ An extensive functional testsuite for LVM2. %endif %changelog +* Wed May 17 2023 Marian Csontos - 2.03.21-2 +- Allow snapshots over raid+integrity LV. + * Fri Apr 21 2023 Marian Csontos - 2.03.21-1 - Update to upstream version 2.03.21. - Allow (write)cache over raid+integrity LV.