Imported Upstream version 2.02.79
[platform/upstream/device-mapper.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         struct dm_list mdas;
29
30         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         if (!(pv = pv_read(cmd, name, &mdas, NULL, 1, 0))) {
37                 if (arg_count(cmd, force_ARG))
38                         return 1;
39                 log_error("Physical Volume %s not found", name);
40                 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         if (is_orphan(pv) && !dm_list_size(&mdas)) {
51                 if (!scan_vgs_for_pvs(cmd, 0)) {
52                         log_error("Rescan for PVs without metadata areas "
53                                   "failed.");
54                         return 0;
55                 }
56                 if (!(pv = pv_read(cmd, name, NULL, NULL, 1, 0))) {
57                         log_error("Failed to read physical volume %s", name);
58                         return 0;
59                 }
60         }
61
62         /* orphan ? */
63         if (is_orphan(pv))
64                 return 1;
65
66         /* Allow partial & exported VGs to be destroyed. */
67         /* we must have -ff to overwrite a non orphan */
68         if (arg_count(cmd, force_ARG) < 2) {
69                 log_error("Can't pvremove physical volume \"%s\" of "
70                           "volume group \"%s\" without -ff", name, pv_vg_name(pv));
71                 return 0;
72         }
73
74         /* prompt */
75         if (!arg_count(cmd, yes_ARG) &&
76             yes_no_prompt(_really_wipe, name, pv_vg_name(pv)) == 'n') {
77                 log_error("%s: physical volume label not removed", name);
78                 return 0;
79         }
80
81         if (arg_count(cmd, force_ARG)) {
82                 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         return 1;
90 }
91
92 static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
93                            void *handle __attribute__((unused)))
94 {
95         struct device *dev;
96         int ret = ECMD_FAILED;
97
98         if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
99                 log_error("Can't get lock for orphan PVs");
100                 return ECMD_FAILED;
101         }
102
103         if (!pvremove_check(cmd, pv_name))
104                 goto error;
105
106         if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
107                 log_error("%s: Couldn't find device.  Check your filters?",
108                           pv_name);
109                 goto error;
110         }
111
112         if (!dev_test_excl(dev)) {
113                 /* FIXME Detect whether device-mapper is still using the device */
114                 log_error("Can't open %s exclusively - not removing. "
115                           "Mounted filesystem?", dev_name(dev));
116                 goto error;
117         }
118
119         /* Wipe existing label(s) */
120         if (!label_remove(dev)) {
121                 log_error("Failed to wipe existing label(s) on %s", pv_name);
122                 goto error;
123         }
124
125         log_print("Labels on physical volume \"%s\" successfully wiped",
126                   pv_name);
127
128         ret = ECMD_PROCESSED;
129
130       error:
131         unlock_vg(cmd, VG_ORPHANS);
132
133         return ret;
134 }
135
136 int pvremove(struct cmd_context *cmd, int argc, char **argv)
137 {
138         int i, r;
139         int ret = ECMD_PROCESSED;
140
141         if (!argc) {
142                 log_error("Please enter a physical volume path");
143                 return EINVALID_CMD_LINE;
144         }
145
146         for (i = 0; i < argc; i++) {
147                 unescape_colons_and_at_signs(argv[i], NULL, NULL);
148                 r = pvremove_single(cmd, argv[i], NULL);
149                 if (r > ret)
150                         ret = r;
151         }
152
153         return ret;
154 }