Branch data Line data Source code
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 : 0 : static int pvremove_check(struct cmd_context *cmd, const char *name)
26 : : {
27 : : struct physical_volume *pv;
28 : : struct dm_list mdas;
29 : :
30 : 0 : dm_list_init(&mdas);
31 : :
32 : : /* FIXME Check partition type is LVM unless --force is given */
33 : :
34 : : /* Is there a pv here already? */
35 : : /* If not, this is an error unless you used -f. */
36 [ # # ]: 0 : if (!(pv = pv_read(cmd, name, &mdas, NULL, 1, 0))) {
37 [ # # ]: 0 : if (arg_count(cmd, force_ARG))
38 : 0 : return 1;
39 : 0 : log_error("Physical Volume %s not found", name);
40 : 0 : return 0;
41 : : }
42 : :
43 : : /*
44 : : * If a PV has no MDAs it may appear to be an
45 : : * orphan until the metadata is read off
46 : : * another PV in the same VG. Detecting this
47 : : * means checking every VG by scanning every
48 : : * PV on the system.
49 : : */
50 [ # # ][ # # ]: 0 : if (is_orphan(pv) && !dm_list_size(&mdas)) {
51 [ # # ]: 0 : if (!scan_vgs_for_pvs(cmd)) {
52 : 0 : log_error("Rescan for PVs without metadata areas "
53 : : "failed.");
54 : 0 : return 0;
55 : : }
56 [ # # ]: 0 : if (!(pv = pv_read(cmd, name, NULL, NULL, 1, 0))) {
57 : 0 : log_error("Failed to read physical volume %s", name);
58 : 0 : return 0;
59 : : }
60 : : }
61 : :
62 : : /* orphan ? */
63 [ # # ]: 0 : if (is_orphan(pv))
64 : 0 : return 1;
65 : :
66 : : /* Allow partial & exported VGs to be destroyed. */
67 : : /* we must have -ff to overwrite a non orphan */
68 [ # # ]: 0 : if (arg_count(cmd, force_ARG) < 2) {
69 : 0 : log_error("Can't pvremove physical volume \"%s\" of "
70 : : "volume group \"%s\" without -ff", name, pv_vg_name(pv));
71 : 0 : return 0;
72 : : }
73 : :
74 : : /* prompt */
75 [ # # # # ]: 0 : if (!arg_count(cmd, yes_ARG) &&
76 : 0 : yes_no_prompt(_really_wipe, name, pv_vg_name(pv)) == 'n') {
77 : 0 : log_error("%s: physical volume label not removed", name);
78 : 0 : return 0;
79 : : }
80 : :
81 [ # # ]: 0 : if (arg_count(cmd, force_ARG)) {
82 [ # # ][ # # ]: 0 : log_warn("WARNING: Wiping physical volume label from "
[ # # ]
83 : : "%s%s%s%s", name,
84 : : !is_orphan(pv) ? " of volume group \"" : "",
85 : : !is_orphan(pv) ? pv_vg_name(pv) : "",
86 : : !is_orphan(pv) ? "\"" : "");
87 : : }
88 : :
89 : 0 : return 1;
90 : : }
91 : :
92 : 0 : static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
93 : : void *handle __attribute((unused)))
94 : : {
95 : : struct device *dev;
96 : 0 : int ret = ECMD_FAILED;
97 : :
98 [ # # ]: 0 : if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
99 : 0 : log_error("Can't get lock for orphan PVs");
100 : 0 : return ECMD_FAILED;
101 : : }
102 : :
103 [ # # ]: 0 : if (!pvremove_check(cmd, pv_name))
104 : 0 : goto error;
105 : :
106 [ # # ]: 0 : if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
107 : 0 : log_error("%s: Couldn't find device. Check your filters?",
108 : : pv_name);
109 : 0 : goto error;
110 : : }
111 : :
112 [ # # ]: 0 : if (!dev_test_excl(dev)) {
113 : : /* FIXME Detect whether device-mapper is still using the device */
114 : 0 : log_error("Can't open %s exclusively - not removing. "
115 : : "Mounted filesystem?", dev_name(dev));
116 : 0 : goto error;
117 : : }
118 : :
119 : : /* Wipe existing label(s) */
120 [ # # ]: 0 : if (!label_remove(dev)) {
121 : 0 : log_error("Failed to wipe existing label(s) on %s", pv_name);
122 : 0 : goto error;
123 : : }
124 : :
125 : 0 : log_print("Labels on physical volume \"%s\" successfully wiped",
126 : : pv_name);
127 : :
128 : 0 : ret = ECMD_PROCESSED;
129 : :
130 : : error:
131 : 0 : unlock_vg(cmd, VG_ORPHANS);
132 : :
133 : 0 : return ret;
134 : : }
135 : :
136 : 0 : int pvremove(struct cmd_context *cmd, int argc, char **argv)
137 : : {
138 : : int i, r;
139 : 0 : int ret = ECMD_PROCESSED;
140 : :
141 [ # # ]: 0 : if (!argc) {
142 : 0 : log_error("Please enter a physical volume path");
143 : 0 : return EINVALID_CMD_LINE;
144 : : }
145 : :
146 [ # # ][ # # ]: 0 : if (arg_count(cmd, yes_ARG) && !arg_count(cmd, force_ARG)) {
147 : 0 : log_error("Option y can only be given with option f");
148 : 0 : return EINVALID_CMD_LINE;
149 : : }
150 : :
151 [ # # ]: 0 : for (i = 0; i < argc; i++) {
152 : 0 : r = pvremove_single(cmd, argv[i], NULL);
153 [ # # ]: 0 : if (r > ret)
154 : 0 : ret = r;
155 : : }
156 : :
157 : 0 : return ret;
158 : : }
|