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

tools: common handling of --persistent option

Move common code for reading and processing
of --persistent arguments for lvcreate and lvchange
into lvmcmdline.

Reuse validate_major_minor() routine for validation.

Don't blindly activate LVs after change in cluster
and instead only local reactivation is supported.
(we have now many limited targets now).

Dropping 'sigint_caught()' handling, since
prompt() is resolving this case itself.
This commit is contained in:
Zdenek Kabelac 2014-09-19 14:57:02 +02:00
parent 73f4fa6bc1
commit f09f85d027
5 changed files with 105 additions and 128 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.112 -
=====================================
Unify handling of --persistent option for lvcreate and lvchange.
Validate major and minor numbers stored in metadata.
Use -fPIE when linking -pie executables.
Enable cache segment type by default.

View File

@ -552,86 +552,73 @@ static int lvchange_readahead(struct cmd_context *cmd,
static int lvchange_persistent(struct cmd_context *cmd,
struct logical_volume *lv)
{
struct lvinfo info;
int active = 0;
int32_t major, minor;
enum activation_change activate = CHANGE_AN;
if (!arg_uint_value(cmd, persistent_ARG, 0)) {
if (!read_and_validate_major_minor(cmd, lv->vg->fid->fmt,
&lv->major, &lv->minor))
return_0;
if (lv->minor == -1) {
if (!(lv->status & FIXED_MINOR)) {
log_error("Minor number is already not persistent "
"for \"%s\"", lv->name);
log_error("Minor number is already not persistent for %s.",
display_lvname(lv));
return 0;
}
lv->status &= ~FIXED_MINOR;
lv->minor = -1;
lv->major = -1;
log_verbose("Disabling persistent device number for \"%s\"",
lv->name);
log_verbose("Disabling persistent device number for %s.",
display_lvname(lv));
} else {
if (!arg_count(cmd, minor_ARG) && lv->minor < 0) {
log_error("Minor number must be specified with -My");
return 0;
}
if (arg_count(cmd, major_ARG) > 1) {
log_error("Option -j/--major may not be repeated.");
return 0;
}
if (arg_count(cmd, minor_ARG) > 1) {
log_error("Option --minor may not be repeated.");
return 0;
}
if (!arg_count(cmd, major_ARG) && lv->major < 0) {
log_error("Major number must be specified with -My");
return 0;
}
if (lv_info(cmd, lv, 0, &info, 0, 0) && info.exists)
active = 1;
major = arg_int_value(cmd, major_ARG, lv->major);
minor = arg_int_value(cmd, minor_ARG, lv->minor);
if (!major_minor_valid(cmd, lv->vg->fid->fmt, major, minor))
return 0;
if (active && !arg_count(cmd, force_ARG) &&
if (lv_is_active(lv)) {
if (!arg_count(cmd, force_ARG) &&
!arg_count(cmd, yes_ARG) &&
yes_no_prompt("Logical volume %s will be "
"deactivated temporarily. "
"Continue? [y/n]: ", lv->name) == 'n') {
log_error("%s device number not changed.",
lv->name);
display_lvname(lv));
return 0;
}
if (sigint_caught())
return_0;
activate = CHANGE_AEY;
if (vg_is_clustered(lv->vg) &&
locking_is_clustered() &&
locking_supports_remote_queries() &&
!lv_is_active_exclusive_locally(lv)) {
/* Reliable reactivate only locally */
log_print_unless_silent("Remotely active LV %s needs "
"individual reactivation.",
display_lvname(lv));
activate = CHANGE_ALY;
}
}
log_verbose("Ensuring %s is inactive.", lv->name);
/* Ensuring LV is not active */
if (!deactivate_lv(cmd, lv)) {
log_error("%s: deactivation failed", lv->name);
log_error("Cannot deactivate %s.", display_lvname(lv));
return 0;
}
lv->status |= FIXED_MINOR;
lv->minor = minor;
lv->major = major;
log_verbose("Setting persistent device number to (%d, %d) "
"for \"%s\"", lv->major, lv->minor, lv->name);
log_verbose("Setting persistent device number to (%d, %d) for %s.",
lv->major, lv->minor, display_lvname(lv));
}
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
log_very_verbose("Updating logical volume %s on disk(s).",
display_lvname(lv));
if (!vg_write(lv->vg) || !vg_commit(lv->vg))
return_0;
if (activate != CHANGE_AN) {
log_verbose("Re-activating logical volume %s", display_lvname(lv));
if (!lv_active_change(cmd, lv, activate)) {
log_error("%s: reactivation failed", display_lvname(lv));
backup(lv->vg);
if (active) {
log_verbose("Re-activating logical volume \"%s\"", lv->name);
if (!activate_lv(cmd, lv)) {
log_error("%s: reactivation failed", lv->name);
return 0;
}
}
backup(lv->vg);
return 1;
}

View File

@ -760,55 +760,18 @@ static int _read_activation_params(struct lvcreate_params *lp,
lp->wipe_signatures = 0;
}
if (arg_count(cmd, major_ARG) > 1) {
log_error("Option -j/--major may not be repeated.");
return 0;
}
if (arg_count(cmd, minor_ARG) > 1) {
log_error("Option --minor may not be repeated.");
return 0;
}
lp->minor = arg_int_value(cmd, minor_ARG, -1);
lp->major = arg_int_value(cmd, major_ARG, -1);
/* Persistent minor */
if (arg_count(cmd, persistent_ARG)) {
/* Persistent minor (and major) */
if (arg_is_set(cmd, persistent_ARG)) {
if (lp->create_pool && !lp->thin) {
log_error("--persistent is not permitted when creating a thin pool device.");
return 0;
}
if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "y")) {
if (lp->minor == -1) {
log_error("Please specify minor number with "
"--minor when using -My");
return 0;
}
if (!strncmp(cmd->kernel_vsn, "2.4.", 4)) {
if (lp->major == -1) {
log_error("Please specify major number with "
"--major when using -My");
return 0;
}
} else {
if (lp->major >= 0)
log_warn("Ignoring supplied major number - kernel assigns "
"major numbers dynamically. Using major number %d instead.",
cmd->dev_types->device_mapper_major);
lp->major = cmd->dev_types->device_mapper_major;
}
if (!major_minor_valid(cmd, vg->fid->fmt, lp->major, lp->minor))
return 0;
} else {
if ((lp->minor != -1) || (lp->major != -1)) {
log_error("--major and --minor incompatible "
"with -Mn");
return 0;
}
}
} else if (arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) {
log_error("--major and --minor require -My");
if (!read_and_validate_major_minor(cmd, vg->fid->fmt,
&lp->major, &lp->minor))
return_0;
} else if (arg_is_set(cmd, major_ARG) || arg_is_set(cmd, minor_ARG)) {
log_error("--major and --minor require -My.");
return 0;
}
@ -844,7 +807,6 @@ static int _lvcreate_params(struct lvcreate_params *lp,
const char *segtype_str;
const char *tag;
memset(lp, 0, sizeof(*lp));
memset(lcp, 0, sizeof(*lcp));
dm_list_init(&lp->tags);
lp->target_attr = ~0;
@ -1248,7 +1210,10 @@ static int _validate_internal_thin_processing(const struct lvcreate_params *lp)
int lvcreate(struct cmd_context *cmd, int argc, char **argv)
{
int r = ECMD_FAILED;
struct lvcreate_params lp;
struct lvcreate_params lp = {
.major = -1,
.minor = -1,
};
struct lvcreate_cmdline_params lcp;
struct volume_group *vg;

View File

@ -576,32 +576,55 @@ int metadatacopies_arg(struct cmd_context *cmd, struct arg_values *av)
return int_arg(cmd, av);
}
int major_minor_valid(const struct cmd_context *cmd, const struct format_type *fmt,
int32_t major, int32_t minor)
int read_and_validate_major_minor(const struct cmd_context *cmd,
const struct format_type *fmt,
int32_t *major, int32_t *minor)
{
if (!strncmp(cmd->kernel_vsn, "2.4.", 4) ||
(fmt->features & FMT_RESTRICTED_LVIDS)) {
if (major < 0 || major > 255) {
log_error("Major number outside range 0-255");
if (strcmp(arg_str_value(cmd, persistent_ARG, "n"), "y")) {
if (arg_is_set(cmd, minor_ARG) || arg_is_set(cmd, major_ARG)) {
log_error("--major and --minor incompatible with -Mn");
return 0;
}
if (minor < 0 || minor > 255) {
log_error("Minor number outside range 0-255");
*major = *minor = -1;
return 1;
}
if (arg_count(cmd, minor_ARG) > 1) {
log_error("Option --minor may not be repeated.");
return 0;
}
} else {
/* 12 bits for major number */
if (major < 0 || major > 4095) {
log_error("Major number outside range 0-4095");
if (arg_count(cmd, major_ARG) > 1) {
log_error("Option -j/--major may not be repeated.");
return 0;
}
/* 20 bits for minor number */
if (minor < 0 || minor > 1048575) {
log_error("Minor number outside range 0-1048575");
if (!strncmp(cmd->kernel_vsn, "2.4.", 4)) {
/* Major is required for 2.4 */
if (!arg_is_set(cmd, major_ARG)) {
log_error("Please specify major number with "
"--major when using -My");
return 0;
}
*major = arg_int_value(cmd, major_ARG, -1);
} else if (arg_is_set(cmd, major_ARG)) {
log_warn("WARNING: Ignoring supplied major number - "
"kernel assigns major numbers dynamically. "
"Using major number %d instead.",
cmd->dev_types->device_mapper_major);
*major = cmd->dev_types->device_mapper_major;
}
if (!arg_is_set(cmd, minor_ARG)) {
log_error("Please specify minor number with --minor when using -My.");
return 0;
}
*minor = arg_int_value(cmd, minor_ARG, -1);
if (!validate_major_minor(cmd, fmt, *major, *minor))
return_0;
return 1;
}

View File

@ -138,8 +138,9 @@ int segtype_arg(struct cmd_context *cmd, struct arg_values *av);
int alloc_arg(struct cmd_context *cmd, struct arg_values *av);
int readahead_arg(struct cmd_context *cmd, struct arg_values *av);
int metadatacopies_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av);
int major_minor_valid(const struct cmd_context * cmd, const struct format_type *fmt,
int32_t major, int32_t minor);
int read_and_validate_major_minor(const struct cmd_context *cmd,
const struct format_type *fmt,
int32_t *major, int32_t *minor);
/* we use the enums to access the switches */
unsigned arg_count(const struct cmd_context *cmd, int a);