diff --git a/lib/activate/activate.h b/lib/activate/activate.h index b95c1e099..119211dfc 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -34,6 +34,7 @@ struct lv_activate_opts { int exclusive; int origin_only; int no_merging; + int real_pool; unsigned revert; }; diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 9fcdde892..1e404e4a2 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -1100,13 +1100,16 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, return_0; if (lv_is_thin_pool(lv)) { - if (!_add_lv_to_dtree(dm, dtree, first_seg(lv)->pool_metadata_lv, origin_only)) - return_0; - if (!_add_lv_to_dtree(dm, dtree, seg_lv(first_seg(lv), 0), origin_only)) - return_0; + if (!_add_dev_to_dtree(dm, dtree, lv, "tpool")) + return_0; + if (!_add_lv_to_dtree(dm, dtree, first_seg(lv)->pool_metadata_lv, origin_only)) + return_0; + /* FIXME code from _create_partial_dtree() should be moved here */ + if (!_add_lv_to_dtree(dm, dtree, seg_lv(first_seg(lv), 0), origin_only)) + return_0; } else if (lv_is_thin_volume(lv)) { - if (!_add_lv_to_dtree(dm, dtree, first_seg(lv)->pool_lv, origin_only)) - return_0; + if (!_add_lv_to_dtree(dm, dtree, first_seg(lv)->pool_lv, origin_only)) + return_0; } return 1; @@ -1451,6 +1454,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm, struct dm_list *snh; struct lv_segment *seg_present; const char *target_name; + struct lv_activate_opts lva; /* Ensure required device-mapper targets are loaded */ seg_present = find_cow(seg->lv) ? : seg; @@ -1495,13 +1499,18 @@ static int _add_segment_to_dtree(struct dev_manager *dm, } else if (lv_is_cow(seg->lv) && !layer) { if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, laopts, "cow")) return_0; - } else if (lv_is_thin_volume(seg->lv)) { - if (!_add_new_lv_to_dtree(dm, dtree, seg->pool_lv, laopts, NULL)) + } else if (!layer && (lv_is_thin_pool(seg->lv) || + lv_is_thin_volume(seg->lv))) { + lva = *laopts; + lva.real_pool = 1; + if (!_add_new_lv_to_dtree(dm, dtree, lv_is_thin_pool(seg->lv) ? + seg->lv : seg->pool_lv, &lva, "tpool")) return_0; } else { if (lv_is_thin_pool(seg->lv) && !_add_new_lv_to_dtree(dm, dtree, seg->pool_metadata_lv, laopts, NULL)) return_0; + /* Add any LVs used by this segment */ for (s = 0; s < seg->area_count; s++) { if ((seg_type(seg, s) == AREA_LV) && diff --git a/lib/thin/thin.c b/lib/thin/thin.c index 0a90e78aa..ead082c21 100644 --- a/lib/thin/thin.c +++ b/lib/thin/thin.c @@ -223,6 +223,21 @@ static int _thin_pool_add_target_line(struct dev_manager *dm, char *metadata_dlid, *pool_dlid; const struct lv_thin_message *lmsg; + if (!laopts->real_pool) { + if (!(pool_dlid = build_dm_uuid(mem, seg->lv->lvid.s, "tpool"))) { + log_error("Failed to build uuid for thin pool LV %s.", seg->pool_lv->name); + return 0; + } + + //if (!dm_tree_node_add_thin_target(node, len, pool_dlid, + // DM_THIN_ERROR_DEVICE_ID)) + if (!dm_tree_node_add_linear_target(node, len) || + !dm_tree_node_add_target_area(node, NULL, pool_dlid, 0)) + return_0; + + return 1; + } + if (!(metadata_dlid = build_dm_uuid(mem, seg->pool_metadata_lv->lvid.s, NULL))) { log_error("Failed to build uuid for metadata LV %s.", seg->pool_metadata_lv->name); @@ -356,14 +371,29 @@ static int _thin_add_target_line(struct dev_manager *dm, struct dm_tree_node *node, uint64_t len, uint32_t *pvmove_mirror_count __attribute__((unused))) { - char *thin_pool_dlid; + char *pool_dlid; + uint32_t device_id = seg->device_id; - if (!(thin_pool_dlid = build_dm_uuid(mem, seg->pool_lv->lvid.s, NULL))) { - log_error("Failed to build uuid for thin pool LV %s.", seg->pool_lv->name); + if (!(pool_dlid = build_dm_uuid(mem, seg->pool_lv->lvid.s, "tpool"))) { + log_error("Failed to build uuid for pool LV %s.", + seg->pool_lv->name); return 0; } - if (!dm_tree_node_add_thin_target(node, len, thin_pool_dlid, seg->device_id)) +#if 0 +{ + /* If we would need to activate 'to be deleted' thin LVs */ + struct lv_thin_message *tmsg; + dm_list_iterate_items(tmsg, &first_seg(seg->pool_lv)->thin_messages) + /* If this node is going to be deleted - use the error target */ + if ((tmsg->type == DM_THIN_MESSAGE_DELETE) && + (tmsg->u.delete_id == seg->device_id)) { + device_id = DM_THIN_ERROR_DEVICE_ID; + break; + } +} +#endif + if (!dm_tree_node_add_thin_target(node, len, pool_dlid, device_id)) return_0; return 1;