[lvm-devel] main - lvremove: use common routine for prompting
Zdenek Kabelac
zkabelac at sourceware.org
Mon Mar 15 10:14:12 UTC 2021
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=0a2d7c57a1120045e1a93a63bc568dc1e3dbb734
Commit: 0a2d7c57a1120045e1a93a63bc568dc1e3dbb734
Parent: a18409b6d1d6a90e432b0b0079ce702d0055fa5a
Author: Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate: Sun Mar 14 13:17:03 2021 +0100
Committer: Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Mon Mar 15 11:08:47 2021 +0100
lvremove: use common routine for prompting
Move code for prompting about removed LV to a single function
and use it also to prompt for removal of origin and all its thick
snapshots and also when removing merging origin.
Function does handle postponed write_and_commit so there is
no 'in-flight' operation while waiting on [y|n] answer.
---
lib/metadata/lv_manip.c | 136 +++++++++++++++++++++++++++---------------------
1 file changed, 76 insertions(+), 60 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index ec8704ce7..1d341eea2 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6527,6 +6527,65 @@ void lv_set_hidden(struct logical_volume *lv)
log_debug_metadata("LV %s in VG %s is now hidden.", lv->name, lv->vg->name);
}
+static int _lv_remove_check_in_use(struct logical_volume *lv, force_t force)
+{
+ struct volume_group *vg = lv->vg;
+ const char *volume_type = "";
+ char buffer[50 * NAME_LEN * 2] = "";
+ int active;
+ int issue_discards =
+ (vg->cmd->current_settings.issue_discards &&
+ !lv_is_thin_volume(lv) &&
+ !lv_is_vdo(lv) &&
+ !lv_is_virtual_origin(lv)) ? 1 : 0;
+
+ switch (lv_check_not_in_use(lv, 1)) {
+ case 2: /* Not active, prompt when discarding real LVs */
+ if (!issue_discards ||
+ lv_is_historical(lv))
+ return 1;
+ active = 0;
+ break;
+ case 1: /* Active, not in use, prompt when visible */
+ if (!lv_is_visible(lv) ||
+ lv_is_pending_delete(lv))
+ return 1;
+ active = 1;
+ break;
+ default: /* Active, in use, can't remove */
+ return_0;
+ }
+
+ if (force == PROMPT) {
+ if (vg->needs_write_and_commit && (!vg_write(vg) || !vg_commit(vg)))
+ return_0;
+
+ if (lv_is_origin(lv)) {
+ volume_type = " origin";
+ (void) dm_snprintf(buffer, sizeof(buffer), " with %u snapshots(s)",
+ lv->origin_count);
+ } else if (lv_is_merging_origin(lv)) {
+ volume_type = " merging origin";
+ (void) dm_snprintf(buffer, sizeof(buffer), " with snapshot %s",
+ display_lvname(find_snapshot(lv)->lv));
+ }
+
+ if (yes_no_prompt("Do you really want to remove%s%s%s%s "
+ "logical volume %s%s? [y/n]: ",
+ issue_discards ? " and DISCARD" : "",
+ active ? " active" : "",
+ vg_is_clustered(vg) ? " clustered" : "",
+ volume_type, display_lvname(lv),
+ buffer) == 'n') {
+ lv->to_remove = 0;
+ log_error("Logical volume %s not removed.", display_lvname(lv));
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
force_t force, int suppress_remove_message)
{
@@ -6535,7 +6594,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
struct logical_volume *pool_lv = NULL;
struct logical_volume *lock_lv = lv;
struct lv_segment *cache_seg = NULL;
- int ask_discard;
struct seg_list *sl;
struct lv_segment *seg = first_seg(lv);
char msg[NAME_LEN + 300], *msg_dup;
@@ -6602,31 +6660,9 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!lockd_lv(cmd, lock_lv, "ex", LDLV_PERSISTENT))
return_0;
- /* FIXME Ensure not referred to by another existing LVs */
- ask_discard = find_config_tree_bool(cmd, devices_issue_discards_CFG, NULL);
-
if (!lv_is_cache_vol(lv)) {
- switch (lv_check_not_in_use(lv, 1)) {
- case 0: return_0;
- case 1: /* Active, not in use */
- if ((force == PROMPT) &&
- !lv_is_pending_delete(lv) &&
- lv_is_visible(lv)) {
- if (vg->needs_write_and_commit && (!vg_write(vg) || !vg_commit(vg)))
- return_0;
- if (yes_no_prompt("Do you really want to remove%s active "
- "%slogical volume %s? [y/n]: ",
- ask_discard ? " and DISCARD" : "",
- vg_is_clustered(vg) ? "clustered " : "",
- display_lvname(lv)) == 'n') {
- log_error("Logical volume %s not removed.", display_lvname(lv));
- return 0;
- }
- ask_discard = 0;
- }
- break;
- default: /* Not active */ ;
- }
+ if (!_lv_remove_check_in_use(lv, force))
+ return_0;
}
if (lv_is_writecache(lv)) {
@@ -6651,17 +6687,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
}
}
- if (!lv_is_historical(lv) && (force == PROMPT) && ask_discard) {
- /* try to store on disks already confirmed removals */
- if (vg->needs_write_and_commit && (!vg_write(vg) || !vg_commit(vg)))
- return_0;
- if (yes_no_prompt("Do you really want to remove and DISCARD "
- "logical volume %s? [y/n]: ",
- display_lvname(lv)) == 'n') {
- log_error("Logical volume %s not removed.", display_lvname(lv));
- return 0;
- }
- }
/* Used cache pool, COW or historical LV cannot be activated */
if (!lv_is_used_cache_pool(lv) &&
@@ -6872,20 +6897,12 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
if (lv_is_origin(lv)) {
/* Remove snapshot LVs first */
- if ((force == PROMPT) &&
- /* Active snapshot already needs to confirm each active LV */
- (yes_no_prompt("Do you really want to remove%s "
- "%sorigin logical volume %s with %u snapshot(s)? [y/n]: ",
- lv_is_active(lv) ? " active" : "",
- vg_is_clustered(lv->vg) ? "clustered " : "",
- display_lvname(lv),
- lv->origin_count) == 'n'))
- goto no_remove;
+ if (!_lv_remove_check_in_use(lv, force))
+ return_0;
- if (!deactivate_lv(cmd, lv)) {
- stack;
+ if (!deactivate_lv(cmd, lv))
goto no_remove;
- }
+
log_verbose("Removing origin logical volume %s with %u snapshots(s).",
display_lvname(lv), lv->origin_count);
@@ -6894,20 +6911,19 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
origin_list)->cow,
force, level + 1))
return_0;
- }
+ } else if (lv_is_merging_origin(lv)) {
+ /* Removing thin merging origin requires to remove its merging snapshot first */
+ if (!_lv_remove_check_in_use(lv, force))
+ return_0;
+
+ if (!deactivate_lv(cmd, lv))
+ goto no_remove;
+
+ log_verbose("Removing merging origin logical volume %s.", display_lvname(lv));
- if (lv_is_merging_origin(lv)) {
- if (!deactivate_lv(cmd, lv)) {
- log_error("Unable to fully deactivate merging origin %s.",
- display_lvname(lv));
- return 0;
- }
if (!lv_remove_with_dependencies(cmd, find_snapshot(lv)->lv,
- force, level + 1)) {
- log_error("Unable to remove merging origin %s.",
- display_lvname(lv));
- return 0;
- }
+ force, level + 1))
+ return_0;
}
if (!level && lv_is_merging_thin_snapshot(lv)) {
More information about the lvm-devel
mailing list