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