]> sourceware.org Git - lvm2.git/blame_incremental - tools/pvscan.c
Scan all devices for lvmetad if 'pvscan --cache' used without device list.
[lvm2.git] / tools / pvscan.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2012 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#include "lvmetad.h"
19#include "lvmcache.h"
20
21int pv_max_name_len = 0;
22int vg_max_name_len = 0;
23
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
70static void _pvscan_display_single(struct cmd_context *cmd,
71 struct physical_volume *pv,
72 void *handle __attribute__((unused)))
73{
74 char uuid[64] __attribute__((aligned(8)));
75 unsigned vg_name_len = 0;
76
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) {
83 log_print("%s", pv_dev_name(pv));
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
100 vg_name_len = strlen(pv_vg_name(pv)) + 1;
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",
109 pv_max_name_len - 2, pv_dev_name(pv), uuid);
110 } else {
111 sprintf(pv_tmp_name, "%s", pv_dev_name(pv));
112 }
113
114 if (is_orphan(pv)) {
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 : " ",
119 display_size(cmd, pv_size(pv)));
120 return;
121 }
122
123 if (pv_status(pv) & EXPORTED_VG) {
124 strncpy(vg_name_this, pv_vg_name(pv), vg_name_len);
125 log_print("PV %-*s is in exported VG %s "
126 "[%s / %s free]",
127 pv_max_name_len, pv_tmp_name,
128 vg_name_this,
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)));
134 return;
135 }
136
137 sprintf(vg_tmp_name, "%s", pv_vg_name(pv));
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 : " ",
141 display_size(cmd, (uint64_t) pv_pe_count(pv) *
142 pv_pe_size(pv)),
143 display_size(cmd, (uint64_t) (pv_pe_count(pv) -
144 pv_pe_alloc_count(pv)) *
145 pv_pe_size(pv)));
146}
147
148static int _pvscan_lvmetad_all_devs(struct cmd_context *cmd)
149{
150 struct dev_iter *iter;
151 struct device *dev;
152 int r = 1;
153
154 if (!(iter = dev_iter_create(cmd->filter, 1))) {
155 log_error("dev_iter creation failed");
156 return 0;
157 }
158
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
181 if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ)) {
182 log_error("Unable to obtain global lock.");
183 return ECMD_FAILED;
184 }
185
186 if (!argc) {
187 if (!_pvscan_lvmetad_all_devs(cmd))
188 ret = ECMD_FAILED;
189 goto out;
190 }
191
192 log_verbose("Using physical volume(s) on command line");
193
194 while (argc--) {
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)) {
211 ret = ECMD_FAILED;
212 break;
213 }
214
215 if (sigint_caught())
216 break;
217 }
218
219out:
220 unlock_vg(cmd, VG_GLOBAL);
221
222 return ret;
223}
224
225int pvscan(struct cmd_context *cmd, int argc, char **argv)
226{
227 int new_pvs_found = 0;
228 int pvs_found = 0;
229
230 struct dm_list *pvslist;
231 struct pv_list *pvl;
232 struct physical_volume *pv;
233
234 uint64_t size_total = 0;
235 uint64_t size_new = 0;
236
237 int len = 0;
238 pv_max_name_len = 0;
239 vg_max_name_len = 0;
240
241 if (arg_count(cmd, cache_ARG))
242 return _pvscan_lvmetad(cmd, argc, argv);
243
244 if (arg_count(cmd, novolumegroup_ARG) && arg_count(cmd, exported_ARG)) {
245 log_error("Options -e and -n are incompatible");
246 return EINVALID_CMD_LINE;
247 }
248
249 if (arg_count(cmd, exported_ARG) || arg_count(cmd, novolumegroup_ARG))
250 log_warn("WARNING: only considering physical volumes %s",
251 arg_count(cmd, exported_ARG) ?
252 "of exported volume group(s)" : "in no volume group");
253
254 if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_WRITE)) {
255 log_error("Unable to obtain global lock.");
256 return ECMD_FAILED;
257 }
258
259 persistent_filter_wipe(cmd->filter);
260 lvmcache_destroy(cmd, 1);
261
262 /* populate lvmcache */
263 if (!lvmetad_vg_list_to_lvmcache(cmd))
264 stack;
265
266 log_verbose("Walking through all physical volumes");
267 if (!(pvslist = get_pvs(cmd))) {
268 unlock_vg(cmd, VG_GLOBAL);
269 stack;
270 return ECMD_FAILED;
271 }
272
273 /* eliminate exported/new if required */
274 dm_list_iterate_items(pvl, pvslist) {
275 pv = pvl->pv;
276
277 if ((arg_count(cmd, exported_ARG)
278 && !(pv_status(pv) & EXPORTED_VG)) ||
279 (arg_count(cmd, novolumegroup_ARG) && (!is_orphan(pv)))) {
280 dm_list_del(&pvl->list);
281 free_pv_fid(pv);
282 continue;
283 }
284
285 /* Also check for MD use? */
286/*******
287 if (MAJOR(pv_create_kdev_t(pv[p]->pv_name)) != MD_MAJOR) {
288 log_warn
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++;
296
297 if (is_orphan(pv)) {
298 new_pvs_found++;
299 size_new += pv_size(pv);
300 size_total += pv_size(pv);
301 } else
302 size_total += (uint64_t) pv_pe_count(pv) * pv_pe_size(pv);
303 }
304
305 /* find maximum pv name length */
306 pv_max_name_len = vg_max_name_len = 0;
307 dm_list_iterate_items(pvl, pvslist) {
308 pv = pvl->pv;
309 len = strlen(pv_dev_name(pv));
310 if (pv_max_name_len < len)
311 pv_max_name_len = len;
312 len = strlen(pv_vg_name(pv));
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
319 dm_list_iterate_items(pvl, pvslist) {
320 _pvscan_display_single(cmd, pvl->pv, NULL);
321 free_pv_fid(pvl->pv);
322 }
323
324 if (!pvs_found) {
325 log_print("No matching physical volumes found");
326 unlock_vg(cmd, VG_GLOBAL);
327 return ECMD_PROCESSED;
328 }
329
330 log_print("Total: %d [%s] / in use: %d [%s] / in no VG: %d [%s]",
331 pvs_found,
332 display_size(cmd, size_total),
333 pvs_found - new_pvs_found,
334 display_size(cmd, (size_total - size_new)),
335 new_pvs_found, display_size(cmd, size_new));
336
337 unlock_vg(cmd, VG_GLOBAL);
338
339 return ECMD_PROCESSED;
340}
This page took 0.022787 seconds and 5 git commands to generate.