Activate the shared store. With this patch, the user is able to create, activate and delete the shared snapshot store with the command. lvcreate -L 32M --sharedstore mikulas -s vg/lv or lvcreate -L 32M --sharedstore fujita-daniel -s vg/lv Creating snapshots within the store will be implemented in further patches. Signed-off-by: Mikulas Patocka --- lib/activate/dev_manager.c | 55 ++++++++++++++++++++++++++++++++------------- lib/metadata/lv_manip.c | 11 +++++++-- 2 files changed, 49 insertions(+), 17 deletions(-) Index: LVM2.2.02.60/lib/activate/dev_manager.c =================================================================== --- LVM2.2.02.60.orig/lib/activate/dev_manager.c 2010-02-10 22:42:33.000000000 +0100 +++ LVM2.2.02.60/lib/activate/dev_manager.c 2010-02-10 22:42:41.000000000 +0100 @@ -984,13 +984,24 @@ static int _add_origin_target_to_dtree(s struct dm_tree_node *dnode, struct logical_volume *lv) { - const char *real_dlid; + const char *real_dlid, *cow_dlid; if (!(real_dlid = build_dlid(dm, lv->lvid.s, "real"))) return_0; - if (!dm_tree_node_add_snapshot_origin_target(dnode, lv->size, real_dlid)) - return_0; + if (lv_is_multisnap_origin(lv)) { + if (!(cow_dlid = build_dlid(dm, + lv->shared_snapshot->cow->lvid.s, "cow"))) + return_0; + if (!dm_tree_node_add_snapshot_shared_target(dnode, lv->size, + real_dlid, cow_dlid, + lv->shared_snapshot->exception_store, + lv->shared_snapshot->chunk_size)) + return_0; + } else { + if (!dm_tree_node_add_snapshot_origin_target(dnode, lv->size, real_dlid)) + return_0; + } return 1; } @@ -1037,6 +1048,9 @@ static int _add_snapshot_target_to_dtree if (lv_is_merging_cow(lv)) return 1; + if (snap_seg->status & SNAPSHOT_SHARED) + return 1; + if (!(origin_dlid = build_dlid(dm, snap_seg->origin->lvid.s, "real"))) return_0; @@ -1071,7 +1085,8 @@ static int _add_target_to_dtree(struct d } static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, - struct logical_volume *lv, const char *layer); + struct logical_volume *lv, + const char *lv_name, const char *layer); static int _add_segment_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, @@ -1100,7 +1115,7 @@ static int _add_segment_to_dtree(struct /* Add mirror log */ if (seg->log_lv && - !_add_new_lv_to_dtree(dm, dtree, seg->log_lv, NULL)) + !_add_new_lv_to_dtree(dm, dtree, seg->log_lv, NULL, NULL)) return_0; /* If this is a snapshot origin, add real LV */ @@ -1110,26 +1125,29 @@ static int _add_segment_to_dtree(struct log_error("Clustered snapshots are not yet supported"); return 0; } - if (lv_is_merging_origin(seg->lv)) { + if (lv_is_multisnap_origin(seg->lv)) { + if (!_add_new_lv_to_dtree(dm, dtree, seg->lv->shared_snapshot->cow, seg->lv->name, "cow")) + return_0; + } else if (lv_is_merging_origin(seg->lv)) { if (!_add_new_lv_to_dtree(dm, dtree, - find_merging_cow(seg->lv)->cow, "cow")) + find_merging_cow(seg->lv)->cow, NULL, "cow")) return_0; /* * Must also add "real" LV for use when * snapshot-merge target is added */ } - if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, "real")) + if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, NULL, "real")) return_0; } else if (lv_is_cow(seg->lv) && !layer) { - if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, "cow")) + if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, NULL, "cow")) return_0; } else { /* Add any LVs used by this segment */ for (s = 0; s < seg->area_count; s++) if ((seg_type(seg, s) == AREA_LV) && (!_add_new_lv_to_dtree(dm, dtree, seg_lv(seg, s), - NULL))) + NULL, NULL))) return_0; } @@ -1151,20 +1169,23 @@ static int _add_segment_to_dtree(struct if (lv_is_origin(seg->lv) && !layer) /* Add any snapshots of this LV */ dm_list_iterate(snh, &seg->lv->snapshot_segs) - if (!_add_new_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow, NULL)) + if (!_add_new_lv_to_dtree(dm, dtree, + dm_list_struct_base(snh, struct lv_segment, + origin_list)->cow, NULL, NULL)) return_0; return 1; } static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, - struct logical_volume *lv, const char *layer) + struct logical_volume *lv, + const char *lv_name, const char *layer) { struct lv_segment *seg; struct lv_layer *lvlayer; struct dm_tree_node *dnode; const struct dm_info *dinfo; - char *name, *dlid, *lv_name; + char *name, *dlid; uint32_t max_stripe_size = UINT32_C(0); uint32_t read_ahead = lv->read_ahead; uint32_t read_ahead_flags = UINT32_C(0); @@ -1190,7 +1211,6 @@ static int _add_new_lv_to_dtree(struct d } } - lv_name = lv->name; if (lv_is_cow(lv) && lv_is_merging_cow(lv)) { if (layer) { /* @@ -1205,6 +1225,11 @@ static int _add_new_lv_to_dtree(struct d } } + if (!lv_name) lv_name = lv->name; + + if (lv_is_cow(lv) && find_cow(lv)->status & SNAPSHOT_SHARED && !layer) + return 1; + if (!(name = build_dm_name(dm->mem, lv->vg->name, lv_name, layer))) return_0; @@ -1443,7 +1468,7 @@ static int _tree_action(struct dev_manag case PRELOAD: case ACTIVATE: /* Add all required new devices to tree */ - if (!_add_new_lv_to_dtree(dm, dtree, lv, NULL)) + if (!_add_new_lv_to_dtree(dm, dtree, lv, NULL, NULL)) goto_out; /* Preload any devices required before any suspensions */ Index: LVM2.2.02.60/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.60.orig/lib/metadata/lv_manip.c 2010-02-10 22:42:39.000000000 +0100 +++ LVM2.2.02.60/lib/metadata/lv_manip.c 2010-02-10 22:42:41.000000000 +0100 @@ -3132,8 +3132,15 @@ int lv_create_single(struct volume_group if (!(lp->permission & LVM_WRITE)) lv->status &= ~LVM_WRITE; - /* COW area must be deactivated if origin is not active */ - if (!origin_active && !deactivate_lv(cmd, lv)) { + /* + * COW area must be deactivated if origin is not active + * We also don't want active cow if it is shared store, + * in this case the target is loaded through the origin + * and there's no reason why the user would want to access + * the cow directly. + */ + if ((!origin_active || lp->shared_store) && + !deactivate_lv(cmd, lv)) { log_error("Aborting. Couldn't deactivate snapshot " "COW area. Manual intervention required."); return 0;