diff options
-rw-r--r-- | WHATS_NEW | 1 | ||||
-rw-r--r-- | lib/metadata/metadata-exported.h | 1 | ||||
-rw-r--r-- | lib/metadata/raid_manip.c | 8 | ||||
-rw-r--r-- | test/shell/lvchange-raid1-writemostly.sh | 41 | ||||
-rw-r--r-- | tools/lvchange.c | 15 |
5 files changed, 65 insertions, 1 deletions
@@ -1,5 +1,6 @@ Version 2.02.169 - ===================================== + Reject writemostly/writebehind in lvchange during resynchronization. Deactivate active origin first before removal for improved workflow. Fix regression of accepting options --type and -m with lvresize (2.02.158). Add lvconvert --swapmetadata, new specific way to swap pool metadata LVs. diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 573c09d90..e4d2267d0 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -1232,6 +1232,7 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype, uint32_t raid_ensure_min_region_size(const struct logical_volume *lv, uint64_t raid_size, uint32_t region_size); int lv_raid_change_region_size(struct logical_volume *lv, int yes, int force, uint32_t new_region_size); +int lv_raid_in_sync(const struct logical_volume *lv); /* -- metadata/raid_manip.c */ /* ++ metadata/cache_manip.c */ diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c index cdd7af8d6..b6215a2dd 100644 --- a/lib/metadata/raid_manip.c +++ b/lib/metadata/raid_manip.c @@ -238,7 +238,7 @@ static int _deactivate_and_remove_lvs(struct volume_group *vg, struct dm_list *r * Returns: 1 if in-sync, 0 otherwise. */ #define _RAID_IN_SYNC_RETRIES 6 -static int _raid_in_sync(struct logical_volume *lv) +static int _raid_in_sync(const struct logical_volume *lv) { int retries = _RAID_IN_SYNC_RETRIES; dm_percent_t sync_percent; @@ -269,6 +269,12 @@ static int _raid_in_sync(struct logical_volume *lv) return (sync_percent == DM_PERCENT_100) ? 1 : 0; } +/* External interface to raid in-sync check */ +int lv_raid_in_sync(const struct logical_volume *lv) +{ + return _raid_in_sync(lv); +} + /* Check if RaidLV @lv is synced or any raid legs of @lv are not synced */ static int _raid_devs_sync_healthy(struct logical_volume *lv) { diff --git a/test/shell/lvchange-raid1-writemostly.sh b/test/shell/lvchange-raid1-writemostly.sh new file mode 100644 index 000000000..edf11bd4e --- /dev/null +++ b/test/shell/lvchange-raid1-writemostly.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# Copyright (C) 2017 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, MA2110-1301 USA + +SKIP_WITH_LVMLOCKD=1 +SKIP_WITH_LVMPOLLD=1 + +. lib/inittest + +which mkfs.ext4 || skip +aux have_raid 1 3 5 || skip + +aux prepare_vg 4 + +for d in $dev1 $dev2 $dev3 $dev4 +do + aux delay_dev $d 1 +done + +# +# Test writemostly prohibited on resyncrhonizing raid1 +# + +# Create 4-way striped LV +lvcreate -aey --ty raid1 -m 3 -L 32M -n $lv1 $vg +not lvchange -y --writemostly $dev1 $vg/$lv1 +check lv_field $vg/$lv1 segtype "raid1" +check lv_field $vg/$lv1 stripes 4 +check lv_attr_bit health $vg/${lv1}_rimage_0 "-" +aux wait_for_sync $vg $lv1 +lvchange -y --writemostly $dev1 $vg/$lv1 +check lv_attr_bit health $vg/${lv1}_rimage_0 "w" + +vgremove -ff $vg diff --git a/tools/lvchange.c b/tools/lvchange.c index 1c00b76f1..cba0496f3 100644 --- a/tools/lvchange.c +++ b/tools/lvchange.c @@ -739,6 +739,21 @@ static int _lvchange_writemostly(struct logical_volume *lv) struct cmd_context *cmd = lv->vg->cmd; struct lv_segment *raid_seg = first_seg(lv); + /* + * Prohibit writebehind and writebehind during synchronization. + * + * FIXME: we can do better once we can distingush between + * an initial sync after a linear -> raid1 upconversion + * and any later additions of legs, requested resyncs + * via lvchange or leg repairs/replacements. + */ + if (!lv_raid_in_sync(lv)) { + log_error("Unable to change write%s on %s while it is not in-sync.", + arg_is_set(cmd, writemostly_ARG) ? "mostly" : "behind", + display_lvname(lv)); + return 0; + } + if (arg_is_set(cmd, writebehind_ARG)) raid_seg->writebehind = arg_uint_value(cmd, writebehind_ARG, 0); |