diff --git a/WHATS_NEW b/WHATS_NEW index d824289ad..3914392f4 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.112 - ===================================== + Inital support for external users of thin pools based on transaction_id. Report some basic percentage info for cache pools. Introduce size_mb_arg_with_percent() for advanced size arg reading. Add extra support for '.' as decimal point in size args. diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index b5fc84ad4..d3c0c4772 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -6559,6 +6559,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct logical_volume *pool_lv = NULL; struct logical_volume *tmp_lv; struct lv_segment *seg, *pool_seg; + int thin_pool_was_active = -1; /* not scanned, inactive, active */ if (new_lv_name && find_lv_in_vg(vg, new_lv_name)) { log_error("Logical volume \"%s\" already exists in " @@ -6679,6 +6680,14 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, } } + if (seg_is_thin_volume(lp) && + lv_is_new_thin_pool(pool_lv)) { + thin_pool_was_active = lv_is_active(pool_lv); + if (!check_new_thin_pool(pool_lv)) + return_NULL; + /* New pool is now inactive */ + } + if (seg_is_cache(lp) && !wipe_cache_pool(pool_lv)) return_NULL; @@ -7003,7 +7012,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, goto revert_new_lv; } /* At this point remove pool messages, snapshot is active */ - if (!update_pool_lv(first_seg(origin_lv)->pool_lv, 0)) { + if (!update_pool_lv(pool_lv, 0)) { stack; goto revert_new_lv; } @@ -7013,7 +7022,23 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, } if (is_change_activating(lp->activate)) { /* Send message so that table preload knows new thin */ - if (!update_pool_lv(first_seg(lv)->pool_lv, 1)) { + if (!lv_is_active(pool_lv)) { + /* Avoid multiple thin-pool activations in this case */ + if (thin_pool_was_active < 0) + thin_pool_was_active = 0; + if (!activate_lv_excl(cmd, pool_lv)) { + log_error("Failed to activate thin pool %s/%s.", + origin_lv->vg->name, origin_lv->name); + goto revert_new_lv; + } + if (!lv_is_active(pool_lv)) { + log_error("Cannot activate thin pool %s, perhaps skipped in lvm.conf volume_list?", + display_lvname(pool_lv)); + return 0; + } + } + /* Keep thin pool active until thin volume is activated */ + if (!update_pool_lv(pool_lv, (thin_pool_was_active < 0) ? 1 : 0)) { stack; goto revert_new_lv; } @@ -7024,6 +7049,14 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, log_error("Failed to activate thin %s.", lv->name); goto deactivate_and_revert_new_lv; } + + /* Restore inactive state if needed */ + if (!thin_pool_was_active && + !deactivate_lv(cmd, pool_lv)) { + log_error("Failed to deactivate thin pool %s.", + display_lvname(pool_lv)); + return NULL; + } } } else if (lp->snapshot) { if (!activate_lv_local(cmd, lv)) {