1*7c604eeaShaad /* $NetBSD: display.c,v 1.1.1.3 2009/12/02 00:26:43 haad Exp $ */
256a34939Shaad
356a34939Shaad /*
456a34939Shaad * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
556a34939Shaad * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
656a34939Shaad *
756a34939Shaad * This file is part of LVM2.
856a34939Shaad *
956a34939Shaad * This copyrighted material is made available to anyone wishing to use,
1056a34939Shaad * modify, copy, or redistribute it subject to the terms and conditions
1156a34939Shaad * of the GNU Lesser General Public License v.2.1.
1256a34939Shaad *
1356a34939Shaad * You should have received a copy of the GNU Lesser General Public License
1456a34939Shaad * along with this program; if not, write to the Free Software Foundation,
1556a34939Shaad * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1656a34939Shaad */
1756a34939Shaad
1856a34939Shaad #include "lib.h"
1956a34939Shaad #include "metadata.h"
2056a34939Shaad #include "display.h"
2156a34939Shaad #include "activate.h"
2256a34939Shaad #include "toolcontext.h"
2356a34939Shaad #include "segtype.h"
2456a34939Shaad
2556a34939Shaad #define SIZE_BUF 128
2656a34939Shaad
2756a34939Shaad typedef enum { SIZE_LONG = 0, SIZE_SHORT = 1, SIZE_UNIT = 2 } size_len_t;
2856a34939Shaad
2956a34939Shaad static const struct {
3056a34939Shaad alloc_policy_t alloc;
3156a34939Shaad const char str[12]; /* must be changed when size extends 11 chars */
3256a34939Shaad } _policies[] = {
3356a34939Shaad {
3456a34939Shaad ALLOC_CONTIGUOUS, "contiguous"}, {
3556a34939Shaad ALLOC_CLING, "cling"}, {
3656a34939Shaad ALLOC_NORMAL, "normal"}, {
3756a34939Shaad ALLOC_ANYWHERE, "anywhere"}, {
3856a34939Shaad ALLOC_INHERIT, "inherit"}
3956a34939Shaad };
4056a34939Shaad
4156a34939Shaad static const int _num_policies = sizeof(_policies) / sizeof(*_policies);
4256a34939Shaad
units_to_bytes(const char * units,char * unit_type)4356a34939Shaad uint64_t units_to_bytes(const char *units, char *unit_type)
4456a34939Shaad {
4556a34939Shaad char *ptr = NULL;
4656a34939Shaad uint64_t v;
4756a34939Shaad
4856a34939Shaad if (isdigit(*units)) {
4956a34939Shaad v = (uint64_t) strtod(units, &ptr);
5056a34939Shaad if (ptr == units)
5156a34939Shaad return 0;
5256a34939Shaad units = ptr;
5356a34939Shaad } else
5456a34939Shaad v = 1;
5556a34939Shaad
5656a34939Shaad if (v == 1)
5756a34939Shaad *unit_type = *units;
5856a34939Shaad else
5956a34939Shaad *unit_type = 'U';
6056a34939Shaad
6156a34939Shaad switch (*units) {
6256a34939Shaad case 'h':
6356a34939Shaad case 'H':
6456a34939Shaad v = UINT64_C(1);
6556a34939Shaad *unit_type = *units;
6656a34939Shaad break;
6756a34939Shaad case 'b':
6856a34939Shaad case 'B':
6956a34939Shaad v *= UINT64_C(1);
7056a34939Shaad break;
7156a34939Shaad #define KILO UINT64_C(1024)
72*7c604eeaShaad case 's':
73*7c604eeaShaad case 'S':
74*7c604eeaShaad v *= (KILO/2);
75*7c604eeaShaad break;
7656a34939Shaad case 'k':
7756a34939Shaad v *= KILO;
7856a34939Shaad break;
7956a34939Shaad case 'm':
8056a34939Shaad v *= KILO * KILO;
8156a34939Shaad break;
8256a34939Shaad case 'g':
8356a34939Shaad v *= KILO * KILO * KILO;
8456a34939Shaad break;
8556a34939Shaad case 't':
8656a34939Shaad v *= KILO * KILO * KILO * KILO;
8756a34939Shaad break;
8856a34939Shaad case 'p':
8956a34939Shaad v *= KILO * KILO * KILO * KILO * KILO;
9056a34939Shaad break;
9156a34939Shaad case 'e':
9256a34939Shaad v *= KILO * KILO * KILO * KILO * KILO * KILO;
9356a34939Shaad break;
9456a34939Shaad #undef KILO
9556a34939Shaad #define KILO UINT64_C(1000)
9656a34939Shaad case 'K':
9756a34939Shaad v *= KILO;
9856a34939Shaad break;
9956a34939Shaad case 'M':
10056a34939Shaad v *= KILO * KILO;
10156a34939Shaad break;
10256a34939Shaad case 'G':
10356a34939Shaad v *= KILO * KILO * KILO;
10456a34939Shaad break;
10556a34939Shaad case 'T':
10656a34939Shaad v *= KILO * KILO * KILO * KILO;
10756a34939Shaad break;
10856a34939Shaad case 'P':
10956a34939Shaad v *= KILO * KILO * KILO * KILO * KILO;
11056a34939Shaad break;
11156a34939Shaad case 'E':
11256a34939Shaad v *= KILO * KILO * KILO * KILO * KILO * KILO;
11356a34939Shaad break;
11456a34939Shaad #undef KILO
11556a34939Shaad default:
11656a34939Shaad return 0;
11756a34939Shaad }
11856a34939Shaad
11956a34939Shaad if (*(units + 1))
12056a34939Shaad return 0;
12156a34939Shaad
12256a34939Shaad return v;
12356a34939Shaad }
12456a34939Shaad
get_alloc_string(alloc_policy_t alloc)12556a34939Shaad const char *get_alloc_string(alloc_policy_t alloc)
12656a34939Shaad {
12756a34939Shaad int i;
12856a34939Shaad
12956a34939Shaad for (i = 0; i < _num_policies; i++)
13056a34939Shaad if (_policies[i].alloc == alloc)
13156a34939Shaad return _policies[i].str;
13256a34939Shaad
13356a34939Shaad return NULL;
13456a34939Shaad }
13556a34939Shaad
get_alloc_from_string(const char * str)13656a34939Shaad alloc_policy_t get_alloc_from_string(const char *str)
13756a34939Shaad {
13856a34939Shaad int i;
13956a34939Shaad
14056a34939Shaad for (i = 0; i < _num_policies; i++)
14156a34939Shaad if (!strcmp(_policies[i].str, str))
14256a34939Shaad return _policies[i].alloc;
14356a34939Shaad
14456a34939Shaad /* Special case for old metadata */
14556a34939Shaad if(!strcmp("next free", str))
14656a34939Shaad return ALLOC_NORMAL;
14756a34939Shaad
14856a34939Shaad log_error("Unrecognised allocation policy %s", str);
14956a34939Shaad return ALLOC_INVALID;
15056a34939Shaad }
15156a34939Shaad
152*7c604eeaShaad #define BASE_UNKNOWN 0
153*7c604eeaShaad #define BASE_SHARED 1
154*7c604eeaShaad #define BASE_1024 7
155*7c604eeaShaad #define BASE_1000 13
156*7c604eeaShaad #define BASE_SPECIAL 19
157*7c604eeaShaad #define NUM_UNIT_PREFIXES 6
158*7c604eeaShaad #define NUM_SPECIAL 3
159*7c604eeaShaad
16056a34939Shaad /* Size supplied in sectors */
_display_size(const struct cmd_context * cmd,uint64_t size,size_len_t sl)16156a34939Shaad static const char *_display_size(const struct cmd_context *cmd,
16256a34939Shaad uint64_t size, size_len_t sl)
16356a34939Shaad {
164*7c604eeaShaad unsigned base = BASE_UNKNOWN;
165*7c604eeaShaad unsigned s;
16656a34939Shaad int suffix = 1, precision;
16756a34939Shaad uint64_t byte = UINT64_C(0);
16856a34939Shaad uint64_t units = UINT64_C(1024);
16956a34939Shaad char *size_buf = NULL;
17056a34939Shaad const char * const size_str[][3] = {
171*7c604eeaShaad /* BASE_UNKNOWN */
172*7c604eeaShaad {" ", " ", " "}, /* [0] */
173*7c604eeaShaad
174*7c604eeaShaad /* BASE_SHARED - Used if cmd->si_unit_consistency = 0 */
175*7c604eeaShaad {" Exabyte", " EB", "E"}, /* [1] */
176*7c604eeaShaad {" Petabyte", " PB", "P"}, /* [2] */
177*7c604eeaShaad {" Terabyte", " TB", "T"}, /* [3] */
178*7c604eeaShaad {" Gigabyte", " GB", "G"}, /* [4] */
179*7c604eeaShaad {" Megabyte", " MB", "M"}, /* [5] */
180*7c604eeaShaad {" Kilobyte", " KB", "K"}, /* [6] */
181*7c604eeaShaad
182*7c604eeaShaad /* BASE_1024 - Used if cmd->si_unit_consistency = 1 */
183*7c604eeaShaad {" Exbibyte", " EiB", "e"}, /* [7] */
184*7c604eeaShaad {" Pebibyte", " PiB", "p"}, /* [8] */
185*7c604eeaShaad {" Tebibyte", " TiB", "t"}, /* [9] */
186*7c604eeaShaad {" Gibibyte", " GiB", "g"}, /* [10] */
187*7c604eeaShaad {" Mebibyte", " MiB", "m"}, /* [11] */
188*7c604eeaShaad {" Kibibyte", " KiB", "k"}, /* [12] */
189*7c604eeaShaad
190*7c604eeaShaad /* BASE_1000 - Used if cmd->si_unit_consistency = 1 */
191*7c604eeaShaad {" Exabyte", " EB", "E"}, /* [13] */
192*7c604eeaShaad {" Petabyte", " PB", "P"}, /* [14] */
193*7c604eeaShaad {" Terabyte", " TB", "T"}, /* [15] */
194*7c604eeaShaad {" Gigabyte", " GB", "G"}, /* [16] */
195*7c604eeaShaad {" Megabyte", " MB", "M"}, /* [17] */
196*7c604eeaShaad {" Kilobyte", " kB", "K"}, /* [18] */
197*7c604eeaShaad
198*7c604eeaShaad /* BASE_SPECIAL */
199*7c604eeaShaad {" Byte ", " B ", "B"}, /* [19] */
200*7c604eeaShaad {" Units ", " Un", "U"}, /* [20] */
201*7c604eeaShaad {" Sectors ", " Se", "S"}, /* [21] */
20256a34939Shaad };
20356a34939Shaad
20456a34939Shaad if (!(size_buf = dm_pool_alloc(cmd->mem, SIZE_BUF))) {
20556a34939Shaad log_error("no memory for size display buffer");
20656a34939Shaad return "";
20756a34939Shaad }
20856a34939Shaad
20956a34939Shaad suffix = cmd->current_settings.suffix;
21056a34939Shaad
211*7c604eeaShaad if (!cmd->si_unit_consistency) {
212*7c604eeaShaad /* Case-independent match */
213*7c604eeaShaad for (s = 0; s < NUM_UNIT_PREFIXES; s++)
21456a34939Shaad if (toupper((int) cmd->current_settings.unit_type) ==
215*7c604eeaShaad *size_str[BASE_SHARED + s][2]) {
216*7c604eeaShaad base = BASE_SHARED;
21756a34939Shaad break;
218*7c604eeaShaad }
219*7c604eeaShaad } else {
220*7c604eeaShaad /* Case-dependent match for powers of 1000 */
221*7c604eeaShaad for (s = 0; s < NUM_UNIT_PREFIXES; s++)
222*7c604eeaShaad if (cmd->current_settings.unit_type ==
223*7c604eeaShaad *size_str[BASE_1000 + s][2]) {
224*7c604eeaShaad base = BASE_1000;
225*7c604eeaShaad break;
226*7c604eeaShaad }
227*7c604eeaShaad
228*7c604eeaShaad /* Case-dependent match for powers of 1024 */
229*7c604eeaShaad if (base == BASE_UNKNOWN)
230*7c604eeaShaad for (s = 0; s < NUM_UNIT_PREFIXES; s++)
231*7c604eeaShaad if (cmd->current_settings.unit_type ==
232*7c604eeaShaad *size_str[BASE_1024 + s][2]) {
233*7c604eeaShaad base = BASE_1024;
234*7c604eeaShaad break;
235*7c604eeaShaad }
236*7c604eeaShaad }
237*7c604eeaShaad
238*7c604eeaShaad if (base == BASE_UNKNOWN)
239*7c604eeaShaad /* Check for special units - s, b or u */
240*7c604eeaShaad for (s = 0; s < NUM_SPECIAL; s++)
241*7c604eeaShaad if (toupper((int) cmd->current_settings.unit_type) ==
242*7c604eeaShaad *size_str[BASE_SPECIAL + s][2]) {
243*7c604eeaShaad base = BASE_SPECIAL;
244*7c604eeaShaad break;
245*7c604eeaShaad }
24656a34939Shaad
24756a34939Shaad if (size == UINT64_C(0)) {
248*7c604eeaShaad if (base == BASE_UNKNOWN)
249*7c604eeaShaad s = 0;
250*7c604eeaShaad sprintf(size_buf, "0%s", suffix ? size_str[base + s][sl] : "");
25156a34939Shaad return size_buf;
25256a34939Shaad }
25356a34939Shaad
25456a34939Shaad size *= UINT64_C(512);
25556a34939Shaad
256*7c604eeaShaad if (base != BASE_UNKNOWN)
25756a34939Shaad byte = cmd->current_settings.unit_factor;
25856a34939Shaad else {
259*7c604eeaShaad /* Human-readable style */
260*7c604eeaShaad if (cmd->current_settings.unit_type == 'H') {
26156a34939Shaad units = UINT64_C(1000);
262*7c604eeaShaad base = BASE_1000;
263*7c604eeaShaad } else {
26456a34939Shaad units = UINT64_C(1024);
265*7c604eeaShaad base = BASE_1024;
266*7c604eeaShaad }
267*7c604eeaShaad
268*7c604eeaShaad if (!cmd->si_unit_consistency)
269*7c604eeaShaad base = BASE_SHARED;
270*7c604eeaShaad
27156a34939Shaad byte = units * units * units * units * units * units;
272*7c604eeaShaad
273*7c604eeaShaad for (s = 0; s < NUM_UNIT_PREFIXES && size < byte; s++)
274*7c604eeaShaad byte /= units;
275*7c604eeaShaad
276*7c604eeaShaad suffix = 1;
27756a34939Shaad }
27856a34939Shaad
27956a34939Shaad /* FIXME Make precision configurable */
28056a34939Shaad switch(toupper((int) cmd->current_settings.unit_type)) {
28156a34939Shaad case 'B':
28256a34939Shaad case 'S':
28356a34939Shaad precision = 0;
28456a34939Shaad break;
28556a34939Shaad default:
28656a34939Shaad precision = 2;
28756a34939Shaad }
28856a34939Shaad
28956a34939Shaad snprintf(size_buf, SIZE_BUF - 1, "%.*f%s", precision,
290*7c604eeaShaad (double) size / byte, suffix ? size_str[base + s][sl] : "");
29156a34939Shaad
29256a34939Shaad return size_buf;
29356a34939Shaad }
29456a34939Shaad
display_size_long(const struct cmd_context * cmd,uint64_t size)29556a34939Shaad const char *display_size_long(const struct cmd_context *cmd, uint64_t size)
29656a34939Shaad {
29756a34939Shaad return _display_size(cmd, size, SIZE_LONG);
29856a34939Shaad }
29956a34939Shaad
display_size_units(const struct cmd_context * cmd,uint64_t size)30056a34939Shaad const char *display_size_units(const struct cmd_context *cmd, uint64_t size)
30156a34939Shaad {
30256a34939Shaad return _display_size(cmd, size, SIZE_UNIT);
30356a34939Shaad }
30456a34939Shaad
display_size(const struct cmd_context * cmd,uint64_t size)30556a34939Shaad const char *display_size(const struct cmd_context *cmd, uint64_t size)
30656a34939Shaad {
30756a34939Shaad return _display_size(cmd, size, SIZE_SHORT);
30856a34939Shaad }
30956a34939Shaad
pvdisplay_colons(const struct physical_volume * pv)31056a34939Shaad void pvdisplay_colons(const struct physical_volume *pv)
31156a34939Shaad {
31256a34939Shaad char uuid[64] __attribute((aligned(8)));
31356a34939Shaad
31456a34939Shaad if (!pv)
31556a34939Shaad return;
31656a34939Shaad
31756a34939Shaad if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
31856a34939Shaad stack;
31956a34939Shaad return;
32056a34939Shaad }
32156a34939Shaad
32256a34939Shaad log_print("%s:%s:%" PRIu64 ":-1:%u:%u:-1:%" PRIu32 ":%u:%u:%u:%s",
32356a34939Shaad pv_dev_name(pv), pv->vg_name, pv->size,
32456a34939Shaad /* FIXME pv->pv_number, Derive or remove? */
32556a34939Shaad pv->status, /* FIXME Support old or new format here? */
32656a34939Shaad pv->status & ALLOCATABLE_PV, /* FIXME remove? */
32756a34939Shaad /* FIXME pv->lv_cur, Remove? */
32856a34939Shaad pv->pe_size / 2,
32956a34939Shaad pv->pe_count,
33056a34939Shaad pv->pe_count - pv->pe_alloc_count,
33156a34939Shaad pv->pe_alloc_count, *uuid ? uuid : "none");
33256a34939Shaad
33356a34939Shaad return;
33456a34939Shaad }
33556a34939Shaad
pvdisplay_segments(const struct physical_volume * pv)33656a34939Shaad void pvdisplay_segments(const struct physical_volume *pv)
33756a34939Shaad {
33856a34939Shaad const struct pv_segment *pvseg;
33956a34939Shaad
34056a34939Shaad if (pv->pe_size)
34156a34939Shaad log_print("--- Physical Segments ---");
34256a34939Shaad
34356a34939Shaad dm_list_iterate_items(pvseg, &pv->segments) {
34456a34939Shaad log_print("Physical extent %u to %u:",
34556a34939Shaad pvseg->pe, pvseg->pe + pvseg->len - 1);
34656a34939Shaad
34756a34939Shaad if (pvseg_is_allocated(pvseg)) {
34856a34939Shaad log_print(" Logical volume\t%s%s/%s",
34956a34939Shaad pvseg->lvseg->lv->vg->cmd->dev_dir,
35056a34939Shaad pvseg->lvseg->lv->vg->name,
35156a34939Shaad pvseg->lvseg->lv->name);
35256a34939Shaad log_print(" Logical extents\t%d to %d",
35356a34939Shaad pvseg->lvseg->le, pvseg->lvseg->le +
35456a34939Shaad pvseg->lvseg->len - 1);
35556a34939Shaad } else
35656a34939Shaad log_print(" FREE");
35756a34939Shaad }
35856a34939Shaad
35956a34939Shaad log_print(" ");
36056a34939Shaad return;
36156a34939Shaad }
36256a34939Shaad
36356a34939Shaad /* FIXME Include label fields */
pvdisplay_full(const struct cmd_context * cmd,const struct physical_volume * pv,void * handle __attribute ((unused)))36456a34939Shaad void pvdisplay_full(const struct cmd_context *cmd,
36556a34939Shaad const struct physical_volume *pv,
36656a34939Shaad void *handle __attribute((unused)))
36756a34939Shaad {
36856a34939Shaad char uuid[64] __attribute((aligned(8)));
36956a34939Shaad const char *size;
37056a34939Shaad
37156a34939Shaad uint32_t pe_free;
37256a34939Shaad uint64_t data_size, pvsize, unusable;
37356a34939Shaad
37456a34939Shaad if (!pv)
37556a34939Shaad return;
37656a34939Shaad
37756a34939Shaad if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
37856a34939Shaad stack;
37956a34939Shaad return;
38056a34939Shaad }
38156a34939Shaad
38256a34939Shaad log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
38356a34939Shaad log_print("PV Name %s", pv_dev_name(pv));
38456a34939Shaad log_print("VG Name %s%s",
38556a34939Shaad is_orphan(pv) ? "" : pv->vg_name,
38656a34939Shaad pv->status & EXPORTED_VG ? " (exported)" : "");
38756a34939Shaad
38856a34939Shaad data_size = (uint64_t) pv->pe_count * pv->pe_size;
38956a34939Shaad if (pv->size > data_size + pv->pe_start) {
39056a34939Shaad pvsize = pv->size;
39156a34939Shaad unusable = pvsize - data_size;
39256a34939Shaad } else {
39356a34939Shaad pvsize = data_size + pv->pe_start;
39456a34939Shaad unusable = pvsize - pv->size;
39556a34939Shaad }
39656a34939Shaad
39756a34939Shaad size = display_size(cmd, pvsize);
39856a34939Shaad if (data_size)
39956a34939Shaad log_print("PV Size %s / not usable %s", /* [LVM: %s]", */
40056a34939Shaad size, display_size(cmd, unusable));
40156a34939Shaad else
40256a34939Shaad log_print("PV Size %s", size);
40356a34939Shaad
40456a34939Shaad /* PV number not part of LVM2 design
40556a34939Shaad log_print("PV# %u", pv->pv_number);
40656a34939Shaad */
40756a34939Shaad
40856a34939Shaad pe_free = pv->pe_count - pv->pe_alloc_count;
40956a34939Shaad if (pv->pe_count && (pv->status & ALLOCATABLE_PV))
41056a34939Shaad log_print("Allocatable yes %s",
41156a34939Shaad (!pe_free && pv->pe_count) ? "(but full)" : "");
41256a34939Shaad else
41356a34939Shaad log_print("Allocatable NO");
41456a34939Shaad
41556a34939Shaad /* LV count is no longer available when displaying PV
41656a34939Shaad log_print("Cur LV %u", vg->lv_count);
41756a34939Shaad */
418*7c604eeaShaad
419*7c604eeaShaad if (cmd->si_unit_consistency)
420*7c604eeaShaad log_print("PE Size %s", display_size(cmd, (uint64_t) pv->pe_size));
421*7c604eeaShaad else
42256a34939Shaad log_print("PE Size (KByte) %" PRIu32, pv->pe_size / 2);
423*7c604eeaShaad
42456a34939Shaad log_print("Total PE %u", pv->pe_count);
42556a34939Shaad log_print("Free PE %" PRIu32, pe_free);
42656a34939Shaad log_print("Allocated PE %u", pv->pe_alloc_count);
42756a34939Shaad log_print("PV UUID %s", *uuid ? uuid : "none");
42856a34939Shaad log_print(" ");
42956a34939Shaad
43056a34939Shaad return;
43156a34939Shaad }
43256a34939Shaad
pvdisplay_short(const struct cmd_context * cmd __attribute ((unused)),const struct volume_group * vg __attribute ((unused)),const struct physical_volume * pv,void * handle __attribute ((unused)))43356a34939Shaad int pvdisplay_short(const struct cmd_context *cmd __attribute((unused)),
43456a34939Shaad const struct volume_group *vg __attribute((unused)),
43556a34939Shaad const struct physical_volume *pv,
43656a34939Shaad void *handle __attribute((unused)))
43756a34939Shaad {
43856a34939Shaad char uuid[64] __attribute((aligned(8)));
43956a34939Shaad
44056a34939Shaad if (!pv)
44156a34939Shaad return 0;
44256a34939Shaad
44356a34939Shaad if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
44456a34939Shaad return_0;
44556a34939Shaad
44656a34939Shaad log_print("PV Name %s ", pv_dev_name(pv));
44756a34939Shaad /* FIXME pv->pv_number); */
44856a34939Shaad log_print("PV UUID %s", *uuid ? uuid : "none");
44956a34939Shaad log_print("PV Status %sallocatable",
45056a34939Shaad (pv->status & ALLOCATABLE_PV) ? "" : "NOT ");
45156a34939Shaad log_print("Total PE / Free PE %u / %u",
45256a34939Shaad pv->pe_count, pv->pe_count - pv->pe_alloc_count);
45356a34939Shaad
45456a34939Shaad log_print(" ");
45556a34939Shaad return 0;
45656a34939Shaad }
45756a34939Shaad
lvdisplay_colons(const struct logical_volume * lv)45856a34939Shaad void lvdisplay_colons(const struct logical_volume *lv)
45956a34939Shaad {
46056a34939Shaad int inkernel;
46156a34939Shaad struct lvinfo info;
46256a34939Shaad inkernel = lv_info(lv->vg->cmd, lv, &info, 1, 0) && info.exists;
46356a34939Shaad
46456a34939Shaad log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
46556a34939Shaad lv->vg->cmd->dev_dir,
46656a34939Shaad lv->vg->name,
46756a34939Shaad lv->name,
46856a34939Shaad lv->vg->name,
46956a34939Shaad (lv->status & (LVM_READ | LVM_WRITE)) >> 8, inkernel ? 1 : 0,
47056a34939Shaad /* FIXME lv->lv_number, */
47156a34939Shaad inkernel ? info.open_count : 0, lv->size, lv->le_count,
47256a34939Shaad /* FIXME Add num allocated to struct! lv->lv_allocated_le, */
47356a34939Shaad (lv->alloc == ALLOC_CONTIGUOUS ? 2 : 0), lv->read_ahead,
47456a34939Shaad inkernel ? info.major : -1, inkernel ? info.minor : -1);
47556a34939Shaad return;
47656a34939Shaad }
47756a34939Shaad
lvdisplay_full(struct cmd_context * cmd,const struct logical_volume * lv,void * handle __attribute ((unused)))47856a34939Shaad int lvdisplay_full(struct cmd_context *cmd,
47956a34939Shaad const struct logical_volume *lv,
48056a34939Shaad void *handle __attribute((unused)))
48156a34939Shaad {
48256a34939Shaad struct lvinfo info;
48356a34939Shaad int inkernel, snap_active = 0;
48456a34939Shaad char uuid[64] __attribute((aligned(8)));
485*7c604eeaShaad struct lv_segment *snap_seg = NULL, *mirror_seg = NULL;
48656a34939Shaad float snap_percent; /* fused, fsize; */
487*7c604eeaShaad percent_range_t percent_range;
48856a34939Shaad
48956a34939Shaad if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid)))
49056a34939Shaad return_0;
49156a34939Shaad
49256a34939Shaad inkernel = lv_info(cmd, lv, &info, 1, 1) && info.exists;
49356a34939Shaad
49456a34939Shaad log_print("--- Logical volume ---");
49556a34939Shaad
49656a34939Shaad log_print("LV Name %s%s/%s", lv->vg->cmd->dev_dir,
49756a34939Shaad lv->vg->name, lv->name);
49856a34939Shaad log_print("VG Name %s", lv->vg->name);
49956a34939Shaad
50056a34939Shaad log_print("LV UUID %s", uuid);
50156a34939Shaad
50256a34939Shaad log_print("LV Write Access %s",
50356a34939Shaad (lv->status & LVM_WRITE) ? "read/write" : "read only");
50456a34939Shaad
50556a34939Shaad if (lv_is_origin(lv)) {
50656a34939Shaad log_print("LV snapshot status source of");
50756a34939Shaad
50856a34939Shaad dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs,
50956a34939Shaad origin_list) {
51056a34939Shaad if (inkernel &&
51156a34939Shaad (snap_active = lv_snapshot_percent(snap_seg->cow,
512*7c604eeaShaad &snap_percent,
513*7c604eeaShaad &percent_range)))
514*7c604eeaShaad if (percent_range == PERCENT_INVALID)
51556a34939Shaad snap_active = 0;
51656a34939Shaad log_print(" %s%s/%s [%s]",
51756a34939Shaad lv->vg->cmd->dev_dir, lv->vg->name,
51856a34939Shaad snap_seg->cow->name,
519*7c604eeaShaad snap_active ? "active" : "INACTIVE");
52056a34939Shaad }
52156a34939Shaad snap_seg = NULL;
52256a34939Shaad } else if ((snap_seg = find_cow(lv))) {
52356a34939Shaad if (inkernel &&
52456a34939Shaad (snap_active = lv_snapshot_percent(snap_seg->cow,
525*7c604eeaShaad &snap_percent,
526*7c604eeaShaad &percent_range)))
527*7c604eeaShaad if (percent_range == PERCENT_INVALID)
52856a34939Shaad snap_active = 0;
52956a34939Shaad
53056a34939Shaad log_print("LV snapshot status %s destination for %s%s/%s",
531*7c604eeaShaad snap_active ? "active" : "INACTIVE",
53256a34939Shaad lv->vg->cmd->dev_dir, lv->vg->name,
53356a34939Shaad snap_seg->origin->name);
53456a34939Shaad }
53556a34939Shaad
53656a34939Shaad if (inkernel && info.suspended)
53756a34939Shaad log_print("LV Status suspended");
53856a34939Shaad else
53956a34939Shaad log_print("LV Status %savailable",
54056a34939Shaad inkernel ? "" : "NOT ");
54156a34939Shaad
54256a34939Shaad /********* FIXME lv_number
54356a34939Shaad log_print("LV # %u", lv->lv_number + 1);
54456a34939Shaad ************/
54556a34939Shaad
54656a34939Shaad if (inkernel)
54756a34939Shaad log_print("# open %u", info.open_count);
54856a34939Shaad
54956a34939Shaad log_print("LV Size %s",
55056a34939Shaad display_size(cmd,
55156a34939Shaad snap_seg ? snap_seg->origin->size : lv->size));
55256a34939Shaad
55356a34939Shaad log_print("Current LE %u",
55456a34939Shaad snap_seg ? snap_seg->origin->le_count : lv->le_count);
55556a34939Shaad
55656a34939Shaad if (snap_seg) {
55756a34939Shaad log_print("COW-table size %s",
55856a34939Shaad display_size(cmd, (uint64_t) lv->size));
55956a34939Shaad log_print("COW-table LE %u", lv->le_count);
56056a34939Shaad
56156a34939Shaad if (snap_active)
56256a34939Shaad log_print("Allocated to snapshot %.2f%% ", snap_percent);
56356a34939Shaad
56456a34939Shaad log_print("Snapshot chunk size %s",
56556a34939Shaad display_size(cmd, (uint64_t) snap_seg->chunk_size));
56656a34939Shaad }
56756a34939Shaad
568*7c604eeaShaad if (lv->status & MIRRORED) {
569*7c604eeaShaad mirror_seg = first_seg(lv);
570*7c604eeaShaad log_print("Mirrored volumes %" PRIu32, mirror_seg->area_count);
571*7c604eeaShaad if (lv->status & CONVERTING)
572*7c604eeaShaad log_print("LV type Mirror undergoing conversion");
573*7c604eeaShaad }
574*7c604eeaShaad
57556a34939Shaad log_print("Segments %u", dm_list_size(&lv->segments));
57656a34939Shaad
57756a34939Shaad /********* FIXME Stripes & stripesize for each segment
578*7c604eeaShaad log_print("Stripe size %s", display_size(cmd, (uint64_t) lv->stripesize));
57956a34939Shaad ***********/
58056a34939Shaad
58156a34939Shaad log_print("Allocation %s", get_alloc_string(lv->alloc));
58256a34939Shaad if (lv->read_ahead == DM_READ_AHEAD_AUTO)
58356a34939Shaad log_print("Read ahead sectors auto");
58456a34939Shaad else if (lv->read_ahead == DM_READ_AHEAD_NONE)
58556a34939Shaad log_print("Read ahead sectors 0");
58656a34939Shaad else
58756a34939Shaad log_print("Read ahead sectors %u", lv->read_ahead);
58856a34939Shaad
58956a34939Shaad if (inkernel && lv->read_ahead != info.read_ahead)
59056a34939Shaad log_print("- currently set to %u", info.read_ahead);
59156a34939Shaad
59256a34939Shaad if (lv->status & FIXED_MINOR) {
59356a34939Shaad if (lv->major >= 0)
59456a34939Shaad log_print("Persistent major %d", lv->major);
59556a34939Shaad log_print("Persistent minor %d", lv->minor);
59656a34939Shaad }
59756a34939Shaad
59856a34939Shaad if (inkernel)
59956a34939Shaad log_print("Block device %d:%d", info.major,
60056a34939Shaad info.minor);
60156a34939Shaad
60256a34939Shaad log_print(" ");
60356a34939Shaad
60456a34939Shaad return 0;
60556a34939Shaad }
60656a34939Shaad
display_stripe(const struct lv_segment * seg,uint32_t s,const char * pre)60756a34939Shaad void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre)
60856a34939Shaad {
60956a34939Shaad switch (seg_type(seg, s)) {
61056a34939Shaad case AREA_PV:
61156a34939Shaad /* FIXME Re-check the conditions for 'Missing' */
61256a34939Shaad log_print("%sPhysical volume\t%s", pre,
61356a34939Shaad seg_pv(seg, s) ?
61456a34939Shaad pv_dev_name(seg_pv(seg, s)) :
61556a34939Shaad "Missing");
61656a34939Shaad
61756a34939Shaad if (seg_pv(seg, s))
61856a34939Shaad log_print("%sPhysical extents\t%d to %d", pre,
61956a34939Shaad seg_pe(seg, s),
62056a34939Shaad seg_pe(seg, s) + seg->area_len - 1);
62156a34939Shaad break;
62256a34939Shaad case AREA_LV:
62356a34939Shaad log_print("%sLogical volume\t%s", pre,
62456a34939Shaad seg_lv(seg, s) ?
62556a34939Shaad seg_lv(seg, s)->name : "Missing");
62656a34939Shaad
62756a34939Shaad if (seg_lv(seg, s))
62856a34939Shaad log_print("%sLogical extents\t%d to %d", pre,
62956a34939Shaad seg_le(seg, s),
63056a34939Shaad seg_le(seg, s) + seg->area_len - 1);
63156a34939Shaad break;
63256a34939Shaad case AREA_UNASSIGNED:
63356a34939Shaad log_print("%sUnassigned area", pre);
63456a34939Shaad }
63556a34939Shaad }
63656a34939Shaad
lvdisplay_segments(const struct logical_volume * lv)63756a34939Shaad int lvdisplay_segments(const struct logical_volume *lv)
63856a34939Shaad {
63956a34939Shaad const struct lv_segment *seg;
64056a34939Shaad
64156a34939Shaad log_print("--- Segments ---");
64256a34939Shaad
64356a34939Shaad dm_list_iterate_items(seg, &lv->segments) {
64456a34939Shaad log_print("Logical extent %u to %u:",
64556a34939Shaad seg->le, seg->le + seg->len - 1);
64656a34939Shaad
64756a34939Shaad log_print(" Type\t\t%s", seg->segtype->ops->name(seg));
64856a34939Shaad
64956a34939Shaad if (seg->segtype->ops->display)
65056a34939Shaad seg->segtype->ops->display(seg);
65156a34939Shaad }
65256a34939Shaad
65356a34939Shaad log_print(" ");
65456a34939Shaad return 1;
65556a34939Shaad }
65656a34939Shaad
vgdisplay_extents(const struct volume_group * vg __attribute ((unused)))65756a34939Shaad void vgdisplay_extents(const struct volume_group *vg __attribute((unused)))
65856a34939Shaad {
65956a34939Shaad return;
66056a34939Shaad }
66156a34939Shaad
vgdisplay_full(const struct volume_group * vg)66256a34939Shaad void vgdisplay_full(const struct volume_group *vg)
66356a34939Shaad {
66456a34939Shaad uint32_t access_str;
66556a34939Shaad uint32_t active_pvs;
66656a34939Shaad char uuid[64] __attribute((aligned(8)));
66756a34939Shaad
66856a34939Shaad active_pvs = vg->pv_count - vg_missing_pv_count(vg);
66956a34939Shaad
67056a34939Shaad log_print("--- Volume group ---");
67156a34939Shaad log_print("VG Name %s", vg->name);
67256a34939Shaad log_print("System ID %s", vg->system_id);
67356a34939Shaad log_print("Format %s", vg->fid->fmt->name);
67456a34939Shaad if (vg->fid->fmt->features & FMT_MDAS) {
67556a34939Shaad log_print("Metadata Areas %d",
67656a34939Shaad dm_list_size(&vg->fid->metadata_areas));
67756a34939Shaad log_print("Metadata Sequence No %d", vg->seqno);
67856a34939Shaad }
67956a34939Shaad access_str = vg->status & (LVM_READ | LVM_WRITE);
68056a34939Shaad log_print("VG Access %s%s%s%s",
68156a34939Shaad access_str == (LVM_READ | LVM_WRITE) ? "read/write" : "",
68256a34939Shaad access_str == LVM_READ ? "read" : "",
68356a34939Shaad access_str == LVM_WRITE ? "write" : "",
68456a34939Shaad access_str == 0 ? "error" : "");
68556a34939Shaad log_print("VG Status %s%sresizable",
686*7c604eeaShaad vg_is_exported(vg) ? "exported/" : "",
687*7c604eeaShaad vg_is_resizeable(vg) ? "" : "NOT ");
68856a34939Shaad /* vg number not part of LVM2 design
68956a34939Shaad log_print ("VG # %u\n", vg->vg_number);
69056a34939Shaad */
69156a34939Shaad if (vg_is_clustered(vg)) {
69256a34939Shaad log_print("Clustered yes");
69356a34939Shaad log_print("Shared %s",
69456a34939Shaad vg->status & SHARED ? "yes" : "no");
69556a34939Shaad }
69656a34939Shaad
69756a34939Shaad log_print("MAX LV %u", vg->max_lv);
698*7c604eeaShaad log_print("Cur LV %u", vg_visible_lvs(vg));
69956a34939Shaad log_print("Open LV %u", lvs_in_vg_opened(vg));
70056a34939Shaad /****** FIXME Max LV Size
70156a34939Shaad log_print ( "MAX LV Size %s",
70256a34939Shaad ( s1 = display_size ( LVM_LV_SIZE_MAX(vg))));
70356a34939Shaad free ( s1);
70456a34939Shaad *********/
70556a34939Shaad log_print("Max PV %u", vg->max_pv);
70656a34939Shaad log_print("Cur PV %u", vg->pv_count);
70756a34939Shaad log_print("Act PV %u", active_pvs);
70856a34939Shaad
70956a34939Shaad log_print("VG Size %s",
71056a34939Shaad display_size(vg->cmd,
71156a34939Shaad (uint64_t) vg->extent_count * vg->extent_size));
71256a34939Shaad
71356a34939Shaad log_print("PE Size %s",
71456a34939Shaad display_size(vg->cmd, (uint64_t) vg->extent_size));
71556a34939Shaad
71656a34939Shaad log_print("Total PE %u", vg->extent_count);
71756a34939Shaad
71856a34939Shaad log_print("Alloc PE / Size %u / %s",
71956a34939Shaad vg->extent_count - vg->free_count,
72056a34939Shaad display_size(vg->cmd,
72156a34939Shaad ((uint64_t) vg->extent_count - vg->free_count) *
72256a34939Shaad vg->extent_size));
72356a34939Shaad
72456a34939Shaad log_print("Free PE / Size %u / %s", vg->free_count,
725*7c604eeaShaad display_size(vg->cmd, vg_free(vg)));
72656a34939Shaad
72756a34939Shaad if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
72856a34939Shaad stack;
72956a34939Shaad return;
73056a34939Shaad }
73156a34939Shaad
73256a34939Shaad log_print("VG UUID %s", uuid);
73356a34939Shaad log_print(" ");
73456a34939Shaad
73556a34939Shaad return;
73656a34939Shaad }
73756a34939Shaad
vgdisplay_colons(const struct volume_group * vg)73856a34939Shaad void vgdisplay_colons(const struct volume_group *vg)
73956a34939Shaad {
74056a34939Shaad uint32_t active_pvs;
74156a34939Shaad const char *access_str;
74256a34939Shaad char uuid[64] __attribute((aligned(8)));
74356a34939Shaad
74456a34939Shaad active_pvs = vg->pv_count - vg_missing_pv_count(vg);
74556a34939Shaad
74656a34939Shaad switch (vg->status & (LVM_READ | LVM_WRITE)) {
74756a34939Shaad case LVM_READ | LVM_WRITE:
74856a34939Shaad access_str = "r/w";
74956a34939Shaad break;
75056a34939Shaad case LVM_READ:
75156a34939Shaad access_str = "r";
75256a34939Shaad break;
75356a34939Shaad case LVM_WRITE:
75456a34939Shaad access_str = "w";
75556a34939Shaad break;
75656a34939Shaad default:
75756a34939Shaad access_str = "";
75856a34939Shaad }
75956a34939Shaad
76056a34939Shaad if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
76156a34939Shaad stack;
76256a34939Shaad return;
76356a34939Shaad }
76456a34939Shaad
76556a34939Shaad log_print("%s:%s:%d:-1:%u:%u:%u:-1:%u:%u:%u:%" PRIu64 ":%" PRIu32
76656a34939Shaad ":%u:%u:%u:%s",
76756a34939Shaad vg->name,
76856a34939Shaad access_str,
76956a34939Shaad vg->status,
77056a34939Shaad /* internal volume group number; obsolete */
77156a34939Shaad vg->max_lv,
772*7c604eeaShaad vg_visible_lvs(vg),
77356a34939Shaad lvs_in_vg_opened(vg),
77456a34939Shaad /* FIXME: maximum logical volume size */
77556a34939Shaad vg->max_pv,
77656a34939Shaad vg->pv_count,
77756a34939Shaad active_pvs,
77856a34939Shaad (uint64_t) vg->extent_count * (vg->extent_size / 2),
77956a34939Shaad vg->extent_size / 2,
78056a34939Shaad vg->extent_count,
78156a34939Shaad vg->extent_count - vg->free_count,
78256a34939Shaad vg->free_count,
78356a34939Shaad uuid[0] ? uuid : "none");
78456a34939Shaad return;
78556a34939Shaad }
78656a34939Shaad
vgdisplay_short(const struct volume_group * vg)78756a34939Shaad void vgdisplay_short(const struct volume_group *vg)
78856a34939Shaad {
78956a34939Shaad log_print("\"%s\" %-9s [%-9s used / %s free]", vg->name,
79056a34939Shaad /********* FIXME if "open" print "/used" else print "/idle"??? ******/
79156a34939Shaad display_size(vg->cmd,
79256a34939Shaad (uint64_t) vg->extent_count * vg->extent_size),
79356a34939Shaad display_size(vg->cmd,
79456a34939Shaad ((uint64_t) vg->extent_count -
79556a34939Shaad vg->free_count) * vg->extent_size),
796*7c604eeaShaad display_size(vg->cmd, vg_free(vg)));
79756a34939Shaad return;
79856a34939Shaad }
79956a34939Shaad
display_formats(const struct cmd_context * cmd)80056a34939Shaad void display_formats(const struct cmd_context *cmd)
80156a34939Shaad {
80256a34939Shaad const struct format_type *fmt;
80356a34939Shaad
80456a34939Shaad dm_list_iterate_items(fmt, &cmd->formats) {
80556a34939Shaad log_print("%s", fmt->name);
80656a34939Shaad }
80756a34939Shaad }
80856a34939Shaad
display_segtypes(const struct cmd_context * cmd)80956a34939Shaad void display_segtypes(const struct cmd_context *cmd)
81056a34939Shaad {
81156a34939Shaad const struct segment_type *segtype;
81256a34939Shaad
81356a34939Shaad dm_list_iterate_items(segtype, &cmd->segtypes) {
81456a34939Shaad log_print("%s", segtype->name);
81556a34939Shaad }
81656a34939Shaad }
81756a34939Shaad
yes_no_prompt(const char * prompt,...)81856a34939Shaad char yes_no_prompt(const char *prompt, ...)
81956a34939Shaad {
82056a34939Shaad int c = 0, ret = 0;
82156a34939Shaad va_list ap;
82256a34939Shaad
82356a34939Shaad sigint_allow();
82456a34939Shaad do {
82556a34939Shaad if (c == '\n' || !c) {
82656a34939Shaad va_start(ap, prompt);
82756a34939Shaad vprintf(prompt, ap);
82856a34939Shaad va_end(ap);
829*7c604eeaShaad fflush(stdout);
83056a34939Shaad }
83156a34939Shaad
83256a34939Shaad if ((c = getchar()) == EOF) {
83356a34939Shaad ret = 'n';
83456a34939Shaad break;
83556a34939Shaad }
83656a34939Shaad
83756a34939Shaad c = tolower(c);
83856a34939Shaad if ((c == 'y') || (c == 'n'))
83956a34939Shaad ret = c;
84056a34939Shaad } while (!ret || c != '\n');
84156a34939Shaad
84256a34939Shaad sigint_restore();
84356a34939Shaad
84456a34939Shaad if (c != '\n')
84556a34939Shaad printf("\n");
84656a34939Shaad
84756a34939Shaad return ret;
84856a34939Shaad }
84956a34939Shaad
850