--- lib/activate/activate.c | 23 +++++++++++++++++++++++ lib/activate/activate.h | 2 ++ lib/activate/dev_manager.c | 21 +++++++++++++++++++++ lib/activate/dev_manager.h | 2 ++ lib/metadata/lv_manip.c | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+) Index: LVM2.2.02.67/lib/activate/dev_manager.c =================================================================== --- LVM2.2.02.67.orig/lib/activate/dev_manager.c 2010-06-09 13:52:30.000000000 +0200 +++ LVM2.2.02.67/lib/activate/dev_manager.c 2010-06-12 11:28:34.000000000 +0200 @@ -898,6 +898,27 @@ int dev_manager_multisnap_prepare_merge( return 1; } +int dev_manager_multisnap_is_merging(struct dev_manager *dm, + struct logical_volume *lv, int *merging) +{ + const char *dlid; + int err; + + if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, NULL))) { + log_error("uuid build failed for %s", lv->name); + return 0; + } + + log_debug("Testing if LV %s is merging", lv->name); + + if (!_multisnapshot_status(dm, dlid, &err, NULL, NULL, NULL, NULL)) + return 0; + + *merging = err > 0; + + return 1; +} + #if 0 log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name); Index: LVM2.2.02.67/lib/activate/dev_manager.h =================================================================== --- LVM2.2.02.67.orig/lib/activate/dev_manager.h 2010-06-09 13:52:30.000000000 +0200 +++ LVM2.2.02.67/lib/activate/dev_manager.h 2010-06-12 11:18:27.000000000 +0200 @@ -71,6 +71,8 @@ int dev_manager_multisnap_delete(struct int dev_manager_multisnap_prepare_merge(struct dev_manager *dm, struct logical_volume *lv, const char *snapid); +int dev_manager_multisnap_is_merging(struct dev_manager *dm, + struct logical_volume *lv, int *merging); /* * Put the desired changes into effect. Index: LVM2.2.02.67/lib/activate/activate.c =================================================================== --- LVM2.2.02.67.orig/lib/activate/activate.c 2010-06-09 13:52:30.000000000 +0200 +++ LVM2.2.02.67/lib/activate/activate.c 2010-06-12 11:17:55.000000000 +0200 @@ -224,6 +224,11 @@ int lv_multisnap_prepare_merge(struct cm return 0; } +int lv_multisnap_is_merging(struct cmd_context *cmd, struct logical_volume *lv, int *merging) +{ + return 0; +} + int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv) { return 1; @@ -1263,6 +1268,24 @@ int lv_multisnap_prepare_merge(struct cm return r; } +int lv_multisnap_is_merging(struct cmd_context *cmd, struct logical_volume *lv, int *merging) +{ + struct dev_manager *dm; + int r; + + if (!activation()) + return 0; + + if (!(dm = dev_manager_create(cmd, lv->vg->name))) + return_0; + + r = dev_manager_multisnap_is_merging(dm, lv, merging); + + dev_manager_destroy(dm); + + return r; +} + int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv) { int r = 1; Index: LVM2.2.02.67/lib/activate/activate.h =================================================================== --- LVM2.2.02.67.orig/lib/activate/activate.h 2010-06-09 13:52:30.000000000 +0200 +++ LVM2.2.02.67/lib/activate/activate.h 2010-06-12 11:16:43.000000000 +0200 @@ -69,6 +69,8 @@ int lv_multisnap_delete(struct cmd_conte struct logical_volume *lv, const char *snapid); int lv_multisnap_prepare_merge(struct cmd_context *cmd, struct logical_volume *lv, const char *snapid); +int lv_multisnap_is_merging(struct cmd_context *cmd, struct logical_volume *lv, + int *merging); int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv); Index: LVM2.2.02.67/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.67.orig/lib/metadata/lv_manip.c 2010-06-09 13:52:15.000000000 +0200 +++ LVM2.2.02.67/lib/metadata/lv_manip.c 2010-06-13 14:26:58.000000000 +0200 @@ -2354,6 +2354,38 @@ int lv_remove_with_dependencies(struct c struct logical_volume *origin = origin_from_cow(lv); /* Remove shared snapshot's virtual snapshots first */ if (lv_is_multisnap_origin(origin)) { + if (!level) { + int origin_active, merging; + struct lvinfo info; + if (!lv_info(cmd, origin, &info, 0, 0)) { + log_error("Check for existence of snapshot " + "origin '%s' failed.", origin->name); + return 0; + } + origin_active = info.exists; + if (!origin_active) { + if (!activate_lv(cmd, origin)) { + log_error("Couldn't activate origin LV %s", origin->name); + return 0; + } + } + if (!lv_multisnap_is_merging(cmd, origin, &merging)) { + log_error("Can't get shared snapshot \"%s\" merging status", + lv->name); + return 0; + } + if (!origin_active) { + if (!deactivate_lv(cmd, origin)) { + log_error("Couldn't deactivate origin LV %s", origin->name); + return 0; + } + } + if (merging) { + log_error("Can't remove shared snapshot volume \"%s\" when merging", + lv->name); + return 0; + } + } dm_list_iterate_items(lvl, &lv->vg->lvs) { struct logical_volume *snap_lv = lvl->lv; struct lv_segment *snap_seg;