diff --git a/lib/activate/activate.h b/lib/activate/activate.h index 9029b8da4..f6c6f54f1 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -35,6 +35,7 @@ struct lv_activate_opts { int origin_only; int no_merging; int real_pool; + int is_activate; unsigned revert; unsigned read_only; }; diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 3b8bd5855..36fbd904c 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -1974,6 +1974,8 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, char *dlid; int r = 0; + laopts->is_activate = (action == ACTIVATE); + if (!(dtree = _create_partial_dtree(dm, lv, laopts->origin_only))) return_0; diff --git a/lib/thin/thin.c b/lib/thin/thin.c index e3747a0cd..96eee76ce 100644 --- a/lib/thin/thin.c +++ b/lib/thin/thin.c @@ -223,6 +223,8 @@ static int _thin_pool_add_target_line(struct dev_manager *dm, char *metadata_dlid, *pool_dlid; const struct lv_thin_message *lmsg; const struct logical_volume *origin; + struct lvinfo info; + uint64_t transaction_id = 0; if (!laopts->real_pool) { if (!(pool_dlid = build_dm_uuid(mem, seg->lv->lvid.s, "tpool"))) { @@ -257,10 +259,35 @@ static int _thin_pool_add_target_line(struct dev_manager *dm, seg->zero_new_blocks ? 0 : 1)) return_0; + /* + * Add messages only for activation tree. + * Otherwise avoid checking for existence of suspended origin. + * Also transation_id is checked only when snapshot origin is active. + * (This might change later) + */ + if (!laopts->is_activate) + return 1; + dm_list_iterate_items(lmsg, &seg->thin_messages) { switch (lmsg->type) { case DM_THIN_MESSAGE_CREATE_THIN: origin = first_seg(lmsg->u.lv)->origin; + /* Check if the origin is suspended */ + if (origin && lv_info(cmd, origin, 0, &info, 0, 0) && + info.exists && !info.suspended) { + /* Origin is not suspended, but the transaction may have been + * already transfered, so test for transaction_id and + * allow to pass in the message for dmtree processing + * so it will skip all messages later. + */ + if (!lv_thin_pool_transaction_id(seg->lv, &transaction_id)) + return_0; /* Thin pool should exist and work */ + if (transaction_id != seg->transaction_id) { + log_error("Can't create snapshot %s as origin %s is not suspended.", + lmsg->u.lv->name, origin->name); + return 0; + } + } log_debug("Thin pool create_%s %s.", (!origin) ? "thin" : "snap", lmsg->u.lv->name); if (!dm_tree_node_add_thin_pool_message(node, (!origin) ? lmsg->type : DM_THIN_MESSAGE_CREATE_SNAP,