1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

thin: lvconvert supports swapping metadata device

Support swapping of metadata device if the thin pool already
exists. This way it's easy to i.e. resize metadata or their
repair operation.

User may create some empty LV, replace existing metadata
or dump and restore them into bigger LV.
This commit is contained in:
Zdenek Kabelac 2012-12-02 16:40:07 +01:00
parent 97f8454ecc
commit 99018b37ee
3 changed files with 60 additions and 2 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.99 - Version 2.02.99 -
=================================== ===================================
Add lvconvert support to swap thin pool metadata volume.
Implement internal function detach_pool_metadata_lv(). Implement internal function detach_pool_metadata_lv().
Fix lvm2app to return all property sizes in bytes. Fix lvm2app to return all property sizes in bytes.
Recognize DM_DISABLE_UDEV environment variable for a complete fallback. Recognize DM_DISABLE_UDEV environment variable for a complete fallback.

View File

@ -231,6 +231,13 @@ Specifies thin pool metadata logical volume.
The size should be in between 2MiB and 16GiB. The size should be in between 2MiB and 16GiB.
Thin pool is specified with the option Thin pool is specified with the option
\fB\-\-thinpool\fP. \fB\-\-thinpool\fP.
When the specified thin pool already exists,
the thin pool's metadata volume will be swapped with the given LV.
Properties of the thin pool like chunk size, discards or zero
are preserved by default in this case.
It can be useful for thin pool metadata repair or its offline resize,
since the content of metadata becomes accessible for
thin provisioning tools \fBthin_dump\fP(8) and \fBthin_restore\fP(8).
.TP .TP
.BR \-\-poolmetadatasize " " \fIThinPoolMetadataSize [ \fIbBsSkKmMgG ] .BR \-\-poolmetadatasize " " \fIThinPoolMetadataSize [ \fIbBsSkKmMgG ]
Sets the size of thin pool's metadata logical volume, Sets the size of thin pool's metadata logical volume,
@ -375,4 +382,6 @@ available in the volume group.
.BR lvextend (8), .BR lvextend (8),
.BR lvreduce (8), .BR lvreduce (8),
.BR lvdisplay (8), .BR lvdisplay (8),
.BR lvscan (8) .BR lvscan (8),
.BR thin_dump(8),
.BR thin_restore(8)

View File

@ -1794,10 +1794,12 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
{ {
int r = 0; int r = 0;
char *name; char *name;
const char *old_name;
int len; int len;
struct lv_segment *seg; struct lv_segment *seg;
struct logical_volume *data_lv; struct logical_volume *data_lv;
struct logical_volume *metadata_lv; struct logical_volume *metadata_lv;
struct logical_volume *pool_metadata_lv;
if (!lv_is_visible(pool_lv)) { if (!lv_is_visible(pool_lv)) {
log_error("Can't convert internal LV %s/%s.", log_error("Can't convert internal LV %s/%s.",
@ -1805,7 +1807,7 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
return 0; return 0;
} }
if (lv_is_thin_type(pool_lv)) { if (lv_is_thin_type(pool_lv) && !lp->pool_metadata_lv_name) {
log_error("Can't use thin logical volume %s/%s for thin pool data.", log_error("Can't use thin logical volume %s/%s for thin pool data.",
pool_lv->vg->name, pool_lv->name); pool_lv->vg->name, pool_lv->name);
return 0; return 0;
@ -1864,6 +1866,50 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
metadata_lv->vg->name, metadata_lv->name); metadata_lv->vg->name, metadata_lv->name);
return 0; return 0;
} }
/* Swap normal LV with pool's metadata LV ? */
if (lv_is_thin_pool(pool_lv)) {
if (!deactivate_lv(cmd, metadata_lv)) {
log_error("Aborting. Failed to deactivate thin metadata lv.");
return 0;
}
if (!arg_count(cmd, yes_ARG) &&
yes_no_prompt("Do you want to swap metadata of %s/%s pool with "
"volume %s/%s? [y/n]: ",
pool_lv->vg->name, pool_lv->name,
pool_lv->vg->name, metadata_lv->name) == 'n') {
log_error("Conversion aborted.");
return 0;
}
seg = first_seg(pool_lv);
/* Swap names between old and new metadata LV */
if (!detach_pool_metadata_lv(seg, &pool_metadata_lv))
return_0;
old_name = metadata_lv->name;
if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0))
return_0;
if (!lv_rename_update(cmd, pool_metadata_lv, old_name, 0))
return_0;
if (!arg_count(cmd, chunksize_ARG))
lp->chunk_size = seg->chunk_size;
else if ((lp->chunk_size != seg->chunk_size) &&
!arg_count(cmd, force_ARG) &&
yes_no_prompt("Do you really want to change chunk size %s to %s for %s/%s "
"pool volume? [y/n]: ", display_size(cmd, seg->chunk_size),
display_size(cmd, lp->chunk_size),
pool_lv->vg->name, pool_lv->name) == 'n') {
log_error("Conversion aborted.");
return 0;
}
if (!arg_count(cmd, discards_ARG))
lp->discards = seg->discards;
if (!arg_count(cmd, zero_ARG))
lp->zero = seg->zero_new_blocks;
goto mda_write;
}
if (!lv_is_active(metadata_lv) && if (!lv_is_active(metadata_lv) &&
!activate_lv_local(cmd, metadata_lv)) { !activate_lv_local(cmd, metadata_lv)) {
log_error("Aborting. Failed to activate thin metadata lv."); log_error("Aborting. Failed to activate thin metadata lv.");
@ -1941,6 +1987,8 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
seg->low_water_mark = 0; seg->low_water_mark = 0;
seg->transaction_id = 0; seg->transaction_id = 0;
mda_write:
seg->chunk_size = lp->chunk_size; seg->chunk_size = lp->chunk_size;
seg->discards = lp->discards; seg->discards = lp->discards;
seg->zero_new_blocks = lp->zero ? 1 : 0; seg->zero_new_blocks = lp->zero ? 1 : 0;