summaryrefslogtreecommitdiff
path: root/tools/pvremove.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pvremove.c')
-rw-r--r--tools/pvremove.c174
1 files changed, 42 insertions, 132 deletions
diff --git a/tools/pvremove.c b/tools/pvremove.c
index 823c069..5c39ee0 100644
--- a/tools/pvremove.c
+++ b/tools/pvremove.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -10,154 +10,64 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tools.h"
-const char _really_wipe[] =
- "Really WIPE LABELS from physical volume \"%s\" of volume group \"%s\" [y/n]? ";
-
-/*
- * Decide whether it is "safe" to wipe the labels on this device.
- * 0 indicates we may not.
- */
-static int pvremove_check(struct cmd_context *cmd, const char *name)
+int pvremove(struct cmd_context *cmd, int argc, char **argv)
{
- struct physical_volume *pv;
-
- /* FIXME Check partition type is LVM unless --force is given */
-
- /* Is there a pv here already? */
- /* If not, this is an error unless you used -f. */
- if (!(pv = pv_read(cmd, name, 1, 0))) {
- if (arg_count(cmd, force_ARG))
- return 1;
- log_error("Physical Volume %s not found", name);
- return 0;
- }
-
- /*
- * If a PV has no MDAs it may appear to be an
- * orphan until the metadata is read off
- * another PV in the same VG. Detecting this
- * means checking every VG by scanning every
- * PV on the system.
- */
- if (is_orphan(pv) && !dm_list_size(&pv->fid->metadata_areas_in_use) &&
- !dm_list_size(&pv->fid->metadata_areas_ignored)) {
- if (!scan_vgs_for_pvs(cmd, 0)) {
- log_error("Rescan for PVs without metadata areas "
- "failed.");
- goto bad;
- }
- free_pv_fid(pv);
- if (!(pv = pv_read(cmd, name, 1, 0))) {
- log_error("Failed to read physical volume %s", name);
- goto bad;
- }
- }
+ struct processing_handle *handle;
+ struct pvcreate_params pp;
+ int ret;
- /* orphan ? */
- if (is_orphan(pv)) {
- free_pv_fid(pv);
- return 1;
- }
-
- /* Allow partial & exported VGs to be destroyed. */
- /* we must have -ff to overwrite a non orphan */
- if (arg_count(cmd, force_ARG) < 2) {
- log_error("PV %s belongs to Volume Group %s so please use vgreduce first.", name, pv_vg_name(pv));
- log_error("(If you are certain you need pvremove, then confirm by using --force twice.)");
- goto bad;
- }
-
- /* prompt */
- if (!arg_count(cmd, yes_ARG) &&
- yes_no_prompt(_really_wipe, name, pv_vg_name(pv)) == 'n') {
- log_error("%s: physical volume label not removed", name);
- goto bad;
+ if (!argc) {
+ log_error("Please enter a physical volume path");
+ return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, force_ARG)) {
- log_warn("WARNING: Wiping physical volume label from "
- "%s%s%s%s", name,
- !is_orphan(pv) ? " of volume group \"" : "",
- !is_orphan(pv) ? pv_vg_name(pv) : "",
- !is_orphan(pv) ? "\"" : "");
+ pvcreate_params_set_defaults(&pp);
+
+ pp.is_remove = 1;
+ pp.force = arg_count(cmd, force_ARG);
+ pp.yes = arg_count(cmd, yes_ARG);
+ pp.pv_count = argc;
+ pp.pv_names = argv;
+
+ /* Needed to change the set of orphan PVs. */
+ if (!lock_global(cmd, "ex")) {
+ /* Let pvremove -ff skip locks */
+ if (pp.force == DONT_PROMPT_OVERRIDE)
+ log_warn("WARNING: skipping global lock for force.");
+ else
+ return_ECMD_FAILED;
}
- free_pv_fid(pv);
- return 1;
+ clear_hint_file(cmd);
-bad:
- free_pv_fid(pv);
- return 0;
-}
+ if (!lvmcache_label_scan(cmd))
+ return_ECMD_FAILED;
-static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
- void *handle __attribute__((unused)))
-{
- struct device *dev;
- int ret = ECMD_FAILED;
+ /* When forcibly clearing a PV we don't care about a VG lock. */
+ if (pp.force == DONT_PROMPT_OVERRIDE)
+ cmd->lockd_vg_disable = 1;
- if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
- log_error("Can't get lock for orphan PVs");
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
return ECMD_FAILED;
}
- if (!pvremove_check(cmd, pv_name))
- goto out;
-
- if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
- log_error("%s: Couldn't find device. Check your filters?",
- pv_name);
- goto out;
- }
-
- if (!dev_test_excl(dev)) {
- /* FIXME Detect whether device-mapper is still using the device */
- log_error("Can't open %s exclusively - not removing. "
- "Mounted filesystem?", dev_name(dev));
- goto out;
- }
-
- /* Wipe existing label(s) */
- if (!label_remove(dev)) {
- log_error("Failed to wipe existing label(s) on %s", pv_name);
- goto out;
- }
-
- if (!lvmetad_pv_gone_by_dev(dev, NULL))
- goto_out;
-
- log_print_unless_silent("Labels on physical volume \"%s\" successfully wiped",
- pv_name);
-
- ret = ECMD_PROCESSED;
-
-out:
- unlock_vg(cmd, VG_ORPHANS);
-
- return ret;
-}
-
-int pvremove(struct cmd_context *cmd, int argc, char **argv)
-{
- int i, r;
- int ret = ECMD_PROCESSED;
-
- if (!argc) {
- log_error("Please enter a physical volume path");
- return EINVALID_CMD_LINE;
- }
+ /*
+ * pvremove uses the same toollib function as pvcreate,
+ * but sets "is_remove" which changes the check function,
+ * and the actual create vs remove step.
+ */
- for (i = 0; i < argc; i++) {
- dm_unescape_colons_and_at_signs(argv[i], NULL, NULL);
- r = pvremove_single(cmd, argv[i], NULL);
- if (r > ret)
- ret = r;
- }
+ if (!pvcreate_each_device(cmd, handle, &pp))
+ ret = ECMD_FAILED;
+ else
+ ret = ECMD_PROCESSED;
+ destroy_processing_handle(cmd, handle);
return ret;
}