Swap uuids, names and minor numbers of the logical volumes being merged --- so that merging of the snapshots can be initiated while the snapshot is mounted. Signed-off-by: Mikulas Patocka --- daemons/clvmd/lvm-functions.c | 2 +- lib/activate/activate.c | 10 +++++----- lib/activate/activate.h | 2 +- lib/activate/dev_manager.c | 17 ++++++++++------- lib/activate/dev_manager.h | 2 +- lib/locking/file_locking.c | 2 +- lib/locking/locking.h | 2 ++ lib/locking/no_locking.c | 2 +- tools/lvconvert.c | 23 ++++++++++++++++++++++- 9 files changed, 44 insertions(+), 18 deletions(-) Index: LVM2.2.02.45/tools/lvconvert.c =================================================================== --- LVM2.2.02.45.orig/tools/lvconvert.c 2009-05-11 13:08:55.000000000 +0200 +++ LVM2.2.02.45/tools/lvconvert.c 2009-05-11 13:09:03.000000000 +0200 @@ -767,6 +767,25 @@ static int lvconvert_snapshot(struct cmd return 1; } +static void swap_lvids(struct logical_volume *lv1, struct logical_volume *lv2) +{ + char *nm; + union lvid li; + int32_t n; + nm = lv1->name; + lv1->name = lv2->name; + lv2->name = nm; + li = lv1->lvid; + lv1->lvid = lv2->lvid; + lv2->lvid = li; + n = lv1->major; + lv1->major = lv2->major; + lv2->major = n; + n = lv1->minor; + lv1->minor = lv2->minor; + lv2->minor = n; +} + static int lvconvert_merge(struct cmd_context *cmd, struct logical_volume *lv, struct lvconvert_params *lp) @@ -786,6 +805,8 @@ static int lvconvert_merge(struct cmd_co cow_seg->status |= SNAPSHOT_MERGE; origin->merging_snapshot = cow_seg; + swap_lvids(origin, lv); + /* store vg on disk(s) */ if (!vg_write(lv->vg)) return_0; @@ -798,7 +819,7 @@ static int lvconvert_merge(struct cmd_co return 0; } - if (!deactivate_lv(cmd, lv)) { + if (!deactivate_lv_no_snap(cmd, lv)) { log_error("Failed to deactivate merging snapshot %s", lv->name); vg_revert(lv->vg); return 0; Index: LVM2.2.02.45/lib/activate/dev_manager.c =================================================================== --- LVM2.2.02.45.orig/lib/activate/dev_manager.c 2009-05-11 13:08:59.000000000 +0200 +++ LVM2.2.02.45/lib/activate/dev_manager.c 2009-05-11 13:09:03.000000000 +0200 @@ -37,6 +37,7 @@ typedef enum { PRELOAD, ACTIVATE, DEACTIVATE, + DEACTIVATE_NO_SNAP, SUSPEND, SUSPEND_WITH_LOCKFS, CLEAN @@ -697,7 +698,7 @@ static int _add_lv_to_dtree(struct dev_m return 1; } -static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logical_volume *lv) +static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logical_volume *lv, int no_snap) { struct dm_tree *dtree; struct dm_list *snh, *snht; @@ -713,9 +714,10 @@ static struct dm_tree *_create_partial_d goto_bad; /* Add any snapshots of this LV */ - dm_list_iterate_safe(snh, snht, &lv->snapshot_segs) - if (!_add_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow)) - goto_bad; + if (!no_snap) + dm_list_iterate_safe(snh, snht, &lv->snapshot_segs) + if (!_add_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow)) + goto_bad; /* Add any LVs used by segments in this LV */ dm_list_iterate_items(seg, &lv->segments) @@ -1172,7 +1174,7 @@ static int _tree_action(struct dev_manag char *dlid; int r = 0; - if (!(dtree = _create_partial_dtree(dm, lv))) + if (!(dtree = _create_partial_dtree(dm, lv, action == DEACTIVATE_NO_SNAP))) return_0; if (!(root = dm_tree_find_node(dtree, 0, 0))) { @@ -1191,6 +1193,7 @@ static int _tree_action(struct dev_manag goto_out; break; case DEACTIVATE: + case DEACTIVATE_NO_SNAP: /* Deactivate LV and all devices it references that nothing else has open. */ if (!dm_tree_deactivate_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1)) goto_out; @@ -1254,11 +1257,11 @@ int dev_manager_preload(struct dev_manag return _tree_action(dm, lv, PRELOAD); } -int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv) +int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv, int no_snap) { int r; - r = _tree_action(dm, lv, DEACTIVATE); + r = _tree_action(dm, lv, !no_snap ? DEACTIVATE : DEACTIVATE_NO_SNAP); fs_del_lv(lv); Index: LVM2.2.02.45/lib/locking/locking.h =================================================================== --- LVM2.2.02.45.orig/lib/locking/locking.h 2008-11-03 23:14:29.000000000 +0100 +++ LVM2.2.02.45/lib/locking/locking.h 2009-05-11 13:09:03.000000000 +0200 @@ -79,6 +79,7 @@ int check_lvm1_vg_inactive(struct cmd_co #define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */ #define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */ #define LCK_CACHE 0x00000100U /* Operation on cache only using P_ lock */ +#define LCK_NO_SNAP 0x00000200U /* Ignore snapshots of this LV */ /* * Additional lock bits for cluster communication @@ -119,6 +120,7 @@ int check_lvm1_vg_inactive(struct cmd_co #define resume_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_RESUME) #define suspend_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD) #define deactivate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE) +#define deactivate_lv_no_snap(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_NO_SNAP) #define activate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD) #define activate_lv_excl(cmd, lv) \ lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD) Index: LVM2.2.02.45/daemons/clvmd/lvm-functions.c =================================================================== --- LVM2.2.02.45.orig/daemons/clvmd/lvm-functions.c 2009-02-22 22:14:38.000000000 +0100 +++ LVM2.2.02.45/daemons/clvmd/lvm-functions.c 2009-05-11 13:09:03.000000000 +0200 @@ -385,7 +385,7 @@ static int do_deactivate_lv(char *resour return 0; /* We don't need to do anything */ } - if (!lv_deactivate(cmd, resource)) + if (!lv_deactivate(cmd, resource, 0)) return EIO; if (lock_flags & LCK_CLUSTER_VG) { Index: LVM2.2.02.45/lib/activate/activate.c =================================================================== --- LVM2.2.02.45.orig/lib/activate/activate.c 2009-05-11 13:08:18.000000000 +0200 +++ LVM2.2.02.45/lib/activate/activate.c 2009-05-11 13:09:03.000000000 +0200 @@ -193,7 +193,7 @@ int lv_resume_if_active(struct cmd_conte { return 1; } -int lv_deactivate(struct cmd_context *cmd, const char *lvid_s) +int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, int no_snap) { return 1; } @@ -604,7 +604,7 @@ static int _lv_preload(struct logical_vo return r; } -static int _lv_deactivate(struct logical_volume *lv) +static int _lv_deactivate(struct logical_volume *lv, int no_snap) { int r; struct dev_manager *dm; @@ -612,7 +612,7 @@ static int _lv_deactivate(struct logical if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) return_0; - if (!(r = dev_manager_deactivate(dm, lv))) + if (!(r = dev_manager_deactivate(dm, lv, no_snap))) stack; dev_manager_destroy(dm); @@ -951,7 +951,7 @@ int lv_resume(struct cmd_context *cmd, c return _lv_resume(cmd, lvid_s, 1); } -int lv_deactivate(struct cmd_context *cmd, const char *lvid_s) +int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, int no_snap) { struct logical_volume *lv; struct lvinfo info; @@ -999,7 +999,7 @@ int lv_deactivate(struct cmd_context *cm stack; memlock_inc(); - r = _lv_deactivate(lv); + r = _lv_deactivate(lv, no_snap); memlock_dec(); fs_unlock(); Index: LVM2.2.02.45/lib/activate/activate.h =================================================================== --- LVM2.2.02.45.orig/lib/activate/activate.h 2009-02-28 01:54:06.000000000 +0100 +++ LVM2.2.02.45/lib/activate/activate.h 2009-05-11 13:09:03.000000000 +0200 @@ -60,7 +60,7 @@ int lv_resume_if_active(struct cmd_conte int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive); int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive); -int lv_deactivate(struct cmd_context *cmd, const char *lvid_s); +int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, int no_snap); int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv); Index: LVM2.2.02.45/lib/activate/dev_manager.h =================================================================== --- LVM2.2.02.45.orig/lib/activate/dev_manager.h 2007-11-12 21:51:53.000000000 +0100 +++ LVM2.2.02.45/lib/activate/dev_manager.h 2009-05-11 13:09:03.000000000 +0200 @@ -52,7 +52,7 @@ int dev_manager_suspend(struct dev_manag int lockfs); int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv); int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv); -int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv); +int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv, int no_snap); int dev_manager_lv_mknodes(const struct logical_volume *lv); int dev_manager_lv_rmnodes(const struct logical_volume *lv); Index: LVM2.2.02.45/lib/locking/file_locking.c =================================================================== --- LVM2.2.02.45.orig/lib/locking/file_locking.c 2008-11-12 10:30:52.000000000 +0100 +++ LVM2.2.02.45/lib/locking/file_locking.c 2009-05-11 13:09:03.000000000 +0200 @@ -237,7 +237,7 @@ static int _file_lock_resource(struct cm break; case LCK_NULL: log_very_verbose("Locking LV %s (NL)", resource); - if (!lv_deactivate(cmd, resource)) + if (!lv_deactivate(cmd, resource, !!(flags & LCK_NO_SNAP))) return 0; break; case LCK_READ: Index: LVM2.2.02.45/lib/locking/no_locking.c =================================================================== --- LVM2.2.02.45.orig/lib/locking/no_locking.c 2008-04-07 21:17:29.000000000 +0200 +++ LVM2.2.02.45/lib/locking/no_locking.c 2009-05-11 13:09:03.000000000 +0200 @@ -44,7 +44,7 @@ static int _no_lock_resource(struct cmd_ case LCK_LV: switch (flags & LCK_TYPE_MASK) { case LCK_NULL: - return lv_deactivate(cmd, resource); + return lv_deactivate(cmd, resource, !(flags & LCK_NO_SNAP)); case LCK_UNLOCK: return lv_resume_if_active(cmd, resource); case LCK_READ: