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

lvremove: confirm if LV was not identified specifically

Make 'lvremove vg' prompt a user before removing each
LV in the VG unless --force is used.

$ lvremove ee
Remove LV ee/pool that was not named directly? [y/n]: n
Remove LV ee/thin2 that was not named directly? [y/n]: n
Remove LV ee/lvol2 that was not named directly? [y/n]: y
  Logical volume "lvol2" successfully removed

$ lvremove --force ee
  Logical volume "thin2" successfully removed
  Logical volume "pool" successfully removed

If an LV is identified by a tag matching on the LV,
that is considered specific identification, and no
new confirmation is used.

If an LV is identified by select matching the LV,
that is NOT considered specific identification,
and the new confirmation is used.  The select
may match the desired LV, plus another unintended
LV in a different VG.
This commit is contained in:
David Teigland 2016-09-28 16:06:10 -05:00
parent 49a1c4d4b0
commit 18d49412d1
4 changed files with 19 additions and 4 deletions

View File

@ -61,6 +61,7 @@ struct logical_volume {
uint64_t timestamp;
unsigned new_lock_args:1;
unsigned process_specific:1; /* lv is identified specifically for processing */
const char *hostname;
const char *lock_args;
};

View File

@ -658,7 +658,7 @@ xx(lvreduce,
xx(lvremove,
"Remove logical volume(s) from the system",
ALL_VGS_IS_DEFAULT, /* all VGs only with --select */
ALL_VGS_IS_DEFAULT | CONFIRM_UNLESS_SPECIFIC, /* all VGs only with --select */
"lvremove\n"
"\t[-A|--autobackup y|n]\n"
"\t[--commandprofile ProfileName]\n"

View File

@ -2352,6 +2352,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
struct lv_list *final_lvl;
struct glv_list *glvl, *tglvl;
int do_report_ret_code = 1;
int lv_is_specific = 0;
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LV);
@ -2435,9 +2436,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
if (arg_is_set(cmd, all_ARG) ||
(lvargs_supplied && str_list_match_item(arg_lvnames, lvl->lv->name))) {
log_very_verbose("Processing lockd_sanlock_lv %s/%s.", vg->name, lvl->lv->name);
} else {
} else
continue;
}
}
/*
@ -2449,15 +2449,19 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
*/
process_lv = process_all;
lv_is_specific = 0;
if (lvargs_supplied && str_list_match_item(arg_lvnames, lvl->lv->name)) {
/* Remove LV from list of unprocessed LV names */
str_list_del(arg_lvnames, lvl->lv->name);
process_lv = 1;
lv_is_specific = 1;
}
if (!process_lv && tags_supplied && str_list_match_list(tags_in, &lvl->lv->tags, NULL))
if (!process_lv && tags_supplied && str_list_match_list(tags_in, &lvl->lv->tags, NULL)) {
process_lv = 1;
lv_is_specific = 1;
}
process_lv = process_lv && select_match_lv(cmd, handle, vg, lvl->lv) && _select_matches(handle);
@ -2477,6 +2481,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
goto_out;
}
final_lvl->lv = lvl->lv;
final_lvl->lv->process_specific = lv_is_specific;
dm_list_add(&final_lvs, &final_lvl->list);
}
log_set_report_object_name_and_id(NULL, NULL);
@ -3829,6 +3834,14 @@ int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
force_t force = (force_t) arg_count(cmd, force_ARG)
? : (arg_is_set(cmd, yes_ARG) ? DONT_PROMPT : PROMPT);
if ((force == PROMPT) &&
!lv->process_specific &&
(cmd->command->flags & CONFIRM_UNLESS_SPECIFIC)) {
if (yes_no_prompt("Remove LV %s that was not named directly? [y/n]: ",
display_lvname(lv)) == 'n')
return ECMD_PROCESSED;
}
if (!lv_remove_with_dependencies(cmd, lv, force, 0))
return_ECMD_FAILED;

View File

@ -118,6 +118,7 @@ struct arg_value_group_list {
#define ENABLE_DUPLICATE_DEVS 0x00000400
/* Command does not accept tags as args. */
#define DISALLOW_TAG_ARGS 0x00000800
#define CONFIRM_UNLESS_SPECIFIC 0x00001000
/* a register of the lvm commands */
struct command {