]> sourceware.org Git - lvm2.git/blame - tools/pvscan.c
Scan all devices for lvmetad if 'pvscan --cache' used without device list.
[lvm2.git] / tools / pvscan.c
CommitLineData
9e300c84 1/*
6606c3ae 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
35216ca6 3 * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
9e300c84 4 *
6606c3ae 5 * This file is part of LVM2.
9e300c84 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.
9e300c84 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
9e300c84
AK
14 */
15
16#include "tools.h"
17
dae08226
PR
18#include "lvmetad.h"
19#include "lvmcache.h"
20
9e300c84
AK
21int pv_max_name_len = 0;
22int vg_max_name_len = 0;
23
35216ca6
AK
24static dev_t _parse_devt(const char *str)
25{ /* Oh. */
26 char *where = (char *) str;
27 int major = strtol(str, &where, 10);
28 int minor;
29
30 if (where == str)
31 return -1;
32
33 if (*where != ':')
34 return -1;
35
36 str = ++where;
37 minor = strtol(str, &where, 10);
38
39 if (where == str)
40 return -1;
41
42 if (*where)
43 return -1;
44
45 return MKDEV(major, minor);
46}
47
48/*
49 * Convert pv_name to struct device or to *devno.
50 */
51static struct device *_device_from_pv_name(const char *pv_name, dev_t *devno)
52{
53 struct device *dev;
54
55 if ((dev = dev_cache_get(pv_name, NULL)))
56 return dev;
57
58 if ((*devno = _parse_devt(pv_name)) == -1) {
59 log_error("Unrecognised device name %s. "
60 "(Use MAJOR:MINOR for new devices.)", pv_name);
61 return NULL;
62 }
63
64 if ((dev = dev_cache_get_by_devt(*devno, NULL)))
65 return dev;
66
67 return NULL;
68}
69
8ef2b021 70static void _pvscan_display_single(struct cmd_context *cmd,
72b2cb61 71 struct physical_volume *pv,
08f1ddea 72 void *handle __attribute__((unused)))
5a52dca9 73{
08f1ddea 74 char uuid[64] __attribute__((aligned(8)));
72b2cb61 75 unsigned vg_name_len = 0;
5a52dca9 76
5a52dca9
AK
77 char pv_tmp_name[NAME_LEN] = { 0, };
78 char vg_tmp_name[NAME_LEN] = { 0, };
79 char vg_name_this[NAME_LEN] = { 0, };
80
81 /* short listing? */
82 if (arg_count(cmd, short_ARG) > 0) {
1b8de4cb 83 log_print("%s", pv_dev_name(pv));
5a52dca9
AK
84 return;
85 }
86
87 if (arg_count(cmd, verbose_ARG) > 1) {
88 /* FIXME As per pv_display! Drop through for now. */
89 /* pv_show(pv); */
90
91 /* FIXME - Moved to Volume Group structure */
92 /* log_print("System Id %s", pv->vg->system_id); */
93
94 /* log_print(" "); */
95 /* return; */
96 }
97
98 memset(pv_tmp_name, 0, sizeof(pv_tmp_name));
99
ff77bb1a 100 vg_name_len = strlen(pv_vg_name(pv)) + 1;
5a52dca9
AK
101
102 if (arg_count(cmd, uuid_ARG)) {
103 if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
104 stack;
105 return;
106 }
107
108 sprintf(pv_tmp_name, "%-*s with UUID %s",
1b8de4cb 109 pv_max_name_len - 2, pv_dev_name(pv), uuid);
5a52dca9 110 } else {
1b8de4cb 111 sprintf(pv_tmp_name, "%s", pv_dev_name(pv));
5a52dca9
AK
112 }
113
9c1dbeb3 114 if (is_orphan(pv)) {
5a52dca9
AK
115 log_print("PV %-*s %-*s %s [%s]",
116 pv_max_name_len, pv_tmp_name,
117 vg_max_name_len, " ",
118 pv->fmt ? pv->fmt->name : " ",
ff77bb1a 119 display_size(cmd, pv_size(pv)));
5a52dca9
AK
120 return;
121 }
122
ff77bb1a
DW
123 if (pv_status(pv) & EXPORTED_VG) {
124 strncpy(vg_name_this, pv_vg_name(pv), vg_name_len);
5a52dca9
AK
125 log_print("PV %-*s is in exported VG %s "
126 "[%s / %s free]",
127 pv_max_name_len, pv_tmp_name,
4c64ed4c 128 vg_name_this,
ff77bb1a
DW
129 display_size(cmd, (uint64_t) pv_pe_count(pv) *
130 pv_pe_size(pv)),
131 display_size(cmd, (uint64_t) (pv_pe_count(pv) -
132 pv_pe_alloc_count(pv))
133 * pv_pe_size(pv)));
5a52dca9
AK
134 return;
135 }
136
ff77bb1a 137 sprintf(vg_tmp_name, "%s", pv_vg_name(pv));
30bab85b
AK
138 log_print("PV %-*s VG %-*s %s [%s / %s free]", pv_max_name_len,
139 pv_tmp_name, vg_max_name_len, vg_tmp_name,
140 pv->fmt ? pv->fmt->name : " ",
67cdbd7e 141 display_size(cmd, (uint64_t) pv_pe_count(pv) *
ff77bb1a 142 pv_pe_size(pv)),
67cdbd7e 143 display_size(cmd, (uint64_t) (pv_pe_count(pv) -
ff77bb1a
DW
144 pv_pe_alloc_count(pv)) *
145 pv_pe_size(pv)));
5a52dca9
AK
146}
147
35216ca6 148static int _pvscan_lvmetad_all_devs(struct cmd_context *cmd)
d06f64dd 149{
35216ca6
AK
150 struct dev_iter *iter;
151 struct device *dev;
152 int r = 1;
d06f64dd 153
35216ca6
AK
154 if (!(iter = dev_iter_create(cmd->filter, 1))) {
155 log_error("dev_iter creation failed");
156 return 0;
d06f64dd
AK
157 }
158
35216ca6
AK
159 while ((dev = dev_iter_get(iter))) {
160 if (!pvscan_lvmetad_single(cmd, dev)) {
161 r = 0;
162 break;
163 }
164
165 if (sigint_caught())
166 break;
167 }
168
169 dev_iter_destroy(iter);
170
171 return r;
172}
173
174static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
175{
176 int ret = ECMD_PROCESSED;
177 struct device *dev;
178 const char *pv_name;
179 dev_t devno;
180
d06f64dd
AK
181 if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ)) {
182 log_error("Unable to obtain global lock.");
183 return ECMD_FAILED;
184 }
185
35216ca6
AK
186 if (!argc) {
187 if (!_pvscan_lvmetad_all_devs(cmd))
188 ret = ECMD_FAILED;
189 goto out;
190 }
191
d06f64dd 192 log_verbose("Using physical volume(s) on command line");
35216ca6 193
d06f64dd 194 while (argc--) {
35216ca6
AK
195 pv_name = *argv++;
196 dev = _device_from_pv_name(pv_name, &devno);
197
198 if (!dev && devno != -1) {
199 /* FIXME Filters? */
200 if (!lvmetad_pv_gone(devno, pv_name)) {
201 ret = ECMD_FAILED;
202 break;
203 }
204
205 log_print("Device %s not found. "
206 "Cleared from lvmetad cache.", pv_name);
207 continue;
208 }
209
210 if (!pvscan_lvmetad_single(cmd, dev)) {
d06f64dd
AK
211 ret = ECMD_FAILED;
212 break;
213 }
35216ca6 214
d06f64dd
AK
215 if (sigint_caught())
216 break;
217 }
218
35216ca6 219out:
d06f64dd
AK
220 unlock_vg(cmd, VG_GLOBAL);
221
222 return ret;
223}
224
dae08226 225int pvscan(struct cmd_context *cmd, int argc, char **argv)
9e300c84
AK
226{
227 int new_pvs_found = 0;
228 int pvs_found = 0;
9e300c84 229
2c44337b 230 struct dm_list *pvslist;
b6c041d7 231 struct pv_list *pvl;
9e300c84
AK
232 struct physical_volume *pv;
233
ee1f91bf
AK
234 uint64_t size_total = 0;
235 uint64_t size_new = 0;
9e300c84
AK
236
237 int len = 0;
238 pv_max_name_len = 0;
239 vg_max_name_len = 0;
240
d742cdf3 241 if (arg_count(cmd, cache_ARG))
d06f64dd 242 return _pvscan_lvmetad(cmd, argc, argv);
dae08226 243
6fda126d 244 if (arg_count(cmd, novolumegroup_ARG) && arg_count(cmd, exported_ARG)) {
b6c041d7 245 log_error("Options -e and -n are incompatible");
ee1f91bf 246 return EINVALID_CMD_LINE;
9e300c84
AK
247 }
248
113f2a01 249 if (arg_count(cmd, exported_ARG) || arg_count(cmd, novolumegroup_ARG))
e7ddf416 250 log_warn("WARNING: only considering physical volumes %s",
6fda126d 251 arg_count(cmd, exported_ARG) ?
9e300c84
AK
252 "of exported volume group(s)" : "in no volume group");
253
e935d217
AK
254 if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_WRITE)) {
255 log_error("Unable to obtain global lock.");
256 return ECMD_FAILED;
257 }
258
60274aba 259 persistent_filter_wipe(cmd->filter);
6eb44b50 260 lvmcache_destroy(cmd, 1);
5a52dca9 261
59a5361f
AK
262 /* populate lvmcache */
263 if (!lvmetad_vg_list_to_lvmcache(cmd))
264 stack;
265
d2393d23 266 log_verbose("Walking through all physical volumes");
e935d217
AK
267 if (!(pvslist = get_pvs(cmd))) {
268 unlock_vg(cmd, VG_GLOBAL);
651ff9b3 269 stack;
ee1f91bf 270 return ECMD_FAILED;
e935d217 271 }
9e300c84
AK
272
273 /* eliminate exported/new if required */
2c44337b 274 dm_list_iterate_items(pvl, pvslist) {
cc282870 275 pv = pvl->pv;
9e300c84 276
25b73380 277 if ((arg_count(cmd, exported_ARG)
59a5361f
AK
278 && !(pv_status(pv) & EXPORTED_VG)) ||
279 (arg_count(cmd, novolumegroup_ARG) && (!is_orphan(pv)))) {
2c44337b 280 dm_list_del(&pvl->list);
35216ca6 281 free_pv_fid(pv);
9e300c84
AK
282 continue;
283 }
284
285 /* Also check for MD use? */
286/*******
287 if (MAJOR(pv_create_kdev_t(pv[p]->pv_name)) != MD_MAJOR) {
258db3ad 288 log_warn
9e300c84
AK
289 ("WARNING: physical volume \"%s\" belongs to a meta device",
290 pv[p]->pv_name);
291 }
292 if (MAJOR(pv[p]->pv_dev) != MD_MAJOR)
293 continue;
294********/
295 pvs_found++;
25d42d50 296
9c1dbeb3 297 if (is_orphan(pv)) {
9e300c84 298 new_pvs_found++;
ff77bb1a
DW
299 size_new += pv_size(pv);
300 size_total += pv_size(pv);
1b9fcf48 301 } else
1641fdf9 302 size_total += (uint64_t) pv_pe_count(pv) * pv_pe_size(pv);
9e300c84
AK
303 }
304
305 /* find maximum pv name length */
306 pv_max_name_len = vg_max_name_len = 0;
2c44337b 307 dm_list_iterate_items(pvl, pvslist) {
f2b7349e 308 pv = pvl->pv;
1b8de4cb 309 len = strlen(pv_dev_name(pv));
9e300c84
AK
310 if (pv_max_name_len < len)
311 pv_max_name_len = len;
ff77bb1a 312 len = strlen(pv_vg_name(pv));
9e300c84
AK
313 if (vg_max_name_len < len)
314 vg_max_name_len = len;
315 }
316 pv_max_name_len += 2;
317 vg_max_name_len += 2;
318
84f48499 319 dm_list_iterate_items(pvl, pvslist) {
dae08226
PR
320 _pvscan_display_single(cmd, pvl->pv, NULL);
321 free_pv_fid(pvl->pv);
84f48499 322 }
9e300c84
AK
323
324 if (!pvs_found) {
325 log_print("No matching physical volumes found");
e935d217 326 unlock_vg(cmd, VG_GLOBAL);
cfb7bfc7 327 return ECMD_PROCESSED;
9e300c84
AK
328 }
329
b6c041d7 330 log_print("Total: %d [%s] / in use: %d [%s] / in no VG: %d [%s]",
9e300c84 331 pvs_found,
72b2cb61 332 display_size(cmd, size_total),
9e300c84 333 pvs_found - new_pvs_found,
72b2cb61
AK
334 display_size(cmd, (size_total - size_new)),
335 new_pvs_found, display_size(cmd, size_new));
9e300c84 336
e935d217
AK
337 unlock_vg(cmd, VG_GLOBAL);
338
cfb7bfc7 339 return ECMD_PROCESSED;
9e300c84 340}
This page took 0.141722 seconds and 5 git commands to generate.