Basic support for "snapshot-merge" target. Adds new function dm_tree_node_add_snapshot_merge_target Signed-off-by: Mikulas Patocka --- libdm/.exported_symbols | 1 libdm/libdevmapper.h | 5 ++++ libdm/libdm-deptree.c | 49 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 8 deletions(-) Index: LVM2.2.02.44/libdm/.exported_symbols =================================================================== --- LVM2.2.02.44.orig/libdm/.exported_symbols 2008-11-03 21:03:00.000000000 +0100 +++ LVM2.2.02.44/libdm/.exported_symbols 2009-02-20 14:29:29.000000000 +0100 @@ -62,6 +62,7 @@ dm_tree_suspend_children dm_tree_children_use_uuid dm_tree_node_add_snapshot_origin_target dm_tree_node_add_snapshot_target +dm_tree_node_add_snapshot_merge_target dm_tree_node_add_error_target dm_tree_node_add_zero_target dm_tree_node_add_linear_target Index: LVM2.2.02.44/libdm/libdevmapper.h =================================================================== --- LVM2.2.02.44.orig/libdm/libdevmapper.h 2008-11-04 16:07:45.000000000 +0100 +++ LVM2.2.02.44/libdm/libdevmapper.h 2009-02-20 14:29:29.000000000 +0100 @@ -364,6 +364,11 @@ int dm_tree_node_add_snapshot_target(str const char *cow_uuid, int persistent, uint32_t chunk_size); +int dm_tree_node_add_snapshot_merge_target(struct dm_tree_node *node, + uint64_t size, + const char *origin_uuid, + const char *cow_uuid, + uint32_t chunk_size); int dm_tree_node_add_error_target(struct dm_tree_node *node, uint64_t size); int dm_tree_node_add_zero_target(struct dm_tree_node *node, Index: LVM2.2.02.44/libdm/libdm-deptree.c =================================================================== --- LVM2.2.02.44.orig/libdm/libdm-deptree.c 2008-12-12 19:45:58.000000000 +0100 +++ LVM2.2.02.44/libdm/libdm-deptree.c 2009-02-20 14:29:29.000000000 +0100 @@ -33,6 +33,7 @@ enum { SEG_MIRRORED, SEG_SNAPSHOT, SEG_SNAPSHOT_ORIGIN, + SEG_SNAPSHOT_MERGE, SEG_STRIPED, SEG_ZERO, }; @@ -48,6 +49,7 @@ struct { { SEG_MIRRORED, "mirror" }, { SEG_SNAPSHOT, "snapshot" }, { SEG_SNAPSHOT_ORIGIN, "snapshot-origin" }, + { SEG_SNAPSHOT_MERGE, "snapshot-merge" }, { SEG_STRIPED, "striped" }, { SEG_ZERO, "zero"}, }; @@ -74,6 +76,7 @@ struct load_segment { uint32_t stripe_size; /* Striped */ + int merge; /* Snapshot */ int persistent; /* Snapshot */ uint32_t chunk_size; /* Snapshot */ struct dm_tree_node *cow; /* Snapshot */ @@ -1308,6 +1311,7 @@ static int _emit_segment_line(struct dm_ break; case SEG_SNAPSHOT: + case SEG_SNAPSHOT_MERGE: if (!_build_dev_string(originbuf, sizeof(originbuf), seg->origin)) return_0; if (!_build_dev_string(cowbuf, sizeof(cowbuf), seg->cow)) @@ -1329,6 +1333,7 @@ static int _emit_segment_line(struct dm_ case SEG_ERROR: case SEG_SNAPSHOT: case SEG_SNAPSHOT_ORIGIN: + case SEG_SNAPSHOT_MERGE: case SEG_ZERO: break; case SEG_LINEAR: @@ -1550,6 +1555,7 @@ static struct load_segment *_add_segment seg->area_count = 0; dm_list_init(&seg->areas); seg->stripe_size = 0; + seg->merge = 0; seg->persistent = 0; seg->chunk_size = 0; seg->cow = NULL; @@ -1586,17 +1592,21 @@ int dm_tree_node_add_snapshot_origin_tar return 1; } -int dm_tree_node_add_snapshot_target(struct dm_tree_node *node, - uint64_t size, - const char *origin_uuid, - const char *cow_uuid, - int persistent, - uint32_t chunk_size) +static int _add_snapshot_target(struct dm_tree_node *node, + uint64_t size, + const char *origin_uuid, + const char *cow_uuid, + int merge, + int persistent, + uint32_t chunk_size) { struct load_segment *seg; struct dm_tree_node *origin_node, *cow_node; + unsigned seg_type; + + seg_type = !merge ? SEG_SNAPSHOT : SEG_SNAPSHOT_MERGE; - if (!(seg = _add_segment(node, SEG_SNAPSHOT, size))) + if (!(seg = _add_segment(node, seg_type, size))) return_0; if (!(origin_node = dm_tree_find_node_by_uuid(node->dtree, origin_uuid))) { @@ -1609,7 +1619,7 @@ int dm_tree_node_add_snapshot_target(str return_0; if (!(cow_node = dm_tree_find_node_by_uuid(node->dtree, cow_uuid))) { - log_error("Couldn't find snapshot origin uuid %s.", cow_uuid); + log_error("Couldn't find snapshot COW device uuid %s.", cow_uuid); return 0; } @@ -1617,12 +1627,35 @@ int dm_tree_node_add_snapshot_target(str if (!_link_tree_nodes(node, cow_node)) return_0; + seg->merge = merge ? 1 : 0; seg->persistent = persistent ? 1 : 0; seg->chunk_size = chunk_size; return 1; } + +int dm_tree_node_add_snapshot_target(struct dm_tree_node *node, + uint64_t size, + const char *origin_uuid, + const char *cow_uuid, + int persistent, + uint32_t chunk_size) +{ + return _add_snapshot_target(node, size, origin_uuid, cow_uuid, 0, + persistent, chunk_size); +} + +int dm_tree_node_add_snapshot_merge_target(struct dm_tree_node *node, + uint64_t size, + const char *origin_uuid, + const char *cow_uuid, + uint32_t chunk_size + ) +{ + return _add_snapshot_target(node, size, origin_uuid, cow_uuid, 1, 1, chunk_size); +} + int dm_tree_node_add_error_target(struct dm_tree_node *node, uint64_t size) {