diff options
Diffstat (limited to 'tools/pvremove.c')
-rw-r--r-- | tools/pvremove.c | 174 |
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; } |