Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2001-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 "lib.h"
17 : : #include "metadata.h"
18 : : #include "display.h"
19 : : #include "activate.h"
20 : : #include "toolcontext.h"
21 : : #include "segtype.h"
22 : :
23 : : #define SIZE_BUF 128
24 : :
25 : : typedef enum { SIZE_LONG = 0, SIZE_SHORT = 1, SIZE_UNIT = 2 } size_len_t;
26 : :
27 : : static const struct {
28 : : alloc_policy_t alloc;
29 : : const char str[12]; /* must be changed when size extends 11 chars */
30 : : } _policies[] = {
31 : : {
32 : : ALLOC_CONTIGUOUS, "contiguous"}, {
33 : : ALLOC_CLING, "cling"}, {
34 : : ALLOC_NORMAL, "normal"}, {
35 : : ALLOC_ANYWHERE, "anywhere"}, {
36 : : ALLOC_INHERIT, "inherit"}
37 : : };
38 : :
39 : : static const int _num_policies = sizeof(_policies) / sizeof(*_policies);
40 : :
41 : 3 : uint64_t units_to_bytes(const char *units, char *unit_type)
42 : : {
43 : 3 : char *ptr = NULL;
44 : : uint64_t v;
45 : :
46 [ - + ]: 3 : if (isdigit(*units)) {
47 : 0 : v = (uint64_t) strtod(units, &ptr);
48 [ # # ]: 0 : if (ptr == units)
49 : 0 : return 0;
50 : 0 : units = ptr;
51 : : } else
52 : 3 : v = 1;
53 : :
54 [ + - ]: 3 : if (v == 1)
55 : 3 : *unit_type = *units;
56 : : else
57 : 0 : *unit_type = 'U';
58 : :
59 [ + - - - - : 3 : switch (*units) {
- - - - -
- - - - -
- ]
60 : : case 'h':
61 : : case 'H':
62 : 3 : v = UINT64_C(1);
63 : 3 : *unit_type = *units;
64 : 3 : break;
65 : : case 'b':
66 : : case 'B':
67 : 0 : v *= UINT64_C(1);
68 : 0 : break;
69 : : #define KILO UINT64_C(1024)
70 : : case 's':
71 : : case 'S':
72 : 0 : v *= (KILO/2);
73 : 0 : break;
74 : : case 'k':
75 : 0 : v *= KILO;
76 : 0 : break;
77 : : case 'm':
78 : 0 : v *= KILO * KILO;
79 : 0 : break;
80 : : case 'g':
81 : 0 : v *= KILO * KILO * KILO;
82 : 0 : break;
83 : : case 't':
84 : 0 : v *= KILO * KILO * KILO * KILO;
85 : 0 : break;
86 : : case 'p':
87 : 0 : v *= KILO * KILO * KILO * KILO * KILO;
88 : 0 : break;
89 : : case 'e':
90 : 0 : v *= KILO * KILO * KILO * KILO * KILO * KILO;
91 : 0 : break;
92 : : #undef KILO
93 : : #define KILO UINT64_C(1000)
94 : : case 'K':
95 : 0 : v *= KILO;
96 : 0 : break;
97 : : case 'M':
98 : 0 : v *= KILO * KILO;
99 : 0 : break;
100 : : case 'G':
101 : 0 : v *= KILO * KILO * KILO;
102 : 0 : break;
103 : : case 'T':
104 : 0 : v *= KILO * KILO * KILO * KILO;
105 : 0 : break;
106 : : case 'P':
107 : 0 : v *= KILO * KILO * KILO * KILO * KILO;
108 : 0 : break;
109 : : case 'E':
110 : 0 : v *= KILO * KILO * KILO * KILO * KILO * KILO;
111 : 0 : break;
112 : : #undef KILO
113 : : default:
114 : 0 : return 0;
115 : : }
116 : :
117 [ - + ]: 3 : if (*(units + 1))
118 : 0 : return 0;
119 : :
120 : 3 : return v;
121 : : }
122 : :
123 : 0 : const char *get_alloc_string(alloc_policy_t alloc)
124 : : {
125 : : int i;
126 : :
127 [ # # ]: 0 : for (i = 0; i < _num_policies; i++)
128 [ # # ]: 0 : if (_policies[i].alloc == alloc)
129 : 0 : return _policies[i].str;
130 : :
131 : 0 : return NULL;
132 : : }
133 : :
134 : 0 : alloc_policy_t get_alloc_from_string(const char *str)
135 : : {
136 : : int i;
137 : :
138 [ # # ]: 0 : for (i = 0; i < _num_policies; i++)
139 [ # # ]: 0 : if (!strcmp(_policies[i].str, str))
140 : 0 : return _policies[i].alloc;
141 : :
142 : : /* Special case for old metadata */
143 [ # # ]: 0 : if(!strcmp("next free", str))
144 : 0 : return ALLOC_NORMAL;
145 : :
146 : 0 : log_error("Unrecognised allocation policy %s", str);
147 : 0 : return ALLOC_INVALID;
148 : : }
149 : :
150 : : #define BASE_UNKNOWN 0
151 : : #define BASE_SHARED 1
152 : : #define BASE_1024 7
153 : : #define BASE_1000 13
154 : : #define BASE_SPECIAL 19
155 : : #define NUM_UNIT_PREFIXES 6
156 : : #define NUM_SPECIAL 3
157 : :
158 : : /* Size supplied in sectors */
159 : 0 : static const char *_display_size(const struct cmd_context *cmd,
160 : : uint64_t size, size_len_t sl)
161 : : {
162 : 0 : unsigned base = BASE_UNKNOWN;
163 : : unsigned s;
164 : 0 : int suffix = 1, precision;
165 : 0 : uint64_t byte = UINT64_C(0);
166 : 0 : uint64_t units = UINT64_C(1024);
167 : 0 : char *size_buf = NULL;
168 : : const char * const size_str[][3] = {
169 : : /* BASE_UNKNOWN */
170 : : {" ", " ", " "}, /* [0] */
171 : :
172 : : /* BASE_SHARED - Used if cmd->si_unit_consistency = 0 */
173 : : {" Exabyte", " EB", "E"}, /* [1] */
174 : : {" Petabyte", " PB", "P"}, /* [2] */
175 : : {" Terabyte", " TB", "T"}, /* [3] */
176 : : {" Gigabyte", " GB", "G"}, /* [4] */
177 : : {" Megabyte", " MB", "M"}, /* [5] */
178 : : {" Kilobyte", " KB", "K"}, /* [6] */
179 : :
180 : : /* BASE_1024 - Used if cmd->si_unit_consistency = 1 */
181 : : {" Exbibyte", " EiB", "e"}, /* [7] */
182 : : {" Pebibyte", " PiB", "p"}, /* [8] */
183 : : {" Tebibyte", " TiB", "t"}, /* [9] */
184 : : {" Gibibyte", " GiB", "g"}, /* [10] */
185 : : {" Mebibyte", " MiB", "m"}, /* [11] */
186 : : {" Kibibyte", " KiB", "k"}, /* [12] */
187 : :
188 : : /* BASE_1000 - Used if cmd->si_unit_consistency = 1 */
189 : : {" Exabyte", " EB", "E"}, /* [13] */
190 : : {" Petabyte", " PB", "P"}, /* [14] */
191 : : {" Terabyte", " TB", "T"}, /* [15] */
192 : : {" Gigabyte", " GB", "G"}, /* [16] */
193 : : {" Megabyte", " MB", "M"}, /* [17] */
194 : : {" Kilobyte", " kB", "K"}, /* [18] */
195 : :
196 : : /* BASE_SPECIAL */
197 : : {" Byte ", " B ", "B"}, /* [19] */
198 : : {" Units ", " Un", "U"}, /* [20] */
199 : : {" Sectors ", " Se", "S"}, /* [21] */
200 : 0 : };
201 : :
202 [ # # ]: 0 : if (!(size_buf = dm_pool_alloc(cmd->mem, SIZE_BUF))) {
203 : 0 : log_error("no memory for size display buffer");
204 : 0 : return "";
205 : : }
206 : :
207 : 0 : suffix = cmd->current_settings.suffix;
208 : :
209 [ # # ]: 0 : if (!cmd->si_unit_consistency) {
210 : : /* Case-independent match */
211 [ # # ]: 0 : for (s = 0; s < NUM_UNIT_PREFIXES; s++)
212 [ # # ]: 0 : if (toupper((int) cmd->current_settings.unit_type) ==
213 : 0 : *size_str[BASE_SHARED + s][2]) {
214 : 0 : base = BASE_SHARED;
215 : 0 : break;
216 : : }
217 : : } else {
218 : : /* Case-dependent match for powers of 1000 */
219 [ # # ]: 0 : for (s = 0; s < NUM_UNIT_PREFIXES; s++)
220 [ # # ]: 0 : if (cmd->current_settings.unit_type ==
221 : 0 : *size_str[BASE_1000 + s][2]) {
222 : 0 : base = BASE_1000;
223 : 0 : break;
224 : : }
225 : :
226 : : /* Case-dependent match for powers of 1024 */
227 [ # # ]: 0 : if (base == BASE_UNKNOWN)
228 [ # # ]: 0 : for (s = 0; s < NUM_UNIT_PREFIXES; s++)
229 [ # # ]: 0 : if (cmd->current_settings.unit_type ==
230 : 0 : *size_str[BASE_1024 + s][2]) {
231 : 0 : base = BASE_1024;
232 : 0 : break;
233 : : }
234 : : }
235 : :
236 [ # # ]: 0 : if (base == BASE_UNKNOWN)
237 : : /* Check for special units - s, b or u */
238 [ # # ]: 0 : for (s = 0; s < NUM_SPECIAL; s++)
239 [ # # ]: 0 : if (toupper((int) cmd->current_settings.unit_type) ==
240 : 0 : *size_str[BASE_SPECIAL + s][2]) {
241 : 0 : base = BASE_SPECIAL;
242 : 0 : break;
243 : : }
244 : :
245 [ # # ]: 0 : if (size == UINT64_C(0)) {
246 [ # # ]: 0 : if (base == BASE_UNKNOWN)
247 : 0 : s = 0;
248 [ # # ]: 0 : sprintf(size_buf, "0%s", suffix ? size_str[base + s][sl] : "");
249 : 0 : return size_buf;
250 : : }
251 : :
252 : 0 : size *= UINT64_C(512);
253 : :
254 [ # # ]: 0 : if (base != BASE_UNKNOWN)
255 : 0 : byte = cmd->current_settings.unit_factor;
256 : : else {
257 : : /* Human-readable style */
258 [ # # ]: 0 : if (cmd->current_settings.unit_type == 'H') {
259 : 0 : units = UINT64_C(1000);
260 : 0 : base = BASE_1000;
261 : : } else {
262 : 0 : units = UINT64_C(1024);
263 : 0 : base = BASE_1024;
264 : : }
265 : :
266 [ # # ]: 0 : if (!cmd->si_unit_consistency)
267 : 0 : base = BASE_SHARED;
268 : :
269 : 0 : byte = units * units * units * units * units * units;
270 : :
271 [ # # ][ # # ]: 0 : for (s = 0; s < NUM_UNIT_PREFIXES && size < byte; s++)
272 : 0 : byte /= units;
273 : :
274 : 0 : suffix = 1;
275 : : }
276 : :
277 : : /* FIXME Make precision configurable */
278 [ # # ]: 0 : switch(toupper((int) cmd->current_settings.unit_type)) {
279 : : case 'B':
280 : : case 'S':
281 : 0 : precision = 0;
282 : 0 : break;
283 : : default:
284 : 0 : precision = 2;
285 : : }
286 : :
287 [ # # ]: 0 : snprintf(size_buf, SIZE_BUF - 1, "%.*f%s", precision,
288 : 0 : (double) size / byte, suffix ? size_str[base + s][sl] : "");
289 : :
290 : 0 : return size_buf;
291 : : }
292 : :
293 : 0 : const char *display_size_long(const struct cmd_context *cmd, uint64_t size)
294 : : {
295 : 0 : return _display_size(cmd, size, SIZE_LONG);
296 : : }
297 : :
298 : 0 : const char *display_size_units(const struct cmd_context *cmd, uint64_t size)
299 : : {
300 : 0 : return _display_size(cmd, size, SIZE_UNIT);
301 : : }
302 : :
303 : 0 : const char *display_size(const struct cmd_context *cmd, uint64_t size)
304 : : {
305 : 0 : return _display_size(cmd, size, SIZE_SHORT);
306 : : }
307 : :
308 : 0 : void pvdisplay_colons(const struct physical_volume *pv)
309 : : {
310 : : char uuid[64] __attribute((aligned(8)));
311 : :
312 [ # # ]: 0 : if (!pv)
313 : 0 : return;
314 : :
315 [ # # ]: 0 : if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
316 : 0 : stack;
317 : 0 : return;
318 : : }
319 : :
320 [ # # ]: 0 : log_print("%s:%s:%" PRIu64 ":-1:%" PRIu64 ":%" PRIu64 ":-1:%" PRIu32 ":%u:%u:%u:%s",
321 : : pv_dev_name(pv), pv->vg_name, pv->size,
322 : : /* FIXME pv->pv_number, Derive or remove? */
323 : : pv->status, /* FIXME Support old or new format here? */
324 : : pv->status & ALLOCATABLE_PV, /* FIXME remove? */
325 : : /* FIXME pv->lv_cur, Remove? */
326 : : pv->pe_size / 2,
327 : : pv->pe_count,
328 : : pv->pe_count - pv->pe_alloc_count,
329 : : pv->pe_alloc_count, *uuid ? uuid : "none");
330 : : }
331 : :
332 : 0 : void pvdisplay_segments(const struct physical_volume *pv)
333 : : {
334 : : const struct pv_segment *pvseg;
335 : :
336 [ # # ]: 0 : if (pv->pe_size)
337 : 0 : log_print("--- Physical Segments ---");
338 : :
339 [ # # ]: 0 : dm_list_iterate_items(pvseg, &pv->segments) {
340 : 0 : log_print("Physical extent %u to %u:",
341 : : pvseg->pe, pvseg->pe + pvseg->len - 1);
342 : :
343 [ # # ]: 0 : if (pvseg_is_allocated(pvseg)) {
344 : 0 : log_print(" Logical volume\t%s%s/%s",
345 : : pvseg->lvseg->lv->vg->cmd->dev_dir,
346 : : pvseg->lvseg->lv->vg->name,
347 : : pvseg->lvseg->lv->name);
348 : 0 : log_print(" Logical extents\t%d to %d",
349 : : pvseg->lvseg->le, pvseg->lvseg->le +
350 : : pvseg->lvseg->len - 1);
351 : : } else
352 : 0 : log_print(" FREE");
353 : : }
354 : :
355 : 0 : log_print(" ");
356 : 0 : }
357 : :
358 : : /* FIXME Include label fields */
359 : 0 : void pvdisplay_full(const struct cmd_context *cmd,
360 : : const struct physical_volume *pv,
361 : : void *handle __attribute((unused)))
362 : : {
363 : : char uuid[64] __attribute((aligned(8)));
364 : : const char *size;
365 : :
366 : : uint32_t pe_free;
367 : : uint64_t data_size, pvsize, unusable;
368 : :
369 [ # # ]: 0 : if (!pv)
370 : 0 : return;
371 : :
372 [ # # ]: 0 : if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
373 : 0 : stack;
374 : 0 : return;
375 : : }
376 : :
377 [ # # ]: 0 : log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
378 : 0 : log_print("PV Name %s", pv_dev_name(pv));
379 [ # # ][ # # ]: 0 : log_print("VG Name %s%s",
380 : : is_orphan(pv) ? "" : pv->vg_name,
381 : : pv->status & EXPORTED_VG ? " (exported)" : "");
382 : :
383 : 0 : data_size = (uint64_t) pv->pe_count * pv->pe_size;
384 [ # # ]: 0 : if (pv->size > data_size + pv->pe_start) {
385 : 0 : pvsize = pv->size;
386 : 0 : unusable = pvsize - data_size;
387 : : } else {
388 : 0 : pvsize = data_size + pv->pe_start;
389 : 0 : unusable = pvsize - pv->size;
390 : : }
391 : :
392 : 0 : size = display_size(cmd, pvsize);
393 [ # # ]: 0 : if (data_size)
394 : 0 : log_print("PV Size %s / not usable %s", /* [LVM: %s]", */
395 : : size, display_size(cmd, unusable));
396 : : else
397 : 0 : log_print("PV Size %s", size);
398 : :
399 : : /* PV number not part of LVM2 design
400 : : log_print("PV# %u", pv->pv_number);
401 : : */
402 : :
403 : 0 : pe_free = pv->pe_count - pv->pe_alloc_count;
404 [ # # ][ # # ]: 0 : if (pv->pe_count && (pv->status & ALLOCATABLE_PV))
405 [ # # ][ # # ]: 0 : log_print("Allocatable yes %s",
406 : : (!pe_free && pv->pe_count) ? "(but full)" : "");
407 : : else
408 : 0 : log_print("Allocatable NO");
409 : :
410 : : /* LV count is no longer available when displaying PV
411 : : log_print("Cur LV %u", vg->lv_count);
412 : : */
413 : :
414 [ # # ]: 0 : if (cmd->si_unit_consistency)
415 : 0 : log_print("PE Size %s", display_size(cmd, (uint64_t) pv->pe_size));
416 : : else
417 : 0 : log_print("PE Size (KByte) %" PRIu32, pv->pe_size / 2);
418 : :
419 : 0 : log_print("Total PE %u", pv->pe_count);
420 : 0 : log_print("Free PE %" PRIu32, pe_free);
421 : 0 : log_print("Allocated PE %u", pv->pe_alloc_count);
422 [ # # ]: 0 : log_print("PV UUID %s", *uuid ? uuid : "none");
423 : 0 : log_print(" ");
424 : : }
425 : :
426 : 0 : int pvdisplay_short(const struct cmd_context *cmd __attribute((unused)),
427 : : const struct volume_group *vg __attribute((unused)),
428 : : const struct physical_volume *pv,
429 : : void *handle __attribute((unused)))
430 : : {
431 : : char uuid[64] __attribute((aligned(8)));
432 : :
433 [ # # ]: 0 : if (!pv)
434 : 0 : return 0;
435 : :
436 [ # # ]: 0 : if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
437 : 0 : return_0;
438 : :
439 : 0 : log_print("PV Name %s ", pv_dev_name(pv));
440 : : /* FIXME pv->pv_number); */
441 [ # # ]: 0 : log_print("PV UUID %s", *uuid ? uuid : "none");
442 [ # # ]: 0 : log_print("PV Status %sallocatable",
443 : : (pv->status & ALLOCATABLE_PV) ? "" : "NOT ");
444 : 0 : log_print("Total PE / Free PE %u / %u",
445 : : pv->pe_count, pv->pe_count - pv->pe_alloc_count);
446 : :
447 : 0 : log_print(" ");
448 : 0 : return 0;
449 : : }
450 : :
451 : 0 : void lvdisplay_colons(const struct logical_volume *lv)
452 : : {
453 : : int inkernel;
454 : : struct lvinfo info;
455 [ # # ][ # # ]: 0 : inkernel = lv_info(lv->vg->cmd, lv, &info, 1, 0) && info.exists;
456 : :
457 [ # # ][ # # ]: 0 : log_print("%s%s/%s:%s:%" PRIu64 ":%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
[ # # ][ # # ]
458 : : lv->vg->cmd->dev_dir,
459 : : lv->vg->name,
460 : : lv->name,
461 : : lv->vg->name,
462 : : (lv->status & (LVM_READ | LVM_WRITE)) >> 8, inkernel ? 1 : 0,
463 : : /* FIXME lv->lv_number, */
464 : : inkernel ? info.open_count : 0, lv->size, lv->le_count,
465 : : /* FIXME Add num allocated to struct! lv->lv_allocated_le, */
466 : : (lv->alloc == ALLOC_CONTIGUOUS ? 2 : 0), lv->read_ahead,
467 : : inkernel ? info.major : -1, inkernel ? info.minor : -1);
468 : 0 : }
469 : :
470 : 0 : int lvdisplay_full(struct cmd_context *cmd,
471 : : const struct logical_volume *lv,
472 : : void *handle __attribute((unused)))
473 : : {
474 : : struct lvinfo info;
475 : 0 : int inkernel, snap_active = 0;
476 : : char uuid[64] __attribute((aligned(8)));
477 : 0 : struct lv_segment *snap_seg = NULL, *mirror_seg = NULL;
478 : : float snap_percent; /* fused, fsize; */
479 : : percent_range_t percent_range;
480 : :
481 [ # # ]: 0 : if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid)))
482 : 0 : return_0;
483 : :
484 [ # # ][ # # ]: 0 : inkernel = lv_info(cmd, lv, &info, 1, 1) && info.exists;
485 : :
486 : 0 : log_print("--- Logical volume ---");
487 : :
488 : 0 : log_print("LV Name %s%s/%s", lv->vg->cmd->dev_dir,
489 : : lv->vg->name, lv->name);
490 : 0 : log_print("VG Name %s", lv->vg->name);
491 : :
492 : 0 : log_print("LV UUID %s", uuid);
493 : :
494 [ # # ]: 0 : log_print("LV Write Access %s",
495 : : (lv->status & LVM_WRITE) ? "read/write" : "read only");
496 : :
497 [ # # ]: 0 : if (lv_is_origin(lv)) {
498 : 0 : log_print("LV snapshot status source of");
499 : :
500 [ # # ]: 0 : dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs,
501 : : origin_list) {
502 [ # # # # ]: 0 : if (inkernel &&
503 : 0 : (snap_active = lv_snapshot_percent(snap_seg->cow,
504 : : &snap_percent,
505 : : &percent_range)))
506 [ # # ]: 0 : if (percent_range == PERCENT_INVALID)
507 : 0 : snap_active = 0;
508 [ # # ]: 0 : log_print(" %s%s/%s [%s]",
509 : : lv->vg->cmd->dev_dir, lv->vg->name,
510 : : snap_seg->cow->name,
511 : : snap_active ? "active" : "INACTIVE");
512 : : }
513 : 0 : snap_seg = NULL;
514 [ # # ]: 0 : } else if ((snap_seg = find_cow(lv))) {
515 [ # # # # ]: 0 : if (inkernel &&
516 : 0 : (snap_active = lv_snapshot_percent(snap_seg->cow,
517 : : &snap_percent,
518 : : &percent_range)))
519 [ # # ]: 0 : if (percent_range == PERCENT_INVALID)
520 : 0 : snap_active = 0;
521 : :
522 [ # # ]: 0 : log_print("LV snapshot status %s destination for %s%s/%s",
523 : : snap_active ? "active" : "INACTIVE",
524 : : lv->vg->cmd->dev_dir, lv->vg->name,
525 : : snap_seg->origin->name);
526 : : }
527 : :
528 [ # # ][ # # ]: 0 : if (inkernel && info.suspended)
529 : 0 : log_print("LV Status suspended");
530 : : else
531 [ # # ]: 0 : log_print("LV Status %savailable",
532 : : inkernel ? "" : "NOT ");
533 : :
534 : : /********* FIXME lv_number
535 : : log_print("LV # %u", lv->lv_number + 1);
536 : : ************/
537 : :
538 [ # # ]: 0 : if (inkernel)
539 : 0 : log_print("# open %u", info.open_count);
540 : :
541 [ # # ]: 0 : log_print("LV Size %s",
542 : : display_size(cmd,
543 : : snap_seg ? snap_seg->origin->size : lv->size));
544 : :
545 [ # # ]: 0 : log_print("Current LE %u",
546 : : snap_seg ? snap_seg->origin->le_count : lv->le_count);
547 : :
548 [ # # ]: 0 : if (snap_seg) {
549 : 0 : log_print("COW-table size %s",
550 : : display_size(cmd, (uint64_t) lv->size));
551 : 0 : log_print("COW-table LE %u", lv->le_count);
552 : :
553 [ # # ]: 0 : if (snap_active)
554 : 0 : log_print("Allocated to snapshot %.2f%% ", snap_percent);
555 : :
556 : 0 : log_print("Snapshot chunk size %s",
557 : : display_size(cmd, (uint64_t) snap_seg->chunk_size));
558 : : }
559 : :
560 [ # # ]: 0 : if (lv->status & MIRRORED) {
561 : 0 : mirror_seg = first_seg(lv);
562 : 0 : log_print("Mirrored volumes %" PRIu32, mirror_seg->area_count);
563 [ # # ]: 0 : if (lv->status & CONVERTING)
564 : 0 : log_print("LV type Mirror undergoing conversion");
565 : : }
566 : :
567 : 0 : log_print("Segments %u", dm_list_size(&lv->segments));
568 : :
569 : : /********* FIXME Stripes & stripesize for each segment
570 : : log_print("Stripe size %s", display_size(cmd, (uint64_t) lv->stripesize));
571 : : ***********/
572 : :
573 : 0 : log_print("Allocation %s", get_alloc_string(lv->alloc));
574 [ # # ]: 0 : if (lv->read_ahead == DM_READ_AHEAD_AUTO)
575 : 0 : log_print("Read ahead sectors auto");
576 [ # # ]: 0 : else if (lv->read_ahead == DM_READ_AHEAD_NONE)
577 : 0 : log_print("Read ahead sectors 0");
578 : : else
579 : 0 : log_print("Read ahead sectors %u", lv->read_ahead);
580 : :
581 [ # # ][ # # ]: 0 : if (inkernel && lv->read_ahead != info.read_ahead)
582 : 0 : log_print("- currently set to %u", info.read_ahead);
583 : :
584 [ # # ]: 0 : if (lv->status & FIXED_MINOR) {
585 [ # # ]: 0 : if (lv->major >= 0)
586 : 0 : log_print("Persistent major %d", lv->major);
587 : 0 : log_print("Persistent minor %d", lv->minor);
588 : : }
589 : :
590 [ # # ]: 0 : if (inkernel)
591 : 0 : log_print("Block device %d:%d", info.major,
592 : : info.minor);
593 : :
594 : 0 : log_print(" ");
595 : :
596 : 0 : return 0;
597 : : }
598 : :
599 : 0 : void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre)
600 : : {
601 [ # # # # ]: 0 : switch (seg_type(seg, s)) {
602 : : case AREA_PV:
603 : : /* FIXME Re-check the conditions for 'Missing' */
604 [ # # ]: 0 : log_print("%sPhysical volume\t%s", pre,
605 : : seg_pv(seg, s) ?
606 : : pv_dev_name(seg_pv(seg, s)) :
607 : : "Missing");
608 : :
609 [ # # ]: 0 : if (seg_pv(seg, s))
610 : 0 : log_print("%sPhysical extents\t%d to %d", pre,
611 : : seg_pe(seg, s),
612 : : seg_pe(seg, s) + seg->area_len - 1);
613 : 0 : break;
614 : : case AREA_LV:
615 [ # # ]: 0 : log_print("%sLogical volume\t%s", pre,
616 : : seg_lv(seg, s) ?
617 : : seg_lv(seg, s)->name : "Missing");
618 : :
619 [ # # ]: 0 : if (seg_lv(seg, s))
620 : 0 : log_print("%sLogical extents\t%d to %d", pre,
621 : : seg_le(seg, s),
622 : : seg_le(seg, s) + seg->area_len - 1);
623 : 0 : break;
624 : : case AREA_UNASSIGNED:
625 : 0 : log_print("%sUnassigned area", pre);
626 : : }
627 : 0 : }
628 : :
629 : 0 : int lvdisplay_segments(const struct logical_volume *lv)
630 : : {
631 : : const struct lv_segment *seg;
632 : :
633 : 0 : log_print("--- Segments ---");
634 : :
635 [ # # ]: 0 : dm_list_iterate_items(seg, &lv->segments) {
636 : 0 : log_print("Logical extent %u to %u:",
637 : : seg->le, seg->le + seg->len - 1);
638 : :
639 : 0 : log_print(" Type\t\t%s", seg->segtype->ops->name(seg));
640 : :
641 [ # # ]: 0 : if (seg->segtype->ops->display)
642 : 0 : seg->segtype->ops->display(seg);
643 : : }
644 : :
645 : 0 : log_print(" ");
646 : 0 : return 1;
647 : : }
648 : :
649 : 0 : void vgdisplay_extents(const struct volume_group *vg __attribute((unused)))
650 : : {
651 : 0 : }
652 : :
653 : 0 : void vgdisplay_full(const struct volume_group *vg)
654 : : {
655 : : uint32_t access_str;
656 : : uint32_t active_pvs;
657 : : char uuid[64] __attribute((aligned(8)));
658 : :
659 : 0 : active_pvs = vg->pv_count - vg_missing_pv_count(vg);
660 : :
661 : 0 : log_print("--- Volume group ---");
662 : 0 : log_print("VG Name %s", vg->name);
663 : 0 : log_print("System ID %s", vg->system_id);
664 : 0 : log_print("Format %s", vg->fid->fmt->name);
665 [ # # ]: 0 : if (vg->fid->fmt->features & FMT_MDAS) {
666 : 0 : log_print("Metadata Areas %d",
667 : : dm_list_size(&vg->fid->metadata_areas));
668 : 0 : log_print("Metadata Sequence No %d", vg->seqno);
669 : : }
670 : 0 : access_str = vg->status & (LVM_READ | LVM_WRITE);
671 [ # # ][ # # ]: 0 : log_print("VG Access %s%s%s%s",
[ # # ][ # # ]
672 : : access_str == (LVM_READ | LVM_WRITE) ? "read/write" : "",
673 : : access_str == LVM_READ ? "read" : "",
674 : : access_str == LVM_WRITE ? "write" : "",
675 : : access_str == 0 ? "error" : "");
676 [ # # ][ # # ]: 0 : log_print("VG Status %s%sresizable",
677 : : vg_is_exported(vg) ? "exported/" : "",
678 : : vg_is_resizeable(vg) ? "" : "NOT ");
679 : : /* vg number not part of LVM2 design
680 : : log_print ("VG # %u\n", vg->vg_number);
681 : : */
682 [ # # ]: 0 : if (vg_is_clustered(vg)) {
683 : 0 : log_print("Clustered yes");
684 [ # # ]: 0 : log_print("Shared %s",
685 : : vg->status & SHARED ? "yes" : "no");
686 : : }
687 : :
688 : 0 : log_print("MAX LV %u", vg->max_lv);
689 : 0 : log_print("Cur LV %u", vg_visible_lvs(vg));
690 : 0 : log_print("Open LV %u", lvs_in_vg_opened(vg));
691 : : /****** FIXME Max LV Size
692 : : log_print ( "MAX LV Size %s",
693 : : ( s1 = display_size ( LVM_LV_SIZE_MAX(vg))));
694 : : free ( s1);
695 : : *********/
696 : 0 : log_print("Max PV %u", vg->max_pv);
697 : 0 : log_print("Cur PV %u", vg->pv_count);
698 : 0 : log_print("Act PV %u", active_pvs);
699 : :
700 : 0 : log_print("VG Size %s",
701 : : display_size(vg->cmd,
702 : : (uint64_t) vg->extent_count * vg->extent_size));
703 : :
704 : 0 : log_print("PE Size %s",
705 : : display_size(vg->cmd, (uint64_t) vg->extent_size));
706 : :
707 : 0 : log_print("Total PE %u", vg->extent_count);
708 : :
709 : 0 : log_print("Alloc PE / Size %u / %s",
710 : : vg->extent_count - vg->free_count,
711 : : display_size(vg->cmd,
712 : : ((uint64_t) vg->extent_count - vg->free_count) *
713 : : vg->extent_size));
714 : :
715 : 0 : log_print("Free PE / Size %u / %s", vg->free_count,
716 : : display_size(vg->cmd, vg_free(vg)));
717 : :
718 [ # # ]: 0 : if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
719 : 0 : stack;
720 : 0 : return;
721 : : }
722 : :
723 : 0 : log_print("VG UUID %s", uuid);
724 : 0 : log_print(" ");
725 : : }
726 : :
727 : 0 : void vgdisplay_colons(const struct volume_group *vg)
728 : : {
729 : : uint32_t active_pvs;
730 : : const char *access_str;
731 : : char uuid[64] __attribute((aligned(8)));
732 : :
733 : 0 : active_pvs = vg->pv_count - vg_missing_pv_count(vg);
734 : :
735 [ # # # # ]: 0 : switch (vg->status & (LVM_READ | LVM_WRITE)) {
736 : : case LVM_READ | LVM_WRITE:
737 : 0 : access_str = "r/w";
738 : 0 : break;
739 : : case LVM_READ:
740 : 0 : access_str = "r";
741 : 0 : break;
742 : : case LVM_WRITE:
743 : 0 : access_str = "w";
744 : 0 : break;
745 : : default:
746 : 0 : access_str = "";
747 : : }
748 : :
749 [ # # ]: 0 : if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
750 : 0 : stack;
751 : 0 : return;
752 : : }
753 : :
754 [ # # ]: 0 : log_print("%s:%s:%" PRIu64 ":-1:%u:%u:%u:-1:%u:%u:%u:%" PRIu64 ":%" PRIu32
755 : : ":%u:%u:%u:%s",
756 : : vg->name,
757 : : access_str,
758 : : vg->status,
759 : : /* internal volume group number; obsolete */
760 : : vg->max_lv,
761 : : vg_visible_lvs(vg),
762 : : lvs_in_vg_opened(vg),
763 : : /* FIXME: maximum logical volume size */
764 : : vg->max_pv,
765 : : vg->pv_count,
766 : : active_pvs,
767 : : (uint64_t) vg->extent_count * (vg->extent_size / 2),
768 : : vg->extent_size / 2,
769 : : vg->extent_count,
770 : : vg->extent_count - vg->free_count,
771 : : vg->free_count,
772 : : uuid[0] ? uuid : "none");
773 : : }
774 : :
775 : 0 : void vgdisplay_short(const struct volume_group *vg)
776 : : {
777 : 0 : log_print("\"%s\" %-9s [%-9s used / %s free]", vg->name,
778 : : /********* FIXME if "open" print "/used" else print "/idle"??? ******/
779 : : display_size(vg->cmd,
780 : : (uint64_t) vg->extent_count * vg->extent_size),
781 : : display_size(vg->cmd,
782 : : ((uint64_t) vg->extent_count -
783 : : vg->free_count) * vg->extent_size),
784 : : display_size(vg->cmd, vg_free(vg)));
785 : 0 : }
786 : :
787 : 0 : void display_formats(const struct cmd_context *cmd)
788 : : {
789 : : const struct format_type *fmt;
790 : :
791 [ # # ]: 0 : dm_list_iterate_items(fmt, &cmd->formats) {
792 : 0 : log_print("%s", fmt->name);
793 : : }
794 : 0 : }
795 : :
796 : 0 : void display_segtypes(const struct cmd_context *cmd)
797 : : {
798 : : const struct segment_type *segtype;
799 : :
800 [ # # ]: 0 : dm_list_iterate_items(segtype, &cmd->segtypes) {
801 : 0 : log_print("%s", segtype->name);
802 : : }
803 : 0 : }
804 : :
805 : 0 : char yes_no_prompt(const char *prompt, ...)
806 : : {
807 : 0 : int c = 0, ret = 0;
808 : : va_list ap;
809 : :
810 : 0 : sigint_allow();
811 : : do {
812 [ # # ][ # # ]: 0 : if (c == '\n' || !c) {
813 : 0 : va_start(ap, prompt);
814 : 0 : vprintf(prompt, ap);
815 : 0 : va_end(ap);
816 : 0 : fflush(stdout);
817 : : }
818 : :
819 [ # # ]: 0 : if ((c = getchar()) == EOF) {
820 : 0 : ret = 'n';
821 : 0 : break;
822 : : }
823 : :
824 : 0 : c = tolower(c);
825 [ # # ][ # # ]: 0 : if ((c == 'y') || (c == 'n'))
826 : 0 : ret = c;
827 [ # # ][ # # ]: 0 : } while (!ret || c != '\n');
828 : :
829 : 0 : sigint_restore();
830 : :
831 [ # # ]: 0 : if (c != '\n')
832 : 0 : printf("\n");
833 : :
834 : 0 : return ret;
835 : : }
836 : :
|