From 1f661c5dd8ffda9d06df619766d6e9d03db57cb9 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Fri, 23 Apr 2010 02:57:39 +0000 Subject: [PATCH] When removing a snapshot avoid preloading the origin if the snapshot-merge target is not active. --- WHATS_NEW | 1 + lib/activate/activate.h | 3 +++ lib/activate/dev_manager.c | 10 ++++------ lib/metadata/snapshot_manip.c | 21 +++++++++++++++------ test/t-snapshot-merge.sh | 17 +++++++++++++++++ 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index e153e1570..f692deff8 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.64 - ================================= + Don't preload the origin when removing a snapshot whose merge is pending. Disallow the addition of mirror images while a conversion is happening. Disallow primary mirror image removal when mirror is not in-sync. Remove obsolete --name parameter from vgcfgrestore. diff --git a/lib/activate/activate.h b/lib/activate/activate.h index 32d9a5cf8..019f44c25 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -95,6 +95,9 @@ int lvs_in_vg_opened(const struct volume_group *vg); int lv_is_active(struct logical_volume *lv); +int lv_has_target_type(struct dm_pool *mem, struct logical_volume *lv, + const char *layer, const char *target_type); + int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv, int do_reg); diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 66cc94c89..cf3aeaed3 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -329,10 +329,8 @@ static int _status(const char *name, const char *uuid, return 0; } -static int _lv_has_target_type(struct dev_manager *dm, - struct logical_volume *lv, - const char *layer, - const char *target_type) +int lv_has_target_type(struct dm_pool *mem, struct logical_volume *lv, + const char *layer, const char *target_type) { int r = 0; char *dlid; @@ -343,7 +341,7 @@ static int _lv_has_target_type(struct dev_manager *dm, char *type = NULL; char *params = NULL; - if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer))) + if (!(dlid = build_dm_uuid(mem, lv->lvid.s, layer))) return_0; if (!(dmt = _setup_task(NULL, dlid, 0, @@ -1183,7 +1181,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, ((dinfo = _cached_info(dm->mem, find_merging_cow(lv)->cow, dtree)) && dinfo->open_count)) { /* FIXME Is there anything simpler to check for instead? */ - if (!_lv_has_target_type(dm, lv, NULL, "snapshot-merge")) + if (!lv_has_target_type(dm->mem, lv, NULL, "snapshot-merge")) clear_snapshot_merge(lv); } } diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c index f7218c266..cb5df6b45 100644 --- a/lib/metadata/snapshot_manip.c +++ b/lib/metadata/snapshot_manip.c @@ -18,6 +18,7 @@ #include "locking.h" #include "toolcontext.h" #include "lv_alloc.h" +#include "activate.h" int lv_is_origin(const struct logical_volume *lv) { @@ -176,16 +177,24 @@ int vg_remove_snapshot(struct logical_volume *cow) dm_list_del(&cow->snapshot->origin_list); origin->origin_count--; + if (find_merging_cow(origin) == find_cow(cow)) { clear_snapshot_merge(origin); /* - * preload origin to: - * - allow proper release of -cow - * - avoid allocations with other devices suspended - * when transitioning from "snapshot-merge" to - * "snapshot-origin after a merge completes. + * preload origin IFF "snapshot-merge" target is active + * - IMPORTANT: avoids preload if onactivate merge is pending */ - preload_origin = 1; + if (lv_has_target_type(origin->vg->cmd->mem, origin, NULL, + "snapshot-merge")) { + /* + * preload origin to: + * - allow proper release of -cow + * - avoid allocations with other devices suspended + * when transitioning from "snapshot-merge" to + * "snapshot-origin after a merge completes. + */ + preload_origin = 1; + } } if (!lv_remove(cow->snapshot->lv)) { diff --git a/test/t-snapshot-merge.sh b/test/t-snapshot-merge.sh index ff78f1436..d7239b9c7 100755 --- a/test/t-snapshot-merge.sh +++ b/test/t-snapshot-merge.sh @@ -76,6 +76,23 @@ dmsetup table ${vg}-${lv1} | grep -q " snapshot-merge " lvremove -f $vg/$lv1 +# "onactivate merge" test +# -- deactivate/remove after disallowed merge attempt, tests +# to make sure preload of origin's metadata is _not_ performed +setup_merge $vg $lv1 +lvs -a +mkdir test_mnt +mount $(lvdev_ $vg $lv1) test_mnt +lvconvert --merge $vg/$(snap_lv_name_ $lv1) +# -- refresh LV while FS is still mounted (merge must not start), +# verify 'snapshot-origin' target is still being used +lvchange --refresh $vg/$lv1 +umount test_mnt +rm -r test_mnt +dmsetup table ${vg}-${lv1} | grep -q " snapshot-origin " +lvremove -f $vg/$lv1 + + # test multiple snapshot merge; tests copy out that is driven by merge setup_merge $vg $lv1 1 lvs -a -- 2.43.5