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

lvm2app: Rework argument handling for lv resize

Extend the lv resize parameter structure to contain everything
the re-size functions need so that the command line does not
need to be present for lower level calls when we call from
library functions.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
This commit is contained in:
Tony Asleson 2013-01-08 16:39:00 -06:00
parent 60c78e6aef
commit 9d550cfc36

View File

@ -47,18 +47,28 @@ struct lvresize_params {
int argc;
char **argv;
/* Arg counts & values */
unsigned ac_policy;
unsigned ac_stripes;
uint32_t ac_stripes_value;
unsigned ac_mirrors;
uint32_t ac_mirrors_value;
unsigned ac_stripesize;
uint64_t ac_stripesize_value;
unsigned ac_alloc;
unsigned ac_no_sync;
unsigned ac_force;
const char *ac_type;
};
static int _validate_stripesize(struct cmd_context *cmd,
const struct volume_group *vg,
struct lvresize_params *lp)
{
if (arg_sign_value(cmd, stripesize_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Stripesize may not be negative.");
return 0;
}
if (arg_uint64_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT * 2) {
if ( lp->ac_stripesize_value > STRIPE_SIZE_LIMIT * 2) {
log_error("Stripe size cannot be larger than %s",
display_size(cmd, (uint64_t) STRIPE_SIZE_LIMIT));
return 0;
@ -66,15 +76,14 @@ static int _validate_stripesize(struct cmd_context *cmd,
if (!(vg->fid->fmt->features & FMT_SEGMENTS))
log_warn("Varied stripesize not supported. Ignoring.");
else if (arg_uint_value(cmd, stripesize_ARG, 0) > (uint64_t) vg->extent_size * 2) {
else if (lp->ac_stripesize_value > (uint64_t) vg->extent_size * 2) {
log_error("Reducing stripe size %s to maximum, "
"physical extent size %s",
display_size(cmd,
(uint64_t) arg_uint_value(cmd, stripesize_ARG, 0)),
display_size(cmd,lp->ac_stripesize_value),
display_size(cmd, (uint64_t) vg->extent_size));
lp->stripe_size = vg->extent_size;
} else
lp->stripe_size = arg_uint_value(cmd, stripesize_ARG, 0);
lp->stripe_size = lp->ac_stripesize_value;
if (lp->stripe_size & (lp->stripe_size - 1)) {
log_error("Stripe size must be power of 2");
@ -114,7 +123,7 @@ static int _request_confirmation(struct cmd_context *cmd,
log_warn("THIS MAY DESTROY YOUR DATA (filesystem etc.)");
if (!arg_count(cmd, force_ARG)) {
if (!lp->ac_force) {
if (yes_no_prompt("Do you really want to reduce %s? [y/n]: ",
lp->lv_name) == 'n') {
log_error("Logical volume %s NOT reduced", lp->lv_name);
@ -155,7 +164,7 @@ static int _fsadm_cmd(struct cmd_context *cmd,
if (verbose_level() >= _LOG_NOTICE)
argv[i++] = "--verbose";
if (arg_count(cmd, force_ARG))
if (lp->ac_force)
argv[i++] = "--force";
argv[i++] = (fcmd == FSADM_CMD_RESIZE) ? "resize" : "check";
@ -295,6 +304,43 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
lp->argc = argc;
lp->argv = argv;
lp->ac_policy = arg_count(cmd, use_policies_ARG);
lp->ac_stripes = arg_count(cmd, stripes_ARG);
if (lp->ac_stripes) {
lp->ac_stripes_value = arg_uint_value(cmd, stripes_ARG, 1);
} else {
lp->ac_stripes_value = 0;
}
lp->ac_mirrors = arg_count(cmd, mirrors_ARG);
if (lp->ac_mirrors) {
if (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Mirrors argument may not be negative");
return 0;
}
lp->ac_mirrors_value = arg_uint_value(cmd, mirrors_ARG, 1) + 1;
} else {
lp->ac_mirrors_value = 0;
}
lp->ac_stripesize = arg_count(cmd, stripesize_ARG);
if (lp->ac_stripesize) {
if (arg_sign_value(cmd, stripesize_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Stripesize may not be negative.");
return 0;
}
lp->ac_stripesize_value = arg_uint64_value(cmd, stripesize_ARG, 0);
}
lp->ac_no_sync = arg_count(cmd, nosync_ARG);
lp->ac_alloc = arg_uint_value(cmd, alloc_ARG, 0);
lp->ac_type = arg_str_value(cmd, type_ARG, NULL);
lp->ac_force = arg_count(cmd, force_ARG);
return 1;
}
@ -456,7 +502,7 @@ static int _lvresize_poolmetadata(struct cmd_context *cmd, struct volume_group *
}
static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
struct lvresize_params *lp)
struct lvresize_params *lp, struct dm_list *pvh)
{
struct logical_volume *lv;
uint32_t stripesize_extents;
@ -472,8 +518,6 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
uint32_t seg_extents;
uint32_t sz, str;
int status;
struct dm_list *pvh = NULL;
int use_policy = arg_count(cmd, use_policies_ARG);
/* does LV exist? */
if (!(lvl = find_lv_in_vg(vg, lp->lv_name))) {
@ -506,29 +550,25 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
return ECMD_FAILED;
}
if (arg_count(cmd, stripes_ARG)) {
if (lp->ac_stripes) {
if (vg->fid->fmt->features & FMT_SEGMENTS)
lp->stripes = arg_uint_value(cmd, stripes_ARG, 1);
lp->stripes = lp->ac_stripes_value;
else
log_warn("Varied striping not supported. Ignoring.");
}
if (arg_count(cmd, mirrors_ARG)) {
if (lp->ac_mirrors) {
if (vg->fid->fmt->features & FMT_SEGMENTS)
lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 1) + 1;
lp->mirrors = lp->ac_mirrors_value;
else
log_warn("Mirrors not supported. Ignoring.");
if (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Mirrors argument may not be negative");
return EINVALID_CMD_LINE;
}
}
if (arg_count(cmd, stripesize_ARG) &&
if (lp->ac_stripesize &&
!_validate_stripesize(cmd, vg, lp))
return EINVALID_CMD_LINE;
if (use_policy) {
if (lp->ac_policy) {
if (!lv_is_cow(lv) &&
!lv_is_thin_pool(lv)) {
log_error("Policy-based resize is supported only for snapshot and thin pool volumes.");
@ -554,7 +594,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
return ECMD_FAILED;
}
alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, lv->alloc);
alloc = (alloc_policy_t)(lp->ac_alloc)?lp->ac_alloc: lv->alloc;
/*
* First adjust to an exact multiple of extent size.
@ -577,10 +617,6 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
lp->extents = lp->size / vg->extent_size;
}
if (!(pvh = lp->argc ? create_pv_list(cmd->mem, vg, lp->argc,
lp->argv, 1) : &vg->pvs))
return_ECMD_FAILED;
if (lp->sizeargs) { /* TODO: reindent or move to function */
switch(lp->percent) {
@ -655,7 +691,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
lp->sizeargs = 0;
goto metadata_resize;
}
if (use_policy)
if (lp->ac_policy)
return ECMD_PROCESSED; /* Nothing to do. */
if (!lp->resizefs) {
log_error("New size (%d extents) matches existing size "
@ -671,8 +707,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
lp->segtype = last_seg(lv)->segtype;
/* FIXME Support LVs with mixed segment types */
if (lp->segtype != get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG,
lp->segtype->name))) {
if (lp->segtype != get_segtype_from_string(cmd, (lp->ac_type)?lp->ac_type:lp->segtype->name)) {
log_error("VolumeType does not match (%s)", lp->segtype->name);
return EINVALID_CMD_LINE;
}
@ -683,7 +718,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
* Has the user specified that they would like the additional
* extents of a mirror not to have an initial sync?
*/
if (seg_is_mirrored(first_seg(lv)) && arg_count(cmd, nosync_ARG))
if (seg_is_mirrored(first_seg(lv)) && lp->ac_no_sync)
lv->status |= LV_NOTSYNCED;
dm_list_iterate_back_items(mirr_seg, &lv->segments) {
@ -694,12 +729,12 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
break;
}
if (!arg_count(cmd, mirrors_ARG) && seg_mirrors) {
if (!lp->ac_mirrors && seg_mirrors) {
log_print_unless_silent("Extending %" PRIu32 " mirror images.",
seg_mirrors);
lp->mirrors = seg_mirrors;
}
if ((arg_count(cmd, mirrors_ARG) || seg_mirrors) &&
if ((lp->ac_mirrors || seg_mirrors) &&
(lp->mirrors != seg_mirrors)) {
log_error("Cannot vary number of mirrors in LV yet.");
return EINVALID_CMD_LINE;
@ -847,7 +882,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
}
lp->resize = LV_EXTEND;
} else if (lp->extents == lv->le_count) {
if (use_policy)
if (lp->ac_policy)
return ECMD_PROCESSED; /* Nothing to do. */
if (!lp->resizefs) {
log_error("New size (%d extents) matches existing size "
@ -1011,6 +1046,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
struct lvresize_params lp = { 0 };
struct volume_group *vg;
int r;
struct dm_list *pvh = NULL;
if (!_lvresize_params(cmd, argc, argv, &lp))
return EINVALID_CMD_LINE;
@ -1022,7 +1058,13 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
return_ECMD_FAILED;
}
if (!(r = _lvresize(cmd, vg, &lp)))
/* How does this list get cleaned up? */
if (!(pvh = lp.argc ? create_pv_list(cmd->mem, vg, lp.argc,
lp.argv, 1) : &vg->pvs)) {
return_ECMD_FAILED;
}
if (!(r = _lvresize(cmd, vg, &lp, pvh)))
stack;
unlock_and_release_vg(cmd, vg, lp.vg_name);