From 53fbce932bcb221c649ee44102ebbb1b0a372e00 Mon Sep 17 00:00:00 2001 From: Dave Wysochanski Date: Mon, 20 Aug 2007 17:04:53 +0000 Subject: [PATCH] Move lv_remove_single() into library (lv_manip.c, metadata-exported.h). Move yes_no_prompt() into library (display.c, display.h). Fixup includes as a result of movement of prior two functions. Fixup force_t enum to be more descriptive. --- lib/display/display.c | 31 +++++++++ lib/display/display.h | 3 + lib/metadata/lv_manip.c | 112 +++++++++++++++++++++++++++++ lib/metadata/metadata-exported.h | 7 +- tools/lvmcmdline.c | 31 --------- tools/lvremove.c | 116 +------------------------------ tools/tools.h | 1 - 7 files changed, 153 insertions(+), 148 deletions(-) diff --git a/lib/display/display.c b/lib/display/display.c index c0f4e5b78..be630c67b 100644 --- a/lib/display/display.c +++ b/lib/display/display.c @@ -726,3 +726,34 @@ void display_segtypes(const struct cmd_context *cmd) } } +char yes_no_prompt(const char *prompt, ...) +{ + int c = 0, ret = 0; + va_list ap; + + sigint_allow(); + do { + if (c == '\n' || !c) { + va_start(ap, prompt); + vprintf(prompt, ap); + va_end(ap); + } + + if ((c = getchar()) == EOF) { + ret = 'n'; + break; + } + + c = tolower(c); + if ((c == 'y') || (c == 'n')) + ret = c; + } while (!ret || c != '\n'); + + sigint_restore(); + + if (c != '\n') + printf("\n"); + + return ret; +} + diff --git a/lib/display/display.h b/lib/display/display.h index 94f9c0eb6..b7fff14bd 100644 --- a/lib/display/display.h +++ b/lib/display/display.h @@ -17,6 +17,7 @@ #define _LVM_DISPLAY_H #include "metadata-exported.h" +#include "locking.h" #include @@ -58,4 +59,6 @@ void display_segtypes(const struct cmd_context *cmd); const char *get_alloc_string(alloc_policy_t alloc); alloc_policy_t get_alloc_from_string(const char *str); +char yes_no_prompt(const char *prompt, ...); + #endif diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index d65fe78f3..005e393a0 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -24,6 +24,7 @@ #include "display.h" #include "segtype.h" #include "archiver.h" +#include "activate.h" struct lv_names { const char *old; @@ -1804,3 +1805,114 @@ struct list *build_parallel_areas_from_lv(struct cmd_context *cmd, return parallel_areas; } + +int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, + force_t force) +{ + struct volume_group *vg; + struct lvinfo info; + struct logical_volume *origin = NULL; + + vg = lv->vg; + + if (!vg_check_status(vg, LVM_WRITE)) + return 0; + + if (lv_is_origin(lv)) { + log_error("Can't remove logical volume \"%s\" under snapshot", + lv->name); + return 0; + } + + if (lv->status & MIRROR_IMAGE) { + log_error("Can't remove logical volume %s used by a mirror", + lv->name); + return 0; + } + + if (lv->status & MIRROR_LOG) { + log_error("Can't remove logical volume %s used as mirror log", + lv->name); + return 0; + } + + if (lv->status & LOCKED) { + log_error("Can't remove locked LV %s", lv->name); + return 0; + } + + /* FIXME Ensure not referred to by another existing LVs */ + + if (lv_info(cmd, lv, &info, 1)) { + if (info.open_count) { + log_error("Can't remove open logical volume \"%s\"", + lv->name); + return 0; + } + + if (info.exists && (force == DONT_FORCE)) { + if (yes_no_prompt("Do you really want to remove active " + "logical volume \"%s\"? [y/n]: ", + lv->name) == 'n') { + log_print("Logical volume \"%s\" not removed", + lv->name); + return 0; + } + } + } + + if (!archive(vg)) + return 0; + + /* If the VG is clustered then make sure no-one else is using the LV + we are about to remove */ + if (vg_status(vg) & CLUSTERED) { + if (!activate_lv_excl(cmd, lv)) { + log_error("Can't get exclusive access to volume \"%s\"", + lv->name); + return 0; + } + } + + /* FIXME Snapshot commit out of sequence if it fails after here? */ + if (!deactivate_lv(cmd, lv)) { + log_error("Unable to deactivate logical volume \"%s\"", + lv->name); + return 0; + } + + if (lv_is_cow(lv)) { + origin = origin_from_cow(lv); + log_verbose("Removing snapshot %s", lv->name); + if (!vg_remove_snapshot(lv)) { + stack; + return 0; + } + } + + log_verbose("Releasing logical volume \"%s\"", lv->name); + if (!lv_remove(lv)) { + log_error("Error releasing logical volume \"%s\"", lv->name); + return 0; + } + + /* store it on disks */ + if (!vg_write(vg)) + return 0; + + backup(vg); + + if (!vg_commit(vg)) + return 0; + + /* If no snapshots left, reload without -real. */ + if (origin && !lv_is_origin(origin)) { + if (!suspend_lv(cmd, origin)) + log_error("Failed to refresh %s without snapshot.", origin->name); + else if (!resume_lv(cmd, origin)) + log_error("Failed to resume %s.", origin->name); + } + + log_print("Logical volume \"%s\" successfully removed", lv->name); + return 1; +} diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index a9c050317..51ebbc5f4 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -108,8 +108,8 @@ typedef enum { */ typedef enum { DONT_FORCE = 0, - FORCE = 1, - FORCE_2 = 2 + FORCE_NO_CONFIRM = 1, /* skip yes/no confirmation of operation */ + FORCE_OVERRIDE = 2 /* skip confirmation and bypass a second condition */ } force_t; struct cmd_context; @@ -365,6 +365,9 @@ int lv_extend(struct logical_volume *lv, /* lv must be part of lv->vg->lvs */ int lv_remove(struct logical_volume *lv); +int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, + force_t force); + int lv_rename(struct cmd_context *cmd, struct logical_volume *lv, const char *new_name); diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c index aeb829685..17c5dba0d 100644 --- a/tools/lvmcmdline.c +++ b/tools/lvmcmdline.c @@ -368,37 +368,6 @@ int segtype_arg(struct cmd_context *cmd, struct arg *a) return 1; } -char yes_no_prompt(const char *prompt, ...) -{ - int c = 0, ret = 0; - va_list ap; - - sigint_allow(); - do { - if (c == '\n' || !c) { - va_start(ap, prompt); - vprintf(prompt, ap); - va_end(ap); - } - - if ((c = getchar()) == EOF) { - ret = 'n'; - break; - } - - c = tolower(c); - if ((c == 'y') || (c == 'n')) - ret = c; - } while (!ret || c != '\n'); - - sigint_restore(); - - if (c != '\n') - printf("\n"); - - return ret; -} - static void __alloc(int size) { if (!(_cmdline.commands = dm_realloc(_cmdline.commands, sizeof(*_cmdline.commands) * size))) { diff --git a/tools/lvremove.c b/tools/lvremove.c index 9dfd1b47f..8d0e1a370 100644 --- a/tools/lvremove.c +++ b/tools/lvremove.c @@ -15,125 +15,13 @@ #include "tools.h" -/* TODO: Next checkin, move to lvm library (lv_manip.c, metadata-exported.h) */ -static int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, - force_t force) -{ - struct volume_group *vg; - struct lvinfo info; - struct logical_volume *origin = NULL; - - vg = lv->vg; - - if (!vg_check_status(vg, LVM_WRITE)) - return 0; - - if (lv_is_origin(lv)) { - log_error("Can't remove logical volume \"%s\" under snapshot", - lv->name); - return 0; - } - - if (lv->status & MIRROR_IMAGE) { - log_error("Can't remove logical volume %s used by a mirror", - lv->name); - return 0; - } - - if (lv->status & MIRROR_LOG) { - log_error("Can't remove logical volume %s used as mirror log", - lv->name); - return 0; - } - - if (lv->status & LOCKED) { - log_error("Can't remove locked LV %s", lv->name); - return 0; - } - - /* FIXME Ensure not referred to by another existing LVs */ - - if (lv_info(cmd, lv, &info, 1)) { - if (info.open_count) { - log_error("Can't remove open logical volume \"%s\"", - lv->name); - return 0; - } - - if (info.exists && (force == DONT_FORCE)) { - if (yes_no_prompt("Do you really want to remove active " - "logical volume \"%s\"? [y/n]: ", - lv->name) == 'n') { - log_print("Logical volume \"%s\" not removed", - lv->name); - return 0; - } - } - } - - if (!archive(vg)) - return 0; - - /* If the VG is clustered then make sure no-one else is using the LV - we are about to remove */ - if (vg_status(vg) & CLUSTERED) { - if (!activate_lv_excl(cmd, lv)) { - log_error("Can't get exclusive access to volume \"%s\"", - lv->name); - return 0; - } - } - - /* FIXME Snapshot commit out of sequence if it fails after here? */ - if (!deactivate_lv(cmd, lv)) { - log_error("Unable to deactivate logical volume \"%s\"", - lv->name); - return 0; - } - - if (lv_is_cow(lv)) { - origin = origin_from_cow(lv); - log_verbose("Removing snapshot %s", lv->name); - if (!vg_remove_snapshot(lv)) { - stack; - return 0; - } - } - - log_verbose("Releasing logical volume \"%s\"", lv->name); - if (!lv_remove(lv)) { - log_error("Error releasing logical volume \"%s\"", lv->name); - return 0; - } - - /* store it on disks */ - if (!vg_write(vg)) - return 0; - - backup(vg); - - if (!vg_commit(vg)) - return 0; - - /* If no snapshots left, reload without -real. */ - if (origin && !lv_is_origin(origin)) { - if (!suspend_lv(cmd, origin)) - log_error("Failed to refresh %s without snapshot.", origin->name); - else if (!resume_lv(cmd, origin)) - log_error("Failed to resume %s.", origin->name); - } - - log_print("Logical volume \"%s\" successfully removed", lv->name); - return 1; -} - static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv, void *handle __attribute((unused))) { if (!lv_remove_single(cmd, lv, arg_count(cmd, force_ARG))) return ECMD_FAILED; - else - return ECMD_PROCESSED; + + return ECMD_PROCESSED; } int lvremove(struct cmd_context *cmd, int argc, char **argv) diff --git a/tools/tools.h b/tools/tools.h index eac7c0282..30b9591e4 100644 --- a/tools/tools.h +++ b/tools/tools.h @@ -144,7 +144,6 @@ int units_arg(struct cmd_context *cmd, struct arg *a); int segtype_arg(struct cmd_context *cmd, struct arg *a); int alloc_arg(struct cmd_context *cmd, struct arg *a); -char yes_no_prompt(const char *prompt, ...); /* we use the enums to access the switches */ unsigned int arg_count(const struct cmd_context *cmd, int a);