1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-10 16:58:47 +03:00

thin: fix error paths for metadata creation

Since we vg_write&commit metadata LV inside  lv_extend() call,
proper restore is needed in case something fails.

So add bad: section which deactivates activated LV
and removes it from VG.

Also check early for metadata LV name lengh fail.
This commit is contained in:
Zdenek Kabelac 2013-07-18 16:01:38 +02:00
parent 7afa9cebcb
commit d72f34af41

View File

@ -433,8 +433,7 @@ int extend_pool(struct logical_volume *pool_lv, const struct segment_type *segty
const struct segment_type *striped;
struct logical_volume *meta_lv, *data_lv;
struct lv_segment *seg;
const size_t len = strlen(pool_lv->name) + 16;
char name[len];
char name[NAME_LEN];
if (pool_lv->le_count) {
/* FIXME move code for manipulation from lv_manip.c */
@ -486,38 +485,53 @@ int extend_pool(struct logical_volume *pool_lv, const struct segment_type *segty
log_warn("WARNING: Pool %s is created without initialization.", pool_lv->name);
}
if (dm_snprintf(name, len, "%s_tmeta", pool_lv->name) < 0)
return_0;
if (dm_snprintf(name, sizeof(name), "%s_tmeta", pool_lv->name) < 0) {
log_error("Name is too long to be a pool name.");
goto bad;
}
if (!(meta_lv = lv_create_empty(name, NULL, LVM_READ | LVM_WRITE,
ALLOC_INHERIT, pool_lv->vg)))
return_0;
goto_bad;
if (!move_lv_segments(meta_lv, pool_lv, 0, 0))
return_0;
goto_bad;
/* Pool data segment */
if (!lv_add_segment(ah, 0, stripes, pool_lv, striped, stripe_size, 0, 0))
return_0;
goto_bad;
if (!(data_lv = insert_layer_for_lv(pool_lv->vg->cmd, pool_lv,
pool_lv->status, "_tdata")))
return_0;
goto_bad;
seg = first_seg(pool_lv);
seg->segtype = segtype; /* Set as thin_pool segment */
seg->lv->status |= THIN_POOL;
if (!attach_pool_metadata_lv(seg, meta_lv))
return_0;
goto_bad;
/* Drop reference as attach_pool_data_lv() takes it again */
if (!remove_seg_from_segs_using_this_lv(data_lv, seg))
return_0;
goto_bad;
if (!attach_pool_data_lv(seg, data_lv))
return_0;
goto_bad;
return 1;
bad:
if (activation()) {
if (deactivate_lv_local(pool_lv->vg->cmd, pool_lv)) {
log_error("Aborting. Could not deactivate pool %s.",
pool_lv->name);
return 0;
}
if (!lv_remove(pool_lv) || !vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg))
log_error("Manual intervention may be required to remove "
"abandoned LV(s) before retrying.");
}
return 0;
}
int update_pool_lv(struct logical_volume *lv, int activate)