master - report: adapt selection code to recognize per-field reserved values
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0956fd230fea55...
Commit: 0956fd230fea550707acb2889223438996102de4
Parent: da545ce3b471e76b3ebcfcb5528118d8dd9264df
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 4 11:21:38 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:50:50 2014 +0200
report: adapt selection code to recognize per-field reserved values
In contrast to per-type reserved values that are applied for all fields
of that type, per-field reserved values are only applied for concrete
field only.
Also add 'struct dm_report_field_reserved_value' to libdm for per-field
reserved value definition. This is defined by field number (an index
in the 'fields' array which is given for the dm_report_init_with_selection
function during report initialization) and the value to use for any
of the specified reserved names.
---
libdm/libdevmapper.h | 27 ++++++++++++
libdm/libdm-report.c | 112 +++++++++++++++++++++++++++++++++-----------------
2 files changed, 101 insertions(+), 38 deletions(-)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index ad504da..dc3da78 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1633,6 +1633,7 @@ struct dm_report_field;
#define DM_REPORT_FIELD_ALIGN_LEFT 0x00000001
#define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
#define DM_REPORT_FIELD_TYPE_MASK 0x00000FF0
+#define DM_REPORT_FIELD_TYPE_NONE 0x00000000
#define DM_REPORT_FIELD_TYPE_STRING 0x00000010
#define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
#define DM_REPORT_FIELD_TYPE_SIZE 0x00000040
@@ -1658,9 +1659,35 @@ struct dm_report_field_type {
const char *desc; /* description of the field */
};
+/*
+ * Per-field reserved value.
+ */
+struct dm_report_field_reserved_value {
+ /* field_num is the position of the field in 'fields'
+ array passed to dm_report_init_with_selection */
+ uint32_t field_num;
+ /* the value is of the same type as the field
+ identified by field_num */
+ const void *value;
+};
+
+/*
+ * Reserved value is a 'value' that is used directly if any of the 'names' is hit.
+ *
+ * If type is any of DM_REPORT_FIELD_TYPE_*, the reserved value is recognized
+ * for all fields of that type.
+ *
+ * If type is DM_REPORT_FIELD_TYPE_NONE, the reserved value is recognized
+ * for the exact field specified - hence the type of the value is automatically
+ * the same as the type of the field itself.
+ *
+ * The array of reserved values is used to initialize reporting with
+ * selection enabled (see also dm_report_init_with_selection function).
+ */
struct dm_report_reserved_value {
const unsigned type; /* DM_REPORT_FIELD_TYPE_* */
const void *value; /* reserved value:
+ struct dm_report_field_reserved_value for DM_REPORT_FIELD_TYPE_NONE
uint64_t for DM_REPORT_FIELD_TYPE_NUMBER
uint64_t for DM_REPORT_FIELD_TYPE_SIZE (number of 512-byte sectors)
uint64_t for DM_REPORT_FIELD_TYPE_PERCENT
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 00c3d3f..ad89cf2 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -1599,6 +1599,18 @@ static int _tok_op_cmp(const char *s, const char **end)
return _tok_op(_op_cmp, s, end, 0);
}
+static char _get_and_skip_quote_char(char const **s)
+{
+ char c = 0;
+
+ if (**s == '"' || **s == '\'') {
+ c = **s;
+ (*s)++;
+ }
+
+ return c;
+}
+
/*
*
* Input:
@@ -1689,38 +1701,62 @@ static const char *_tok_value_string(const char *s,
return s;
}
+static const char *_reserved_name(const char **names, const char *s, size_t len)
+{
+ const char **name = names;
+ while (*name) {
+ if ((strlen(*name) == len) && !strncmp(*name, s, len))
+ return *name;
+ name++;
+ }
+ return NULL;
+}
+
/*
* Used to replace a string representation of the reserved value
* found in selection with the exact reserved value of certain type.
*/
-static const char *_get_reserved_value(struct dm_report *rh, unsigned type,
- const char *s, const char **begin, const char **end,
- const struct dm_report_reserved_value **reserved)
-{
- const struct dm_report_reserved_value *iter = rh->reserved_values;
- const char **name;
+static const char *_get_reserved(struct dm_report *rh, unsigned type,
+ uint32_t field_num, int implicit,
+ const char *s, const char **begin, const char **end,
+ const struct dm_report_reserved_value **reserved)
+{
+ const struct dm_report_reserved_value *iter = implicit ? NULL : rh->reserved_values;
+ const char *tmp_begin, *tmp_end, *tmp_s = s;
+ const char *name = NULL;
+ char c;
*reserved = NULL;
if (!iter)
return s;
- while (iter->type) {
- if (iter->type & type) {
- name = iter->names;
- while (*name) {
- if (!strcmp(*name, s)) {
- *begin = s;
- *end = s += strlen(*name);
- *reserved = iter;
- return s;
- }
- name++;
- }
+ c = _get_and_skip_quote_char(&tmp_s);
+ if (!(tmp_s = _tok_value_string(tmp_s, &tmp_begin, &tmp_end, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL)))
+ return s;
+
+ while (iter->value) {
+ if (!iter->type) {
+ /* DM_REPORT_FIELD_TYPE_NONE - per-field reserved value */
+ if (((((const struct dm_report_field_reserved_value *) iter->value)->field_num) == field_num) &&
+ (name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
+ break;
+ } else if (iter->type & type) {
+ /* DM_REPORT_FIELD_TYPE_* - per-type reserved value */
+ if ((name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
+ break;
}
iter++;
}
+ if (name) {
+ /* found! */
+ *begin = tmp_begin;
+ *end = tmp_end;
+ s = tmp_s;
+ *reserved = iter;
+ }
+
return s;
}
@@ -1880,18 +1916,6 @@ static int _add_item_to_string_list(struct dm_pool *mem, const char *begin,
return 1;
}
-static char _get_and_skip_quote_char(char const **s)
-{
- char c = 0;
-
- if (**s == '"' || **s == '\'') {
- c = **s;
- (*s)++;
- }
-
- return c;
-}
-
/*
* Input:
* ft - field type for which the value is parsed
@@ -2033,8 +2057,10 @@ bad:
*/
static const char *_tok_value(struct dm_report *rh,
const struct dm_report_field_type *ft,
- const char *s, const char **begin,
- const char **end, uint32_t *flags,
+ uint32_t field_num, int implicit,
+ const char *s,
+ const char **begin, const char **end,
+ uint32_t *flags,
const struct dm_report_reserved_value **reserved,
struct dm_pool *mem, void *custom)
{
@@ -2046,7 +2072,7 @@ static const char *_tok_value(struct dm_report *rh,
s = _skip_space(s);
- s = _get_reserved_value(rh, expected_type, s, begin, end, reserved);
+ s = _get_reserved(rh, expected_type, field_num, implicit, s, begin, end, reserved);
if (*reserved) {
*flags |= expected_type;
return s;
@@ -2149,6 +2175,14 @@ static const char *_tok_field_name(const char *s,
return s;
}
+static const void *_get_reserved_value(const struct dm_report_reserved_value *reserved)
+{
+ if (reserved->type)
+ return reserved->value;
+ else
+ return ((const struct dm_report_field_reserved_value *) reserved->value)->value;
+}
+
static struct field_selection *_create_field_selection(struct dm_report *rh,
uint32_t field_num,
int implicit,
@@ -2229,7 +2263,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
switch (flags & DM_REPORT_FIELD_TYPE_MASK) {
case DM_REPORT_FIELD_TYPE_STRING:
if (reserved) {
- fs->v.s = (const char *) reserved->value;
+ fs->v.s = (const char *) _get_reserved_value(reserved);
dm_pool_free(rh->mem, s);
} else {
fs->v.s = s;
@@ -2241,7 +2275,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_NUMBER:
if (reserved)
- fs->v.i = *(uint64_t *) reserved->value;
+ fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
else {
if (((fs->v.i = strtoull(s, NULL, 10)) == ULLONG_MAX) &&
(errno == ERANGE)) {
@@ -2257,7 +2291,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_SIZE:
if (reserved)
- fs->v.d = (double) * (uint64_t *) reserved->value;
+ fs->v.d = (double) * (uint64_t *) _get_reserved_value(reserved);
else {
fs->v.d = strtod(s, NULL);
if (errno == ERANGE) {
@@ -2276,7 +2310,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_PERCENT:
if (reserved)
- fs->v.i = *(uint64_t *) reserved->value;
+ fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
else {
fs->v.d = strtod(s, NULL);
if ((errno == ERANGE) || (fs->v.d < 0) || (fs->v.d > 100)) {
@@ -2508,7 +2542,9 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
custom = &str_list;
else
custom = NULL;
- if (!(last = _tok_value(rh, ft, last, &vs, &ve, &flags, &reserved, rh->mem, custom)))
+ if (!(last = _tok_value(rh, ft, field_num, implicit,
+ last, &vs, &ve, &flags,
+ &reserved, rh->mem, custom)))
goto_bad;
}
9 years, 10 months
master - tools: add --binary arg to pvs, vgs, lvs and {pv, vg, lv}display -C and report/binary_values_as_numeric lvm.conf option
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=da545ce3b471e7...
Commit: da545ce3b471e76b3ebcfcb5528118d8dd9264df
Parent: d2af4f84c94cb8202565ac32c5f1df673cd92e0c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 2 13:16:32 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:40:17 2014 +0200
tools: add --binary arg to pvs,vgs,lvs and {pv,vg,lv}display -C and report/binary_values_as_numeric lvm.conf option
The --binary option, if used, causes all the binary values reported
in reporting commands to be displayed as "0" or "1" instead of descriptive
literal values (value "unknown" is still used for values that could not be
determined).
Also, add report/binary_values_as_numeric lvm.conf option with the same
functionality as the --binary option (the --binary option prevails
if both --binary cmd option and report/binary_values_as_numeric lvm.conf
option is used at the same time). The report/binary_values_as_numeric is
also profilable.
This makes it easier to use and check lvm reporting command output in scripts.
---
conf/command_profile_template.profile.in | 1 +
conf/example.conf.in | 6 +++++
lib/commands/toolcontext.c | 1 +
lib/commands/toolcontext.h | 1 +
lib/config/config_settings.h | 1 +
lib/report/report.c | 15 +++++++++++++-
man/lvdisplay.8.in | 1 +
man/lvs.8.in | 6 +++++
man/pvdisplay.8.in | 1 +
man/pvs.8.in | 6 +++++
man/vgdisplay.8.in | 1 +
man/vgs.8.in | 6 +++++
tools/args.h | 1 +
tools/commands.h | 32 +++++++++++++++++------------
tools/lvmcmdline.c | 3 ++
15 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/conf/command_profile_template.profile.in b/conf/command_profile_template.profile.in
index 36d4343..592a69d 100644
--- a/conf/command_profile_template.profile.in
+++ b/conf/command_profile_template.profile.in
@@ -13,6 +13,7 @@
#
global {
units="h"
+ report_binary_values_as_numeric=0
si_unit_consistency=1
suffix=1
lvdisplay_shows_full_device_path=0
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 935d3e7..162770a 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1022,6 +1022,12 @@ activation {
# Output each column as a row. If set, this also implies report/prefixes=1.
# colums_as_rows=0
+ # Use binary values "0" or "1" instead of descriptive literal values for
+ # columns that have exactly two valid values to report (not counting the
+ # "unknown" value which denotes that the value could not be determined).
+ #
+ # binary_values_as_numeric = 0
+
# Comma separated list of columns to sort by when reporting 'lvm devtypes' command.
# See 'lvm devtypes -o help' for the list of possible fields.
# devtypes_sort="devtype_name"
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 18fa12d..6ac4a42 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -297,6 +297,7 @@ int process_profilable_config(struct cmd_context *cmd) {
}
cmd->si_unit_consistency = find_config_tree_bool(cmd, global_si_unit_consistency_CFG, NULL);
+ cmd->report_binary_values_as_numeric = find_config_tree_bool(cmd, report_binary_values_as_numeric_CFG, NULL);
cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
return 1;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 9023a6c..162af55 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -88,6 +88,7 @@ struct cmd_context {
unsigned partial_activation:1;
unsigned auto_set_activation_skip:1;
unsigned si_unit_consistency:1;
+ unsigned report_binary_values_as_numeric:1;
unsigned metadata_read_only:1;
unsigned ignore_clustered_vgs:1;
unsigned threaded:1; /* Set if running within a thread e.g. clvmd */
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index d277e0e..2ddf888 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -233,6 +233,7 @@ cfg(report_separator_CFG, "separator", report_CFG_SECTION, CFG_PROFILABLE, CFG_T
cfg(report_prefixes_CFG, "prefixes", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_PREFIXES, vsn(2, 2, 36), NULL)
cfg(report_quoted_CFG, "quoted", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_QUOTED, vsn(2, 2, 39), NULL)
cfg(report_colums_as_rows_CFG, "colums_as_rows", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_COLUMNS_AS_ROWS, vsn(1, 0, 0), NULL)
+cfg(report_binary_values_as_numeric_CFG, "binary_values_as_numeric", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, 0, vsn(2, 2, 108), NULL)
cfg(report_devtypes_sort_CFG, "devtypes_sort", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_SORT, vsn(2, 2, 101), NULL)
cfg(report_devtypes_cols_CFG, "devtypes_cols", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_COLS, vsn(2, 2, 101), NULL)
cfg(report_devtypes_cols_verbose_CFG, "devtypes_cols_verbose", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_COLS_VERB, vsn(2, 2, 101), NULL)
diff --git a/lib/report/report.c b/lib/report/report.c
index d74321e..284a718 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -43,6 +43,8 @@ struct lvm_report_object {
static const uint64_t _zero64 = UINT64_C(0);
static const uint64_t _one64 = UINT64_C(1);
+static const char * const _str_zero = "0";
+static const char * const _str_one = "1";
static const uint64_t _reserved_number_undef_64 = UINT64_C(-1);
static const uint64_t _reserved_number_unmanaged_64 = UINT64_C(-2);
@@ -1173,11 +1175,22 @@ static int _lvactive_disp(struct dm_report *rh, struct dm_pool *mem,
/* PV/VG/LV Attributes */
+/*
+ * Display either "0"/"1" or ""/"word" based on bin_value,
+ * cmd->report_binary_values_as_numeric selects the mode to use.
+*/
static int _binary_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
struct dm_report_field *field, int bin_value, const char *word,
void *private)
{
- return _field_set_value(field, bin_value ? word : "", bin_value ? &_one64 : &_zero64);
+ const struct cmd_context *cmd = (const struct cmd_context *) private;
+
+ if (cmd->report_binary_values_as_numeric)
+ /* "0"/"1" */
+ return _field_set_value(field, bin_value ? _str_one : _str_zero, bin_value ? &_one64 : &_zero64);
+ else
+ /* blank/"word" */
+ return _field_set_value(field, bin_value ? word : "", bin_value ? &_one64 : &_zero64);
}
static int _pvallocatable_disp(struct dm_report *rh, struct dm_pool *mem,
diff --git a/man/lvdisplay.8.in b/man/lvdisplay.8.in
index 1283d58..ed113dd 100644
--- a/man/lvdisplay.8.in
+++ b/man/lvdisplay.8.in
@@ -25,6 +25,7 @@ lvdisplay \(em display attributes of a logical volume
.B lvdisplay
.BR \-C | \-\-columns
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
diff --git a/man/lvs.8.in b/man/lvs.8.in
index 1afd63d..b7e3ecc 100644
--- a/man/lvs.8.in
+++ b/man/lvs.8.in
@@ -4,6 +4,7 @@ lvs \(em report information about logical volumes
.SH SYNOPSIS
.B lvs
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
@@ -44,6 +45,11 @@ for common options.
.B \-\-aligned
Use with \fB\-\-separator\fP to align the output columns.
.TP
+.B \-\-binary
+Use binary values "0" or "1" instead of descriptive literal values
+for columns that have exactly two valid values to report (not counting
+the "unknown" value which denotes that the value could not be determined).
+.TP
.B \-\-all
Include information in the output about internal Logical Volumes that
are components of normally-accessible Logical Volumes, such as mirrors,
diff --git a/man/pvdisplay.8.in b/man/pvdisplay.8.in
index 0399c1e..70c9bfc 100644
--- a/man/pvdisplay.8.in
+++ b/man/pvdisplay.8.in
@@ -26,6 +26,7 @@ pvdisplay \- display attributes of a physical volume
.B pvdisplay
.BR \-C | \-\-columns
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
diff --git a/man/pvs.8.in b/man/pvs.8.in
index ccd84a5..605b13d 100644
--- a/man/pvs.8.in
+++ b/man/pvs.8.in
@@ -5,6 +5,7 @@ pvs \(em report information about physical volumes
.B pvs
.RB [ \-a | \-\-all ]
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
@@ -45,6 +46,11 @@ initialized with \fBpvcreate\fP(8).
.B \-\-aligned
Use with \fB\-\-separator\fP to align the output columns.
.TP
+.B \-\-binary
+Use binary values "0" or "1" instead of descriptive literal values
+for columns that have exactly two valid values to report (not counting
+the "unknown" value which denotes that the value could not be determined).
+.TP
.B \-\-nameprefixes
Add an "LVM2_" prefix plus the field name to the output. Useful
with \fB\-\-noheadings\fP to produce a list of field=value pairs that can
diff --git a/man/vgdisplay.8.in b/man/vgdisplay.8.in
index 97cb314..1e472d3 100644
--- a/man/vgdisplay.8.in
+++ b/man/vgdisplay.8.in
@@ -26,6 +26,7 @@ vgdisplay \(em display attributes of volume groups
.B vgdisplay
.BR \-C | \-\-columns
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
diff --git a/man/vgs.8.in b/man/vgs.8.in
index de0ef9b..6dd52f1 100644
--- a/man/vgs.8.in
+++ b/man/vgs.8.in
@@ -5,6 +5,7 @@ vgs \(em report information about volume groups
.B vgs
.RB [ \-a | \-\-all ]
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
@@ -43,6 +44,11 @@ List all volume groups. Equivalent to not specifying any volume groups.
.B \-\-aligned
Use with \fB\-\-separator\fP to align the output columns.
.TP
+.B \-\-binary
+Use binary values "0" or "1" instead of descriptive literal values
+for columns that have exactly two valid values to report (not counting
+the "unknown" value which denotes that the value could not be determined).
+.TP
.B \-\-nameprefixes
Add an "LVM2_" prefix plus the field name to the output. Useful
with \fB\-\-noheadings\fP to produce a list of field=value pairs that can
diff --git a/tools/args.h b/tools/args.h
index 54e225f..d4a8643 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -32,6 +32,7 @@ arg(restorefile_ARG, '\0', "restorefile", string_arg, 0)
arg(labelsector_ARG, '\0', "labelsector", int_arg, 0)
arg(driverloaded_ARG, '\0', "driverloaded", yes_no_arg, 0)
arg(aligned_ARG, '\0', "aligned", NULL, 0)
+arg(binary_ARG, '\0', "binary", NULL, 0)
arg(unbuffered_ARG, '\0', "unbuffered", NULL, 0)
arg(noheadings_ARG, '\0', "noheadings", NULL, 0)
arg(segments_ARG, '\0', "segments", NULL, 0)
diff --git a/tools/commands.h b/tools/commands.h
index 1484aef..7d36bc5 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -33,6 +33,7 @@ xx(devtypes,
PERMITTED_READ_ONLY,
"devtypes" "\n"
"\t[--aligned]\n"
+ "\t[--binary]\n"
"\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
@@ -49,7 +50,7 @@ xx(devtypes,
"\t[-v|--verbose]\n"
"\t[--version]" "\n",
- aligned_ARG, nameprefixes_ARG,
+ aligned_ARG, binary_ARG, nameprefixes_ARG,
noheadings_ARG, nosuffix_ARG, options_ARG,
rows_ARG, select_ARG, separator_ARG, sort_ARG,
unbuffered_ARG, unquoted_ARG)
@@ -562,6 +563,7 @@ xx(lvs,
"lvs" "\n"
"\t[-a|--all]\n"
"\t[--aligned]\n"
+ "\t[--binary]\n"
"\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
@@ -586,11 +588,11 @@ xx(lvs,
"\t[--version]" "\n"
"\t[LogicalVolume[Path] [LogicalVolume[Path]...]]\n",
- aligned_ARG, all_ARG, ignorelockingfailure_ARG, ignoreskippedcluster_ARG,
- nameprefixes_ARG, noheadings_ARG, nolocking_ARG, nosuffix_ARG, options_ARG,
- partial_ARG, readonly_ARG, rows_ARG, segments_ARG, select_ARG,
- separator_ARG, sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG,
- unquoted_ARG)
+ aligned_ARG, all_ARG, binary_ARG, ignorelockingfailure_ARG,
+ ignoreskippedcluster_ARG, nameprefixes_ARG, noheadings_ARG,
+ nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG,
+ readonly_ARG, rows_ARG, segments_ARG, select_ARG, separator_ARG,
+ sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG, unquoted_ARG)
xx(lvscan,
"List all logical volumes in all volume groups",
@@ -806,6 +808,7 @@ xx(pvs,
"pvs" "\n"
"\t[-a|--all]\n"
"\t[--aligned]\n"
+ "\t[--binary]\n"
"\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]" "\n"
"\t[-h|-?|--help] " "\n"
@@ -830,10 +833,11 @@ xx(pvs,
"\t[--version]\n"
"\t[PhysicalVolume [PhysicalVolume...]]\n",
- aligned_ARG, all_ARG, ignorelockingfailure_ARG, ignoreskippedcluster_ARG,
- nameprefixes_ARG, noheadings_ARG, nolocking_ARG, nosuffix_ARG, options_ARG,
- partial_ARG, readonly_ARG, rows_ARG, segments_ARG, select_ARG, separator_ARG,
- sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG, unquoted_ARG)
+ aligned_ARG, all_ARG, binary_ARG, ignorelockingfailure_ARG,
+ ignoreskippedcluster_ARG, nameprefixes_ARG, noheadings_ARG, nolocking_ARG,
+ nosuffix_ARG, options_ARG, partial_ARG, readonly_ARG, rows_ARG,
+ segments_ARG, select_ARG, separator_ARG, sort_ARG, trustcache_ARG,
+ unbuffered_ARG, units_ARG, unquoted_ARG)
xx(pvscan,
"List all physical volumes",
@@ -1194,6 +1198,7 @@ xx(vgs,
PERMITTED_READ_ONLY,
"vgs" "\n"
"\t[--aligned]\n"
+ "\t[--binary]\n"
"\t[-a|--all]\n"
"\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
@@ -1218,9 +1223,10 @@ xx(vgs,
"\t[--version]\n"
"\t[VolumeGroupName [VolumeGroupName...]]\n",
- aligned_ARG, all_ARG, ignorelockingfailure_ARG, ignoreskippedcluster_ARG,
- nameprefixes_ARG, noheadings_ARG, nolocking_ARG, nosuffix_ARG, options_ARG,
- partial_ARG, readonly_ARG, rows_ARG, select_ARG, separator_ARG, sort_ARG,
+ aligned_ARG, all_ARG, binary_ARG, ignorelockingfailure_ARG,
+ ignoreskippedcluster_ARG, nameprefixes_ARG, noheadings_ARG,
+ nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG,
+ readonly_ARG, rows_ARG, select_ARG, separator_ARG, sort_ARG,
trustcache_ARG, unbuffered_ARG, units_ARG, unquoted_ARG)
xx(vgscan,
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 66f691e..780e9d0 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -930,6 +930,9 @@ static int _get_settings(struct cmd_context *cmd)
return EINVALID_CMD_LINE;
}
+ if (arg_count(cmd, binary_ARG))
+ cmd->report_binary_values_as_numeric = 1;
+
if (arg_count(cmd, trustcache_ARG)) {
if (arg_count(cmd, all_ARG)) {
log_error("--trustcache is incompatible with --all");
9 years, 10 months
master - report: add separate fields for PV/VG/LV attributes
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d2af4f84c94cb8...
Commit: d2af4f84c94cb8202565ac32c5f1df673cd92e0c
Parent: 4b9b1f23199edb7e02230481a5e53ac1fa548384
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 2 11:09:14 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:40:17 2014 +0200
report: add separate fields for PV/VG/LV attributes
Physical Volume Fields:
pv_allocatable - Whether this device can be used for allocation.
pv_exported - Whether this device is exported.
pv_missing - Whether this device is missing in system.
Volume Group Fields:
vg_permissions - VG permissions.
vg_extendable - Whether VG is extendable.
vg_exported - Whether VG is exported.
vg_partial - Whether VG is partial.
vg_allocation_policy - VG allocation policy.
vg_clustered - Whether VG is clustered.
Logical Volume Fields:
lv_volume_type - LV volume type.
lv_initial_image_sync - Whether mirror/RAID images underwent initial resynchronization.
lv_image_synced - Whether mirror/RAID image is synchronized.
lv_merging - Whether snapshot LV is being merged to origin.
lv_converting - Whether LV is being converted.
lv_allocation_policy - LV allocation policy.
lv_allocation_locked - Whether LV is locked against allocation changes.
lv_fixed_minor - Whether LV has fixed minor number assigned.
lv_merge_failed - Whether snapshot merge failed.
lv_snapshot_invalid - Whether snapshot LV is invalid.
lv_target_type - Kernel target type the LV is related to.
lv_health_status - LV health status.
lv_skip_activation - Whether LV is skipped on activation.
Logical Volume Info Fields
lv_permissions - LV permissions.
lv_suspended - Whether LV is suspended.
lv_live_table - Whether LV has live table present.
lv_inactive_table - Whether LV has inactive table present.
lv_device_open - Whether LV device is open.
---
lib/properties/prop_common.h | 9 +-
lib/report/columns.h | 27 ++++
lib/report/properties.c | 60 ++++++++
lib/report/report.c | 333 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 425 insertions(+), 4 deletions(-)
diff --git a/lib/properties/prop_common.h b/lib/properties/prop_common.h
index 6d4c2e4..d7d01af 100644
--- a/lib/properties/prop_common.h
+++ b/lib/properties/prop_common.h
@@ -122,12 +122,13 @@ static int _ ## NAME ## _get (const void *obj, struct lvm_property_type *prop) \
#define STR 1
#define NUM 2
-#define SIZ 3
-#define PCT 4
-#define STR_LIST 5
+#define BIN 3
+#define SIZ 4
+#define PCT 5
+#define STR_LIST 6
#define FIELD_MODIFIABLE 0x00000001
#define FIELD(type, strct, field_type, head, field, width, fn, id, desc, settable) \
- { type, #id, settable, field_type == STR, ((field_type == NUM) || (field_type == SIZ) || (field_type == PCT)), { .integer = 0 }, _ ## id ## _get, _ ## id ## _set },
+ { type, #id, settable, field_type == STR, ((field_type == NUM) || (field_type == BIN) || (field_type == SIZ) || (field_type == PCT)), { .integer = 0 }, _ ## id ## _get, _ ## id ## _set },
#endif
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 96c30d4..2769c2d 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -35,6 +35,19 @@ FIELD(LVS, lv, STR, "Path", lvid, 4, lvpath, lv_path, "Full pathname for LV. Bla
FIELD(LVS, lv, STR, "DMPath", lvid, 6, lvdmpath, lv_dm_path, "Internal device-mapper pathname for LV (in /dev/mapper directory).", 0)
FIELD(LVS, lv, STR, "Parent", lvid, 6, lvparent, lv_parent, "For LVs that are components of another LV, the parent LV.", 0)
FIELD(LVS, lv, STR, "Attr", lvid, 4, lvstatus, lv_attr, "Various attributes - see man page.", 0)
+FIELD(LVS, lv, STR, "Type", lvid, 10, lvvolumetype, lv_volume_type, "LV volume type.", 0)
+FIELD(LVS, lv, BIN, "InitImgSync", lvid, 10, lvinitialimagesync, lv_initial_image_sync, "Whether mirror/RAID images underwent initial resynchronization.", 0)
+FIELD(LVS, lv, BIN, "ImgSynced", lvid, 10, lvimagesynced, lv_image_synced, "Whether mirror/RAID image is synchronized.", 0)
+FIELD(LVS, lv, BIN, "Merging", lvid, 10, lvmerging, lv_merging, "Whether snapshot LV is being merged to origin.", 0)
+FIELD(LVS, lv, BIN, "Converting", lvid, 10, lvconverting, lv_converting, "Whether LV is being converted.", 0)
+FIELD(LVS, lv, STR, "AllocPol", lvid, 10, lvallocationpolicy, lv_allocation_policy, "LV allocation policy.", 0)
+FIELD(LVS, lv, BIN, "AllocLock", lvid, 10, lvallocationlocked, lv_allocation_locked, "Whether LV is locked against allocation changes.", 0)
+FIELD(LVS, lv, BIN, "FixMin", lvid, 10, lvfixedminor, lv_fixed_minor, "Whether LV has fixed minor number assigned.", 0)
+FIELD(LVS, lv, BIN, "MergeFailed", lvid, 15, lvmergefailed, lv_merge_failed, "Whether snapshot merge failed.", 0)
+FIELD(LVS, lv, BIN, "SnapInvalid", lvid, 15, lvsnapshotinvalid, lv_snapshot_invalid, "Whether snapshot LV is invalid.", 0)
+FIELD(LVS, lv, STR, "TargetType", lvid, 10, lvtargettype, lv_target_type, "Kernel target type the LV is related to.", 0)
+FIELD(LVS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
+FIELD(LVS, lv, BIN, "SkipAct", lvid, 15, lvskipactivation, lv_skip_activation, "Whether LV is skipped on activation.", 0)
FIELD(LVS, lv, STR, "Active", lvid, 6, lvactive, lv_active, "Active state of the LV.", 0)
FIELD(LVS, lv, NUM, "Maj", major, 3, int32, lv_major, "Persistent major number or -1 if not persistent.", 0)
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, lv_minor, "Persistent minor number or -1 if not persistent.", 0)
@@ -69,6 +82,11 @@ FIELD(LVS, lv, STR_LIST, "Modules", lvid, 7, modules, lv_modules, "Kernel device
FIELD(LVSINFO, lv, NUM, "KMaj", lvid, 4, lvkmaj, lv_kernel_major, "Currently assigned major number or -1 if LV is not active.", 0)
FIELD(LVSINFO, lv, NUM, "KMin", lvid, 4, lvkmin, lv_kernel_minor, "Currently assigned minor number or -1 if LV is not active.", 0)
FIELD(LVSINFO, lv, SIZ, "KRahead", lvid, 7, lvkreadahead, lv_kernel_read_ahead, "Currently-in-use read ahead setting in current units.", 0)
+FIELD(LVSINFO, lv, STR, "LPerms", lvid, 8, lvpermissions, lv_permissions, "LV permissions.", 0)
+FIELD(LVSINFO, lv, BIN, "Suspended", lvid, 10, lvsuspended, lv_suspended, "Whether LV is suspended.", 0)
+FIELD(LVSINFO, lv, BIN, "LiveTable", lvid, 20, lvlivetable, lv_live_table, "Whether LV has live table present.", 0)
+FIELD(LVSINFO, lv, BIN, "InactiveTable", lvid, 20, lvinactivetable, lv_inactive_table, "Whether LV has inactive table present.", 0)
+FIELD(LVSINFO, lv, BIN, "DevOpen", lvid, 10, lvdeviceopen, lv_device_open, "Whether LV device is open.", 0)
FIELD(LABEL, label, STR, "Fmt", type, 3, pvfmt, pv_fmt, "Type of metadata.", 0)
FIELD(LABEL, label, STR, "PV UUID", type, 38, pvuuid, pv_uuid, "Unique identifier.", 0)
@@ -82,6 +100,9 @@ FIELD(PVS, pv, SIZ, "PSize", id, 5, pvsize, pv_size, "Size of PV in current unit
FIELD(PVS, pv, SIZ, "PFree", id, 5, pvfree, pv_free, "Total amount of unallocated space in current units.", 0)
FIELD(PVS, pv, SIZ, "Used", id, 4, pvused, pv_used, "Total amount of allocated space in current units.", 0)
FIELD(PVS, pv, STR, "Attr", id, 4, pvstatus, pv_attr, "Various attributes - see man page.", 0)
+FIELD(PVS, pv, BIN, "Allocatable", id, 10, pvallocatable, pv_allocatable, "Whether this device can be used for allocation.", 0)
+FIELD(PVS, pv, BIN, "Exported", id, 10, pvexported, pv_exported, "Whether this device is exported.", 0)
+FIELD(PVS, pv, BIN, "Missing", id, 10, pvmissing, pv_missing, "Whether this device is missing in system.", 0)
FIELD(PVS, pv, NUM, "PE", pe_count, 3, uint32, pv_pe_count, "Total number of Physical Extents.", 0)
FIELD(PVS, pv, NUM, "Alloc", pe_alloc_count, 5, uint32, pv_pe_alloc_count, "Total number of allocated Physical Extents.", 0)
FIELD(PVS, pv, STR_LIST, "PV Tags", tags, 7, tags, pv_tags, "Tags, if any.", 0)
@@ -94,6 +115,12 @@ FIELD(VGS, vg, STR, "Fmt", cmd, 3, vgfmt, vg_fmt, "Type of metadata.", 0)
FIELD(VGS, vg, STR, "VG UUID", id, 38, uuid, vg_uuid, "Unique identifier.", 0)
FIELD(VGS, vg, STR, "VG", name, 4, string, vg_name, "Name.", 0)
FIELD(VGS, vg, STR, "Attr", cmd, 5, vgstatus, vg_attr, "Various attributes - see man page.", 0)
+FIELD(VGS, vg, STR, "VPerms", cmd, 10, vgpermissions, vg_permissions, "VG permissions.", 0)
+FIELD(VGS, vg, BIN, "Extendable", cmd, 10, vgextendable, vg_extendable, "Whether VG is extendable.", 0)
+FIELD(VGS, vg, BIN, "Exported", cmd, 10, vgexported, vg_exported, "Whether VG is exported.", 0)
+FIELD(VGS, vg, BIN, "Partial", cmd, 10, vgpartial, vg_partial, "Whether VG is partial.", 0)
+FIELD(VGS, vg, STR, "AllocPol", cmd, 10, vgallocationpolicy, vg_allocation_policy, "VG allocation policy.", 0)
+FIELD(VGS, vg, BIN, "Clustered", cmd, 10, vgclustered, vg_clustered, "Whether VG is clustered.", 0)
FIELD(VGS, vg, SIZ, "VSize", cmd, 5, vgsize, vg_size, "Total size of VG in current units.", 0)
FIELD(VGS, vg, NUM, "VFree", cmd, 5, vgfree, vg_free, "Total amount of free space in current units.", 0)
FIELD(VGS, vg, STR, "SYS ID", system_id, 6, string, vg_sysid, "System ID indicating when and where it was created.", 0)
diff --git a/lib/report/properties.c b/lib/report/properties.c
index d6f14f1..8fb1e92 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -159,6 +159,65 @@ GET_PV_NUM_PROPERTY_FN(pv_ba_start, SECTOR_SIZE * pv->ba_start)
GET_PV_NUM_PROPERTY_FN(pv_ba_size, SECTOR_SIZE * pv->ba_size)
#define _pv_ba_size_set prop_not_implemented_set
+#define _pv_allocatable_set prop_not_implemented_set
+#define _pv_allocatable_get prop_not_implemented_get
+#define _pv_exported_set prop_not_implemented_set
+#define _pv_exported_get prop_not_implemented_get
+#define _pv_missing_set prop_not_implemented_set
+#define _pv_missing_get prop_not_implemented_get
+
+#define _vg_permissions_set prop_not_implemented_set
+#define _vg_permissions_get prop_not_implemented_get
+#define _vg_extendable_set prop_not_implemented_set
+#define _vg_extendable_get prop_not_implemented_get
+#define _vg_exported_set prop_not_implemented_set
+#define _vg_exported_get prop_not_implemented_get
+#define _vg_partial_set prop_not_implemented_set
+#define _vg_partial_get prop_not_implemented_get
+#define _vg_allocation_policy_set prop_not_implemented_set
+#define _vg_allocation_policy_get prop_not_implemented_get
+#define _vg_clustered_set prop_not_implemented_set
+#define _vg_clustered_get prop_not_implemented_get
+
+#define _lv_volume_type_set prop_not_implemented_set
+#define _lv_volume_type_get prop_not_implemented_get
+#define _lv_initial_image_sync_set prop_not_implemented_set
+#define _lv_initial_image_sync_get prop_not_implemented_get
+#define _lv_image_synced_get prop_not_implemented_get
+#define _lv_image_synced_set prop_not_implemented_set
+#define _lv_image_synced_get prop_not_implemented_get
+#define _lv_merging_set prop_not_implemented_set
+#define _lv_merging_get prop_not_implemented_get
+#define _lv_converting_set prop_not_implemented_set
+#define _lv_converting_get prop_not_implemented_get
+#define _lv_permissions_set prop_not_implemented_set
+#define _lv_permissions_get prop_not_implemented_get
+#define _lv_allocation_policy_set prop_not_implemented_set
+#define _lv_allocation_policy_get prop_not_implemented_get
+#define _lv_allocation_locked_set prop_not_implemented_set
+#define _lv_allocation_locked_get prop_not_implemented_get
+#define _lv_fixed_minor_set prop_not_implemented_set
+#define _lv_fixed_minor_get prop_not_implemented_get
+#define _lv_merge_failed_set prop_not_implemented_set
+#define _lv_merge_failed_get prop_not_implemented_get
+#define _lv_snapshot_invalid_set prop_not_implemented_set
+#define _lv_snapshot_invalid_get prop_not_implemented_get
+#define _lv_suspended_set prop_not_implemented_set
+#define _lv_suspended_get prop_not_implemented_get
+#define _lv_live_table_set prop_not_implemented_set
+#define _lv_live_table_get prop_not_implemented_get
+#define _lv_inactive_table_set prop_not_implemented_set
+#define _lv_inactive_table_get prop_not_implemented_get
+#define _lv_device_open_set prop_not_implemented_set
+#define _lv_device_open_get prop_not_implemented_get
+#define _lv_target_type_set prop_not_implemented_set
+#define _lv_target_type_get prop_not_implemented_get
+#define _lv_health_status_set prop_not_implemented_set
+#define _lv_health_status_get prop_not_implemented_get
+#define _lv_target_type_get prop_not_implemented_get
+#define _lv_skip_activation_set prop_not_implemented_set
+#define _lv_skip_activation_get prop_not_implemented_get
+
/* LV */
GET_LV_STR_PROPERTY_FN(lv_uuid, lv_uuid_dup(lv))
#define _lv_uuid_set prop_not_implemented_set
@@ -348,6 +407,7 @@ struct lvm_property_type _properties[] = {
#undef STR
#undef NUM
+#undef BIN
#undef SIZ
#undef PCT
#undef STR_LIST
diff --git a/lib/report/report.c b/lib/report/report.c
index 27d2de7..d74321e 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -42,6 +42,7 @@ struct lvm_report_object {
};
static const uint64_t _zero64 = UINT64_C(0);
+static const uint64_t _one64 = UINT64_C(1);
static const uint64_t _reserved_number_undef_64 = UINT64_C(-1);
static const uint64_t _reserved_number_unmanaged_64 = UINT64_C(-2);
@@ -68,6 +69,8 @@ static const struct dm_report_reserved_value _report_reserved_values[] = {
{0, NULL, NULL}
};
+static const char *_str_unknown = "unknown";
+
static int _field_set_value(struct dm_report_field *field, const void *data, const void *sort)
{
dm_report_field_set_value(field, data, sort);
@@ -1168,6 +1171,334 @@ static int _lvactive_disp(struct dm_report *rh, struct dm_pool *mem,
return _field_set_value(field, repstr, NULL);
}
+/* PV/VG/LV Attributes */
+
+static int _binary_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
+ struct dm_report_field *field, int bin_value, const char *word,
+ void *private)
+{
+ return _field_set_value(field, bin_value ? word : "", bin_value ? &_one64 : &_zero64);
+}
+
+static int _pvallocatable_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int allocatable = (((const struct physical_volume *) data)->status & ALLOCATABLE_PV) != 0;
+ return _binary_disp(rh, mem, field, allocatable, "allocatable", private);
+}
+
+static int _pvexported_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int exported = (((const struct physical_volume *) data)->status & EXPORTED_VG) != 0;
+ return _binary_disp(rh, mem, field, exported, "exported", private);
+}
+
+static int _pvmissing_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int missing = (((const struct physical_volume *) data)->status & MISSING_PV) != 0;
+ return _binary_disp(rh, mem, field, missing, "missing", private);
+}
+
+static int _vgpermissions_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const char *perms = ((const struct volume_group *) data)->status & LVM_WRITE ? "writeable" : "read-only";
+ return _string_disp(rh, mem, field, &perms, private);
+}
+
+static int _vgextendable_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int extendable = (vg_is_resizeable((const struct volume_group *) data)) != 0;
+ return _binary_disp(rh, mem, field, extendable, "extendable", private);
+}
+
+static int _vgexported_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int exported = (vg_is_exported((const struct volume_group *) data)) != 0;
+ return _binary_disp(rh, mem, field, exported, "exported", private);
+}
+
+static int _vgpartial_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int partial = (vg_missing_pv_count((const struct volume_group *) data)) != 0;
+ return _binary_disp(rh, mem, field, partial, "partial", private);
+}
+
+static int _vgallocationpolicy_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const char *alloc_policy = get_alloc_string(((const struct volume_group *) data)->alloc) ? : _str_unknown;
+ return _string_disp(rh, mem, field, &alloc_policy, private);
+}
+
+static int _vgclustered_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int clustered = (vg_is_clustered((const struct volume_group *) data)) != 0;
+ return _binary_disp(rh, mem, field, clustered, "clustered", private);
+}
+
+static int _lvvolumetype_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const char *type = lv_type_name((const struct logical_volume *) data);
+ return _string_disp(rh, mem, field, &type, private);
+}
+
+static int _lvinitialimagesync_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ int initial_image_sync;
+
+ if (lv_is_raid(lv) || lv_is_mirrored(lv))
+ initial_image_sync = (lv->status & LV_NOTSYNCED) == 0;
+ else
+ initial_image_sync = 0;
+
+ return _binary_disp(rh, mem, field, initial_image_sync, "initial image sync", private);
+}
+
+static int _lvimagesynced_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ int image_synced;
+
+ if (lv_is_raid_image(lv))
+ image_synced = !lv_is_visible(lv) && lv_raid_image_in_sync(lv);
+ else if (lv_is_mirror_image(lv))
+ image_synced = lv_mirror_image_in_sync(lv);
+ else
+ image_synced = 0;
+
+ return _binary_disp(rh, mem, field, image_synced, "image synced", private);
+}
+
+static int _lvmerging_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ int merging;
+
+ if (lv_is_origin(lv) || lv_is_external_origin(lv))
+ merging = lv_is_merging_origin(lv);
+ else if (lv_is_cow(lv))
+ merging = lv_is_merging_cow(lv);
+ else if (lv_is_thin_volume(lv))
+ merging = lv_is_merging_thin_snapshot(lv);
+ else
+ merging = 0;
+
+ return _binary_disp(rh, mem, field, merging, "merging", private);
+}
+
+static int _lvconverting_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int converting = (((const struct logical_volume *) data)->status & CONVERTING) != 0;
+ return _binary_disp(rh, mem, field, converting, "converting", private);
+}
+
+static int _lvpermissions_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct lv_with_info *lvi = (const struct lv_with_info *) data;
+ const char *perms = "";
+
+ if (!(lvi->lv->status & PVMOVE)) {
+ if (lvi->lv->status & LVM_WRITE) {
+ if (lvi->info->read_only)
+ perms = "read-only-override";
+ else
+ perms = "writeable";
+ } else if (lvi->lv->status & LVM_READ)
+ perms = "read-only";
+ else
+ perms = _str_unknown;
+ }
+
+ return _string_disp(rh, mem, field, &perms, private);
+}
+
+static int _lvallocationpolicy_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const char *alloc_policy = get_alloc_string(((const struct logical_volume *) data)->alloc) ? : _str_unknown;
+ return _string_disp(rh, mem, field, &alloc_policy, private);
+}
+
+static int _lvallocationlocked_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int alloc_locked = (((const struct logical_volume *) data)->status & LOCKED) != 0;
+ return _binary_disp(rh, mem, field, alloc_locked, "allocation locked", private);
+}
+
+static int _lvfixedminor_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int fixed_minor = (((const struct logical_volume *) data)->status & FIXED_MINOR) != 0;
+ return _binary_disp(rh, mem, field, fixed_minor, "fixed minor", private);
+}
+
+static int _lvmergefailed_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ dm_percent_t snap_percent;
+ int merge_failed;
+
+ if (!lv_is_cow(lv) || !lv_snapshot_percent(lv, &snap_percent))
+ return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+
+ merge_failed = snap_percent == LVM_PERCENT_MERGE_FAILED;
+ return _binary_disp(rh, mem, field, merge_failed, "merge failed", private);
+}
+
+static int _lvsnapshotinvalid_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ dm_percent_t snap_percent;
+ int snap_invalid;
+
+ if (!lv_is_cow(lv))
+ return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+
+ snap_invalid = !lv_snapshot_percent(lv, &snap_percent) || snap_percent == DM_PERCENT_INVALID;
+ return _binary_disp(rh, mem, field, snap_invalid, "snapshot invalid", private);
+}
+
+static int _lvsuspended_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct lv_with_info *lvi = (const struct lv_with_info *) data;
+
+ if (lvi->info->exists)
+ return _binary_disp(rh, mem, field, lvi->info->suspended, "suspended", private);
+
+ return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+}
+
+static int _lvlivetable_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct lv_with_info *lvi = (const struct lv_with_info *) data;
+
+ if (lvi->info->exists)
+ return _binary_disp(rh, mem, field, lvi->info->live_table, "live table present", private);
+
+ return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+}
+
+static int _lvinactivetable_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct lv_with_info *lvi = (const struct lv_with_info *) data;
+
+ if (lvi->info->exists)
+ return _binary_disp(rh, mem, field, lvi->info->inactive_table, "inactive table present", private);
+
+ return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+}
+
+static int _lvdeviceopen_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct lv_with_info *lvi = (const struct lv_with_info *) data;
+
+ if (lvi->info->exists)
+ return _binary_disp(rh, mem, field, lvi->info->open_count, "open", private);
+
+ return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+}
+
+static int _lvtargettype_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ const char *target_type = "unknown";
+
+ if (lv_is_thin_pool(lv) || lv_is_thin_volume(lv))
+ target_type = "thin";
+ else if (lv_is_cache_type(lv))
+ target_type = "cache";
+ else if (lv_is_raid_type(lv))
+ target_type = "raid";
+ else if (lv_is_mirror_type(lv))
+ target_type = "mirror";
+ else if (lv_is_cow(lv) || lv_is_origin(lv))
+ target_type = "snapshot";
+ else if (lv_is_virtual(lv))
+ target_type = "virtual";
+
+ return _string_disp(rh, mem, field, &target_type, private);
+}
+
+static int _lvhealthstatus_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ const char *health = "";
+ uint64_t n;
+
+ if (lv->status & PARTIAL_LV)
+ health = "partial";
+ else if (lv_is_raid_type(lv)) {
+ if (!activation())
+ health = "unknown";
+ else if (!lv_raid_healthy(lv))
+ health = "refresh needed";
+ else if (lv_is_raid(lv)) {
+ if (lv_raid_mismatch_count(lv, &n) && n)
+ health = "mismatches exist";
+ } else if (lv->status & LV_WRITEMOSTLY)
+ health = "writemostly";
+ }
+
+ return _string_disp(rh, mem, field, &health, private);
+}
+
+static int _lvskipactivation_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ int skip_activation = (((const struct logical_volume *) data)->status & LV_ACTIVATION_SKIP) != 0;
+ return _binary_disp(rh, mem, field, skip_activation, "skip activation", private);
+}
+
/* Report object types */
/* necessary for displaying something for PVs not belonging to VG */
@@ -1249,6 +1580,7 @@ static const struct dm_report_object_type _devtypes_report_types[] = {
#define STR DM_REPORT_FIELD_TYPE_STRING
#define NUM DM_REPORT_FIELD_TYPE_NUMBER
+#define BIN DM_REPORT_FIELD_TYPE_NUMBER
#define SIZ DM_REPORT_FIELD_TYPE_SIZE
#define PCT DM_REPORT_FIELD_TYPE_PERCENT
#define STR_LIST DM_REPORT_FIELD_TYPE_STRING_LIST
@@ -1277,6 +1609,7 @@ static const struct dm_report_field_type _devtypes_fields[] = {
#undef STR
#undef NUM
+#undef BIN
#undef SIZ
#undef STR_LIST
#undef FIELD
9 years, 10 months
master - refactor: use new LVSINFO report type for lv_kernel_{major, minor, read_ahead} field
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4b9b1f23199edb...
Commit: 4b9b1f23199edb7e02230481a5e53ac1fa548384
Parent: ecb2be5d1642aa0142d216f9e52f64fd3e8c3fc8
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 2 14:31:39 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:40:17 2014 +0200
refactor: use new LVSINFO report type for lv_kernel_{major,minor,read_ahead} field
---
lib/report/columns.h | 7 ++++---
lib/report/report.c | 21 +++++++++------------
2 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 8d42387..96c30d4 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -39,9 +39,6 @@ FIELD(LVS, lv, STR, "Active", lvid, 6, lvactive, lv_active, "Active state of the
FIELD(LVS, lv, NUM, "Maj", major, 3, int32, lv_major, "Persistent major number or -1 if not persistent.", 0)
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, lv_minor, "Persistent minor number or -1 if not persistent.", 0)
FIELD(LVS, lv, SIZ, "Rahead", lvid, 6, lvreadahead, lv_read_ahead, "Read ahead setting in current units.", 0)
-FIELD(LVS, lv, NUM, "KMaj", lvid, 4, lvkmaj, lv_kernel_major, "Currently assigned major number or -1 if LV is not active.", 0)
-FIELD(LVS, lv, NUM, "KMin", lvid, 4, lvkmin, lv_kernel_minor, "Currently assigned minor number or -1 if LV is not active.", 0)
-FIELD(LVS, lv, SIZ, "KRahead", lvid, 7, lvkreadahead, lv_kernel_read_ahead, "Currently-in-use read ahead setting in current units.", 0)
FIELD(LVS, lv, SIZ, "LSize", size, 5, size64, lv_size, "Size of LV in current units.", 0)
FIELD(LVS, lv, SIZ, "MSize", lvid, 6, lvmetadatasize, lv_metadata_size, "For thin pools, the size of the LV that holds the metadata.", 0)
FIELD(LVS, lv, NUM, "#Seg", lvid, 4, lvsegcount, seg_count, "Number of segments in LV.", 0)
@@ -69,6 +66,10 @@ FIELD(LVS, lv, STR, "Time", lvid, 26, lvtime, lv_time, "Creation time of the LV,
FIELD(LVS, lv, STR, "Host", lvid, 10, lvhost, lv_host, "Creation host of the LV, if known.", 0)
FIELD(LVS, lv, STR_LIST, "Modules", lvid, 7, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 0)
+FIELD(LVSINFO, lv, NUM, "KMaj", lvid, 4, lvkmaj, lv_kernel_major, "Currently assigned major number or -1 if LV is not active.", 0)
+FIELD(LVSINFO, lv, NUM, "KMin", lvid, 4, lvkmin, lv_kernel_minor, "Currently assigned minor number or -1 if LV is not active.", 0)
+FIELD(LVSINFO, lv, SIZ, "KRahead", lvid, 7, lvkreadahead, lv_kernel_read_ahead, "Currently-in-use read ahead setting in current units.", 0)
+
FIELD(LABEL, label, STR, "Fmt", type, 3, pvfmt, pv_fmt, "Type of metadata.", 0)
FIELD(LABEL, label, STR, "PV UUID", type, 38, pvuuid, pv_uuid, "Unique identifier.", 0)
FIELD(LABEL, label, SIZ, "DevSize", dev, 7, devsize, dev_size, "Size of underlying device in current units.", 0)
diff --git a/lib/report/report.c b/lib/report/report.c
index eb4c5ac..27d2de7 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -195,11 +195,10 @@ static int _lvkmaj_disp(struct dm_report *rh, struct dm_pool *mem __attribute__(
struct dm_report_field *field,
const void *data, void *private __attribute__((unused)))
{
- const struct logical_volume *lv = (const struct logical_volume *) data;
- int major;
+ const struct lv_with_info *lvi = (const struct lv_with_info *) data;
- if ((major = lv_kernel_major(lv)) >= 0)
- return dm_report_field_int(rh, field, &major);
+ if (lvi->info && lvi->info->exists && lvi->info->major >= 0)
+ return dm_report_field_int(rh, field, &lvi->info->major);
return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
}
@@ -208,11 +207,10 @@ static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute__(
struct dm_report_field *field,
const void *data, void *private __attribute__((unused)))
{
- const struct logical_volume *lv = (const struct logical_volume *) data;
- int minor;
+ const struct lv_with_info *lvi = (const struct lv_with_info *) data;
- if ((minor = lv_kernel_minor(lv)) >= 0)
- return dm_report_field_int(rh, field, &minor);
+ if (lvi->info && lvi->info->exists && lvi->info->minor >= 0)
+ return dm_report_field_int(rh, field, &lvi->info->minor);
return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
}
@@ -549,13 +547,12 @@ static int _lvkreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data,
void *private)
{
- const struct logical_volume *lv = (const struct logical_volume *) data;
- uint32_t read_ahead = lv_kernel_read_ahead(lv);
+ const struct lv_with_info *lvi = (const struct lv_with_info *) data;
- if (read_ahead == UINT32_MAX)
+ if (!lvi->info || !lvi->info->exists)
return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
- return _size32_disp(rh, mem, field, &read_ahead, private);
+ return _size32_disp(rh, mem, field, &lvi->info->read_ahead, private);
}
static int _vgsize_disp(struct dm_report *rh, struct dm_pool *mem,
9 years, 10 months
master - reporter: add separate LVSINFO report type
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ecb2be5d1642aa...
Commit: ecb2be5d1642aa0142d216f9e52f64fd3e8c3fc8
Parent: 6b58647848dca8f0e7bab04f4c6491dab28173ff
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 2 09:45:53 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:40:17 2014 +0200
reporter: add separate LVSINFO report type
LVSINFO is exactly the same as existing LVS report type,
but it has the "struct lvinfo" populated in addition for
use - this is useful for fields that display the status
of the LV device itself (e.g. suspended state, tables
present/missing...).
Currently, such properties are reported within the "lv_attr"
field so separation is unnecessary - the "lvinfo" call
to populate the "struct lvinfo" is directly a part of the
field reporting function - _lvstatus_disp/lv_attr_dup.
With upcoming patches, we'd like the lv_attr field bits
to be separated into their own fields. To avoid calling
"lvinfo" fn as many times as there are fields requiring
the "lv_info" structure to be populated while reporting
one row related to one LV, we're separating former LVS
into LVS and LVSINFO report type. With this, there's
just one "lvinfo" call for one report row and LV reporting
fields will take the info needed from this struct then,
hence reusing it and not calling "lvinfo" fn on their own.
---
lib/report/report.c | 20 ++++++++++++++++----
lib/report/report.h | 16 +++++++++-------
tools/reporter.c | 32 ++++++++++++++++++++++++++------
3 files changed, 51 insertions(+), 17 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index 3b71989..eb4c5ac 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -27,9 +27,14 @@
#include <stddef.h> /* offsetof() */
+struct lv_with_info {
+ struct logical_volume *lv;
+ struct lvinfo *info;
+};
+
struct lvm_report_object {
struct volume_group *vg;
- struct logical_volume *lv;
+ struct lv_with_info *lvi;
struct physical_volume *pv;
struct lv_segment *seg;
struct pv_segment *pvseg;
@@ -1192,7 +1197,12 @@ static void *_obj_get_vg(void *obj)
static void *_obj_get_lv(void *obj)
{
- return ((struct lvm_report_object *)obj)->lv;
+ return ((struct lvm_report_object *)obj)->lvi->lv;
+}
+
+static void *_obj_get_lv_with_info(void *obj)
+{
+ return ((struct lvm_report_object *)obj)->lvi;
}
static void *_obj_get_pv(void *obj)
@@ -1223,6 +1233,7 @@ static void *_obj_get_devtypes(void *obj)
static const struct dm_report_object_type _report_types[] = {
{ VGS, "Volume Group", "vg_", _obj_get_vg },
{ LVS, "Logical Volume", "lv_", _obj_get_lv },
+ { LVSINFO, "Logical Volume Device", "lv_", _obj_get_lv_with_info },
{ PVS, "Physical Volume", "pv_", _obj_get_pv },
{ LABEL, "Physical Volume Label", "pv_", _obj_get_label },
{ SEGS, "Logical Volume Segment", "seg_", _obj_get_seg },
@@ -1318,13 +1329,14 @@ void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
int report_object(void *handle, struct volume_group *vg,
struct logical_volume *lv, struct physical_volume *pv,
struct lv_segment *seg, struct pv_segment *pvseg,
- struct label *label)
+ struct lvinfo *lvinfo, struct label *label)
{
struct device dummy_device = { .dev = 0 };
struct label dummy_label = { .dev = &dummy_device };
+ struct lv_with_info lvi = { .lv = lv, .info = lvinfo };
struct lvm_report_object obj = {
.vg = vg,
- .lv = lv,
+ .lvi = &lvi,
.pv = pv,
.seg = seg,
.pvseg = pvseg,
diff --git a/lib/report/report.h b/lib/report/report.h
index a89a637..089fc15 100644
--- a/lib/report/report.h
+++ b/lib/report/report.h
@@ -18,15 +18,17 @@
#include "metadata-exported.h"
#include "label.h"
+#include "activate.h"
typedef enum {
LVS = 1,
- PVS = 2,
- VGS = 4,
- SEGS = 8,
- PVSEGS = 16,
- LABEL = 32,
- DEVTYPES = 64
+ LVSINFO = 2,
+ PVS = 4,
+ VGS = 8,
+ SEGS = 16,
+ PVSEGS = 32,
+ LABEL = 64,
+ DEVTYPES = 128
} report_type_t;
struct field;
@@ -43,7 +45,7 @@ void report_free(void *handle);
int report_object(void *handle, struct volume_group *vg,
struct logical_volume *lv, struct physical_volume *pv,
struct lv_segment *seg, struct pv_segment *pvseg,
- struct label *label);
+ struct lvinfo *lvinfo, struct label *label);
int report_devtypes(void *handle);
int report_output(void *handle);
diff --git a/tools/reporter.c b/tools/reporter.c
index b08d97b..524d6c4 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -31,7 +31,7 @@ static int _vgs_single(struct cmd_context *cmd __attribute__((unused)),
const char *vg_name, struct volume_group *vg,
void *handle)
{
- if (!report_object(handle, vg, NULL, NULL, NULL, NULL, NULL))
+ if (!report_object(handle, vg, NULL, NULL, NULL, NULL, NULL, NULL))
return_ECMD_FAILED;
check_current_backup(vg);
@@ -42,7 +42,21 @@ static int _vgs_single(struct cmd_context *cmd __attribute__((unused)),
static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
- if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL, NULL))
+ if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL, NULL, NULL))
+ return_ECMD_FAILED;
+
+ return ECMD_PROCESSED;
+}
+
+static int _lvs_with_info_single(struct cmd_context *cmd, struct logical_volume *lv,
+ void *handle)
+{
+ struct lvinfo lvinfo;
+
+ if (!lv_info(cmd, lv, 0, &lvinfo, 1, 1))
+ return_ECMD_FAILED;
+
+ if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL, &lvinfo, NULL))
return_ECMD_FAILED;
return ECMD_PROCESSED;
@@ -51,7 +65,7 @@ static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
static int _segs_single(struct cmd_context *cmd __attribute__((unused)),
struct lv_segment *seg, void *handle)
{
- if (!report_object(handle, seg->lv->vg, seg->lv, NULL, seg, NULL, NULL))
+ if (!report_object(handle, seg->lv->vg, seg->lv, NULL, seg, NULL, NULL, NULL))
return_ECMD_FAILED;
return ECMD_PROCESSED;
@@ -107,7 +121,7 @@ static int _pvsegs_sub_single(struct cmd_context *cmd,
dm_list_init(&_free_logical_volume.snapshot_segs);
if (!report_object(handle, vg, seg ? seg->lv : &_free_logical_volume, pvseg->pv,
- seg ? : &_free_lv_segment, pvseg, pv_label(pvseg->pv))) {
+ seg ? : &_free_lv_segment, pvseg, NULL, pv_label(pvseg->pv))) {
ret = ECMD_FAILED;
goto_out;
}
@@ -177,7 +191,7 @@ static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
pv = pvl->pv;
}
- if (!report_object(handle, vg, NULL, pv, NULL, NULL, NULL)) {
+ if (!report_object(handle, vg, NULL, pv, NULL, NULL, NULL, NULL)) {
stack;
ret = ECMD_FAILED;
}
@@ -195,7 +209,7 @@ out:
static int _label_single(struct cmd_context *cmd, struct label *label,
void *handle)
{
- if (!report_object(handle, NULL, NULL, NULL, NULL, NULL, label))
+ if (!report_object(handle, NULL, NULL, NULL, NULL, NULL, NULL, label))
return_ECMD_FAILED;
return ECMD_PROCESSED;
@@ -378,6 +392,8 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
report_type = PVS;
else if (report_type & SEGS)
report_type = SEGS;
+ else if (report_type & LVSINFO)
+ report_type = LVSINFO;
else if (report_type & LVS)
report_type = LVS;
@@ -389,6 +405,10 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
r = process_each_lv(cmd, argc, argv, 0, report_handle,
&_lvs_single);
break;
+ case LVSINFO:
+ r = process_each_lv(cmd, argc, argv, 0, report_handle,
+ &_lvs_with_info_single);
+ break;
case VGS:
r = process_each_vg(cmd, argc, argv, 0,
report_handle, &_vgs_single);
9 years, 10 months
master - lv_manip: add get_lv_type_name/lv_is_linear and lv_is_striped helper fns
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6b58647848dca8...
Commit: 6b58647848dca8f0e7bab04f4c6491dab28173ff
Parent: a4734354ceedffc72314feb5323e73e63d5e8ec8
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Jul 1 10:37:01 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:40:17 2014 +0200
lv_manip: add get_lv_type_name/lv_is_linear and lv_is_striped helper fns
The get_lv_type_name helps with translating volume type
to human readable form (can be used in reports or
various messages if needed).
The lv_is_linear and lv_is_striped complete the set of
lv_is_* functions that identify exact volume types.
---
lib/metadata/lv_manip.c | 147 ++++++++++++++++++++++++++++++++++++++
lib/metadata/metadata-exported.h | 8 ++
2 files changed, 155 insertions(+), 0 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 306a34b..fc98b2a 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -82,6 +82,153 @@ struct pv_and_int {
struct physical_volume *pv;
int *i;
};
+
+typedef enum {
+ LV_TYPE_UNKNOWN,
+ LV_TYPE_PVMOVE,
+ LV_TYPE_ORIGIN,
+ LV_TYPE_EXTERNAL_ORIGIN,
+ LV_TYPE_SNAPSHOT,
+ LV_TYPE_THIN,
+ LV_TYPE_THIN_SNAPSHOT,
+ LV_TYPE_THIN_POOL,
+ LV_TYPE_THIN_POOL_DATA,
+ LV_TYPE_THIN_POOL_METADATA,
+ LV_TYPE_THIN_POOL_METADATA_SPARE,
+ LV_TYPE_CACHE,
+ LV_TYPE_CACHE_POOL,
+ LV_TYPE_CACHE_POOL_DATA,
+ LV_TYPE_CACHE_POOL_METADATA,
+ LV_TYPE_CACHE_POOL_METADATA_SPARE,
+ LV_TYPE_VIRTUAL,
+ LV_TYPE_RAID,
+ LV_TYPE_RAID_IMAGE,
+ LV_TYPE_RAID_METADATA,
+ LV_TYPE_MIRROR,
+ LV_TYPE_MIRROR_IMAGE,
+ LV_TYPE_MIRROR_LOG,
+ LV_TYPE_LINEAR,
+ LV_TYPE_STRIPED
+} lv_type_t;
+
+static const char *_lv_type_names[] = {
+ [LV_TYPE_UNKNOWN] = "unknown",
+ [LV_TYPE_PVMOVE] = "pvmove",
+ [LV_TYPE_ORIGIN] = "origin",
+ [LV_TYPE_EXTERNAL_ORIGIN] = "external-origin",
+ [LV_TYPE_SNAPSHOT] = "snapshot",
+ [LV_TYPE_THIN] = "thin",
+ [LV_TYPE_THIN_SNAPSHOT] = "thin-snapshot",
+ [LV_TYPE_THIN_POOL] = "thin-pool",
+ [LV_TYPE_THIN_POOL_DATA] = "thin-pool-data",
+ [LV_TYPE_THIN_POOL_METADATA] = "thin-pool-metadata",
+ [LV_TYPE_THIN_POOL_METADATA_SPARE] = "thin-pool-metadata-spare",
+ [LV_TYPE_CACHE] = "cache",
+ [LV_TYPE_CACHE_POOL] = "cache-pool",
+ [LV_TYPE_CACHE_POOL_DATA] = "cache-pool-data",
+ [LV_TYPE_CACHE_POOL_METADATA] = "cache-pool-metadata",
+ [LV_TYPE_CACHE_POOL_METADATA_SPARE] = "cache-pool-metadata-spare",
+ [LV_TYPE_VIRTUAL] = "virtual",
+ [LV_TYPE_RAID] = "raid",
+ [LV_TYPE_RAID_IMAGE] = "raid-image",
+ [LV_TYPE_RAID_METADATA] = "raid-metadata",
+ [LV_TYPE_MIRROR] = "mirror",
+ [LV_TYPE_MIRROR_IMAGE] = "mirror-image",
+ [LV_TYPE_MIRROR_LOG] = "mirror-log",
+ [LV_TYPE_LINEAR] = "linear",
+ [LV_TYPE_STRIPED] = "striped"
+};
+
+static lv_type_t _get_lv_type(const struct logical_volume *lv)
+{
+ lv_type_t type = LV_TYPE_UNKNOWN;
+ struct lv_segment *seg;
+
+ if (lv->status & PVMOVE)
+ type = LV_TYPE_PVMOVE;
+ else if (lv_is_origin(lv))
+ type = LV_TYPE_ORIGIN;
+ else if (lv_is_external_origin(lv))
+ type = LV_TYPE_EXTERNAL_ORIGIN;
+ else if (lv_is_cow(lv))
+ type = LV_TYPE_SNAPSHOT;
+ else if (lv_is_thin_volume(lv))
+ type = first_seg(lv)->origin ? LV_TYPE_THIN_SNAPSHOT : LV_TYPE_THIN;
+ else if (lv_is_thin_pool(lv))
+ type = LV_TYPE_THIN_POOL;
+ else if (lv_is_thin_pool_data(lv))
+ type = LV_TYPE_THIN_POOL_DATA;
+ else if (lv_is_thin_pool_metadata(lv))
+ type = LV_TYPE_THIN_POOL_METADATA;
+ else if (lv_is_pool_metadata_spare(lv))
+ type = LV_TYPE_THIN_POOL_METADATA_SPARE;
+ else if (lv_is_cache(lv))
+ type = LV_TYPE_CACHE;
+ else if (lv_is_cache_pool(lv))
+ type = LV_TYPE_CACHE_POOL;
+ else if (lv_is_cache_pool_data(lv))
+ type = LV_TYPE_CACHE_POOL_DATA;
+ else if (lv_is_cache_pool_metadata(lv))
+ type = LV_TYPE_CACHE_POOL_METADATA;
+ else if (lv_is_pool_metadata_spare(lv))
+ type = LV_TYPE_CACHE_POOL_METADATA_SPARE;
+ else if (lv_is_virtual(lv))
+ type = LV_TYPE_VIRTUAL;
+ else if (lv_is_raid(lv))
+ type = LV_TYPE_RAID;
+ else if (lv_is_raid_image(lv))
+ type = LV_TYPE_RAID_IMAGE;
+ else if (lv_is_raid_metadata(lv))
+ type = LV_TYPE_RAID_METADATA;
+ else if (lv_is_mirrored(lv))
+ type = LV_TYPE_MIRROR;
+ else if (lv_is_mirror_image(lv))
+ type = LV_TYPE_MIRROR_IMAGE;
+ else if (lv_is_mirror_log(lv))
+ type = LV_TYPE_MIRROR_LOG;
+
+ /* none of the above, check linear... */
+ if (type == LV_TYPE_UNKNOWN) {
+ type = LV_TYPE_LINEAR;
+ dm_list_iterate_items(seg, &lv->segments) {
+ if (!seg_is_linear(seg)) {
+ type = LV_TYPE_UNKNOWN;
+ break;
+ }
+ }
+ }
+
+ /* ...if not even linear, check striped... */
+ if (type == LV_TYPE_UNKNOWN) {
+ type = LV_TYPE_STRIPED;
+ dm_list_iterate_items(seg, &lv->segments) {
+ if (!seg_is_striped(seg)) {
+ type = LV_TYPE_UNKNOWN;
+ break;
+ }
+ }
+ }
+
+ return type;
+}
+
+const char *lv_type_name(const struct logical_volume *lv) {
+ lv_type_t type = _get_lv_type(lv);
+ return _lv_type_names[type];
+}
+
+int lv_is_linear(const struct logical_volume *lv)
+{
+ lv_type_t type = _get_lv_type(lv);
+ return type == LV_TYPE_LINEAR;
+}
+
+int lv_is_striped(const struct logical_volume *lv)
+{
+ lv_type_t type = _get_lv_type(lv);
+ return type == LV_TYPE_STRIPED;
+}
+
static int _lv_is_on_pv(struct logical_volume *lv, void *data)
{
int *is_on_pv = ((struct pv_and_int *)data)->i;
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 85ea944..bfb4651 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -899,6 +899,14 @@ int get_pv_list_for_lv(struct dm_pool *mem,
struct lv_segment *first_seg(const struct logical_volume *lv);
struct lv_segment *last_seg(const struct logical_volume *lv);
+/* Human-readable LV type name. */
+const char *lv_type_name(const struct logical_volume *lv);
+
+/*
+ * Useful function to determine linear and striped volumes.
+ */
+int lv_is_linear(const struct logical_volume *lv);
+int lv_is_striped(const struct logical_volume *lv);
/*
* Useful functions for managing snapshots.
9 years, 10 months
master - refactor: remove static modifier for lv_raid_image_in_sync and lv_raid_healthy fn
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a4734354ceedff...
Commit: a4734354ceedffc72314feb5323e73e63d5e8ec8
Parent: 9d2c445d0ac10bf54d39d9aa6e8695c469456489
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Jul 1 09:56:03 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:40:17 2014 +0200
refactor: remove static modifier for lv_raid_image_in_sync and lv_raid_healthy fn
...to make use of it in other parts of the code.
---
lib/metadata/lv.c | 12 ++++++------
lib/metadata/lv.h | 3 +++
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 308b93d..1ede9d6 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -472,7 +472,7 @@ uint64_t lv_size(const struct logical_volume *lv)
return lv->size;
}
-static int _lv_mimage_in_sync(const struct logical_volume *lv)
+int lv_mirror_image_in_sync(const struct logical_volume *lv)
{
dm_percent_t percent;
struct lv_segment *seg = first_seg(lv);
@@ -491,7 +491,7 @@ static int _lv_mimage_in_sync(const struct logical_volume *lv)
return (percent == DM_PERCENT_100) ? 1 : 0;
}
-static int _lv_raid_image_in_sync(const struct logical_volume *lv)
+int lv_raid_image_in_sync(const struct logical_volume *lv)
{
unsigned s;
dm_percent_t percent;
@@ -555,7 +555,7 @@ static int _lv_raid_image_in_sync(const struct logical_volume *lv)
*
* Returns: 1 if healthy, 0 if device is not health
*/
-static int _lv_raid_healthy(const struct logical_volume *lv)
+int lv_raid_healthy(const struct logical_volume *lv)
{
unsigned s;
char *raid_health;
@@ -662,14 +662,14 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
else if (lv_is_thin_pool_data(lv))
repstr[0] = 'T';
else if (lv->status & MIRROR_IMAGE)
- repstr[0] = (_lv_mimage_in_sync(lv)) ? 'i' : 'I';
+ repstr[0] = (lv_mirror_image_in_sync(lv)) ? 'i' : 'I';
else if (lv->status & RAID_IMAGE)
/*
* Visible RAID_IMAGES are sub-LVs that have been exposed for
* top-level use by being split from the RAID array with
* '--splitmirrors 1 --trackchanges'. They always report 'I'.
*/
- repstr[0] = (!lv_is_visible(lv) && _lv_raid_image_in_sync(lv)) ?
+ repstr[0] = (!lv_is_visible(lv) && lv_raid_image_in_sync(lv)) ?
'i' : 'I';
else if (lv->status & MIRROR_LOG)
repstr[0] = 'l';
@@ -768,7 +768,7 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
uint64_t n;
if (!activation())
repstr[8] = 'X'; /* Unknown */
- else if (!_lv_raid_healthy(lv))
+ else if (!lv_raid_healthy(lv))
repstr[8] = 'r'; /* RAID needs 'r'efresh */
else if (lv->status & RAID) {
if (lv_raid_mismatch_count(lv, &n) && n)
diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h
index f298162..3a21f94 100644
--- a/lib/metadata/lv.h
+++ b/lib/metadata/lv.h
@@ -98,4 +98,7 @@ const struct logical_volume *lv_lock_holder(const struct logical_volume *lv);
struct logical_volume *lv_ondisk(struct logical_volume *lv);
struct profile *lv_config_profile(const struct logical_volume *lv);
char *lv_profile_dup(struct dm_pool *mem, const struct logical_volume *lv);
+int lv_mirror_image_in_sync(const struct logical_volume *lv);
+int lv_raid_image_in_sync(const struct logical_volume *lv);
+int lv_raid_healthy(const struct logical_volume *lv);
#endif /* _LVM_LV_H */
9 years, 10 months
master - cleanup: just safely copy string
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9d2c445d0ac10b...
Commit: 9d2c445d0ac10bf54d39d9aa6e8695c469456489
Parent: 86e116450ec32243f10abbe9b093bdeaab6e0f76
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 3 21:31:15 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 4 12:31:17 2014 +0200
cleanup: just safely copy string
Keep analyzers happier and use constrained strcpy.
---
lib/cache/lvmcache.c | 2 +-
lib/format1/import-export.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 3244205..41bac8b 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1707,7 +1707,7 @@ static int _get_pv_if_in_vg(struct lvmcache_info *info,
* lvmcache_label_scan() and drop cached
* vginfo so make a local copy of string.
*/
- strcpy(vgname, info->vginfo->vgname);
+ (void) dm_strncpy(vgname, info->vginfo->vgname, sizeof(vgname));
memcpy(vgid, info->vginfo->vgid, sizeof(vgid));
if (get_pv_from_vg_by_id(info->fmt, vgname, vgid,
diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c
index 5ef19ef..8aa4d33 100644
--- a/lib/format1/import-export.c
+++ b/lib/format1/import-export.c
@@ -347,7 +347,7 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
snprintf((char *)lvd->lv_name, sizeof(lvd->lv_name), "%s%s/%s",
dev_dir, vg->name, lv->name);
- strcpy((char *)lvd->vg_name, vg->name);
+ (void) dm_strncpy((char *)lvd->vg_name, vg->name, sizeof(lvd->vg_name));
if (lv->status & LVM_READ)
lvd->lv_access |= LV_READ;
9 years, 10 months
master - cleanup: drop unneeded initialization
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=86e116450ec322...
Commit: 86e116450ec32243f10abbe9b093bdeaab6e0f76
Parent: 1f72f8ed40a6cf72d424118cbb57d8a5961cc891
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 3 21:30:27 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 4 12:31:17 2014 +0200
cleanup: drop unneeded initialization
Code assigns this variable right after clearing.
---
lib/config/config.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/config/config.c b/lib/config/config.c
index 2ed3db6..8148a18 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -1142,7 +1142,7 @@ const struct dm_config_node *find_config_tree_node(struct cmd_context *cmd, int
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
- int profile_applied = 0;
+ int profile_applied;
const struct dm_config_node *cn;
profile_applied = _apply_local_profile(cmd, profile);
@@ -1160,7 +1160,7 @@ const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
- int profile_applied = 0;
+ int profile_applied;
const char *str;
profile_applied = _apply_local_profile(cmd, profile);
@@ -1181,7 +1181,7 @@ const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, st
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
- int profile_applied = 0;
+ int profile_applied;
const char *str;
profile_applied = _apply_local_profile(cmd, profile);
@@ -1204,7 +1204,7 @@ int find_config_tree_int(struct cmd_context *cmd, int id, struct profile *profil
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
- int profile_applied = 0;
+ int profile_applied;
int i;
profile_applied = _apply_local_profile(cmd, profile);
@@ -1225,7 +1225,7 @@ int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
- int profile_applied = 0;
+ int profile_applied;
int i64;
profile_applied = _apply_local_profile(cmd, profile);
@@ -1246,7 +1246,7 @@ float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *pr
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
- int profile_applied = 0;
+ int profile_applied;
float f;
profile_applied = _apply_local_profile(cmd, profile);
@@ -1267,7 +1267,7 @@ int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profi
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
- int profile_applied = 0;
+ int profile_applied;
int b;
profile_applied = _apply_local_profile(cmd, profile);
9 years, 10 months
master - dev-type: print aborting log_error
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1f72f8ed40a6cf...
Commit: 1f72f8ed40a6cf72d424118cbb57d8a5961cc891
Parent: a94abc0fdd33b31cd292d9b9a61ddceb7b72208f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 3 12:15:19 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 4 12:31:17 2014 +0200
dev-type: print aborting log_error
When wiping is aborted print immediate log_error message
(log_error comes 1st.)
---
lib/device/dev-type.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index 0d91017..902b7d1 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -507,8 +507,10 @@ static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
if (!_type_in_flag_list(type, types_no_prompt)) {
if (!yes && (force == PROMPT) &&
yes_no_prompt("WARNING: %s signature detected on %s at offset %s. "
- "Wipe it? [y/n] ", type, name, offset) != 'y')
- return_0;
+ "Wipe it? [y/n]: ", type, name, offset) == 'n') {
+ log_error("Aborted wiping of %s.", type);
+ return 0;
+ }
log_print_unless_silent(_msg_wiping, type, name);
} else
log_verbose(_msg_wiping, type, name);
@@ -591,9 +593,11 @@ static int _wipe_signature(struct device *dev, const char *type, const char *nam
/* Specifying --yes => do not ask. */
if (!yes && (force == PROMPT) &&
- yes_no_prompt("WARNING: %s detected on %s. Wipe it? [y/n] ",
- type, name) != 'y')
- return_0;
+ yes_no_prompt("WARNING: %s detected on %s. Wipe it? [y/n]: ",
+ type, name) == 'n') {
+ log_error("Aborted wiping of %s.", type);
+ return 0;
+ }
log_print_unless_silent("Wiping %s on %s.", type, name);
if (!dev_set(dev, offset_found, wipe_len, 0)) {
9 years, 10 months