]>
Commit | Line | Data |
---|---|---|
5a52dca9 | 1 | /* |
6606c3ae | 2 | * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved. |
be684599 | 3 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. |
5a52dca9 | 4 | * |
6606c3ae | 5 | * This file is part of LVM2. |
5a52dca9 | 6 | * |
6606c3ae AK |
7 | * This copyrighted material is made available to anyone wishing to use, |
8 | * modify, copy, or redistribute it subject to the terms and conditions | |
be684599 | 9 | * of the GNU Lesser General Public License v.2.1. |
5a52dca9 | 10 | * |
be684599 | 11 | * You should have received a copy of the GNU Lesser General Public License |
6606c3ae AK |
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 | |
5a52dca9 AK |
14 | */ |
15 | ||
16 | #include "tools.h" | |
5a52dca9 AK |
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 | ||
08c17458 AK |
29 | /* FIXME Check partition type is LVM unless --force is given */ |
30 | ||
7810d55d AK |
31 | /* Is there a pv here already? */ |
32 | /* If not, this is an error unless you used -f. */ | |
3cac20f8 | 33 | if (!(pv = pv_read(cmd, name, 1, 0))) { |
7810d55d AK |
34 | if (arg_count(cmd, force_ARG)) |
35 | return 1; | |
67e6c7e7 AK |
36 | log_error("Physical Volume %s not found", name); |
37 | return 0; | |
7810d55d | 38 | } |
5a52dca9 | 39 | |
32a478cb AK |
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 | */ | |
30581623 PR |
47 | if (is_orphan(pv) && !dm_list_size(&pv->fid->metadata_areas_in_use) && |
48 | !dm_list_size(&pv->fid->metadata_areas_ignored)) { | |
728074ac | 49 | if (!scan_vgs_for_pvs(cmd, 0)) { |
32a478cb AK |
50 | log_error("Rescan for PVs without metadata areas " |
51 | "failed."); | |
84f48499 | 52 | goto bad; |
32a478cb | 53 | } |
84f48499 | 54 | free_pv_fid(pv); |
3cac20f8 | 55 | if (!(pv = pv_read(cmd, name, 1, 0))) { |
32a478cb | 56 | log_error("Failed to read physical volume %s", name); |
84f48499 | 57 | goto bad; |
32a478cb AK |
58 | } |
59 | } | |
60 | ||
5a52dca9 | 61 | /* orphan ? */ |
84f48499 PR |
62 | if (is_orphan(pv)) { |
63 | free_pv_fid(pv); | |
5a52dca9 | 64 | return 1; |
84f48499 | 65 | } |
5a52dca9 AK |
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) { | |
07e711ec AK |
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.)"); | |
84f48499 | 72 | goto bad; |
5a52dca9 AK |
73 | } |
74 | ||
75 | /* prompt */ | |
76 | if (!arg_count(cmd, yes_ARG) && | |
ff77bb1a | 77 | yes_no_prompt(_really_wipe, name, pv_vg_name(pv)) == 'n') { |
fec4de95 | 78 | log_error("%s: physical volume label not removed", name); |
84f48499 | 79 | goto bad; |
5a52dca9 AK |
80 | } |
81 | ||
82 | if (arg_count(cmd, force_ARG)) { | |
e7ddf416 | 83 | log_warn("WARNING: Wiping physical volume label from " |
5a52dca9 | 84 | "%s%s%s%s", name, |
3df2c388 | 85 | !is_orphan(pv) ? " of volume group \"" : "", |
ff77bb1a | 86 | !is_orphan(pv) ? pv_vg_name(pv) : "", |
3df2c388 | 87 | !is_orphan(pv) ? "\"" : ""); |
5a52dca9 AK |
88 | } |
89 | ||
84f48499 | 90 | free_pv_fid(pv); |
5a52dca9 | 91 | return 1; |
84f48499 PR |
92 | |
93 | bad: | |
94 | free_pv_fid(pv); | |
95 | return 0; | |
5a52dca9 AK |
96 | } |
97 | ||
cfb7bfc7 | 98 | static int pvremove_single(struct cmd_context *cmd, const char *pv_name, |
08f1ddea | 99 | void *handle __attribute__((unused))) |
5a52dca9 AK |
100 | { |
101 | struct device *dev; | |
d38bf361 | 102 | int ret = ECMD_FAILED; |
5a52dca9 | 103 | |
d38bf361 | 104 | if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) { |
5a52dca9 | 105 | log_error("Can't get lock for orphan PVs"); |
cfb7bfc7 | 106 | return ECMD_FAILED; |
5a52dca9 AK |
107 | } |
108 | ||
109 | if (!pvremove_check(cmd, pv_name)) | |
dc9ef7a0 | 110 | goto out; |
5a52dca9 AK |
111 | |
112 | if (!(dev = dev_cache_get(pv_name, cmd->filter))) { | |
b9ade4bc AK |
113 | log_error("%s: Couldn't find device. Check your filters?", |
114 | pv_name); | |
dc9ef7a0 | 115 | goto out; |
5a52dca9 AK |
116 | } |
117 | ||
9b02bdbc | 118 | if (!dev_test_excl(dev)) { |
94e33a6c | 119 | /* FIXME Detect whether device-mapper is still using the device */ |
ba4f5d80 AK |
120 | log_error("Can't open %s exclusively - not removing. " |
121 | "Mounted filesystem?", dev_name(dev)); | |
dc9ef7a0 | 122 | goto out; |
9b02bdbc AK |
123 | } |
124 | ||
5a52dca9 AK |
125 | /* Wipe existing label(s) */ |
126 | if (!label_remove(dev)) { | |
127 | log_error("Failed to wipe existing label(s) on %s", pv_name); | |
dc9ef7a0 | 128 | goto out; |
5a52dca9 AK |
129 | } |
130 | ||
b804340f | 131 | /* FIXME Avoid error if we expect that daemon might not know device */ |
d06f64dd | 132 | if (!lvmetad_pv_gone(dev)) |
b804340f | 133 | goto_out; |
dae08226 | 134 | |
5a52dca9 AK |
135 | log_print("Labels on physical volume \"%s\" successfully wiped", |
136 | pv_name); | |
137 | ||
d38bf361 | 138 | ret = ECMD_PROCESSED; |
cfb7bfc7 | 139 | |
dc9ef7a0 | 140 | out: |
d38bf361 AK |
141 | unlock_vg(cmd, VG_ORPHANS); |
142 | ||
143 | return ret; | |
5a52dca9 AK |
144 | } |
145 | ||
146 | int pvremove(struct cmd_context *cmd, int argc, char **argv) | |
147 | { | |
cfb7bfc7 AK |
148 | int i, r; |
149 | int ret = ECMD_PROCESSED; | |
5a52dca9 AK |
150 | |
151 | if (!argc) { | |
152 | log_error("Please enter a physical volume path"); | |
153 | return EINVALID_CMD_LINE; | |
154 | } | |
155 | ||
5a52dca9 | 156 | for (i = 0; i < argc; i++) { |
e59e2f7c | 157 | dm_unescape_colons_and_at_signs(argv[i], NULL, NULL); |
cfb7bfc7 AK |
158 | r = pvremove_single(cmd, argv[i], NULL); |
159 | if (r > ret) | |
160 | ret = r; | |
5a52dca9 AK |
161 | } |
162 | ||
cfb7bfc7 | 163 | return ret; |
5a52dca9 | 164 | } |