1 /* $NetBSD: pvremove.c,v 1.1.1.2 2009/12/02 00:25:54 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 * 7 * This file is part of LVM2. 8 * 9 * This copyrighted material is made available to anyone wishing to use, 10 * modify, copy, or redistribute it subject to the terms and conditions 11 * of the GNU Lesser General Public License v.2.1. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #include "tools.h" 19 20 const char _really_wipe[] = 21 "Really WIPE LABELS from physical volume \"%s\" of volume group \"%s\" [y/n]? "; 22 23 /* 24 * Decide whether it is "safe" to wipe the labels on this device. 25 * 0 indicates we may not. 26 */ 27 static int pvremove_check(struct cmd_context *cmd, const char *name) 28 { 29 struct physical_volume *pv; 30 struct dm_list mdas; 31 32 dm_list_init(&mdas); 33 34 /* FIXME Check partition type is LVM unless --force is given */ 35 36 /* Is there a pv here already? */ 37 /* If not, this is an error unless you used -f. */ 38 if (!(pv = pv_read(cmd, name, &mdas, NULL, 1, 0))) { 39 if (arg_count(cmd, force_ARG)) 40 return 1; 41 log_error("Physical Volume %s not found", name); 42 return 0; 43 } 44 45 /* 46 * If a PV has no MDAs it may appear to be an 47 * orphan until the metadata is read off 48 * another PV in the same VG. Detecting this 49 * means checking every VG by scanning every 50 * PV on the system. 51 */ 52 if (is_orphan(pv) && !dm_list_size(&mdas)) { 53 if (!scan_vgs_for_pvs(cmd)) { 54 log_error("Rescan for PVs without metadata areas " 55 "failed."); 56 return 0; 57 } 58 if (!(pv = pv_read(cmd, name, NULL, NULL, 1, 0))) { 59 log_error("Failed to read physical volume %s", name); 60 return 0; 61 } 62 } 63 64 /* orphan ? */ 65 if (is_orphan(pv)) 66 return 1; 67 68 /* Allow partial & exported VGs to be destroyed. */ 69 /* we must have -ff to overwrite a non orphan */ 70 if (arg_count(cmd, force_ARG) < 2) { 71 log_error("Can't pvremove physical volume \"%s\" of " 72 "volume group \"%s\" without -ff", name, pv_vg_name(pv)); 73 return 0; 74 } 75 76 /* prompt */ 77 if (!arg_count(cmd, yes_ARG) && 78 yes_no_prompt(_really_wipe, name, pv_vg_name(pv)) == 'n') { 79 log_print("%s: physical volume label not removed", name); 80 return 0; 81 } 82 83 if (arg_count(cmd, force_ARG)) { 84 log_warn("WARNING: Wiping physical volume label from " 85 "%s%s%s%s", name, 86 !is_orphan(pv) ? " of volume group \"" : "", 87 !is_orphan(pv) ? pv_vg_name(pv) : "", 88 !is_orphan(pv) ? "\"" : ""); 89 } 90 91 return 1; 92 } 93 94 static int pvremove_single(struct cmd_context *cmd, const char *pv_name, 95 void *handle __attribute((unused))) 96 { 97 struct device *dev; 98 int ret = ECMD_FAILED; 99 100 if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) { 101 log_error("Can't get lock for orphan PVs"); 102 return ECMD_FAILED; 103 } 104 105 if (!pvremove_check(cmd, pv_name)) 106 goto error; 107 108 if (!(dev = dev_cache_get(pv_name, cmd->filter))) { 109 log_error("%s: Couldn't find device. Check your filters?", 110 pv_name); 111 goto error; 112 } 113 114 if (!dev_test_excl(dev)) { 115 /* FIXME Detect whether device-mapper is still using the device */ 116 log_error("Can't open %s exclusively - not removing. " 117 "Mounted filesystem?", dev_name(dev)); 118 goto error; 119 } 120 121 /* Wipe existing label(s) */ 122 if (!label_remove(dev)) { 123 log_error("Failed to wipe existing label(s) on %s", pv_name); 124 goto error; 125 } 126 127 log_print("Labels on physical volume \"%s\" successfully wiped", 128 pv_name); 129 130 ret = ECMD_PROCESSED; 131 132 error: 133 unlock_vg(cmd, VG_ORPHANS); 134 135 return ret; 136 } 137 138 int pvremove(struct cmd_context *cmd, int argc, char **argv) 139 { 140 int i, r; 141 int ret = ECMD_PROCESSED; 142 143 if (!argc) { 144 log_error("Please enter a physical volume path"); 145 return EINVALID_CMD_LINE; 146 } 147 148 if (arg_count(cmd, yes_ARG) && !arg_count(cmd, force_ARG)) { 149 log_error("Option y can only be given with option f"); 150 return EINVALID_CMD_LINE; 151 } 152 153 for (i = 0; i < argc; i++) { 154 r = pvremove_single(cmd, argv[i], NULL); 155 if (r > ret) 156 ret = r; 157 } 158 159 return ret; 160 } 161