mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-18 10:04:20 +03:00
thin: lvresize supports pool metadata resize
Add support for lvresize of thin pool metadata device. lvresize --poolmetadatasize +20 vgname/thinpool_lv or lvresize -L +20 vgname/thinpool_lv_tmeta Where the second one allows all the args for resize (striping...) and the first option resizes accoding to the last metadata lv segment.
This commit is contained in:
parent
72c3ae253e
commit
87aca628d6
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.99 -
|
Version 2.02.99 -
|
||||||
===================================
|
===================================
|
||||||
|
Add lvresize support for online thin pool metadata volume resize.
|
||||||
Add helper functions find_pool_lv() and pool_can_resize_metadata().
|
Add helper functions find_pool_lv() and pool_can_resize_metadata().
|
||||||
Add detection for thin pool metadata resize kernel support.
|
Add detection for thin pool metadata resize kernel support.
|
||||||
Report lvs volume type 'e' with higher priority.
|
Report lvs volume type 'e' with higher priority.
|
||||||
|
@ -61,7 +61,7 @@ lvcreate \- create a logical volume in an existing volume group
|
|||||||
.RB [ \-\-discards
|
.RB [ \-\-discards
|
||||||
.RI { ignore | nopassdown | passdown }]
|
.RI { ignore | nopassdown | passdown }]
|
||||||
.RB [ \-\-poolmetadatasize
|
.RB [ \-\-poolmetadatasize
|
||||||
.IR ThinPoolMetadataSize [ bBsSkKmMgG ]]]
|
.IR MetadataVolumeSize [ bBsSkKmMgG ]]]
|
||||||
.RB [ \-\-thinpool
|
.RB [ \-\-thinpool
|
||||||
.IR ThinPoolLogicalVolume { Name | Path }
|
.IR ThinPoolLogicalVolume { Name | Path }
|
||||||
.RB [ \-s | \-\-snapshot
|
.RB [ \-s | \-\-snapshot
|
||||||
@ -271,7 +271,7 @@ Sets access permissions to read only (\fIr\fP) or read and write (\fIrw\fP).
|
|||||||
.br
|
.br
|
||||||
Default is read and write.
|
Default is read and write.
|
||||||
.TP
|
.TP
|
||||||
.IR \fB\-\-poolmetadatasize " " ThinPoolMetadataSize [ bBsSkKmMgG ]
|
.IR \fB\-\-poolmetadatasize " " MetadataVolumeSize [ bBsSkKmMgG ]
|
||||||
Sets the size of thin pool's metadata logical volume.
|
Sets the size of thin pool's metadata logical volume.
|
||||||
Supported values are in range between 2MiB and 16GiB.
|
Supported values are in range between 2MiB and 16GiB.
|
||||||
Default value is (Pool_LV_size / Pool_LV_chunk_size * 64b).
|
Default value is (Pool_LV_size / Pool_LV_chunk_size * 64b).
|
||||||
|
@ -11,6 +11,8 @@ lvresize \- resize a logical volume
|
|||||||
.RI [ + | \- ] LogicalExtentsNumber [ % { VG | LV | PVS | FREE | ORIGIN "}] |"
|
.RI [ + | \- ] LogicalExtentsNumber [ % { VG | LV | PVS | FREE | ORIGIN "}] |"
|
||||||
.RB [ \-L | \-\-size
|
.RB [ \-L | \-\-size
|
||||||
.RI [ + | \- ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]}
|
.RI [ + | \- ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]}
|
||||||
|
.RB [ \-\-poolmetadatasize
|
||||||
|
.RI [ + ] MetadataVolumeSize [ bBsSkKmMgG ]
|
||||||
.RB [ \-f | \-\-force ]
|
.RB [ \-f | \-\-force ]
|
||||||
.RB [ \-n | \-\-nofsck ]
|
.RB [ \-n | \-\-nofsck ]
|
||||||
.RB [ \-r | \-\-resizefs ]
|
.RB [ \-r | \-\-resizefs ]
|
||||||
@ -73,6 +75,13 @@ Defaults to whatever the last segment of the Logical Volume uses.
|
|||||||
Not applicable to LVs using the original metadata LVM format, which must
|
Not applicable to LVs using the original metadata LVM format, which must
|
||||||
use a single value throughout.
|
use a single value throughout.
|
||||||
.TP
|
.TP
|
||||||
|
.IR \fB\-\-poolmetadatasize " [" + ] MetadataVolumeSize [ bBsSkKmMgG ]
|
||||||
|
Change or set the thin pool metadata logical volume size.
|
||||||
|
With the \fI+\fP sign the value is added to the actual size
|
||||||
|
of the metadata volume and rounded to the full extent size
|
||||||
|
and without it, the value is taken as an absolute one.
|
||||||
|
Maximal size is 16GiB. Default unit is megabytes.
|
||||||
|
.TP
|
||||||
.BR \-I ", " \-\-stripesize " " \fIStripeSize
|
.BR \-I ", " \-\-stripesize " " \fIStripeSize
|
||||||
Gives the number of kilobytes for the granularity of the stripes.
|
Gives the number of kilobytes for the granularity of the stripes.
|
||||||
Defaults to whatever the last segment of the Logical Volume uses.
|
Defaults to whatever the last segment of the Logical Volume uses.
|
||||||
|
@ -233,7 +233,7 @@ xx(lvcreate,
|
|||||||
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
||||||
"\t{-l|--extents LogicalExtentsNumber[%{VG|FREE|ORIGIN}] |\n"
|
"\t{-l|--extents LogicalExtentsNumber[%{VG|FREE|ORIGIN}] |\n"
|
||||||
"\t -L|--size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
|
"\t -L|--size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
|
||||||
"\t[--poolmetadatasize Size[bBsSkKmMgG]]\n"
|
"\t[--poolmetadatasize MetadataVolumeSize[bBsSkKmMgG]]\n"
|
||||||
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
|
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
|
||||||
"\t[-n|--name LogicalVolumeName]\n"
|
"\t[-n|--name LogicalVolumeName]\n"
|
||||||
"\t[--noudevsync]\n"
|
"\t[--noudevsync]\n"
|
||||||
@ -308,6 +308,7 @@ xx(lvextend,
|
|||||||
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
||||||
"\t{-l|--extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n"
|
"\t{-l|--extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n"
|
||||||
"\t -L|--size [+]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
|
"\t -L|--size [+]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
|
||||||
|
"\t --poolmetadatasize [+]MetadataVolumeSize[bBsSkKmMgG]}\n"
|
||||||
"\t[-m|--mirrors Mirrors]\n"
|
"\t[-m|--mirrors Mirrors]\n"
|
||||||
"\t[--nosync]\n"
|
"\t[--nosync]\n"
|
||||||
"\t[--use-policies]\n"
|
"\t[--use-policies]\n"
|
||||||
@ -321,7 +322,8 @@ xx(lvextend,
|
|||||||
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
|
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
|
||||||
|
|
||||||
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, mirrors_ARG,
|
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, mirrors_ARG,
|
||||||
nofsck_ARG, nosync_ARG, noudevsync_ARG, resizefs_ARG, size_ARG, stripes_ARG,
|
nofsck_ARG, nosync_ARG, noudevsync_ARG, poolmetadatasize_ARG,
|
||||||
|
resizefs_ARG, size_ARG, stripes_ARG,
|
||||||
stripesize_ARG, test_ARG, type_ARG, use_policies_ARG)
|
stripesize_ARG, test_ARG, type_ARG, use_policies_ARG)
|
||||||
|
|
||||||
xx(lvmchange,
|
xx(lvmchange,
|
||||||
@ -437,6 +439,7 @@ xx(lvresize,
|
|||||||
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
|
||||||
"\t{-l|--extents [+|-]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n"
|
"\t{-l|--extents [+|-]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n"
|
||||||
"\t -L|--size [+|-]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
|
"\t -L|--size [+|-]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
|
||||||
|
"\t --poolmetadatasize [+]MetadataVolumeSize[bBsSkKmMgG]}\n"
|
||||||
"\t[-n|--nofsck]\n"
|
"\t[-n|--nofsck]\n"
|
||||||
"\t[--noudevsync]\n"
|
"\t[--noudevsync]\n"
|
||||||
"\t[-r|--resizefs]\n"
|
"\t[-r|--resizefs]\n"
|
||||||
@ -447,7 +450,8 @@ xx(lvresize,
|
|||||||
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
|
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
|
||||||
|
|
||||||
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, nofsck_ARG,
|
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, nofsck_ARG,
|
||||||
noudevsync_ARG, resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG,
|
noudevsync_ARG, resizefs_ARG, poolmetadatasize_ARG,
|
||||||
|
size_ARG, stripes_ARG, stripesize_ARG,
|
||||||
test_ARG, type_ARG)
|
test_ARG, type_ARG)
|
||||||
|
|
||||||
xx(lvs,
|
xx(lvs,
|
||||||
|
149
tools/lvresize.c
149
tools/lvresize.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -30,7 +30,10 @@ struct lvresize_params {
|
|||||||
/* size */
|
/* size */
|
||||||
uint32_t extents;
|
uint32_t extents;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
int sizeargs;
|
||||||
sign_t sign;
|
sign_t sign;
|
||||||
|
uint64_t poolmetadatasize;
|
||||||
|
sign_t poolmetadatasign;
|
||||||
percent_type_t percent;
|
percent_type_t percent;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -192,6 +195,7 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
|
|||||||
int use_policy = arg_count(cmd, use_policies_ARG);
|
int use_policy = arg_count(cmd, use_policies_ARG);
|
||||||
|
|
||||||
lp->sign = SIGN_NONE;
|
lp->sign = SIGN_NONE;
|
||||||
|
lp->poolmetadatasign = SIGN_NONE;
|
||||||
lp->resize = LV_ANY;
|
lp->resize = LV_ANY;
|
||||||
|
|
||||||
cmd_name = command_name(cmd);
|
cmd_name = command_name(cmd);
|
||||||
@ -211,13 +215,14 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
|
|||||||
* one or more PVs. Most likely, the intent was "resize this
|
* one or more PVs. Most likely, the intent was "resize this
|
||||||
* LV the best you can with these PVs"
|
* LV the best you can with these PVs"
|
||||||
*/
|
*/
|
||||||
if ((arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG) == 0) &&
|
lp->sizeargs = arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG);
|
||||||
(argc >= 2)) {
|
if ((lp->sizeargs == 0) && (argc >= 2)) {
|
||||||
lp->extents = 100;
|
lp->extents = 100;
|
||||||
lp->percent = PERCENT_PVS;
|
lp->percent = PERCENT_PVS;
|
||||||
lp->sign = SIGN_PLUS;
|
lp->sign = SIGN_PLUS;
|
||||||
} else if ((arg_count(cmd, extents_ARG) +
|
} else if ((lp->sizeargs != 1) &&
|
||||||
arg_count(cmd, size_ARG) != 1)) {
|
((lp->sizeargs == 2) ||
|
||||||
|
!arg_count(cmd, poolmetadatasize_ARG))) {
|
||||||
log_error("Please specify either size or extents but not "
|
log_error("Please specify either size or extents but not "
|
||||||
"both.");
|
"both.");
|
||||||
return 0;
|
return 0;
|
||||||
@ -235,6 +240,15 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
|
|||||||
lp->sign = arg_sign_value(cmd, size_ARG, SIGN_NONE);
|
lp->sign = arg_sign_value(cmd, size_ARG, SIGN_NONE);
|
||||||
lp->percent = PERCENT_NONE;
|
lp->percent = PERCENT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg_count(cmd, poolmetadatasize_ARG)) {
|
||||||
|
lp->poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, 0);
|
||||||
|
lp->poolmetadatasign = arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE);
|
||||||
|
if (lp->poolmetadatasign == SIGN_MINUS) {
|
||||||
|
log_error("Can't reduce pool metadata size.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lp->resize == LV_EXTEND && lp->sign == SIGN_MINUS) {
|
if (lp->resize == LV_EXTEND && lp->sign == SIGN_MINUS) {
|
||||||
@ -242,7 +256,8 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lp->resize == LV_REDUCE && lp->sign == SIGN_PLUS) {
|
if (lp->resize == LV_REDUCE &&
|
||||||
|
((lp->sign == SIGN_PLUS) || (lp->poolmetadatasign == SIGN_PLUS))) {
|
||||||
log_error("Positive sign not permitted - use lvextend");
|
log_error("Positive sign not permitted - use lvextend");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -306,18 +321,23 @@ static int _adjust_policy_params(struct cmd_context *cmd,
|
|||||||
if (lv_is_thin_pool(lv)) {
|
if (lv_is_thin_pool(lv)) {
|
||||||
if (!lv_thin_pool_percent(lv, 1, &percent))
|
if (!lv_thin_pool_percent(lv, 1, &percent))
|
||||||
return_0;
|
return_0;
|
||||||
if (percent > policy_threshold) {
|
if ((PERCENT_0 < percent && percent <= PERCENT_100) &&
|
||||||
/* FIXME: metadata resize support missing */
|
(percent > policy_threshold)) {
|
||||||
log_error("Resize for %s/%s is not yet supported.",
|
if (!pool_can_resize_metadata(lv)) {
|
||||||
|
log_error_once("Online metadata resize for %s/%s is not supported.",
|
||||||
lp->vg_name, lp->lv_name);
|
lp->vg_name, lp->lv_name);
|
||||||
return ECMD_FAILED;
|
return 0;
|
||||||
|
}
|
||||||
|
lp->poolmetadatasize = (first_seg(lv)->metadata_lv->size *
|
||||||
|
policy_amount + 99) / 100;
|
||||||
|
lp->poolmetadatasign = SIGN_PLUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lv_thin_pool_percent(lv, 0, &percent))
|
if (!lv_thin_pool_percent(lv, 0, &percent))
|
||||||
return_0;
|
return_0;
|
||||||
if (!(PERCENT_0 < percent && percent <= PERCENT_100) ||
|
if (!(PERCENT_0 < percent && percent <= PERCENT_100) ||
|
||||||
percent <= policy_threshold)
|
percent <= policy_threshold)
|
||||||
return 1; /* nothing to do */
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
if (!lv_snapshot_percent(lv, &percent))
|
if (!lv_snapshot_percent(lv, &percent))
|
||||||
return_0;
|
return_0;
|
||||||
@ -326,6 +346,7 @@ static int _adjust_policy_params(struct cmd_context *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
lp->extents = policy_amount;
|
lp->extents = policy_amount;
|
||||||
|
lp->sizeargs = (lp->extents) ? 1 : 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -358,6 +379,74 @@ static uint32_t lvseg_get_stripes(struct lv_segment *seg, uint32_t *stripesize)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _lvresize_poolmetadata(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
struct lvresize_params *lp,
|
||||||
|
const struct logical_volume *pool_lv,
|
||||||
|
struct dm_list *pvh,
|
||||||
|
alloc_policy_t alloc)
|
||||||
|
{
|
||||||
|
struct logical_volume *lv;
|
||||||
|
struct lv_segment *mseg;
|
||||||
|
uint32_t extents;
|
||||||
|
uint32_t seg_mirrors;
|
||||||
|
|
||||||
|
if (!pool_can_resize_metadata(pool_lv)) {
|
||||||
|
log_error("Support for online metadata resize not detected.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lp->poolmetadatasize % vg->extent_size) {
|
||||||
|
lp->poolmetadatasize += vg->extent_size -
|
||||||
|
(lp->poolmetadatasize % vg->extent_size);
|
||||||
|
log_print_unless_silent("Rounding pool metadata size to boundary between physical extents: %s",
|
||||||
|
display_size(cmd, lp->poolmetadatasize));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(extents = extents_from_size(vg->cmd, lp->poolmetadatasize,
|
||||||
|
vg->extent_size)))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
lv = first_seg(pool_lv)->metadata_lv;
|
||||||
|
if (lp->poolmetadatasign == SIGN_PLUS) {
|
||||||
|
if (extents >= (MAX_EXTENT_COUNT - lv->le_count)) {
|
||||||
|
log_error("Unable to extend %s by %u extents, exceeds limit (%u).",
|
||||||
|
lv->name, lv->le_count, MAX_EXTENT_COUNT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
extents += lv->le_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extents * vg->extent_size > DM_THIN_MAX_METADATA_SIZE) {
|
||||||
|
log_print_unless_silent("Rounding size to maximum supported size 16GiB "
|
||||||
|
"for metadata volume %s.", lv->name);
|
||||||
|
extents = (DM_THIN_MAX_METADATA_SIZE + vg->extent_size - 1) /
|
||||||
|
vg->extent_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extents == lv->le_count) {
|
||||||
|
log_print_unless_silent("Metadata volume %s has already %s.",
|
||||||
|
lv->name, display_size(cmd, lv->size));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_print_unless_silent("Extending logical volume %s to %s.",
|
||||||
|
lv->name,
|
||||||
|
display_size(cmd, (uint64_t) extents * vg->extent_size));
|
||||||
|
mseg = last_seg(lv);
|
||||||
|
seg_mirrors = lv_mirror_count(lv);
|
||||||
|
if (!lv_extend(lv,
|
||||||
|
mseg->segtype,
|
||||||
|
mseg->area_count / seg_mirrors,
|
||||||
|
mseg->stripe_size,
|
||||||
|
seg_mirrors,
|
||||||
|
mseg->region_size,
|
||||||
|
extents - lv->le_count, NULL,
|
||||||
|
pvh, alloc))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
|
static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
struct lvresize_params *lp)
|
struct lvresize_params *lp)
|
||||||
{
|
{
|
||||||
@ -485,6 +574,8 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
|
|||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lp->sizeargs) { /* TODO: reindent or move to function */
|
||||||
|
|
||||||
switch(lp->percent) {
|
switch(lp->percent) {
|
||||||
case PERCENT_VG:
|
case PERCENT_VG:
|
||||||
lp->extents = percent_of_extents(lp->extents, vg->extent_count,
|
lp->extents = percent_of_extents(lp->extents, vg->extent_count,
|
||||||
@ -552,6 +643,11 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lp->extents == lv->le_count) {
|
if (lp->extents == lv->le_count) {
|
||||||
|
/* A bit of hack - but still may resize metadata */
|
||||||
|
if (lp->poolmetadatasize) {
|
||||||
|
lp->sizeargs = 0;
|
||||||
|
goto metadata_resize;
|
||||||
|
}
|
||||||
if (use_policy)
|
if (use_policy)
|
||||||
return ECMD_PROCESSED; /* Nothing to do. */
|
return ECMD_PROCESSED; /* Nothing to do. */
|
||||||
if (!lp->resizefs) {
|
if (!lp->resizefs) {
|
||||||
@ -778,6 +874,9 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
|
|||||||
log_warn("Thin pool volumes do not have filesystem.");
|
log_warn("Thin pool volumes do not have filesystem.");
|
||||||
lp->resizefs = 0;
|
lp->resizefs = 0;
|
||||||
}
|
}
|
||||||
|
} else if (lp->poolmetadatasize) {
|
||||||
|
log_error("--poolmetadatasize can be used only with thin pools.");
|
||||||
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((lp->resize == LV_REDUCE) && lp->argc)
|
if ((lp->resize == LV_REDUCE) && lp->argc)
|
||||||
@ -832,18 +931,34 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
|
|||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If thin metadata, must suspend thin pool */
|
||||||
|
if (lv_is_thin_pool_metadata(lv)) {
|
||||||
|
if (!(lock_lv = find_pool_lv(lv)))
|
||||||
|
return_0;
|
||||||
|
/* If snapshot, must suspend all associated devices */
|
||||||
|
} else if (lv_is_cow(lv))
|
||||||
|
lock_lv = origin_from_cow(lv);
|
||||||
|
else
|
||||||
|
lock_lv = lv;
|
||||||
|
|
||||||
|
} /* lp->sizeargs */
|
||||||
|
|
||||||
|
if (lp->poolmetadatasize) {
|
||||||
|
metadata_resize:
|
||||||
|
if (!(status = _lvresize_poolmetadata(cmd, vg, lp, lv, pvh, alloc))) {
|
||||||
|
stack;
|
||||||
|
return ECMD_FAILED;
|
||||||
|
} else if ((status == 2) && !lp->sizeargs)
|
||||||
|
return ECMD_PROCESSED;
|
||||||
|
lock_lv = lv;
|
||||||
|
}
|
||||||
|
|
||||||
/* store vg on disk(s) */
|
/* store vg on disk(s) */
|
||||||
if (!vg_write(vg)) {
|
if (!vg_write(vg)) {
|
||||||
stack;
|
stack;
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If snapshot, must suspend all associated devices */
|
|
||||||
if (lv_is_cow(lv))
|
|
||||||
lock_lv = origin_from_cow(lv);
|
|
||||||
else
|
|
||||||
lock_lv = lv;
|
|
||||||
|
|
||||||
if (!suspend_lv(cmd, lock_lv)) {
|
if (!suspend_lv(cmd, lock_lv)) {
|
||||||
log_error("Failed to suspend %s", lock_lv->name);
|
log_error("Failed to suspend %s", lock_lv->name);
|
||||||
vg_revert(vg);
|
vg_revert(vg);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user