master - report: select: add support for percent selection
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=51a86dc2f8cdfe...
Commit: 51a86dc2f8cdfe3de9f0876548731ede1f6a4f24
Parent: cfed0d09e8ef8f0f819420a15c9165d4fd49a890
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 9 16:23:45 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:21 2014 +0200
report: select: add support for percent selection
---
lib/properties/prop_common.h | 3 +-
lib/report/columns.h | 10 ++--
lib/report/report.c | 1 +
libdm/libdevmapper.h | 8 ++-
libdm/libdm-report.c | 99 ++++++++++++++++++++++++++++++------------
5 files changed, 84 insertions(+), 37 deletions(-)
diff --git a/lib/properties/prop_common.h b/lib/properties/prop_common.h
index e2249e1..6972f9f 100644
--- a/lib/properties/prop_common.h
+++ b/lib/properties/prop_common.h
@@ -123,7 +123,8 @@ static int _ ## NAME ## _get (const void *obj, struct lvm_property_type *prop) \
#define STR 1
#define NUM 2
#define SIZ 3
-#define STR_LIST 4
+#define PCT 4
+#define STR_LIST 5
#define FIELD_MODIFIABLE 0x00000001
#define FIELD(type, strct, field_type, head, field, width, fn, id, desc, settable) \
diff --git a/lib/report/columns.h b/lib/report/columns.h
index e3998ef..70a3b65 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -44,11 +44,11 @@ FIELD(LVS, lv, SIZ, "MSize", lvid, 6, lvmetadatasize, lv_metadata_size, "For thi
FIELD(LVS, lv, NUM, "#Seg", lvid, 4, lvsegcount, seg_count, "Number of segments in LV.", 0)
FIELD(LVS, lv, STR, "Origin", lvid, 6, origin, origin, "For snapshots, the origin device of this LV.", 0)
FIELD(LVS, lv, SIZ, "OSize", lvid, 5, originsize, origin_size, "For snapshots, the size of the origin device of this LV.", 0)
-FIELD(LVS, lv, NUM, "Data%", lvid, 6, datapercent, data_percent, "For snapshot and thin pools and volumes, the percentage full if LV is active.", 0)
-FIELD(LVS, lv, NUM, "Snap%", lvid, 6, snpercent, snap_percent, "For snapshots, the percentage full if LV is active.", 0)
-FIELD(LVS, lv, NUM, "Meta%", lvid, 6, metadatapercent, metadata_percent, "For thin pools, the percentage of metadata full if LV is active.", 0)
-FIELD(LVS, lv, NUM, "Cpy%Sync", lvid, 8, copypercent, copy_percent, "For RAID, mirrors and pvmove, current percentage in-sync.", 0)
-FIELD(LVS, lv, NUM, "Cpy%Sync", lvid, 8, copypercent, sync_percent, "For RAID, mirrors and pvmove, current percentage in-sync.", 0)
+FIELD(LVS, lv, PCT, "Data%", lvid, 6, datapercent, data_percent, "For snapshot and thin pools and volumes, the percentage full if LV is active.", 0)
+FIELD(LVS, lv, PCT, "Snap%", lvid, 6, snpercent, snap_percent, "For snapshots, the percentage full if LV is active.", 0)
+FIELD(LVS, lv, PCT, "Meta%", lvid, 6, metadatapercent, metadata_percent, "For thin pools, the percentage of metadata full if LV is active.", 0)
+FIELD(LVS, lv, PCT, "Cpy%Sync", lvid, 8, copypercent, copy_percent, "For RAID, mirrors and pvmove, current percentage in-sync.", 0)
+FIELD(LVS, lv, PCT, "Cpy%Sync", lvid, 8, copypercent, sync_percent, "For RAID, mirrors and pvmove, current percentage in-sync.", 0)
FIELD(LVS, lv, NUM, "Mismatches", lvid, 10, raidmismatchcount, raid_mismatch_count, "For RAID, number of mismatches found or repaired.", 0)
FIELD(LVS, lv, STR, "SyncAction", lvid, 10, raidsyncaction, raid_sync_action, "For RAID, the current synchronization action being performed.", 0)
FIELD(LVS, lv, NUM, "WBehind", lvid, 7, raidwritebehind, raid_write_behind, "For RAID1, the number of outstanding writes allowed to writemostly devices.", 0)
diff --git a/lib/report/report.c b/lib/report/report.c
index 6f507b6..34b7b07 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1203,6 +1203,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 SIZ DM_REPORT_FIELD_TYPE_SIZE
+#define PCT DM_REPORT_FIELD_TYPE_PERCENT
#define STR_LIST DM_REPORT_FIELD_TYPE_STRING_LIST
#define FIELD(type, strct, sorttype, head, field, width, func, id, desc, writeable) \
{type, sorttype, offsetof(type_ ## strct, field), width, \
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index ecf5640..fab1071 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1628,15 +1628,16 @@ struct dm_report_field;
/*
* dm_report_field_type flags
*/
-#define DM_REPORT_FIELD_MASK 0x000000FF
+#define DM_REPORT_FIELD_MASK 0x00000FFF
#define DM_REPORT_FIELD_ALIGN_MASK 0x0000000F
#define DM_REPORT_FIELD_ALIGN_LEFT 0x00000001
#define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
-#define DM_REPORT_FIELD_TYPE_MASK 0x000000F0
+#define DM_REPORT_FIELD_TYPE_MASK 0x00000FF0
#define DM_REPORT_FIELD_TYPE_STRING 0x00000010
#define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
#define DM_REPORT_FIELD_TYPE_SIZE 0x00000040
-#define DM_REPORT_FIELD_TYPE_STRING_LIST 0x00000080
+#define DM_REPORT_FIELD_TYPE_PERCENT 0x00000080
+#define DM_REPORT_FIELD_TYPE_STRING_LIST 0x00000100
#define DM_REPORT_FIELD_TYPE_ID_LEN 32
#define DM_REPORT_FIELD_TYPE_HEADING_LEN 32
@@ -1666,6 +1667,7 @@ struct dm_report_reserved_value {
const void const *value; /* reserved value:
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
const char * for DM_REPORT_FIELD_TYPE_STRING */
const char **names; /* null-terminated array of names for this reserved value */
const char *description; /* description of the reserved value */
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index f053f3d..0461bdf 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -59,10 +59,10 @@ struct dm_report {
/*
* Internal per-field flags
*/
-#define FLD_HIDDEN 0x00000100
-#define FLD_SORT_KEY 0x00000200
-#define FLD_ASCENDING 0x00000400
-#define FLD_DESCENDING 0x00000800
+#define FLD_HIDDEN 0x00001000
+#define FLD_SORT_KEY 0x00002000
+#define FLD_ASCENDING 0x00004000
+#define FLD_DESCENDING 0x00008000
struct field_properties {
struct dm_list list;
@@ -82,15 +82,15 @@ struct op_def {
const char *desc;
};
-#define FLD_CMP_MASK 0x000FF000
-#define FLD_CMP_EQUAL 0x00001000
-#define FLD_CMP_NOT 0x00002000
-#define FLD_CMP_GT 0x00004000
-#define FLD_CMP_LT 0x00008000
-#define FLD_CMP_REGEX 0x00010000
-#define FLD_CMP_NUMBER 0x00020000
+#define FLD_CMP_MASK 0x00FF0000
+#define FLD_CMP_EQUAL 0x00010000
+#define FLD_CMP_NOT 0x00020000
+#define FLD_CMP_GT 0x00040000
+#define FLD_CMP_LT 0x00080000
+#define FLD_CMP_REGEX 0x00100000
+#define FLD_CMP_NUMBER 0x00200000
/*
- * #define FLD_CMP_STRING 0x00040000
+ * #define FLD_CMP_STRING 0x00400000
* We could defined FLD_CMP_STRING here for completeness here,
* but it's not needed - we can check operator compatibility with
* field type by using FLD_CMP_REGEX and FLD_CMP_NUMBER flags only.
@@ -515,6 +515,7 @@ static const char *_get_field_type_name(unsigned field_type)
case DM_REPORT_FIELD_TYPE_STRING: return "string";
case DM_REPORT_FIELD_TYPE_NUMBER: return "number";
case DM_REPORT_FIELD_TYPE_SIZE: return "size";
+ case DM_REPORT_FIELD_TYPE_PERCENT: return "percent";
case DM_REPORT_FIELD_TYPE_STRING_LIST: return "string list";
default: return "unknown";
}
@@ -1150,6 +1151,13 @@ static int _compare_selection_field(struct dm_report *rh,
r = _cmp_field_regex((const char *) f->sort_value, fs->v.r, fs->flags);
else {
switch(f->props->flags & DM_REPORT_FIELD_TYPE_MASK) {
+ case DM_REPORT_FIELD_TYPE_PERCENT:
+ /*
+ * Check against real percent values only.
+ * That means DM_PERCENT_0 <= percent <= DM_PERCENT_100.
+ */
+ if (*(const uint64_t *) f->sort_value > DM_PERCENT_100)
+ return 0;
case DM_REPORT_FIELD_TYPE_NUMBER:
r = _cmp_field_int(field_id, *(const uint64_t *) f->sort_value, fs->v.i, fs->flags);
break;
@@ -1553,6 +1561,7 @@ static int _check_reserved_values_supported(const struct dm_report_reserved_valu
const struct dm_report_reserved_value *iter;
static uint32_t supported_reserved_types = DM_REPORT_FIELD_TYPE_NUMBER |
DM_REPORT_FIELD_TYPE_SIZE |
+ DM_REPORT_FIELD_TYPE_PERCENT |
DM_REPORT_FIELD_TYPE_STRING;
if (!reserved_values)
@@ -1835,33 +1844,46 @@ static const char *_tok_value(struct dm_report *rh,
case DM_REPORT_FIELD_TYPE_NUMBER:
case DM_REPORT_FIELD_TYPE_SIZE:
+ case DM_REPORT_FIELD_TYPE_PERCENT:
if (!(s = _tok_value_number(s, begin, end))) {
log_error("Failed to parse numeric value "
"for selection field %s.", ft->id);
return NULL;
}
+
factor = (uint64_t *) custom;
- *factor = dm_units_to_factor(s, &c, 0, &tmp);
- if (expected_type == DM_REPORT_FIELD_TYPE_NUMBER) {
- if (*factor) {
- log_error("Found size unit specifier but "
- "only numeric value expected for "
- "selection field %s.",ft->id);
+ if (*s == DM_PERCENT_CHAR) {
+ s++;
+ c = DM_PERCENT_CHAR;
+ if (expected_type != DM_REPORT_FIELD_TYPE_PERCENT) {
+ log_error("Found percent value but %s value "
+ "expected for selection field %s.",
+ expected_type == DM_REPORT_FIELD_TYPE_NUMBER ?
+ "numeric" : "size", ft->id);
return NULL;
}
- *flags |= DM_REPORT_FIELD_TYPE_NUMBER;
- } else {
+ } else if ((*factor = dm_units_to_factor(s, &c, 0, &tmp))) {
s = tmp;
+ if (expected_type != DM_REPORT_FIELD_TYPE_SIZE) {
+ log_error("Found size unit specifier "
+ "but %s value expected for "
+ "selection field %s.",
+ expected_type == DM_REPORT_FIELD_TYPE_NUMBER ?
+ "numeric" : "percent", ft->id);
+ return NULL;
+ }
+ } else if (expected_type == DM_REPORT_FIELD_TYPE_SIZE) {
/*
* If size unit is not defined in the selection
- * use use 'm' (1 MiB) by default. This is the
+ * and the type expected is size, use use 'm'
+ * (1 MiB) for the unit by default. This is the
* same behaviour as seen in lvcreate -L <size>.
*/
- if (!*factor)
- *factor = 1024*1024;
- *flags |= DM_REPORT_FIELD_TYPE_SIZE;
+ *factor = 1024*1024;
}
+
+ *flags |= expected_type;
}
return s;
@@ -2014,6 +2036,24 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
}
dm_pool_free(rh->mem, s);
break;
+ case DM_REPORT_FIELD_TYPE_PERCENT:
+ if (reserved)
+ fs->v.i = *(uint64_t *) reserved->value;
+ else {
+ fs->v.d = strtod(s, NULL);
+ if ((errno == ERANGE) || (fs->v.d < 0) || (fs->v.d > 100)) {
+ log_error(_out_of_range_msg, s, field_id);
+ goto error;
+ }
+
+ fs->v.i = (dm_percent_t) (DM_PERCENT_1 * fs->v.d);
+
+ if (_check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_PERCENT, &fs->v.i)) {
+ log_error("Percent value %s found in selection is reserved.", s);
+ goto error;
+ }
+ }
+ break;
case DM_REPORT_FIELD_TYPE_STRING_LIST:
fs->v.l = *(struct selection_str_list **)custom;
if (_check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_STRING_LIST, fs->v.l)) {
@@ -2065,6 +2105,7 @@ static void _display_selection_help(struct dm_report *rh)
log_warn(" field - Reporting field.");
log_warn(" number - Non-negative integer value.");
log_warn(" size - Floating point value with units, 'm' unit used by default if not specified.");
+ log_warn(" percent - Non-negative integer with or without %% suffix.");
log_warn(" string - Characters quoted by \' or \" or unquoted.");
log_warn(" string list - Strings enclosed by [ ] and elements delimited by either");
log_warn(" \"all items must match\" or \"at least one item must match\" operator.");
@@ -2191,12 +2232,13 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
goto bad;
}
- /* some operators can compare only numeric fields */
+ /* some operators can compare only numeric fields (NUMBER, SIZE or PERCENT) */
if ((flags & FLD_CMP_NUMBER) &&
(ft->flags != DM_REPORT_FIELD_TYPE_NUMBER) &&
- (ft->flags != DM_REPORT_FIELD_TYPE_SIZE)) {
+ (ft->flags != DM_REPORT_FIELD_TYPE_SIZE) &&
+ (ft->flags != DM_REPORT_FIELD_TYPE_PERCENT)) {
_display_selection_help(rh);
- log_error("Operator can be used only with numeric or size fields: %s", ws);
+ log_error("Operator can be used only with number, size or percent fields: %s", ws);
goto bad;
}
@@ -2206,7 +2248,8 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
goto_bad;
} else {
if (ft->flags == DM_REPORT_FIELD_TYPE_SIZE ||
- ft->flags == DM_REPORT_FIELD_TYPE_NUMBER)
+ ft->flags == DM_REPORT_FIELD_TYPE_NUMBER ||
+ ft->flags == DM_REPORT_FIELD_TYPE_PERCENT)
custom = &factor;
else if (ft->flags == DM_REPORT_FIELD_TYPE_STRING_LIST)
custom = &str_list;
8 years, 9 months
master - report: select: refactor: move percent handling code to libdm for reuse
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=cfed0d09e8ef8f...
Commit: cfed0d09e8ef8f0f819420a15c9165d4fd49a890
Parent: 35c4e4489c9eef22691332b43e51b03055e4fe92
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 9 12:08:27 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:21 2014 +0200
report: select: refactor: move percent handling code to libdm for reuse
---
lib/activate/activate.c | 22 +++++-----
lib/activate/activate.h | 10 ++--
lib/activate/dev_manager.c | 40 ++++++++++----------
lib/activate/dev_manager.h | 8 ++--
lib/display/display.c | 18 ++++----
lib/metadata/lv.c | 14 +++---
lib/metadata/lv_manip.c | 34 ++++++++--------
lib/metadata/metadata-exported.h | 2 +-
lib/metadata/mirror.c | 12 +++---
lib/metadata/raid_manip.c | 4 +-
lib/metadata/segtype.h | 2 +-
lib/metadata/thin_manip.c | 4 +-
lib/mirror/mirrored.c | 4 +-
lib/misc/lvm-percent.c | 24 -----------
lib/misc/lvm-percent.h | 25 +-----------
lib/raid/raid.c | 4 +-
lib/replicator/replicator.c | 4 +-
lib/report/properties.c | 26 ++++++------
lib/report/report.c | 79 +++++++++++++-------------------------
lib/snapshot/snapshot.c | 12 +++---
lib/thin/thin.c | 16 ++++----
libdm/libdevmapper.h | 32 +++++++++++++++
libdm/libdm-report.c | 60 ++++++++++++++++++++++++++++
liblvm/lvm2app.h | 25 +++---------
liblvm/lvm_base.c | 2 +-
test/api/thin_percent.c | 2 +-
tools/lvconvert.c | 20 +++++-----
tools/lvcreate.c | 2 +-
tools/lvscan.c | 4 +-
tools/polldaemon.c | 12 +++---
30 files changed, 266 insertions(+), 257 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 41d74c7..adaff52 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -253,16 +253,16 @@ int lv_check_not_in_use(struct cmd_context *cmd, struct logical_volume *lv,
{
return 0;
}
-int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent)
+int lv_snapshot_percent(const struct logical_volume *lv, dm_percent_t *percent)
{
return 0;
}
int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
- int wait, percent_t *percent, uint32_t *event_nr)
+ int wait, dm_percent_t *percent, uint32_t *event_nr)
{
return 0;
}
-int lv_raid_percent(const struct logical_volume *lv, percent_t *percent)
+int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
{
return 0;
}
@@ -295,12 +295,12 @@ int lv_cache_policy_info(struct logical_volume *lv,
return 0;
}
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- percent_t *percent)
+ dm_percent_t *percent)
{
return 0;
}
int lv_thin_percent(const struct logical_volume *lv, int mapped,
- percent_t *percent)
+ dm_percent_t *percent)
{
return 0;
}
@@ -765,7 +765,7 @@ int lv_check_transient(struct logical_volume *lv)
/*
* Returns 1 if percent set, else 0 on failure.
*/
-int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent)
+int lv_snapshot_percent(const struct logical_volume *lv, dm_percent_t *percent)
{
int r;
struct dev_manager *dm;
@@ -788,7 +788,7 @@ int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent)
/* FIXME Merge with snapshot_percent */
int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
- int wait, percent_t *percent, uint32_t *event_nr)
+ int wait, dm_percent_t *percent, uint32_t *event_nr)
{
int r;
struct dev_manager *dm;
@@ -796,7 +796,7 @@ int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
/* If mirrored LV is temporarily shrinked to 1 area (= linear),
* it should be considered in-sync. */
if (dm_list_size(&lv->segments) == 1 && first_seg(lv)->area_count == 1) {
- *percent = PERCENT_100;
+ *percent = DM_PERCENT_100;
return 1;
}
@@ -817,7 +817,7 @@ int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
return r;
}
-int lv_raid_percent(const struct logical_volume *lv, percent_t *percent)
+int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
{
return lv_mirror_percent(lv->vg->cmd, lv, 0, percent, NULL);
}
@@ -1145,7 +1145,7 @@ int lv_cache_policy_info(struct logical_volume *lv,
* Returns 1 if percent set, else 0 on failure.
*/
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- percent_t *percent)
+ dm_percent_t *percent)
{
int r;
struct dev_manager *dm;
@@ -1171,7 +1171,7 @@ int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
* Returns 1 if percent set, else 0 on failure.
*/
int lv_thin_percent(const struct logical_volume *lv,
- int mapped, percent_t *percent)
+ int mapped, dm_percent_t *percent)
{
int r;
struct dev_manager *dm;
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 946494e..b6cf474 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -112,10 +112,10 @@ int lv_check_transient(struct logical_volume *lv);
/*
* Returns 1 if percent has been set, else 0.
*/
-int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent);
+int lv_snapshot_percent(const struct logical_volume *lv, dm_percent_t *percent);
int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
- int wait, percent_t *percent, uint32_t *event_nr);
-int lv_raid_percent(const struct logical_volume *lv, percent_t *percent);
+ int wait, dm_percent_t *percent, uint32_t *event_nr);
+int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent);
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health);
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt);
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action);
@@ -127,9 +127,9 @@ int lv_cache_policy_info(struct logical_volume *lv,
const char **policy_name, int *policy_argc,
const char ***policy_argv);
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- percent_t *percent);
+ dm_percent_t *percent);
int lv_thin_percent(const struct logical_volume *lv, int mapped,
- percent_t *percent);
+ dm_percent_t *percent);
int lv_thin_pool_transaction_id(const struct logical_volume *lv,
uint64_t *transaction_id);
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id);
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 22b13ec..e30b176 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -719,28 +719,28 @@ int add_linear_area_to_dtree(struct dm_tree_node *node, uint64_t size, uint32_t
return 1;
}
-static percent_range_t _combine_percent(percent_t a, percent_t b,
- uint32_t numerator, uint32_t denominator)
+static dm_percent_range_t _combine_percent(dm_percent_t a, dm_percent_t b,
+ uint32_t numerator, uint32_t denominator)
{
- if (a == PERCENT_MERGE_FAILED || b == PERCENT_MERGE_FAILED)
- return PERCENT_MERGE_FAILED;
+ if (a == LVM_PERCENT_MERGE_FAILED || b == LVM_PERCENT_MERGE_FAILED)
+ return LVM_PERCENT_MERGE_FAILED;
- if (a == PERCENT_INVALID || b == PERCENT_INVALID)
- return PERCENT_INVALID;
+ if (a == DM_PERCENT_INVALID || b == DM_PERCENT_INVALID)
+ return DM_PERCENT_INVALID;
- if (a == PERCENT_100 && b == PERCENT_100)
- return PERCENT_100;
+ if (a == DM_PERCENT_100 && b == DM_PERCENT_100)
+ return DM_PERCENT_100;
- if (a == PERCENT_0 && b == PERCENT_0)
- return PERCENT_0;
+ if (a == DM_PERCENT_0 && b == DM_PERCENT_0)
+ return DM_PERCENT_0;
- return (percent_range_t) make_percent(numerator, denominator);
+ return (dm_percent_range_t) dm_make_percent(numerator, denominator);
}
static int _percent_run(struct dev_manager *dm, const char *name,
const char *dlid,
const char *target_type, int wait,
- const struct logical_volume *lv, percent_t *overall_percent,
+ const struct logical_volume *lv, dm_percent_t *overall_percent,
uint32_t *event_nr, int fail_if_percent_unsupported)
{
int r = 0;
@@ -754,7 +754,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
struct lv_segment *seg = NULL;
struct segment_type *segtype;
int first_time = 1;
- percent_t percent = PERCENT_INVALID;
+ dm_percent_t percent = DM_PERCENT_INVALID;
uint64_t total_numerator = 0, total_denominator = 0;
@@ -829,12 +829,12 @@ static int _percent_run(struct dev_manager *dm, const char *name,
if (first_time) {
/* above ->target_percent() was not executed! */
/* FIXME why return PERCENT_100 et. al. in this case? */
- *overall_percent = PERCENT_100;
+ *overall_percent = DM_PERCENT_100;
if (fail_if_percent_unsupported)
goto_out;
}
- log_debug_activation("LV percent: %f", percent_to_float(*overall_percent));
+ log_debug_activation("LV percent: %f", dm_percent_to_float(*overall_percent));
r = 1;
out:
@@ -844,7 +844,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
static int _percent(struct dev_manager *dm, const char *name, const char *dlid,
const char *target_type, int wait,
- const struct logical_volume *lv, percent_t *percent,
+ const struct logical_volume *lv, dm_percent_t *percent,
uint32_t *event_nr, int fail_if_percent_unsupported)
{
if (dlid && *dlid) {
@@ -988,7 +988,7 @@ void dev_manager_exit(void)
int dev_manager_snapshot_percent(struct dev_manager *dm,
const struct logical_volume *lv,
- percent_t *percent)
+ dm_percent_t *percent)
{
const struct logical_volume *snap_lv;
char *name;
@@ -1041,7 +1041,7 @@ int dev_manager_snapshot_percent(struct dev_manager *dm,
/* FIXME Cope with more than one target */
int dev_manager_mirror_percent(struct dev_manager *dm,
const struct logical_volume *lv, int wait,
- percent_t *percent, uint32_t *event_nr)
+ dm_percent_t *percent, uint32_t *event_nr)
{
char *name;
const char *dlid;
@@ -1325,7 +1325,7 @@ out:
int dev_manager_thin_pool_percent(struct dev_manager *dm,
const struct logical_volume *lv,
- int metadata, percent_t *percent)
+ int metadata, dm_percent_t *percent)
{
char *name;
const char *dlid;
@@ -1348,7 +1348,7 @@ int dev_manager_thin_pool_percent(struct dev_manager *dm,
int dev_manager_thin_percent(struct dev_manager *dm,
const struct logical_volume *lv,
- int mapped, percent_t *percent)
+ int mapped, dm_percent_t *percent)
{
char *name;
const char *dlid;
diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h
index 446b349..9bdc413 100644
--- a/lib/activate/dev_manager.h
+++ b/lib/activate/dev_manager.h
@@ -50,10 +50,10 @@ int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
struct dm_info *info, uint32_t *read_ahead);
int dev_manager_snapshot_percent(struct dev_manager *dm,
const struct logical_volume *lv,
- percent_t *percent);
+ dm_percent_t *percent);
int dev_manager_mirror_percent(struct dev_manager *dm,
const struct logical_volume *lv, int wait,
- percent_t *percent, uint32_t *event_nr);
+ dm_percent_t *percent, uint32_t *event_nr);
int dev_manager_raid_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct dm_status_raid **status);
@@ -69,10 +69,10 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
int noflush);
int dev_manager_thin_pool_percent(struct dev_manager *dm,
const struct logical_volume *lv,
- int metadata, percent_t *percent);
+ int metadata, dm_percent_t *percent);
int dev_manager_thin_percent(struct dev_manager *dm,
const struct logical_volume *lv,
- int mapped, percent_t *percent);
+ int mapped, dm_percent_t *percent);
int dev_manager_thin_device_id(struct dev_manager *dm,
const struct logical_volume *lv,
uint32_t *device_id);
diff --git a/lib/display/display.c b/lib/display/display.c
index 70a4cda..9780f10 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -427,11 +427,11 @@ int lvdisplay_full(struct cmd_context *cmd,
struct lv_segment *snap_seg = NULL, *mirror_seg = NULL;
struct lv_segment *seg = NULL;
int lvm1compat;
- percent_t snap_percent;
+ dm_percent_t snap_percent;
int thin_data_active = 0, thin_metadata_active = 0;
- percent_t thin_data_percent, thin_metadata_percent;
+ dm_percent_t thin_data_percent, thin_metadata_percent;
int thin_active = 0;
- percent_t thin_percent;
+ dm_percent_t thin_percent;
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid)))
return_0;
@@ -477,7 +477,7 @@ int lvdisplay_full(struct cmd_context *cmd,
if (inkernel &&
(snap_active = lv_snapshot_percent(snap_seg->cow,
&snap_percent)))
- if (snap_percent == PERCENT_INVALID)
+ if (snap_percent == DM_PERCENT_INVALID)
snap_active = 0;
if (lvm1compat)
log_print(" %s%s/%s [%s]",
@@ -494,7 +494,7 @@ int lvdisplay_full(struct cmd_context *cmd,
if (inkernel &&
(snap_active = lv_snapshot_percent(snap_seg->cow,
&snap_percent)))
- if (snap_percent == PERCENT_INVALID)
+ if (snap_percent == DM_PERCENT_INVALID)
snap_active = 0;
if (lvm1compat)
@@ -555,15 +555,15 @@ int lvdisplay_full(struct cmd_context *cmd,
if (thin_data_active)
log_print("Allocated pool data %.2f%%",
- percent_to_float(thin_data_percent));
+ dm_percent_to_float(thin_data_percent));
if (thin_metadata_active)
log_print("Allocated metadata %.2f%%",
- percent_to_float(thin_metadata_percent));
+ dm_percent_to_float(thin_metadata_percent));
if (thin_active)
log_print("Mapped size %.2f%%",
- percent_to_float(thin_percent));
+ dm_percent_to_float(thin_percent));
log_print("Current LE %u",
snap_seg ? snap_seg->origin->le_count : lv->le_count);
@@ -575,7 +575,7 @@ int lvdisplay_full(struct cmd_context *cmd,
if (snap_active)
log_print("Allocated to snapshot %.2f%%",
- percent_to_float(snap_percent));
+ dm_percent_to_float(snap_percent));
log_print("Snapshot chunk size %s",
display_size(cmd, (uint64_t) snap_seg->chunk_size));
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 5414d94..733e9f6 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -392,7 +392,7 @@ uint64_t lv_size(const struct logical_volume *lv)
static int _lv_mimage_in_sync(const struct logical_volume *lv)
{
- percent_t percent;
+ dm_percent_t percent;
struct lv_segment *seg = first_seg(lv);
struct lv_segment *mirror_seg;
@@ -406,13 +406,13 @@ static int _lv_mimage_in_sync(const struct logical_volume *lv)
NULL))
return_0;
- return (percent == PERCENT_100) ? 1 : 0;
+ return (percent == DM_PERCENT_100) ? 1 : 0;
}
static int _lv_raid_image_in_sync(const struct logical_volume *lv)
{
unsigned s;
- percent_t percent;
+ dm_percent_t percent;
char *raid_health;
struct lv_segment *seg, *raid_seg = NULL;
@@ -444,7 +444,7 @@ static int _lv_raid_image_in_sync(const struct logical_volume *lv)
if (!lv_raid_percent(raid_seg->lv, &percent))
return_0;
- if (percent == PERCENT_100)
+ if (percent == DM_PERCENT_100)
return 1;
/* Find out which sub-LV this is. */
@@ -537,7 +537,7 @@ static int _lv_raid_healthy(const struct logical_volume *lv)
char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
{
- percent_t snap_percent;
+ dm_percent_t snap_percent;
struct lvinfo info;
struct lv_segment *seg;
char *repstr;
@@ -628,13 +628,13 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
/* Snapshot dropped? */
if (info.live_table && lv_is_cow(lv)) {
if (!lv_snapshot_percent(lv, &snap_percent) ||
- snap_percent == PERCENT_INVALID) {
+ snap_percent == DM_PERCENT_INVALID) {
if (info.suspended)
repstr[4] = 'S'; /* Susp Inv snapshot */
else
repstr[4] = 'I'; /* Invalid snapshot */
}
- else if (snap_percent == PERCENT_MERGE_FAILED) {
+ else if (snap_percent == LVM_PERCENT_MERGE_FAILED) {
if (info.suspended)
repstr[4] = 'M'; /* Susp snapshot merge failed */
else
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 9fe441d..0aac385 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -418,7 +418,7 @@ uint32_t find_free_lvnum(struct logical_volume *lv)
return i;
}
-percent_t copy_percent(const struct logical_volume *lv)
+dm_percent_t copy_percent(const struct logical_volume *lv)
{
uint32_t numerator = 0u, denominator = 0u;
struct lv_segment *seg;
@@ -434,7 +434,7 @@ percent_t copy_percent(const struct logical_volume *lv)
numerator += seg->area_len;
}
- return denominator ? make_percent( numerator, denominator ) : 100.0;
+ return denominator ? dm_make_percent( numerator, denominator ) : 100.0;
}
/*
@@ -3157,7 +3157,7 @@ int lv_extend(struct logical_volume *lv,
if ((lv->le_count != extents) &&
segtype_is_mirrored(segtype) &&
(lv->status & LV_NOTSYNCED)) {
- percent_t sync_percent = PERCENT_INVALID;
+ dm_percent_t sync_percent = DM_PERCENT_INVALID;
if (!lv_is_active_locally(lv)) {
log_error("%s/%s is not active locally."
@@ -3178,7 +3178,7 @@ int lv_extend(struct logical_volume *lv,
log_error("Failed to get sync percent for %s/%s",
lv->vg->name, lv->name);
goto out;
- } else if (sync_percent == PERCENT_100) {
+ } else if (sync_percent == DM_PERCENT_100) {
log_verbose("Skipping initial resync for "
"extended portion of %s/%s",
lv->vg->name, lv->name);
@@ -3576,32 +3576,32 @@ static int _fsadm_cmd(struct cmd_context *cmd,
static int _adjust_policy_params(struct cmd_context *cmd,
struct logical_volume *lv, struct lvresize_params *lp)
{
- percent_t percent;
+ dm_percent_t percent;
int policy_threshold, policy_amount;
if (lv_is_thin_pool(lv)) {
policy_threshold =
find_config_tree_int(cmd, activation_thin_pool_autoextend_threshold_CFG,
- lv_config_profile(lv)) * PERCENT_1;
+ lv_config_profile(lv)) * DM_PERCENT_1;
policy_amount =
find_config_tree_int(cmd, activation_thin_pool_autoextend_percent_CFG,
lv_config_profile(lv));
- if (!policy_amount && policy_threshold < PERCENT_100)
+ if (!policy_amount && policy_threshold < DM_PERCENT_100)
return 0;
} else {
policy_threshold =
- find_config_tree_int(cmd, activation_snapshot_autoextend_threshold_CFG, NULL) * PERCENT_1;
+ find_config_tree_int(cmd, activation_snapshot_autoextend_threshold_CFG, NULL) * DM_PERCENT_1;
policy_amount =
find_config_tree_int(cmd, activation_snapshot_autoextend_percent_CFG, NULL);
}
- if (policy_threshold >= PERCENT_100)
+ if (policy_threshold >= DM_PERCENT_100)
return 1; /* nothing to do */
if (lv_is_thin_pool(lv)) {
if (!lv_thin_pool_percent(lv, 1, &percent))
return_0;
- if ((PERCENT_0 < percent && percent <= PERCENT_100) &&
+ if ((DM_PERCENT_0 < percent && percent <= DM_PERCENT_100) &&
(percent > policy_threshold)) {
if (!thin_pool_feature_supported(lv, THIN_FEATURE_METADATA_RESIZE)) {
log_error_once("Online metadata resize for %s/%s is not supported.",
@@ -3615,14 +3615,14 @@ static int _adjust_policy_params(struct cmd_context *cmd,
if (!lv_thin_pool_percent(lv, 0, &percent))
return_0;
- if (!(PERCENT_0 < percent && percent <= PERCENT_100) ||
+ if (!(DM_PERCENT_0 < percent && percent <= DM_PERCENT_100) ||
percent <= policy_threshold)
return 1;
} else {
if (!lv_snapshot_percent(lv, &percent))
return_0;
- if (!(PERCENT_0 < percent && percent <= PERCENT_100) || percent <= policy_threshold)
- return 1; /* nothing to do */
+ if (!(DM_PERCENT_0 < percent && percent <= DM_PERCENT_100) || percent <= policy_threshold)
+ return 1; /* nothing to do */
}
lp->extents = policy_amount;
@@ -4876,7 +4876,7 @@ static int _lv_remove_segs_using_this_lv(struct cmd_context *cmd, struct logical
int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *lv,
const force_t force, unsigned level)
{
- percent_t snap_percent;
+ dm_percent_t snap_percent;
struct dm_list *snh, *snht;
struct lv_list *lvl;
struct lvinfo info;
@@ -4896,12 +4896,12 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
lv->name);
return 0;
}
- if ((snap_percent != PERCENT_INVALID) &&
- (snap_percent != PERCENT_MERGE_FAILED)) {
+ if ((snap_percent != DM_PERCENT_INVALID) &&
+ (snap_percent != LVM_PERCENT_MERGE_FAILED)) {
log_error("Can't remove merging snapshot logical volume \"%s\"",
lv->name);
return 0;
- } else if ((snap_percent == PERCENT_MERGE_FAILED) &&
+ } else if ((snap_percent == LVM_PERCENT_MERGE_FAILED) &&
(force == PROMPT) &&
yes_no_prompt("Removing snapshot \"%s\" that failed to merge may leave origin \"%s\" inconsistent. "
"Proceed? [y/n]: ", lv->name, origin_from_cow(lv)->name) == 'n')
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 6f97564..237ed18 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1065,7 +1065,7 @@ struct dm_list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv);
uint32_t find_free_lvnum(struct logical_volume *lv);
-percent_t copy_percent(const struct logical_volume *lv_mirr);
+dm_percent_t copy_percent(const struct logical_volume *lv_mirr);
char *generate_lv_name(struct volume_group *vg, const char *format,
char *buffer, size_t len);
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index b03cdbe..81a5f19 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -575,7 +575,7 @@ static int _move_removable_mimages_to_end(struct logical_volume *lv,
static int _mirrored_lv_in_sync(struct logical_volume *lv)
{
- percent_t sync_percent;
+ dm_percent_t sync_percent;
if (!lv_mirror_percent(lv->vg->cmd, lv, 0, &sync_percent,
NULL)) {
@@ -590,7 +590,7 @@ static int _mirrored_lv_in_sync(struct logical_volume *lv)
return 0;
}
- return (sync_percent == PERCENT_100) ? 1 : 0;
+ return (sync_percent == DM_PERCENT_100) ? 1 : 0;
}
/*
@@ -1701,7 +1701,7 @@ int remove_mirror_log(struct cmd_context *cmd,
struct dm_list *removable_pvs,
int force)
{
- percent_t sync_percent;
+ dm_percent_t sync_percent;
struct volume_group *vg = lv->vg;
/* Unimplemented features */
@@ -1734,7 +1734,7 @@ int remove_mirror_log(struct cmd_context *cmd,
return 0;
}
- if (sync_percent == PERCENT_100)
+ if (sync_percent == DM_PERCENT_100)
init_mirror_in_sync(1);
else {
/* A full resync will take place */
@@ -1896,7 +1896,7 @@ int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
struct alloc_handle *ah;
const struct segment_type *segtype;
struct dm_list *parallel_areas;
- percent_t sync_percent;
+ dm_percent_t sync_percent;
int in_sync;
struct logical_volume *log_lv;
unsigned old_log_count;
@@ -1964,7 +1964,7 @@ int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
/* check sync status */
if (mirror_in_sync() ||
(lv_mirror_percent(cmd, lv, 0, &sync_percent, NULL) &&
- (sync_percent == PERCENT_100)))
+ (sync_percent == DM_PERCENT_100)))
in_sync = 1;
else
in_sync = 0;
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index ac0f948..4c13b66 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -87,7 +87,7 @@ static int _activate_sublv_preserving_excl(struct logical_volume *top_lv,
*/
static int _raid_in_sync(struct logical_volume *lv)
{
- percent_t sync_percent;
+ dm_percent_t sync_percent;
if (!lv_raid_percent(lv, &sync_percent)) {
log_error("Unable to determine sync status of %s/%s.",
@@ -95,7 +95,7 @@ static int _raid_in_sync(struct logical_volume *lv)
return 0;
}
- return (sync_percent == PERCENT_100) ? 1 : 0;
+ return (sync_percent == DM_PERCENT_100) ? 1 : 0;
}
/*
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index 1a4a92f..891c378 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -112,7 +112,7 @@ struct segtype_handler {
int (*target_status_compatible) (const char *type);
int (*check_transient_status) (struct lv_segment *seg, char *params);
int (*target_percent) (void **target_state,
- percent_t *percent,
+ dm_percent_t *percent,
struct dm_pool * mem,
struct cmd_context *cmd,
struct lv_segment *seg, char *params,
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index cccd244..8520440 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -231,8 +231,8 @@ int thin_pool_feature_supported(const struct logical_volume *lv, int feature)
int pool_below_threshold(const struct lv_segment *pool_seg)
{
- percent_t percent;
- int threshold = PERCENT_1 *
+ dm_percent_t percent;
+ int threshold = DM_PERCENT_1 *
find_config_tree_int(pool_seg->lv->vg->cmd, activation_thin_pool_autoextend_threshold_CFG,
lv_config_profile(pool_seg->lv));
diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
index 5040011..1ab06ce 100644
--- a/lib/mirror/mirrored.c
+++ b/lib/mirror/mirrored.c
@@ -166,7 +166,7 @@ static struct mirror_state *_mirrored_init_target(struct dm_pool *mem,
}
static int _mirrored_target_percent(void **target_state,
- percent_t *percent,
+ dm_percent_t *percent,
struct dm_pool *mem,
struct cmd_context *cmd,
struct lv_segment *seg, char *params,
@@ -213,7 +213,7 @@ static int _mirrored_target_percent(void **target_state,
if (seg)
seg->extents_copied = seg->area_len * numerator / denominator;
- *percent = make_percent(numerator, denominator);
+ *percent = dm_make_percent(numerator, denominator);
return 1;
}
diff --git a/lib/misc/lvm-percent.c b/lib/misc/lvm-percent.c
index 013544f..95c41d6 100644
--- a/lib/misc/lvm-percent.c
+++ b/lib/misc/lvm-percent.c
@@ -15,30 +15,6 @@
#include "lib.h"
#include "lvm-percent.h"
-float percent_to_float(percent_t v)
-{
- return (float)v / PERCENT_1;
-}
-
-percent_t make_percent(uint64_t numerator, uint64_t denominator)
-{
- percent_t percent;
- if (!denominator)
- return PERCENT_100; /* FIXME? */
- if (!numerator)
- return PERCENT_0;
- if (numerator == denominator)
- return PERCENT_100;
- switch (percent = PERCENT_100 * ((double) numerator / (double) denominator)) {
- case PERCENT_100:
- return PERCENT_100 - 1;
- case PERCENT_0:
- return PERCENT_0 + 1;
- default:
- return percent;
- }
-}
-
uint32_t percent_of_extents(uint32_t percents, uint32_t count, int roundup)
{
return (uint32_t)(((uint64_t)percents * (uint64_t)count +
diff --git a/lib/misc/lvm-percent.h b/lib/misc/lvm-percent.h
index ff3de42..481c947 100644
--- a/lib/misc/lvm-percent.h
+++ b/lib/misc/lvm-percent.h
@@ -16,20 +16,6 @@
#define _LVM_PERCENT_H
#include <stdint.h>
-/*
- * A fixed-point representation of percent values. One percent equals to
- * PERCENT_1 as defined below. Values that are not multiples of PERCENT_1
- * represent fractions, with precision of 1/1000000 of a percent. See
- * percent_to_float for a conversion to a floating-point representation.
- *
- * You should always use make_percent when building percent_t values. The
- * implementation of make_percent is biased towards the middle: it ensures that
- * the result is PERCENT_0 or PERCENT_100 if and only if this is the actual
- * value -- it never rounds any intermediate value (> 0 or < 100) to either 0
- * or 100.
- */
-typedef int32_t percent_t;
-
typedef enum {
SIGN_NONE = 0,
SIGN_PLUS = 1,
@@ -45,16 +31,7 @@ typedef enum {
PERCENT_ORIGIN
} percent_type_t;
-typedef enum {
- PERCENT_0 = 0,
- PERCENT_1 = 1000000,
- PERCENT_100 = 100 * PERCENT_1,
- PERCENT_INVALID = -1,
- PERCENT_MERGE_FAILED = -2
-} percent_range_t;
-
-float percent_to_float(percent_t v);
-percent_t make_percent(uint64_t numerator, uint64_t denominator);
+#define LVM_PERCENT_MERGE_FAILED DM_PERCENT_FAILED
uint32_t percent_of_extents(uint32_t percents, uint32_t count, int roundup);
diff --git a/lib/raid/raid.c b/lib/raid/raid.c
index b77c315..33ba5b7 100644
--- a/lib/raid/raid.c
+++ b/lib/raid/raid.c
@@ -269,7 +269,7 @@ static void _raid_destroy(struct segment_type *segtype)
#ifdef DEVMAPPER_SUPPORT
static int _raid_target_percent(void **target_state,
- percent_t *percent,
+ dm_percent_t *percent,
struct dm_pool *mem,
struct cmd_context *cmd,
struct lv_segment *seg, char *params,
@@ -305,7 +305,7 @@ static int _raid_target_percent(void **target_state,
if (seg)
seg->extents_copied = seg->area_len * numerator / denominator;
- *percent = make_percent(numerator, denominator);
+ *percent = dm_make_percent(numerator, denominator);
return 1;
}
diff --git a/lib/replicator/replicator.c b/lib/replicator/replicator.c
index 76bdbca..6a116d2 100644
--- a/lib/replicator/replicator.c
+++ b/lib/replicator/replicator.c
@@ -363,7 +363,7 @@ static int _replicator_add_target_line(struct dev_manager *dm,
/* FIXME: write something useful for replicator here */
static int _replicator_target_percent(void **target_state,
- percent_t *percent,
+ dm_percent_t *percent,
struct dm_pool *mem,
struct cmd_context *cmd,
struct lv_segment *seg,
@@ -709,7 +709,7 @@ static int _replicator_dev_add_target_line(struct dev_manager *dm,
/* FIXME: write something useful for replicator-dev here */
static int _replicator_dev_target_percent(void **target_state,
- percent_t *percent,
+ dm_percent_t *percent,
struct dm_pool *mem,
struct cmd_context *cmd,
struct lv_segment *seg,
diff --git a/lib/report/properties.c b/lib/report/properties.c
index ec7bc4d..0c49b0f 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -47,12 +47,12 @@
#define GET_PVSEG_STR_PROPERTY_FN(NAME, VALUE) \
GET_STR_PROPERTY_FN(NAME, VALUE, pv_segment, pvseg)
-static percent_t _copy_percent(const struct logical_volume *lv)
+static dm_percent_t _copy_percent(const struct logical_volume *lv)
{
- percent_t percent;
+ dm_percent_t percent;
if (!lv_mirror_percent(lv->vg->cmd, lv, 0, &percent, NULL))
- percent = PERCENT_INVALID;
+ percent = DM_PERCENT_INVALID;
return percent;
}
@@ -91,34 +91,34 @@ static uint32_t _raidmaxrecoveryrate(const struct logical_volume *lv)
return first_seg(lv)->max_recovery_rate;
}
-static percent_t _snap_percent(const struct logical_volume *lv)
+static dm_percent_t _snap_percent(const struct logical_volume *lv)
{
- percent_t percent;
+ dm_percent_t percent;
if (!lv_is_cow(lv) || !lv_snapshot_percent(lv, &percent))
- percent = PERCENT_INVALID;
+ percent = DM_PERCENT_INVALID;
return percent;
}
-static percent_t _data_percent(const struct logical_volume *lv)
+static dm_percent_t _data_percent(const struct logical_volume *lv)
{
- percent_t percent;
+ dm_percent_t percent;
if (lv_is_cow(lv))
return _snap_percent(lv);
if (lv_is_thin_volume(lv))
- return lv_thin_percent(lv, 0, &percent) ? percent : PERCENT_INVALID;
+ return lv_thin_percent(lv, 0, &percent) ? percent : DM_PERCENT_INVALID;
- return lv_thin_pool_percent(lv, 0, &percent) ? percent : PERCENT_INVALID;
+ return lv_thin_pool_percent(lv, 0, &percent) ? percent : DM_PERCENT_INVALID;
}
-static percent_t _metadata_percent(const struct logical_volume *lv)
+static dm_percent_t _metadata_percent(const struct logical_volume *lv)
{
- percent_t percent;
+ dm_percent_t percent;
- return lv_thin_pool_percent(lv, 1, &percent) ? percent : PERCENT_INVALID;
+ return lv_thin_pool_percent(lv, 1, &percent) ? percent : DM_PERCENT_INVALID;
}
/* PV */
diff --git a/lib/report/report.c b/lib/report/report.c
index 7f509e1..6f507b6 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -36,7 +36,6 @@ struct lvm_report_object {
struct label *label;
};
-static const uint64_t _hundred64 = UINT64_C(100);
static const uint64_t _zero64 = UINT64_C(0);
static const uint64_t _reserved_number_undef_64 = UINT64_C(-1);
@@ -71,35 +70,6 @@ static int _field_set_value(struct dm_report_field *field, const void *data, con
return 1;
}
-static int _field_set_percent(struct dm_report_field *field,
- struct dm_pool *mem,
- percent_t percent)
-{
- char *repstr;
- uint64_t *sortval;
-
- if (percent == PERCENT_INVALID)
- return _field_set_value(field, "", &_reserved_number_undef_64);
-
- if (!(repstr = dm_pool_alloc(mem, 8)) ||
- !(sortval = dm_pool_alloc(mem, sizeof(uint64_t)))) {
- if (repstr)
- dm_pool_free(mem, repstr);
- log_error("dm_pool_alloc failed.");
- return 0;
- }
-
- if (dm_snprintf(repstr, 7, "%.2f", percent_to_float(percent)) < 0) {
- dm_pool_free(mem, repstr);
- log_error("Percentage too large.");
- return 0;
- }
-
- *sortval = (uint64_t)(percent * 1000.f);
-
- return _field_set_value(field, repstr, sortval);
-}
-
/*
* Data-munging functions to prepare each data type for display and sorting
*/
@@ -904,21 +874,23 @@ static int _snapcount_disp(struct dm_report *rh, struct dm_pool *mem,
return _uint32_disp(rh, mem, field, &count, private);
}
-static int _snpercent_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
+static int _snpercent_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
struct dm_report_field *field,
const void *data, void *private __attribute__((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
- percent_t snap_percent;
+ dm_percent_t snap_percent;
if ((lv_is_cow(lv) || lv_is_merging_origin(lv)) &&
lv_snapshot_percent(lv, &snap_percent)) {
- if ((snap_percent != PERCENT_INVALID) &&
- (snap_percent != PERCENT_MERGE_FAILED))
- return _field_set_percent(field, mem, snap_percent);
+ if ((snap_percent != DM_PERCENT_INVALID) &&
+ (snap_percent != LVM_PERCENT_MERGE_FAILED))
+ return dm_report_field_percent(rh, field, &snap_percent);
- if (!lv_is_merging_origin(lv))
- return _field_set_value(field, "100.00", &_hundred64);
+ if (!lv_is_merging_origin(lv)) {
+ snap_percent = DM_PERCENT_100;
+ return dm_report_field_percent(rh, field, &snap_percent);
+ }
/*
* on activate merge that hasn't started yet would
@@ -926,27 +898,28 @@ static int _snpercent_disp(struct dm_report *rh __attribute__((unused)), struct
*/
}
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ snap_percent = DM_PERCENT_INVALID;
+ return dm_report_field_percent(rh, field, &snap_percent);
}
-static int _copypercent_disp(struct dm_report *rh __attribute__((unused)),
- struct dm_pool *mem,
+static int _copypercent_disp(struct dm_report *rh,
+ struct dm_pool *mem __attribute__((unused)),
struct dm_report_field *field,
const void *data, void *private __attribute__((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
- percent_t percent;
+ dm_percent_t percent = DM_PERCENT_INVALID;
if (((lv_is_raid(lv) && lv_raid_percent(lv, &percent)) ||
((lv->status & (PVMOVE | MIRRORED)) &&
lv_mirror_percent(lv->vg->cmd, lv, 0, &percent, NULL))) &&
- (percent != PERCENT_INVALID)) {
+ (percent != DM_PERCENT_INVALID)) {
percent = copy_percent(lv);
- return _field_set_percent(field, mem, percent);
+ return dm_report_field_percent(rh, field, &percent);
}
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return dm_report_field_percent(rh, field, &percent);
}
static int _raidsyncaction_disp(struct dm_report *rh __attribute__((unused)),
@@ -1024,17 +997,17 @@ static int _raidmaxrecoveryrate_disp(struct dm_report *rh __attribute__((unused)
}
/* Called only with lv_is_thin_pool/volume */
-static int _dtpercent_disp(int metadata, struct dm_pool *mem,
+static int _dtpercent_disp(int metadata, struct dm_report *rh,
struct dm_report_field *field,
const void *data, void *private)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
- percent_t percent;
+ dm_percent_t percent = DM_PERCENT_INVALID;
/* Suppress data percent if not using driver */
/* cannot use lv_is_active_locally - need to check for layer -tpool */
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return dm_report_field_percent(rh, field, &percent);
if (lv_is_thin_pool(lv)) {
if (!lv_thin_pool_percent(lv, metadata, &percent))
@@ -1044,7 +1017,7 @@ static int _dtpercent_disp(int metadata, struct dm_pool *mem,
return_0;
}
- return _field_set_percent(field, mem, percent);
+ return dm_report_field_percent(rh, field, &percent);
}
static int _datapercent_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1052,24 +1025,26 @@ static int _datapercent_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
+ dm_percent_t percent = DM_PERCENT_INVALID;
if (lv_is_cow(lv))
return _snpercent_disp(rh, mem, field, data, private);
if (lv_is_thin_pool(lv) || lv_is_thin_volume(lv))
- return _dtpercent_disp(0, mem, field, data, private);
+ return _dtpercent_disp(0, rh, field, data, private);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return dm_report_field_percent(rh, field, &percent);
}
-static int _metadatapercent_disp(struct dm_report *rh, struct dm_pool *mem,
+static int _metadatapercent_disp(struct dm_report *rh,
+ struct dm_pool *mem __attribute__((unused)),
struct dm_report_field *field,
const void *data, void *private)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
if (lv_is_thin_pool(lv))
- return _dtpercent_disp(1, mem, field, data, private);
+ return _dtpercent_disp(1, rh, field, data, private);
return _field_set_value(field, "", &_reserved_number_undef_64);
}
diff --git a/lib/snapshot/snapshot.c b/lib/snapshot/snapshot.c
index a4ee2ea..afa1a90 100644
--- a/lib/snapshot/snapshot.c
+++ b/lib/snapshot/snapshot.c
@@ -107,7 +107,7 @@ static int _snap_target_status_compatible(const char *type)
}
static int _snap_target_percent(void **target_state __attribute__((unused)),
- percent_t *percent,
+ dm_percent_t *percent,
struct dm_pool *mem __attribute__((unused)),
struct cmd_context *cmd __attribute__((unused)),
struct lv_segment *seg __attribute__((unused)),
@@ -120,19 +120,19 @@ static int _snap_target_percent(void **target_state __attribute__((unused)),
return_0;
if (s->invalid)
- *percent = PERCENT_INVALID;
+ *percent = DM_PERCENT_INVALID;
else if (s->merge_failed)
- *percent = PERCENT_MERGE_FAILED;
+ *percent = LVM_PERCENT_MERGE_FAILED;
else {
*total_numerator += s->used_sectors;
*total_denominator += s->total_sectors;
if (s->has_metadata_sectors &&
s->used_sectors == s->metadata_sectors)
- *percent = PERCENT_0;
+ *percent = DM_PERCENT_0;
else if (s->used_sectors == s->total_sectors)
- *percent = PERCENT_100;
+ *percent = DM_PERCENT_100;
else
- *percent = make_percent(*total_numerator, *total_denominator);
+ *percent = dm_make_percent(*total_numerator, *total_denominator);
}
return 1;
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index 28f3e43..020ccc1 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -382,7 +382,7 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
}
static int _thin_pool_target_percent(void **target_state __attribute__((unused)),
- percent_t *percent,
+ dm_percent_t *percent,
struct dm_pool *mem,
struct cmd_context *cmd __attribute__((unused)),
struct lv_segment *seg,
@@ -397,13 +397,13 @@ static int _thin_pool_target_percent(void **target_state __attribute__((unused))
/* With 'seg' report metadata percent, otherwice data percent */
if (seg) {
- *percent = make_percent(s->used_metadata_blocks,
- s->total_metadata_blocks);
+ *percent = dm_make_percent(s->used_metadata_blocks,
+ s->total_metadata_blocks);
*total_numerator += s->used_metadata_blocks;
*total_denominator += s->total_metadata_blocks;
} else {
- *percent = make_percent(s->used_data_blocks,
- s->total_data_blocks);
+ *percent = dm_make_percent(s->used_data_blocks,
+ s->total_data_blocks);
*total_numerator += s->used_data_blocks;
*total_denominator += s->total_data_blocks;
}
@@ -603,7 +603,7 @@ static int _thin_add_target_line(struct dev_manager *dm,
}
static int _thin_target_percent(void **target_state __attribute__((unused)),
- percent_t *percent,
+ dm_percent_t *percent,
struct dm_pool *mem,
struct cmd_context *cmd __attribute__((unused)),
struct lv_segment *seg,
@@ -618,11 +618,11 @@ static int _thin_target_percent(void **target_state __attribute__((unused)),
return_0;
if (seg) {
- *percent = make_percent(s->mapped_sectors, seg->lv->size);
+ *percent = dm_make_percent(s->mapped_sectors, seg->lv->size);
*total_denominator += seg->lv->size;
} else {
/* No lv_segment info here */
- *percent = PERCENT_INVALID;
+ *percent = DM_PERCENT_INVALID;
/* FIXME: Using denominator to pass the mapped info upward? */
*total_denominator += s->highest_mapped_sector;
}
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 0dae981..ecf5640 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1582,6 +1582,36 @@ int dm_regex_match(struct dm_regex *regex, const char *s);
*/
uint32_t dm_regex_fingerprint(struct dm_regex *regex);
+/******************
+ * percent handling
+ ******************/
+/*
+ * A fixed-point representation of percent values. One percent equals to
+ * DM_PERCENT_1 as defined below. Values that are not multiples of DM_PERCENT_1
+ * represent fractions, with precision of 1/1000000 of a percent. See
+ * dm_percent_to_float for a conversion to a floating-point representation.
+ *
+ * You should always use dm_make_percent when building dm_percent_t values. The
+ * implementation of dm_make_percent is biased towards the middle: it ensures that
+ * the result is DM_PERCENT_0 or DM_PERCENT_100 if and only if this is the actual
+ * value -- it never rounds any intermediate value (> 0 or < 100) to either 0
+ * or 100.
+*/
+#define DM_PERCENT_CHAR '%'
+
+typedef enum {
+ DM_PERCENT_0 = 0,
+ DM_PERCENT_1 = 1000000,
+ DM_PERCENT_100 = 100 * DM_PERCENT_1,
+ DM_PERCENT_INVALID = -1,
+ DM_PERCENT_FAILED = -2
+} dm_percent_range_t;
+
+typedef int32_t dm_percent_t;
+
+float dm_percent_to_float(dm_percent_t percent);
+dm_percent_t dm_make_percent(uint64_t numerator, uint64_t denominator);
+
/*********************
* reporting functions
*********************/
@@ -1698,6 +1728,8 @@ int dm_report_field_int(struct dm_report *rh, struct dm_report_field *field,
const int *data);
int dm_report_field_uint64(struct dm_report *rh, struct dm_report_field *field,
const uint64_t *data);
+int dm_report_field_percent(struct dm_report *rh, struct dm_report_field *field,
+ const dm_percent_t *data);
/*
* For custom fields, allocate the data in 'mem' and use
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index aa640de..f053f3d 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -236,6 +236,41 @@ struct str_list_sort_value {
struct str_list_sort_value_item *items;
};
+int dm_report_field_percent(struct dm_report *rh,
+ struct dm_report_field *field,
+ const dm_percent_t *data)
+{
+ char *repstr;
+ uint64_t *sortval;
+
+ if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {
+ log_error("dm_report_field_percent: dm_pool_alloc failed for sort_value.");
+ return 0;
+ }
+
+ *sortval = (uint64_t)(*data);
+
+ if (*data == DM_PERCENT_INVALID) {
+ dm_report_field_set_value(field, "", sortval);
+ return 1;
+ }
+
+ if (!(repstr = dm_pool_alloc(rh->mem, 8))) {
+ dm_pool_free(rh->mem, sortval);
+ log_error("dm_report_field_percent: dm_pool_alloc failed for percent report string.");
+ return 0;
+ }
+
+ if (dm_snprintf(repstr, 7, "%.2f", dm_percent_to_float(*data)) < 0) {
+ dm_pool_free(rh->mem, sortval);
+ log_error("dm_report_field_percent: percentage too large.");
+ return 0;
+ }
+
+ dm_report_field_set_value(field, repstr, sortval);
+ return 1;
+}
+
int dm_report_field_string_list(struct dm_report *rh,
struct dm_report_field *field,
const struct dm_list *data,
@@ -1484,6 +1519,31 @@ static int _check_value_is_reserved(struct dm_report *rh, unsigned type, const v
return 0;
}
+float dm_percent_to_float(dm_percent_t percent)
+{
+ return (float) percent / DM_PERCENT_1;
+}
+
+dm_percent_t dm_make_percent(uint64_t numerator, uint64_t denominator)
+{
+ dm_percent_t percent;
+
+ if (!denominator)
+ return DM_PERCENT_100; /* FIXME? */
+ if (!numerator)
+ return DM_PERCENT_0;
+ if (numerator == denominator)
+ return DM_PERCENT_100;
+ switch (percent = DM_PERCENT_100 * ((double) numerator / (double) denominator)) {
+ case DM_PERCENT_100:
+ return DM_PERCENT_100 - 1;
+ case DM_PERCENT_0:
+ return DM_PERCENT_0 + 1;
+ default:
+ return percent;
+ }
+}
+
/*
* Used to check whether the reserved_values definition passed to
* dm_report_init_with_selection contains only supported reserved value types.
diff --git a/liblvm/lvm2app.h b/liblvm/lvm2app.h
index a91640a..3692f9a 100644
--- a/liblvm/lvm2app.h
+++ b/liblvm/lvm2app.h
@@ -1828,7 +1828,7 @@ uint64_t lvm_pv_get_free(const pv_t pv);
* The memory allocated for a string property value is tied to the vg_t handle
* and will be released when lvm_vg_close() is called. For "percent" values
* (those obtained for copy_percent and snap_percent properties), please see
- * percent_range_t and lvm_percent_to_float().
+ * dm_percent_range_t and lvm_percent_to_float().
*
* Example:
* lvm_property_value value;
@@ -1957,24 +1957,13 @@ pv_t lvm_pv_from_uuid(vg_t vg, const char *uuid);
*/
int lvm_pv_resize(const pv_t pv, uint64_t new_size);
-#ifndef _LVM_PERCENT_H
+#define PERCENT_0 DM_PERCENT_0
+#define PERCENT_1 DM_PERCENT_1
+#define PERCENT_100 DM_PERCENT_100
+#define PERCENT_INVALID DM_PERCENT_INVALID
+#define PERCENT_MERGE_FAILED DM_PERCENT_FAILED
-/**
- * This type defines a couple of special percent values. The PERCENT_0 and
- * PERCENT_100 constants designate *exact* percentages: values are never
- * rounded to either of these two.
- */
-typedef enum {
- PERCENT_0 = 0,
- PERCENT_1 = 1000000,
- PERCENT_100 = 100 * PERCENT_1,
- PERCENT_INVALID = -1,
- PERCENT_MERGE_FAILED = -2
-} percent_range_t;
-
-typedef int32_t percent_t;
-
-#endif
+typedef dm_percent_t percent_t;
/**
* Convert a (fixed-point) value obtained from the percent-denominated
diff --git a/liblvm/lvm_base.c b/liblvm/lvm_base.c
index 47ad241..80d8dbb 100644
--- a/liblvm/lvm_base.c
+++ b/liblvm/lvm_base.c
@@ -197,5 +197,5 @@ const char *lvm_vgname_from_device(lvm_t libh, const char *device)
*/
float lvm_percent_to_float(percent_t v)
{
- return percent_to_float(v);
+ return dm_percent_to_float(v);
}
diff --git a/test/api/thin_percent.c b/test/api/thin_percent.c
index 0df896c..61a928c 100644
--- a/test/api/thin_percent.c
+++ b/test/api/thin_percent.c
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
v = lvm_lv_get_property(lv, "snap_percent");
assert(v.is_valid);
- assert(v.value.integer == (uint64_t) PERCENT_INVALID);
+ assert(v.value.integer == (uint64_t) DM_PERCENT_INVALID);
v = lvm_lv_get_property(lv, "origin");
assert(v.is_valid);
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 75eb565..e857a70 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -799,28 +799,28 @@ static progress_t _poll_merge_progress(struct cmd_context *cmd,
const char *name __attribute__((unused)),
struct daemon_parms *parms)
{
- percent_t percent = PERCENT_0;
+ dm_percent_t percent = DM_PERCENT_0;
if (!lv_is_merging_origin(lv) ||
!lv_snapshot_percent(lv, &percent)) {
log_error("%s: Failed query for merging percentage. Aborting merge.", lv->name);
return PROGRESS_CHECK_FAILED;
- } else if (percent == PERCENT_INVALID) {
+ } else if (percent == DM_PERCENT_INVALID) {
log_error("%s: Merging snapshot invalidated. Aborting merge.", lv->name);
return PROGRESS_CHECK_FAILED;
- } else if (percent == PERCENT_MERGE_FAILED) {
+ } else if (percent == LVM_PERCENT_MERGE_FAILED) {
log_error("%s: Merge failed. Retry merge or inspect manually.", lv->name);
return PROGRESS_CHECK_FAILED;
}
if (parms->progress_display)
log_print_unless_silent("%s: %s: %.1f%%", lv->name, parms->progress_title,
- 100.0 - percent_to_float(percent));
+ 100.0 - dm_percent_to_float(percent));
else
log_verbose("%s: %s: %.1f%%", lv->name, parms->progress_title,
- 100.0 - percent_to_float(percent));
+ 100.0 - dm_percent_to_float(percent));
- if (percent == PERCENT_0)
+ if (percent == DM_PERCENT_0)
return PROGRESS_FINISHED_ALL;
return PROGRESS_UNFINISHED;
@@ -1836,7 +1836,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
struct dm_list *failed_pvs;
struct cmd_context *cmd = lv->vg->cmd;
struct lv_segment *seg = first_seg(lv);
- percent_t sync_percent;
+ dm_percent_t sync_percent;
if (!arg_count(cmd, type_ARG))
lp->segtype = seg->segtype;
@@ -1911,7 +1911,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
return 0;
}
- if (sync_percent != PERCENT_100) {
+ if (sync_percent != DM_PERCENT_100) {
log_error("WARNING: %s/%s is not in-sync.",
lv->vg->name, lv->name);
log_error("WARNING: Portions of the array may"
@@ -2106,7 +2106,7 @@ static int _lvconvert_merge_old_snapshot(struct cmd_context *cmd,
struct logical_volume *origin = origin_from_cow(lv);
struct lv_segment *snap_seg = find_snapshot(lv);
struct lvinfo info;
- percent_t snap_percent;
+ dm_percent_t snap_percent;
/* Check if merge is possible */
if (!lv_is_cow(lv)) {
@@ -2141,7 +2141,7 @@ static int _lvconvert_merge_old_snapshot(struct cmd_context *cmd,
if (lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)
&& info.exists && info.live_table &&
(!lv_snapshot_percent(lv, &snap_percent) ||
- snap_percent == PERCENT_INVALID)) {
+ snap_percent == DM_PERCENT_INVALID)) {
log_error("Unable to merge invalidated snapshot LV \"%s\".",
lv->name);
return 0;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 86264f3..47459ec 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -331,7 +331,7 @@ static int _determine_cache_argument(struct volume_group *vg,
/*
* Update extents parameters based on other parameters which affect the size
* calculation.
- * NOTE: We must do this here because of the percent_t typedef and because we
+ * NOTE: We must do this here because of the dm_percent_t typedef and because we
* need the vg.
*/
static int _update_extents_params(struct volume_group *vg,
diff --git a/tools/lvscan.c b/tools/lvscan.c
index 47e79d6..2641054 100644
--- a/tools/lvscan.c
+++ b/tools/lvscan.c
@@ -20,7 +20,7 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
{
struct lvinfo info;
int inkernel, snap_active = 1;
- percent_t snap_percent; /* fused, fsize; */
+ dm_percent_t snap_percent; /* fused, fsize; */
const char *active_str, *snapshot_str;
@@ -31,7 +31,7 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_cow(lv)) {
if (inkernel &&
(snap_active = lv_snapshot_percent(lv, &snap_percent)))
- if (snap_percent == PERCENT_INVALID)
+ if (snap_percent == DM_PERCENT_INVALID)
snap_active = 0;
}
diff --git a/tools/polldaemon.c b/tools/polldaemon.c
index 0765930..8d5c6ba 100644
--- a/tools/polldaemon.c
+++ b/tools/polldaemon.c
@@ -21,13 +21,13 @@ progress_t poll_mirror_progress(struct cmd_context *cmd,
struct logical_volume *lv, const char *name,
struct daemon_parms *parms)
{
- percent_t segment_percent = PERCENT_0, overall_percent = PERCENT_0;
+ dm_percent_t segment_percent = DM_PERCENT_0, overall_percent = DM_PERCENT_0;
uint32_t event_nr = 0;
if (!lv_is_mirrored(lv) ||
!lv_mirror_percent(cmd, lv, !parms->interval, &segment_percent,
&event_nr) ||
- (segment_percent == PERCENT_INVALID)) {
+ (segment_percent == DM_PERCENT_INVALID)) {
log_error("ABORTING: Mirror percentage check failed.");
return PROGRESS_CHECK_FAILED;
}
@@ -35,15 +35,15 @@ progress_t poll_mirror_progress(struct cmd_context *cmd,
overall_percent = copy_percent(lv);
if (parms->progress_display)
log_print_unless_silent("%s: %s: %.1f%%", name, parms->progress_title,
- percent_to_float(overall_percent));
+ dm_percent_to_float(overall_percent));
else
log_verbose("%s: %s: %.1f%%", name, parms->progress_title,
- percent_to_float(overall_percent));
+ dm_percent_to_float(overall_percent));
- if (segment_percent != PERCENT_100)
+ if (segment_percent != DM_PERCENT_100)
return PROGRESS_UNFINISHED;
- if (overall_percent == PERCENT_100)
+ if (overall_percent == DM_PERCENT_100)
return PROGRESS_FINISHED_ALL;
return PROGRESS_FINISHED_SEGMENT;
8 years, 9 months
master - report: select: add support for reserved value recognition in report selection string - add struct dm_report_reserved_value
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=35c4e4489c9eef...
Commit: 35c4e4489c9eef22691332b43e51b03055e4fe92
Parent: a075ec15c4a8e704fbb9519326d0c97371ead2f3
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri May 30 15:02:21 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:21 2014 +0200
report: select: add support for reserved value recognition in report selection string - add struct dm_report_reserved_value
Make dm_report_init_with_selection to accept an argument with an
array of reserved values where each element contains a triple:
{dm report field type, reserved value, array of strings representing this value}
When the selection is parsed, we always check whether a string
representation of some reserved value is not hit and if it is,
we use the reserved value assigned for this string instead of
trying to parse it as a value of certain field type.
This makes it possible to define selections like:
... --select lv_major=undefined (or -1 or unknown or undef or whatever string representations are registered for this reserved value in the future)
... --select lv_read_ahead=auto
... --select vg_mda_copies=unmanaged
With this, each time the field value of certain type is hit
and when we compare it with the selection, we use the proper
value for comparison.
For now, register these reserved values that are used at the moment
(also more descriptive names are used for the values):
const uint64_t _reserved_number_undef_64 = UINT64_MAX;
const uint64_t _reserved_number_unmanaged_64 = UINT64_MAX - 1;
const uint64_t _reserved_size_auto_64 = UINT64_MAX;
{
{DM_REPORT_FIELD_TYPE_NUMBER, _reserved_number_undef_64, {"-1", "undefined", "undef", "unknown", NULL}},
{DM_REPORT_FIELD_TYPE_NUMBER, _reserved_number_unmanaged_64, {"unmanaged", NULL}},
{DM_REPORT_FIELD_TYPE_SIZE, _reserved_size_auto_64, {"auto", NULL}},
NULL
}
Same reserved value of different field types do not collide.
All arrays are null-terminated.
The list of reserved values is automatically displayed within
selection help output:
Selection operands
------------------
...
Reserved values
---------------
-1, undefined, undef, unknown - Reserved value for undefined numeric value. [number]
unmanaged - Reserved value for unmanaged number of metadata copies in VG. [number]
auto - Reserved value for size that is automatically calculated. [size]
Selection operators
-------------------
...
---
lib/report/report.c | 72 +++++++++++------
libdm/libdevmapper.h | 11 +++
libdm/libdm-report.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++----
tools/dmsetup.c | 2 +-
4 files changed, 268 insertions(+), 43 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index e8ff5bb..7f509e1 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -37,10 +37,33 @@ struct lvm_report_object {
};
static const uint64_t _hundred64 = UINT64_C(100);
-static const uint64_t _minusone64 = UINT64_C(-1);
-static const int32_t _minusone32 = INT32_C(-1);
static const uint64_t _zero64 = UINT64_C(0);
+static const uint64_t _reserved_number_undef_64 = UINT64_C(-1);
+static const uint64_t _reserved_number_unmanaged_64 = UINT64_C(-2);
+static const uint64_t _reserved_size_auto_64 = UINT64_C(-1);
+
+/*
+ * 32 bit signed is casted to 64 bit unsigned in dm_report_field internally!
+ * So when stored in the struct, the _reserved_number_undef_32 is actually
+ * equal to _reserved_number_undef_64.
+ */
+static const int32_t _reserved_number_undef_32 = INT32_C(-1);
+
+static const char const *_reserved_number_undef_64_names[]={"-1", "undefined", "undef", "unknown", NULL};
+static const char const *_reserved_number_unmanaged_64_names[]={"unmanaged", NULL};
+static const char const *_reserved_size_auto_64_names[]={"auto", NULL};
+
+static const struct dm_report_reserved_value _report_reserved_values[] = {
+ {DM_REPORT_FIELD_TYPE_NUMBER, &_reserved_number_undef_64, _reserved_number_undef_64_names,
+ "Reserved value for undefined numeric value."},
+ {DM_REPORT_FIELD_TYPE_NUMBER, &_reserved_number_unmanaged_64, _reserved_number_unmanaged_64_names,
+ "Reserved value for unmanaged number of metadata copies in VG."},
+ {DM_REPORT_FIELD_TYPE_SIZE, &_reserved_size_auto_64, _reserved_size_auto_64_names,
+ "Reserved value for size that is automatically calculated."},
+ {0, NULL, NULL}
+};
+
static int _field_set_value(struct dm_report_field *field, const void *data, const void *sort)
{
dm_report_field_set_value(field, data, sort);
@@ -56,7 +79,7 @@ static int _field_set_percent(struct dm_report_field *field,
uint64_t *sortval;
if (percent == PERCENT_INVALID)
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
if (!(repstr = dm_pool_alloc(mem, 8)) ||
!(sortval = dm_pool_alloc(mem, sizeof(uint64_t)))) {
@@ -203,7 +226,7 @@ static int _lvkmaj_disp(struct dm_report *rh, struct dm_pool *mem __attribute__(
if ((major = lv_kernel_major(lv)) >= 0)
return dm_report_field_int(rh, field, &major);
- return dm_report_field_int32(rh, field, &_minusone32);
+ return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
}
static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
@@ -216,7 +239,7 @@ static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute__(
if ((minor = lv_kernel_minor(lv)) >= 0)
return dm_report_field_int(rh, field, &minor);
- return dm_report_field_int32(rh, field, &_minusone32);
+ return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
}
static int _lvstatus_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
@@ -502,7 +525,7 @@ static int _lvreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
const struct logical_volume *lv = (const struct logical_volume *) data;
if (lv->read_ahead == DM_READ_AHEAD_AUTO)
- return _field_set_value(field, "auto", &_minusone64);
+ return _field_set_value(field, "auto", &_reserved_size_auto_64);
return _size32_disp(rh, mem, field, &lv->read_ahead, private);
}
@@ -516,7 +539,7 @@ static int _lvkreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
uint32_t read_ahead = lv_kernel_read_ahead(lv);
if (read_ahead == UINT32_MAX)
- return dm_report_field_int32(rh, field, &_minusone32);
+ return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
return _size32_disp(rh, mem, field, &read_ahead, private);
}
@@ -604,7 +627,7 @@ static int _thinzero_disp(struct dm_report *rh, struct dm_pool *mem,
if (seg_is_thin_pool(seg))
return _uint32_disp(rh, mem, field, &seg->zero_new_blocks, private);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _transactionid_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -616,7 +639,7 @@ static int _transactionid_disp(struct dm_report *rh, struct dm_pool *mem,
if (seg_is_thin_pool(seg))
return dm_report_field_uint64(rh, field, &seg->transaction_id);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _thinid_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -628,7 +651,7 @@ static int _thinid_disp(struct dm_report *rh, struct dm_pool *mem,
if (seg_is_thin_volume(seg))
return dm_report_field_uint32(rh, field, &seg->device_id);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _discards_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -794,7 +817,7 @@ static int _vgmdacopies_disp(struct dm_report *rh, struct dm_pool *mem,
uint32_t count = vg_mda_copies(vg);
if (count == VGMETADATACOPIES_UNMANAGED)
- return _field_set_value(field, "unmanaged", &_minusone64);
+ return _field_set_value(field, "unmanaged", &_reserved_number_unmanaged_64);
return _uint32_disp(rh, mem, field, &count, private);
}
@@ -903,7 +926,7 @@ static int _snpercent_disp(struct dm_report *rh __attribute__((unused)), struct
*/
}
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _copypercent_disp(struct dm_report *rh __attribute__((unused)),
@@ -923,7 +946,7 @@ static int _copypercent_disp(struct dm_report *rh __attribute__((unused)),
return _field_set_percent(field, mem, percent);
}
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _raidsyncaction_disp(struct dm_report *rh __attribute__((unused)),
@@ -953,7 +976,7 @@ static int _raidmismatchcount_disp(struct dm_report *rh __attribute__((unused)),
if (lv_is_raid(lv) && lv_raid_mismatch_count(lv, &mismatch_count))
return dm_report_field_uint64(rh, field, &mismatch_count);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _raidwritebehind_disp(struct dm_report *rh __attribute__((unused)),
@@ -967,7 +990,7 @@ static int _raidwritebehind_disp(struct dm_report *rh __attribute__((unused)),
if (lv_is_raid_type(lv) && first_seg(lv)->writebehind)
return dm_report_field_uint32(rh, field, &first_seg(lv)->writebehind);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _raidminrecoveryrate_disp(struct dm_report *rh __attribute__((unused)),
@@ -982,7 +1005,7 @@ static int _raidminrecoveryrate_disp(struct dm_report *rh __attribute__((unused)
return dm_report_field_uint32(rh, field,
&first_seg(lv)->min_recovery_rate);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _raidmaxrecoveryrate_disp(struct dm_report *rh __attribute__((unused)),
@@ -997,7 +1020,7 @@ static int _raidmaxrecoveryrate_disp(struct dm_report *rh __attribute__((unused)
return dm_report_field_uint32(rh, field,
&first_seg(lv)->max_recovery_rate);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
/* Called only with lv_is_thin_pool/volume */
@@ -1011,7 +1034,7 @@ static int _dtpercent_disp(int metadata, struct dm_pool *mem,
/* Suppress data percent if not using driver */
/* cannot use lv_is_active_locally - need to check for layer -tpool */
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
if (lv_is_thin_pool(lv)) {
if (!lv_thin_pool_percent(lv, metadata, &percent))
@@ -1036,7 +1059,7 @@ static int _datapercent_disp(struct dm_report *rh, struct dm_pool *mem,
if (lv_is_thin_pool(lv) || lv_is_thin_volume(lv))
return _dtpercent_disp(0, mem, field, data, private);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _metadatapercent_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1048,7 +1071,7 @@ static int _metadatapercent_disp(struct dm_report *rh, struct dm_pool *mem,
if (lv_is_thin_pool(lv))
return _dtpercent_disp(1, mem, field, data, private);
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _lvmetadatasize_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1063,7 +1086,7 @@ static int _lvmetadatasize_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &size, private);
}
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _thincount_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1078,7 +1101,7 @@ static int _thincount_disp(struct dm_report *rh, struct dm_pool *mem,
return _uint32_disp(rh, mem, field, &count, private);
}
- return _field_set_value(field, "", &_minusone64);
+ return _field_set_value(field, "", &_reserved_number_undef_64);
}
static int _lvtime_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1264,8 +1287,9 @@ void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
rh = dm_report_init_with_selection(report_type,
devtypes_report ? _devtypes_report_types : _report_types,
- devtypes_report ? _devtypes_fields : _fields, format,
- separator, report_flags, keys, selection, cmd);
+ devtypes_report ? _devtypes_fields : _fields,
+ format, separator, report_flags, keys,
+ selection, _report_reserved_values, cmd);
if (rh && field_prefixes)
dm_report_set_output_field_name_prefix(rh, "lvm2_");
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index d256373..0dae981 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1631,6 +1631,16 @@ struct dm_report_field_type {
const char *desc; /* description of the field */
};
+struct dm_report_reserved_value {
+ const unsigned type; /* DM_REPORT_FIELD_TYPE_* */
+ const void const *value; /* reserved value:
+ uint64_t for DM_REPORT_FIELD_TYPE_NUMBER
+ uint64_t for DM_REPORT_FIELD_TYPE_SIZE (number of 512-byte sectors)
+ const char * for DM_REPORT_FIELD_TYPE_STRING */
+ const char **names; /* null-terminated array of names for this reserved value */
+ const char *description; /* description of the reserved value */
+};
+
/*
* dm_report_init output_flags
*/
@@ -1658,6 +1668,7 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
uint32_t output_flags,
const char *sort_keys,
const char *selection,
+ const struct dm_report_reserved_value reserved_values[],
void *private_data);
int dm_report_object(struct dm_report *rh, void *object);
int dm_report_set_output_selection(struct dm_report *rh, uint32_t *report_types,
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 1c35166..aa640de 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -52,6 +52,8 @@ struct dm_report {
void *private;
struct selection_node *selection_root;
+ /* Null-terminated array of reserved values */
+ const struct dm_report_reserved_value *reserved_values;
};
/*
@@ -1412,6 +1414,102 @@ static const char *_tok_value_string(const char *s,
}
/*
+ * 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;
+
+ *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++;
+ }
+ }
+ iter++;
+ }
+
+ return s;
+}
+
+/*
+ * Used to check whether a value of certain type used in selection is reserved.
+ */
+static int _check_value_is_reserved(struct dm_report *rh, unsigned type, const void *value)
+{
+ const struct dm_report_reserved_value *iter = rh->reserved_values;
+
+ if (!iter)
+ return 0;
+
+ while (iter->type) {
+ if (iter->type & type) {
+ switch (type) {
+ case DM_REPORT_FIELD_TYPE_NUMBER:
+ if (*(uint64_t *)iter->value == *(uint64_t *)value)
+ return 1;
+ break;
+ case DM_REPORT_FIELD_TYPE_STRING:
+ if (!strcmp((const char *)iter->value, (const char *) value))
+ return 1;
+ break;
+ case DM_REPORT_FIELD_TYPE_SIZE:
+ if (_close_enough(*(double *)iter->value, *(double *) value))
+ return 1;
+ break;
+ case DM_REPORT_FIELD_TYPE_STRING_LIST:
+ // TODO: add comparison for string list
+ break;
+ }
+ }
+ iter++;
+ }
+
+ return 0;
+}
+
+/*
+ * Used to check whether the reserved_values definition passed to
+ * dm_report_init_with_selection contains only supported reserved value types.
+ */
+static int _check_reserved_values_supported(const struct dm_report_reserved_value reserved_values[])
+{
+ const struct dm_report_reserved_value *iter;
+ static uint32_t supported_reserved_types = DM_REPORT_FIELD_TYPE_NUMBER |
+ DM_REPORT_FIELD_TYPE_SIZE |
+ DM_REPORT_FIELD_TYPE_STRING;
+
+ if (!reserved_values)
+ return 1;
+
+ iter = reserved_values;
+
+ while (iter->type) {
+ if (!(iter->type & supported_reserved_types))
+ return 0;
+ iter++;
+ }
+
+ return 1;
+}
+
+/*
* Input:
* ft - field type for which the value is parsed
* s - a pointer to the parsed string
@@ -1420,11 +1518,14 @@ static const char *_tok_value_string(const char *s,
* end - a pointer to the end of the token + 1
* flags - parsing flags
*/
-static const char *_tok_value_regex(const struct dm_report_field_type *ft,
+static const char *_tok_value_regex(struct dm_report *rh,
+ const struct dm_report_field_type *ft,
const char *s, const char **begin,
- const char **end, uint32_t *flags)
+ const char **end, uint32_t *flags,
+ const struct dm_report_reserved_value **reserved)
{
char c;
+ *reserved = NULL;
s = _skip_space(s);
@@ -1628,9 +1729,11 @@ bad:
* custom - custom data specific to token type
* (e.g. size unit factor)
*/
-static const char *_tok_value(const struct dm_report_field_type *ft,
+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,
+ const struct dm_report_reserved_value **reserved,
struct dm_pool *mem, void *custom)
{
int expected_type = ft->flags & DM_REPORT_FIELD_TYPE_MASK;
@@ -1641,6 +1744,12 @@ static const char *_tok_value(const struct dm_report_field_type *ft,
s = _skip_space(s);
+ s = _get_reserved_value(rh, expected_type, s, begin, end, reserved);
+ if (*reserved) {
+ *flags |= expected_type;
+ return s;
+ }
+
switch (expected_type) {
case DM_REPORT_FIELD_TYPE_STRING:
@@ -1728,6 +1837,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
const char *v,
size_t len,
uint32_t flags,
+ const struct dm_report_reserved_value *reserved,
void *custom)
{
static const char *_out_of_range_msg = "Field selection value %s out of supported range for field %s.";
@@ -1798,29 +1908,58 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
switch (flags & DM_REPORT_FIELD_TYPE_MASK) {
case DM_REPORT_FIELD_TYPE_STRING:
- fs->v.s = s;
+ if (reserved) {
+ fs->v.s = (const char *) reserved->value;
+ dm_pool_free(rh->mem, s);
+ } else {
+ fs->v.s = s;
+ if (_check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_STRING, fs->v.s)) {
+ log_error("String value %s found in selection is reserved.", fs->v.s);
+ goto error;
+ }
+ }
break;
case DM_REPORT_FIELD_TYPE_NUMBER:
- if (((fs->v.i = strtoull(s, NULL, 10)) == ULLONG_MAX) &&
- (errno == ERANGE)) {
- log_error(_out_of_range_msg, s, field_id);
- goto error;
+ if (reserved)
+ fs->v.i = *(uint64_t *) reserved->value;
+ else {
+ if (((fs->v.i = strtoull(s, NULL, 10)) == ULLONG_MAX) &&
+ (errno == ERANGE)) {
+ log_error(_out_of_range_msg, s, field_id);
+ goto error;
+ }
+ if (_check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_NUMBER, &fs->v.i)) {
+ log_error("Numeric value %" PRIu64 " found in selection is reserved.", fs->v.i);
+ goto error;
+ }
}
dm_pool_free(rh->mem, s);
break;
case DM_REPORT_FIELD_TYPE_SIZE:
- fs->v.d = strtod(s, NULL);
- if (errno == ERANGE) {
- log_error(_out_of_range_msg, s, field_id);
- goto error;
+ if (reserved)
+ fs->v.d = (double) * (uint64_t *) reserved->value;
+ else {
+ fs->v.d = strtod(s, NULL);
+ if (errno == ERANGE) {
+ log_error(_out_of_range_msg, s, field_id);
+ goto error;
+ }
+ if (custom && (factor = *((uint64_t *)custom)))
+ fs->v.d *= factor;
+ fs->v.d /= 512; /* store size in sectors! */
+ if (_check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_SIZE, &fs->v.d)) {
+ log_error("Size value %f found in selection is reserved.", fs->v.d);
+ goto error;
+ }
}
- if (custom && (factor = *((uint64_t *)custom)))
- fs->v.d *= factor;
- fs->v.d /= 512; /* store size in sectors! */
dm_pool_free(rh->mem, s);
break;
case DM_REPORT_FIELD_TYPE_STRING_LIST:
fs->v.l = *(struct selection_str_list **)custom;
+ if (_check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_STRING_LIST, fs->v.l)) {
+ log_error("String list value found in selection is reserved.");
+ goto error;
+ }
break;
default:
log_error(INTERNAL_ERROR "_create_field_selection: "
@@ -1854,7 +1993,12 @@ static struct selection_node *_alloc_selection_node(struct dm_pool *mem, uint32_
static void _display_selection_help(struct dm_report *rh)
{
+ static const char _grow_object_failed_msg[] = "_display_selection_help: dm_pool_grow_object failed";
struct op_def *t;
+ const struct dm_report_reserved_value *rv;
+ size_t len_all, len_final = 0;
+ const char **rvs;
+ char *rvs_all;
log_warn("Selection operands");
log_warn("------------------");
@@ -1866,6 +2010,42 @@ static void _display_selection_help(struct dm_report *rh)
log_warn(" \"all items must match\" or \"at least one item must match\" operator.");
log_warn(" regular expression - Characters quoted by \' or \" or unquoted.");
log_warn(" ");
+ if (rh->reserved_values) {
+ log_warn("Reserved values");
+ log_warn("---------------");
+
+ for (rv = rh->reserved_values; rv->type; rv++) {
+ for (len_all = 0, rvs = rv->names; *rvs; rvs++)
+ len_all += strlen(*rvs) + 2;
+ if (len_all > len_final)
+ len_final = len_all;
+ }
+
+ for (rv = rh->reserved_values; rv->type; rv++) {
+ if (!dm_pool_begin_object(rh->mem, 256)) {
+ log_error("_display_selection_help: dm_pool_begin_object failed");
+ break;
+ }
+ for (rvs = rv->names; *rvs; rvs++) {
+ if (((rvs != rv->names) && !dm_pool_grow_object(rh->mem, ", ", 2)) ||
+ !dm_pool_grow_object(rh->mem, *rvs, strlen(*rvs))) {
+ log_error(_grow_object_failed_msg);
+ goto out_reserved_values;
+ }
+ }
+ if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
+ log_error(_grow_object_failed_msg);
+ goto out_reserved_values;
+ }
+ rvs_all = dm_pool_end_object(rh->mem);
+
+ log_warn(" %-*s - %s [%s]", (int) len_final, rvs_all, rv->description,
+ _get_field_type_name(rv->type));
+ dm_pool_free(rh->mem, rvs_all);
+ }
+ log_warn(" ");
+ }
+out_reserved_values:
log_warn("Selection operators");
log_warn("-------------------");
log_warn(" Comparison operators:");
@@ -1913,6 +2093,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
uint32_t flags, field_num;
const struct dm_report_field_type *ft;
struct selection_str_list *str_list;
+ const struct dm_report_reserved_value *reserved;
uint64_t factor;
void *custom;
char *tmp;
@@ -1961,7 +2142,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
/* comparison value */
if (flags & FLD_CMP_REGEX) {
- if (!(last = _tok_value_regex(ft, last, &vs, &ve, &flags)))
+ if (!(last = _tok_value_regex(rh, ft, last, &vs, &ve, &flags, &reserved)))
goto_bad;
} else {
if (ft->flags == DM_REPORT_FIELD_TYPE_SIZE ||
@@ -1971,14 +2152,14 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
custom = &str_list;
else
custom = NULL;
- if (!(last = _tok_value(ft, last, &vs, &ve, &flags, rh->mem, custom)))
+ if (!(last = _tok_value(rh, ft, last, &vs, &ve, &flags, &reserved, rh->mem, custom)))
goto_bad;
}
*next = _skip_space(last);
/* create selection */
- if (!(fs = _create_field_selection(rh, field_num, vs, (size_t) (ve - vs), flags, custom)))
+ if (!(fs = _create_field_selection(rh, field_num, vs, (size_t) (ve - vs), flags, reserved, custom)))
return_NULL;
/* create selection node */
@@ -2119,6 +2300,7 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
uint32_t output_flags,
const char *sort_keys,
const char *selection,
+ const struct dm_report_reserved_value reserved_values[],
void *private_data)
{
struct dm_report *rh;
@@ -2134,6 +2316,14 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
return rh;
}
+ if (!_check_reserved_values_supported(reserved_values)) {
+ log_error(INTERNAL_ERROR "dm_report_init_with_selection: "
+ "trying to register unsupported reserved value type, "
+ "skipping report selection");
+ return rh;
+ }
+ rh->reserved_values = reserved_values;
+
if (!strcasecmp(selection, DM_REPORT_FIELD_RESERVED_NAME_HELP) ||
!strcmp(selection, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT)) {
_display_fields(rh, 0, 1);
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index 1a5e068..454141e 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -2934,7 +2934,7 @@ static int _report_init(const struct command *cmd)
if (!(_report = dm_report_init_with_selection(&_report_type, _report_types,
_report_fields, options, separator, flags, keys,
- selection, NULL)))
+ selection, NULL, NULL)))
goto out;
if ((_report_type & DR_TREE) && !_build_whole_deptree(cmd)) {
8 years, 9 months
master - report: select: show field type in field list if in context of selection
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a075ec15c4a8e7...
Commit: a075ec15c4a8e704fbb9519326d0c97371ead2f3
Parent: 6d667adeeab7eb7b88a596ebd998fa0a32a4f61c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 16 14:06:04 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:21 2014 +0200
report: select: show field type in field list if in context of selection
When the field list is displayed as help for constructing selection
criteria, show also the field value type. This is useful for users
to know what set of operators are allowed for the type - the subsequent
"Selection operands" section in the help output summarize all known
types that can be used in selection.
---
libdm/libdm-report.c | 27 +++++++++++++++++++++------
1 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index df29b6b..1c35166 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -472,10 +472,22 @@ void dm_report_field_set_value(struct dm_report_field *field, const void *value,
log_warn(INTERNAL_ERROR "Using string as sort value for numerical field.");
}
+static const char *_get_field_type_name(unsigned field_type)
+{
+ switch (field_type) {
+ case DM_REPORT_FIELD_TYPE_STRING: return "string";
+ case DM_REPORT_FIELD_TYPE_NUMBER: return "number";
+ case DM_REPORT_FIELD_TYPE_SIZE: return "size";
+ case DM_REPORT_FIELD_TYPE_STRING_LIST: return "string list";
+ default: return "unknown";
+ }
+}
+
/*
* show help message
*/
-static void _display_fields(struct dm_report *rh, int display_all_fields_item)
+static void _display_fields(struct dm_report *rh, int display_all_fields_item
+ int display_field_types)
{
uint32_t f;
const struct dm_report_object_type *type;
@@ -511,7 +523,10 @@ static void _display_fields(struct dm_report *rh, int display_all_fields_item)
}
/* FIXME Add line-wrapping at terminal width (or 80 cols) */
- log_warn(" %-*s - %s", (int) id_len, rh->fields[f].id, rh->fields[f].desc);
+ log_warn(" %-*s - %s%s%s%s", (int) id_len, rh->fields[f].id, rh->fields[f].desc,
+ display_field_types ? " [" : "",
+ display_field_types ? _get_field_type_name(rh->fields[f].flags & DM_REPORT_FIELD_TYPE_MASK) : "",
+ display_field_types ? "]" : "");
last_desc = desc;
}
}
@@ -770,7 +785,7 @@ static int _parse_fields(struct dm_report *rh, const char *format,
we++;
if (!_field_match(rh, ws, (size_t) (we - ws), report_type_only)) {
- _display_fields(rh, 1);
+ _display_fields(rh, 1, 0);
log_warn(" ");
if (strcasecmp(ws, DM_REPORT_FIELD_RESERVED_NAME_HELP) &&
strcmp(ws, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT))
@@ -800,7 +815,7 @@ static int _parse_keys(struct dm_report *rh, const char *keys,
while (*we && *we != ',')
we++;
if (!_key_match(rh, ws, (size_t) (we - ws), report_type_only)) {
- _display_fields(rh, 1);
+ _display_fields(rh, 1, 0);
log_warn(" ");
if (strcasecmp(ws, DM_REPORT_FIELD_RESERVED_NAME_HELP) &&
strcmp(ws, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT))
@@ -1914,7 +1929,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
c = we[0];
tmp = (char *) we;
tmp[0] = '\0';
- _display_fields(rh, 0);
+ _display_fields(rh, 0, 1);
log_warn(" ");
log_error("Unrecognised selection field: %s", ws);
tmp[0] = c;
@@ -2121,7 +2136,7 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
if (!strcasecmp(selection, DM_REPORT_FIELD_RESERVED_NAME_HELP) ||
!strcmp(selection, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT)) {
- _display_fields(rh, 0);
+ _display_fields(rh, 0, 1);
log_warn(" ");
_display_selection_help(rh);
dm_report_free(rh);
8 years, 9 months
master - report: select: add help for creating selections
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6d667adeeab7eb...
Commit: 6d667adeeab7eb7b88a596ebd998fa0a32a4f61c
Parent: 03a3f6078de3790a6fca3db8deb4bd204df611f1
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu May 29 09:42:14 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:21 2014 +0200
report: select: add help for creating selections
The "<lvm command> -S/--select help" shows help (including list of fields to match against):
...field list here including the field type name...
Selection operands
------------------
field - Reporting field.
number - Non-negative integer value.
size - Floating point value with units specified.
string - Characters quoted by ' or " or unquoted.
string list - Strings enclosed by [ ] and elements delimited by either
"all items must match" or "at least one item must match" operator.
regular expression - Characters quoted by ' or " or unquoted.
Selection operators
-------------------
Comparison operators:
=~ - Matching regular expression.
!~ - Not matching regular expression.
= - Equal to.
!= - Not equal to.
>= - Greater than or equal to.
> - Greater than
<= - Less than or equal to.
< - Less than.
Logical and grouping operators:
&& - All fields must match
, - All fields must match
|| - At least one field must match
# - At least one field must match
! - Logical negation
( - Left parenthesis
) - Right parenthesis
[ - List start
] - List end
---
libdm/libdm-report.c | 56 ++++++++++++++++++++++++++++++++++++++++++++-----
tools/reporter.c | 5 +++-
2 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 380c4dc..df29b6b 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -475,7 +475,7 @@ void dm_report_field_set_value(struct dm_report_field *field, const void *value,
/*
* show help message
*/
-static void _display_fields(struct dm_report *rh)
+static void _display_fields(struct dm_report *rh, int display_all_fields_item)
{
uint32_t f;
const struct dm_report_object_type *type;
@@ -503,9 +503,11 @@ static void _display_fields(struct dm_report *rh)
log_warn("%*.*s", (int) strlen(desc) + 7,
(int) strlen(desc) + 7,
"-------------------------------------------------------------------------------");
- log_warn(" %sall%-*s - %s", type->prefix,
- (int) (id_len - 3 - strlen(type->prefix)), "",
- "All fields in this section.");
+ if (display_all_fields_item) {
+ log_warn(" %sall%-*s - %s", type->prefix,
+ (int) (id_len - 3 - strlen(type->prefix)), "",
+ "All fields in this section.");
+ }
}
/* FIXME Add line-wrapping at terminal width (or 80 cols) */
@@ -768,7 +770,7 @@ static int _parse_fields(struct dm_report *rh, const char *format,
we++;
if (!_field_match(rh, ws, (size_t) (we - ws), report_type_only)) {
- _display_fields(rh);
+ _display_fields(rh, 1);
log_warn(" ");
if (strcasecmp(ws, DM_REPORT_FIELD_RESERVED_NAME_HELP) &&
strcmp(ws, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT))
@@ -798,7 +800,7 @@ static int _parse_keys(struct dm_report *rh, const char *keys,
while (*we && *we != ',')
we++;
if (!_key_match(rh, ws, (size_t) (we - ws), report_type_only)) {
- _display_fields(rh);
+ _display_fields(rh, 1);
log_warn(" ");
if (strcasecmp(ws, DM_REPORT_FIELD_RESERVED_NAME_HELP) &&
strcmp(ws, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT))
@@ -1835,6 +1837,34 @@ static struct selection_node *_alloc_selection_node(struct dm_pool *mem, uint32_
return sn;
}
+static void _display_selection_help(struct dm_report *rh)
+{
+ struct op_def *t;
+
+ log_warn("Selection operands");
+ log_warn("------------------");
+ log_warn(" field - Reporting field.");
+ log_warn(" number - Non-negative integer value.");
+ log_warn(" size - Floating point value with units, 'm' unit used by default if not specified.");
+ log_warn(" string - Characters quoted by \' or \" or unquoted.");
+ log_warn(" string list - Strings enclosed by [ ] and elements delimited by either");
+ log_warn(" \"all items must match\" or \"at least one item must match\" operator.");
+ log_warn(" regular expression - Characters quoted by \' or \" or unquoted.");
+ log_warn(" ");
+ log_warn("Selection operators");
+ log_warn("-------------------");
+ log_warn(" Comparison operators:");
+ t = _op_cmp;
+ for (; t->string; t++)
+ log_warn(" %4s - %s", t->string, t->desc);
+ log_warn(" ");
+ log_warn(" Logical and grouping operators:");
+ t = _op_log;
+ for (; t->string; t++)
+ log_warn(" %4s - %s", t->string, t->desc);
+ log_warn(" ");
+}
+
static char _sel_syntax_error_at_msg[] = "Selection syntax error at '%s'.";
/*
@@ -1884,6 +1914,8 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
c = we[0];
tmp = (char *) we;
tmp[0] = '\0';
+ _display_fields(rh, 0);
+ log_warn(" ");
log_error("Unrecognised selection field: %s", ws);
tmp[0] = c;
goto bad;
@@ -1893,10 +1925,12 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
/* comparison operator */
if (!(flags = _tok_op_cmp(we, &last))) {
+ _display_selection_help(rh);
log_error("Unrecognised comparison operator: %s", we);
goto bad;
}
if (!last) {
+ _display_selection_help(rh);
log_error("Missing value after operator");
goto bad;
}
@@ -1905,6 +1939,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
if ((flags & FLD_CMP_NUMBER) &&
(ft->flags != DM_REPORT_FIELD_TYPE_NUMBER) &&
(ft->flags != DM_REPORT_FIELD_TYPE_SIZE)) {
+ _display_selection_help(rh);
log_error("Operator can be used only with numeric or size fields: %s", ws);
goto bad;
}
@@ -2084,6 +2119,15 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
return rh;
}
+ if (!strcasecmp(selection, DM_REPORT_FIELD_RESERVED_NAME_HELP) ||
+ !strcmp(selection, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT)) {
+ _display_fields(rh, 0);
+ log_warn(" ");
+ _display_selection_help(rh);
+ dm_report_free(rh);
+ return NULL;
+ }
+
if (!(root = _alloc_selection_node(rh->mem, SEL_OR)))
return_0;
diff --git a/tools/reporter.c b/tools/reporter.c
index 56980cf..1e91f8f 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -358,7 +358,10 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
if ( (!strcasecmp(options, DM_REPORT_FIELD_RESERVED_NAME_HELP) ||
!strcmp(options, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT)) ||
(!strcasecmp(keys, DM_REPORT_FIELD_RESERVED_NAME_HELP) ||
- !strcmp(keys, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT)) )
+ !strcmp(keys, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT)) ||
+ (selection &&
+ (!strcasecmp(selection, DM_REPORT_FIELD_RESERVED_NAME_HELP) ||
+ !strcmp(selection, DM_REPORT_FIELD_RESERVED_NAME_HELP_ALT))) )
return r;
return_ECMD_FAILED;
}
8 years, 9 months
master - report: select: add support for comparing string lists with selection defined
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=03a3f6078de379...
Commit: 03a3f6078de3790a6fca3db8deb4bd204df611f1
Parent: 8faa4ded9cd12005df9ba71a2c3464eb7b69de71
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu May 29 09:42:02 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:20 2014 +0200
report: select: add support for comparing string lists with selection defined
---
libdm/libdm-report.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 64e0e8e..380c4dc 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -1004,6 +1004,75 @@ static int _cmp_field_string(const char *field_id, const char *a, const char *b,
return 0;
}
+/* Matches if all items from selection string list match. */
+static int _cmp_field_string_list_all(const struct str_list_sort_value *val,
+ const struct selection_str_list *sel)
+{
+ struct dm_str_list *sel_item;
+ unsigned int i = 1;
+
+ /* if item count differs, it's clear the lists do not match */
+ if (val->items[0].len != dm_list_size(sel->list))
+ return 0;
+
+ /* both lists are sorted so they either match 1:1 or not */
+ dm_list_iterate_items(sel_item, sel->list) {
+ if (strncmp(sel_item->str, val->value + val->items[i].pos, val->items[i].len))
+ return 0;
+ i++;
+ }
+
+ return 1;
+}
+
+/* Matches if any item from selection string list matches. */
+static int _cmp_field_string_list_any(const struct str_list_sort_value *val,
+ const struct selection_str_list *sel)
+{
+ struct dm_str_list *sel_item;
+ unsigned int i;
+
+ /* if value has no items and selection has at least one, it's clear there's no match */
+ if ((val->items[0].len == 0) && dm_list_size(sel->list))
+ return 0;
+
+ dm_list_iterate_items(sel_item, sel->list) {
+ /*
+ * TODO: Optimize this so we don't need to compare the whole lists' content.
+ * Make use of the fact that the lists are sorted!
+ */
+ for (i = 1; i <= val->items[0].len; i++) {
+ if (!strncmp(sel_item->str, val->value + val->items[i].pos, val->items[i].len))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int _cmp_field_string_list(const char *field_id,
+ const struct str_list_sort_value *value,
+ const struct selection_str_list *selection, uint32_t flags)
+{
+ int r;
+
+ switch (selection->type & SEL_MASK) {
+ case SEL_AND:
+ r = _cmp_field_string_list_all(value, selection);
+ break;
+ case SEL_OR:
+ r = _cmp_field_string_list_any(value, selection);
+ break;
+ default:
+ log_error(INTERNAL_ERROR "_cmp_field_string_list: unsupported string "
+ "list type found, expecting either AND or OR list for "
+ "selection field %s", field_id);
+ return 0;
+ }
+
+ return flags & FLD_CMP_NOT ? !r : r;
+}
+
static int _cmp_field_regex(const char *s, struct dm_regex *r, uint32_t flags)
{
int match = dm_regex_match(r, s) >= 0;
@@ -1036,6 +1105,10 @@ static int _compare_selection_field(struct dm_report *rh,
case DM_REPORT_FIELD_TYPE_STRING:
r = _cmp_field_string(field_id, (const char *) f->sort_value, fs->v.s, fs->flags);
break;
+ case DM_REPORT_FIELD_TYPE_STRING_LIST:
+ r = _cmp_field_string_list(field_id, (const struct str_list_sort_value *) f->sort_value,
+ fs->v.l, fs->flags);
+ break;
default:
log_error(INTERNAL_ERROR "_compare_selection_field: unknown field type for field %s", field_id);
}
8 years, 9 months
master - report: select: add support for processing string lists in selection
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8faa4ded9cd120...
Commit: 8faa4ded9cd12005df9ba71a2c3464eb7b69de71
Parent: a6694cfc299111127e6f6f261ba1b99b3a3f9a19
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu May 29 09:41:50 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:20 2014 +0200
report: select: add support for processing string lists in selection
Selection list items are enclosed in '[' and ']' (if there's only
one item, the '[' and ']' can be omitted). Each element of the list
is a string (either quoted or unquoted, like the usual string operand
used in selection) and each element is delimited either by conjunction
(meaining "match all") or disjunction operator (meaning "match any").
For example, if "," is the conjuction operator and "/" is the
disjunction operator then:
lv_tags=[a,b,c]
...will match all fields where tags contain *all* a, b and c.
lv_tags=[a/b/c]
...will match all fields where tags contain *any* of a, b, or c.
Mixing operators within the list is not supported:
lv_tags=[a,b/c]
...will give an error.
The order in which items are defined in the selection do not matter.
This patch enhances the selection parsing functionality to recognize
such lists.
---
libdm/libdm-report.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 198 insertions(+), 6 deletions(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index e61d2c9..64e0e8e 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -123,6 +123,10 @@ static struct op_def _op_cmp[] = {
#define SEL_PRECEDENCE_PS 0x00001000
#define SEL_PRECEDENCE_PE 0x00002000
+#define SEL_LIST_MASK 0x000F0000
+#define SEL_LIST_LS 0x00010000
+#define SEL_LIST_LE 0x00020000
+
static struct op_def _op_log[] = {
{ "&&", SEL_AND, "All fields must match" },
{ ",", SEL_AND, "All fields must match" },
@@ -131,9 +135,16 @@ static struct op_def _op_log[] = {
{ "!", SEL_MODIFIER_NOT, "Logical negation" },
{ "(", SEL_PRECEDENCE_PS, "Left parenthesis" },
{ ")", SEL_PRECEDENCE_PE, "Right parenthesis" },
+ { "[", SEL_LIST_LS, "List start" },
+ { "]", SEL_LIST_LE, "List end"},
{ NULL, 0, NULL},
};
+struct selection_str_list {
+ unsigned type; /* either SEL_AND or SEL_OR */
+ struct dm_list *list;
+};
+
struct field_selection {
struct field_properties *fp;
uint32_t flags;
@@ -142,6 +153,7 @@ struct field_selection {
uint64_t i;
double d;
struct dm_regex *r;
+ struct selection_str_list *l;
} v;
};
@@ -1349,6 +1361,171 @@ static const char *_tok_value_regex(const struct dm_report_field_type *ft,
return s;
}
+static int _str_list_item_cmp(const void *a, const void *b)
+{
+ const struct dm_str_list **item_a = (const struct dm_str_list **) a;
+ const struct dm_str_list **item_b = (const struct dm_str_list **) b;
+
+ return strcmp((*item_a)->str, (*item_b)->str);
+}
+
+static int _add_item_to_string_list(struct dm_pool *mem, const char *begin,
+ const char *end, struct dm_list *list)
+{
+ struct dm_str_list *item;
+
+ if (begin == end)
+ return_0;
+
+ if (!(item = dm_pool_zalloc(mem, sizeof(*item))) ||
+ !(item->str = dm_pool_strndup(mem, begin, end - begin))) {
+ log_error("_add_item_to_string_list: memory allocation failed for string list item");
+ return 0;
+ }
+ dm_list_add(list, &item->list);
+
+ 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
+ * mem - memory pool to allocate from
+ * s - a pointer to the parsed string
+ * Output:
+ * begin - a pointer to the beginning of the token (whole list)
+ * end - a pointer to the end of the token + 1 (whole list)
+ * sel_str_list - the list of strings parsed
+ */
+static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
+ struct dm_pool *mem, const char *s,
+ const char **begin, const char **end,
+ struct selection_str_list **sel_str_list)
+{
+ static const char _str_list_item_parsing_failed[] = "Failed to parse string list value "
+ "for selection field %s.";
+ struct selection_str_list *ssl = NULL;
+ struct dm_str_list *item;
+ const char *begin_item, *end_item, *tmp;
+ uint32_t end_op_flags, end_op_flag_hit;
+ struct dm_str_list **arr;
+ size_t list_size;
+ unsigned int i;
+ int list_end;
+ char c;
+
+ if (!(ssl = dm_pool_alloc(mem, sizeof(*ssl))) ||
+ !(ssl->list = dm_pool_alloc(mem, sizeof(*ssl->list)))) {
+ log_error("_tok_value_string_list: memory allocation failed for selection list");
+ goto bad;
+ }
+ dm_list_init(ssl->list);
+ ssl->type = 0;
+ *begin = s;
+
+ if (!_tok_op_log(s, &tmp, SEL_LIST_LS)) {
+ /* Only one item - SEL_LIST_LS and SEL_LIST_LE not used */
+ c = _get_and_skip_quote_char(&s);
+ if (!(s = _tok_value_string(s, &begin_item, &end_item, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL))) {
+ log_error(_str_list_item_parsing_failed, ft->id);
+ goto bad;
+ }
+ if (!_add_item_to_string_list(mem, begin_item, end_item, ssl->list))
+ goto_bad;
+ ssl->type = SEL_OR;
+ goto out;
+ }
+
+ /* More than one item - items enclosed in SEL_LIST_LS and SEL_LIST_LE.
+ * Each element is terminated by AND or OR operator or 'list end'.
+ * The first operator hit is then the one allowed for the whole list,
+ * no mixing allowed!
+ */
+ end_op_flags = SEL_LIST_LE | SEL_AND | SEL_OR;
+ s++;
+ while (*s) {
+ s = _skip_space(s);
+ c = _get_and_skip_quote_char(&s);
+ if (!(s = _tok_value_string(s, &begin_item, &end_item, c, end_op_flags, NULL))) {
+ log_error(_str_list_item_parsing_failed, ft->id);
+ goto bad;
+ }
+ s = _skip_space(s);
+
+ if (!(end_op_flag_hit = _tok_op_log(s, &tmp, end_op_flags))) {
+ log_error("Invalid operator in selection list.");
+ goto bad;
+ }
+
+ list_end = end_op_flag_hit == SEL_LIST_LE;
+
+ if (ssl->type) {
+ if (!list_end && !(ssl->type & end_op_flag_hit)) {
+ log_error("Only one type of logical operator allowed "
+ "in selection list at a time.");
+ goto bad;
+ }
+ } else
+ ssl->type = list_end ? SEL_OR : end_op_flag_hit;
+
+ if (!_add_item_to_string_list(mem, begin_item, end_item, ssl->list))
+ goto_bad;
+
+ s = tmp;
+
+ if (list_end)
+ break;
+ }
+
+ if (end_op_flag_hit != SEL_LIST_LE) {
+ log_error("Missing list end for selection field %s", ft->id);
+ goto bad;
+ }
+
+ /* Sort the list. */
+ if (!(list_size = dm_list_size(ssl->list))) {
+ log_error(INTERNAL_ERROR "_tok_value_string_list: list has no items");
+ goto bad;
+ } else if (list_size == 1)
+ goto out;
+ if (!(arr = dm_malloc(sizeof(item) * list_size))) {
+ log_error("_tok_value_string_list: memory allocation failed for sort array");
+ goto bad;
+ }
+
+ i = 0;
+ dm_list_iterate_items(item, ssl->list)
+ arr[i++] = item;
+ qsort(arr, list_size, sizeof(item), _str_list_item_cmp);
+ dm_list_init(ssl->list);
+ for (i = 0; i < list_size; i++)
+ dm_list_add(ssl->list, &arr[i]->list);
+
+ dm_free(arr);
+out:
+ *end = s;
+ *sel_str_list = ssl;
+ return s;
+bad:
+ *end = s;
+ if (ssl)
+ dm_pool_free(mem, ssl);
+ *sel_str_list = NULL;
+ return s;
+}
+
/*
* Input:
* ft - field type for which the value is parsed
@@ -1367,19 +1544,17 @@ static const char *_tok_value(const struct dm_report_field_type *ft,
struct dm_pool *mem, void *custom)
{
int expected_type = ft->flags & DM_REPORT_FIELD_TYPE_MASK;
+ struct selection_str_list **str_list;
uint64_t *factor;
const char *tmp;
- char c = 0;
+ char c;
s = _skip_space(s);
switch (expected_type) {
case DM_REPORT_FIELD_TYPE_STRING:
- if (*s == '"' || *s == '\'') {
- c = *s;
- s++;
- }
+ c = _get_and_skip_quote_char(&s);
if (!(s = _tok_value_string(s, begin, end, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL))) {
log_error("Failed to parse string value "
"for selection field %s.", ft->id);
@@ -1388,6 +1563,17 @@ static const char *_tok_value(const struct dm_report_field_type *ft,
*flags |= DM_REPORT_FIELD_TYPE_STRING;
break;
+ case DM_REPORT_FIELD_TYPE_STRING_LIST:
+ str_list = (struct selection_str_list **) custom;
+ s = _tok_value_string_list(ft, mem, s, begin, end, str_list);
+ if (!(*str_list)) {
+ log_error("Failed to parse string list value "
+ "for selection field %s.", ft->id);
+ return NULL;
+ }
+ *flags |= DM_REPORT_FIELD_TYPE_STRING_LIST;
+ break;
+
case DM_REPORT_FIELD_TYPE_NUMBER:
case DM_REPORT_FIELD_TYPE_SIZE:
if (!(s = _tok_value_number(s, begin, end))) {
@@ -1511,7 +1697,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
goto error;
}
} else {
- /* STRING, NUMBER or SIZE */
+ /* STRING, NUMBER, SIZE or STRING_LIST */
if (!(s = dm_pool_alloc(rh->mem, len + 1))) {
log_error("dm_report: dm_pool_alloc failed to store "
"value for selection field %s", field_id);
@@ -1543,6 +1729,9 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
fs->v.d /= 512; /* store size in sectors! */
dm_pool_free(rh->mem, s);
break;
+ case DM_REPORT_FIELD_TYPE_STRING_LIST:
+ fs->v.l = *(struct selection_str_list **)custom;
+ break;
default:
log_error(INTERNAL_ERROR "_create_field_selection: "
"unknown type of selection field %s", field_id);
@@ -1605,6 +1794,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
const char *last;
uint32_t flags, field_num;
const struct dm_report_field_type *ft;
+ struct selection_str_list *str_list;
uint64_t factor;
void *custom;
char *tmp;
@@ -1654,6 +1844,8 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
if (ft->flags == DM_REPORT_FIELD_TYPE_SIZE ||
ft->flags == DM_REPORT_FIELD_TYPE_NUMBER)
custom = &factor;
+ else if (ft->flags == DM_REPORT_FIELD_TYPE_STRING_LIST)
+ custom = &str_list;
else
custom = NULL;
if (!(last = _tok_value(ft, last, &vs, &ve, &flags, rh->mem, custom)))
8 years, 9 months
master - report: select: add DM_REPORT_FIELD_TYPE_STRING_LIST to make a difference between STRING and STRING_LIST
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a6694cfc299111...
Commit: a6694cfc299111127e6f6f261ba1b99b3a3f9a19
Parent: 76467bdcfd297ffbe2c088b6340ecc7d17d56742
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu May 29 09:41:36 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:20 2014 +0200
report: select: add DM_REPORT_FIELD_TYPE_STRING_LIST to make a difference between STRING and STRING_LIST
The {pv,vg,lv,seg}_tags and lv_modules fields are reported as string
lists using the new dm_report_field_string_list - so we just pass
the list to the fn that takes care of reporting and item sorting itself.
---
lib/properties/prop_common.h | 1 +
lib/report/columns.h | 10 +++++-----
lib/report/properties.c | 1 +
lib/report/report.c | 22 +++++++++++++---------
libdm/libdevmapper.h | 17 +++++++++--------
libdm/libdm-report.c | 4 +++-
6 files changed, 32 insertions(+), 23 deletions(-)
diff --git a/lib/properties/prop_common.h b/lib/properties/prop_common.h
index d6a0bb7..e2249e1 100644
--- a/lib/properties/prop_common.h
+++ b/lib/properties/prop_common.h
@@ -123,6 +123,7 @@ static int _ ## NAME ## _get (const void *obj, struct lvm_property_type *prop) \
#define STR 1
#define NUM 2
#define SIZ 3
+#define STR_LIST 4
#define FIELD_MODIFIABLE 0x00000001
#define FIELD(type, strct, field_type, head, field, width, fn, id, desc, settable) \
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 8328321..e3998ef 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -60,11 +60,11 @@ FIELD(LVS, lv, STR, "Log", lvid, 3, loglv, mirror_log, "For mirrors, the LV hold
FIELD(LVS, lv, STR, "Data", lvid, 4, datalv, data_lv, "For thin pools, the LV holding the associated data.", 0)
FIELD(LVS, lv, STR, "Meta", lvid, 4, metadatalv, metadata_lv, "For thin pools, the LV holding the associated metadata.", 0)
FIELD(LVS, lv, STR, "Pool", lvid, 4, poollv, pool_lv, "For thin volumes, the thin pool LV for this volume.", 0)
-FIELD(LVS, lv, STR, "LV Tags", tags, 7, tags, lv_tags, "Tags, if any.", 0)
+FIELD(LVS, lv, STR_LIST, "LV Tags", tags, 7, tags, lv_tags, "Tags, if any.", 0)
FIELD(LVS, lv, STR, "LProfile", lvid, 8, lvprofile, lv_profile, "Configuration profile attached to this LV.", 0)
FIELD(LVS, lv, STR, "Time", lvid, 26, lvtime, lv_time, "Creation time of the LV, if known", 0)
FIELD(LVS, lv, STR, "Host", lvid, 10, lvhost, lv_host, "Creation host of the LV, if known.", 0)
-FIELD(LVS, lv, STR, "Modules", lvid, 7, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 0)
+FIELD(LVS, lv, STR_LIST, "Modules", lvid, 7, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 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)
@@ -80,7 +80,7 @@ FIELD(PVS, pv, SIZ, "Used", id, 4, pvused, pv_used, "Total amount of allocated s
FIELD(PVS, pv, STR, "Attr", id, 4, pvstatus, pv_attr, "Various attributes - see man page.", 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, "PV Tags", tags, 7, tags, pv_tags, "Tags, if any.", 0)
+FIELD(PVS, pv, STR_LIST, "PV Tags", tags, 7, tags, pv_tags, "Tags, if any.", 0)
FIELD(PVS, pv, NUM, "#PMda", id, 5, pvmdas, pv_mda_count, "Number of metadata areas on this device.", 0)
FIELD(PVS, pv, NUM, "#PMdaUse", id, 8, pvmdasused, pv_mda_used_count, "Number of metadata areas in use on this device.", 0)
FIELD(PVS, pv, NUM, "BA start", ba_start, 8, size64, pv_ba_start, "Offset to the start of PV Bootloader Area on the underlying device in current units.", 0)
@@ -102,7 +102,7 @@ FIELD(VGS, vg, NUM, "#PV", pv_count, 3, uint32, pv_count, "Number of PVs.", 0)
FIELD(VGS, vg, NUM, "#LV", cmd, 3, lvcount, lv_count, "Number of LVs.", 0)
FIELD(VGS, vg, NUM, "#SN", cmd, 3, snapcount, snap_count, "Number of snapshots.", 0)
FIELD(VGS, vg, NUM, "Seq", seqno, 3, uint32, vg_seqno, "Revision number of internal metadata. Incremented whenever it changes.", 0)
-FIELD(VGS, vg, STR, "VG Tags", tags, 7, tags, vg_tags, "Tags, if any.", 0)
+FIELD(VGS, vg, STR_LIST, "VG Tags", tags, 7, tags, vg_tags, "Tags, if any.", 0)
FIELD(VGS, vg, STR, "VProfile", cmd, 8, vgprofile, vg_profile, "Configuration profile attached to this VG.", 0)
FIELD(VGS, vg, NUM, "#VMda", cmd, 5, vgmdas, vg_mda_count, "Number of metadata areas on this VG.", 0)
FIELD(VGS, vg, NUM, "#VMdaUse", cmd, 8, vgmdasused, vg_mda_used_count, "Number of metadata areas in use on this VG.", 0)
@@ -127,7 +127,7 @@ FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, seg_start, "Offset within the
FIELD(SEGS, seg, NUM, "Start", list, 5, segstartpe, seg_start_pe, "Offset within the LV to the start of the segment in physical extents.", 0)
FIELD(SEGS, seg, SIZ, "SSize", list, 5, segsize, seg_size, "Size of segment in current units.", 0)
FIELD(SEGS, seg, SIZ, "SSize", list, 5, segsizepe, seg_size_pe, "Size of segment in physical extents.", 0)
-FIELD(SEGS, seg, STR, "Seg Tags", tags, 8, tags, seg_tags, "Tags, if any.", 0)
+FIELD(SEGS, seg, STR_LIST, "Seg Tags", tags, 8, tags, seg_tags, "Tags, if any.", 0)
FIELD(SEGS, seg, STR, "PE Ranges", list, 9, peranges, seg_pe_ranges, "Ranges of Physical Extents of underlying devices in command line format.", 0)
FIELD(SEGS, seg, STR, "Devices", list, 7, devices, devices, "Underlying devices used with starting extent numbers.", 0)
FIELD(SEGS, seg, STR, "Monitor", list, 7, segmonitor, seg_monitor, "Dmeventd monitoring status of the segment.", 0)
diff --git a/lib/report/properties.c b/lib/report/properties.c
index 876a408..ec7bc4d 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -343,6 +343,7 @@ struct lvm_property_type _properties[] = {
#undef STR
#undef NUM
#undef SIZ
+#undef STR_LIST
#undef FIELD
int lvseg_get_property(const struct lv_segment *lvseg,
diff --git a/lib/report/report.c b/lib/report/report.c
index 8a87bd2..e8ff5bb 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -23,6 +23,7 @@
#include "segtype.h"
#include "lvmcache.h"
#include "device-types.h"
+#include "str_list.h"
#include <stddef.h> /* offsetof() */
@@ -126,17 +127,13 @@ static int _peranges_disp(struct dm_report *rh __attribute__((unused)), struct d
return _field_set_value(field, str, NULL);
}
-static int _tags_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
+static int _tags_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute__((unused)))
{
const struct dm_list *tagsl = (const struct dm_list *) data;
- char *tags_str;
- if (!(tags_str = tags_format_and_copy(mem, tagsl)))
- return_0;
-
- return _field_set_value(field, tags_str, NULL);
+ return dm_report_field_string_list(rh, field, tagsl, NULL);
}
static int _modules_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -144,12 +141,17 @@ static int _modules_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
- char *modules_str;
+ struct dm_list *modules;
+
+ if (!(modules = str_list_create(mem))) {
+ log_error("modules str_list allocation failed");
+ return 0;
+ }
- if (!(modules_str = lv_modules_dup(mem, lv)))
+ if (!(list_lv_modules(mem, lv, modules)))
return_0;
- return _field_set_value(field, modules_str, NULL);
+ return dm_report_field_string_list(rh, field, modules, NULL);
}
static int _lvprofile_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1203,6 +1205,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 SIZ DM_REPORT_FIELD_TYPE_SIZE
+#define STR_LIST DM_REPORT_FIELD_TYPE_STRING_LIST
#define FIELD(type, strct, sorttype, head, field, width, func, id, desc, writeable) \
{type, sorttype, offsetof(type_ ## strct, field), width, \
#id, head, &_ ## func ## _disp, desc},
@@ -1229,6 +1232,7 @@ static const struct dm_report_field_type _devtypes_fields[] = {
#undef STR
#undef NUM
#undef SIZ
+#undef STR_LIST
#undef FIELD
void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index e007b9b..d256373 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1598,14 +1598,15 @@ struct dm_report_field;
/*
* dm_report_field_type flags
*/
-#define DM_REPORT_FIELD_MASK 0x000000FF
-#define DM_REPORT_FIELD_ALIGN_MASK 0x0000000F
-#define DM_REPORT_FIELD_ALIGN_LEFT 0x00000001
-#define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
-#define DM_REPORT_FIELD_TYPE_MASK 0x000000F0
-#define DM_REPORT_FIELD_TYPE_STRING 0x00000010
-#define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
-#define DM_REPORT_FIELD_TYPE_SIZE 0x00000040
+#define DM_REPORT_FIELD_MASK 0x000000FF
+#define DM_REPORT_FIELD_ALIGN_MASK 0x0000000F
+#define DM_REPORT_FIELD_ALIGN_LEFT 0x00000001
+#define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
+#define DM_REPORT_FIELD_TYPE_MASK 0x000000F0
+#define DM_REPORT_FIELD_TYPE_STRING 0x00000010
+#define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
+#define DM_REPORT_FIELD_TYPE_SIZE 0x00000040
+#define DM_REPORT_FIELD_TYPE_STRING_LIST 0x00000080
#define DM_REPORT_FIELD_TYPE_ID_LEN 32
#define DM_REPORT_FIELD_TYPE_HEADING_LEN 32
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 0feef17..e61d2c9 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -1949,7 +1949,9 @@ static int _row_compare(const void *a, const void *b)
} else { /* FLD_DESCENDING */
return (numa < numb) ? 1 : -1;
}
- } else { /* DM_REPORT_FIELD_TYPE_STRING */
+ } else {
+ /* DM_REPORT_FIELD_TYPE_STRING
+ * DM_REPORT_FIELD_TYPE_STRING_LIST */
const char *stra = (const char *) sfa->sort_value;
const char *strb = (const char *) sfb->sort_value;
int cmp = strcmp(stra, strb);
8 years, 9 months
master - report: select: add dm_report_field_string_list to libdm
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=76467bdcfd297f...
Commit: 76467bdcfd297ffbe2c088b6340ecc7d17d56742
Parent: 5abdb52fdc66316d3e7d54085d4e79160024b95e
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu May 29 09:41:18 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:20 2014 +0200
report: select: add dm_report_field_string_list to libdm
Add a separate dm_report_field_string_list fn to libdevmapper to
support reporting string lists. Before, the code used libdevmappers's
dm_report_field_string fn which required formatting the list to a
single string. This functionality is now moved to libdevmapper
and the code that needs to report the string list just needs
to pass the list itself and libdevmapper will take care of this.
This also enhances code reuse.
The dm_report_field_string_list also accepts an argument to define
custom delimiter to use. If not defined, a default "," (comma) is
used as item delimiter in the string list reported.
The dm_report_field_string_list automatically sorts the items in
the list before formatting it to a final string. It also encodes
the position and length within the final string where each element
can be found. This can be used to support checking against each
list item reported since since when formatted as a single string
for the actual report, we would lose this information otherwise
(we don't want to copy each item, the position and length within
the final string is enough for us to get the original items back).
When such lists are checked against the selection tree, we can check
each item individually this way and we can support operators like
"match any" and "match all".
---
libdm/libdevmapper.h | 2 +
libdm/libdm-report.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 129 insertions(+), 0 deletions(-)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index f3e2b92..e007b9b 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1676,6 +1676,8 @@ int dm_report_set_output_field_name_prefix(struct dm_report *rh,
*/
int dm_report_field_string(struct dm_report *rh, struct dm_report_field *field,
const char *const *data);
+int dm_report_field_string_list(struct dm_report *rh, struct dm_report_field *field,
+ const struct dm_list *data, const char *delimiter);
int dm_report_field_int32(struct dm_report *rh, struct dm_report_field *field,
const int32_t *data);
int dm_report_field_uint32(struct dm_report *rh, struct dm_report_field *field,
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 93cba9f..0feef17 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -204,6 +204,133 @@ int dm_report_field_string(struct dm_report *rh,
return 1;
}
+static int _str_cmp(const void *a, const void *b)
+{
+ const char **str_a = (const char **) a;
+ const char **str_b = (const char **) b;
+
+ return strcmp(*str_a, *str_b);
+}
+
+struct str_list_sort_value_item {
+ unsigned pos;
+ size_t len;
+};
+
+struct str_list_sort_value {
+ const char *value;
+ struct str_list_sort_value_item *items;
+};
+
+int dm_report_field_string_list(struct dm_report *rh,
+ struct dm_report_field *field,
+ const struct dm_list *data,
+ const char *delimiter)
+{
+ static const char _string_list_grow_object_failed_msg[] = "dm_report_field_string_list: dm_pool_grow_object_failed";
+ struct str_list_sort_value *sort_value = NULL;
+ unsigned int list_size, pos, i;
+ const char **arr = NULL;
+ struct dm_str_list *sl;
+ size_t delimiter_len, len;
+ void *object;
+ int r = 0;
+
+ if (!(sort_value = dm_pool_zalloc(rh->mem, sizeof(struct str_list_sort_value)))) {
+ log_error("dm_report_field_string_list: dm_pool_zalloc failed for sort_value");
+ return 0;
+ }
+
+ list_size = dm_list_size(data);
+
+ /*
+ * Sort value stores the pointer to the report_string and then
+ * position and length for each list element withing the report_string.
+ * The first element stores number of elements in 'len' (therefore
+ * list_size + 1 is used below for the extra element).
+ */
+ if (!(sort_value->items = dm_pool_zalloc(rh->mem, (list_size + 1) * sizeof(struct str_list_sort_value_item)))) {
+ log_error("dm_report_fiel_string_list: dm_pool_zalloc failed for sort value items");
+ goto out;
+ }
+ sort_value->items[0].len = list_size;
+
+ /* zero items */
+ if (!list_size) {
+ sort_value->value = field->report_string = "";
+ sort_value->items[1].pos = 0;
+ sort_value->items[1].len = 0;
+ field->sort_value = sort_value;
+ return 1;
+ }
+
+ /* one item */
+ if (list_size == 1) {
+ sl = (struct dm_str_list *) dm_list_first(data);
+ if (!(sort_value->value = field->report_string = dm_pool_strdup(rh->mem, sl->str))) {
+ log_error("dm_report_field_string_list: dm_pool_strdup failed");
+ goto out;
+ }
+ sort_value->items[1].pos = 0;
+ sort_value->items[1].len = strlen(sl->str);
+ field->sort_value = sort_value;
+ return 1;
+ }
+
+ /* more than one item - sort the list */
+ if (!(arr = dm_malloc(sizeof(char *) * list_size))) {
+ log_error("dm_report_field_string_list: dm_malloc failed");
+ goto out;
+ }
+ i = 0;
+ dm_list_iterate_items(sl, data)
+ arr[i++] = sl->str;
+ qsort(arr, i, sizeof(char *), _str_cmp);
+
+ if (!(dm_pool_begin_object(rh->mem, 256))) {
+ log_error(_string_list_grow_object_failed_msg);
+ goto out;
+ }
+
+ if (!delimiter)
+ delimiter = ",";
+ delimiter_len = strlen(delimiter);
+
+ /* start from 1 - the item 0 stores the list size! */
+ for (i = 1, pos = 0; i <= list_size; i++) {
+ len = strlen(arr[i-1]);
+ if (!dm_pool_grow_object(rh->mem, arr[i-1], len) ||
+ (i != list_size && !dm_pool_grow_object(rh->mem, delimiter, delimiter_len))) {
+ log_error(_string_list_grow_object_failed_msg);
+ goto out;
+ }
+ /*
+ * save position and length of the string
+ * element in report_string for sort_value
+ */
+ sort_value->items[i].pos = pos;
+ sort_value->items[i].len = len;
+ pos = i == list_size ? pos+len : pos+len+1;
+ }
+
+ if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
+ log_error(_string_list_grow_object_failed_msg);
+ goto out;
+ }
+
+ object = dm_pool_end_object(rh->mem);
+ sort_value->value = object;
+ field->sort_value = sort_value;
+ field->report_string = object;
+ r = 1;
+out:
+ if (!r && sort_value)
+ dm_pool_free(rh->mem, sort_value);
+ if (arr)
+ dm_free(arr);
+ return r;
+}
+
int dm_report_field_int(struct dm_report *rh,
struct dm_report_field *field, const int *data)
{
8 years, 9 months
master - report: select: refactor: move str_list to libdm
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5abdb52fdc6631...
Commit: 5abdb52fdc66316d3e7d54085d4e79160024b95e
Parent: fe952e735ae260849a9a9c04f38bbb08f8e6c22b
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu May 29 09:41:03 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jun 17 16:27:20 2014 +0200
report: select: refactor: move str_list to libdm
The list of strings is used quite frequently and we'd like to reuse
this simple structure for report selection support too. Make it part
of libdevmapper for general reuse throughout the code.
This also simplifies the LVM code a bit since we don't need to
include and manage lvm-types.h anymore (the string list was the
only structure defined there).
---
daemons/clvmd/lvm-functions.c | 1 -
include/.symlinks.in | 1 -
lib/cache/lvmcache.h | 6 +++---
lib/commands/toolcontext.c | 2 +-
lib/datastruct/lvm-types.h | 26 --------------------------
lib/datastruct/str_list.c | 12 ++++++------
lib/device/dev-cache.c | 19 +++++++++----------
lib/device/dev-cache.h | 2 +-
lib/device/dev-io.c | 3 +--
lib/device/device.h | 5 ++---
lib/display/display.c | 2 +-
lib/filters/filter-persistent.c | 2 +-
lib/filters/filter-regex.c | 2 +-
lib/format1/disk-rep.h | 1 -
lib/format_text/format-text.h | 1 -
lib/format_text/layout.h | 1 -
lib/format_text/tags.c | 2 +-
lib/log/log.c | 2 +-
lib/metadata/lv_manip.c | 2 +-
lib/metadata/metadata.c | 8 ++++----
lib/metadata/mirror.c | 4 ++--
lib/misc/lib.h | 1 -
lib/report/properties.h | 1 -
libdm/libdevmapper.h | 8 ++++++++
liblvm/lvm_misc.c | 2 +-
liblvm/lvm_prop.c | 1 -
old-tests/device/dev_cache_t.c | 4 ++--
old-tests/device/random.h | 2 --
tools/lvrename.c | 1 -
tools/pvchange.c | 2 +-
tools/toollib.c | 6 +++---
tools/tools.h | 1 -
tools/vgrename.c | 2 +-
33 files changed, 51 insertions(+), 84 deletions(-)
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
index 9fd71e8..1754b7d 100644
--- a/daemons/clvmd/lvm-functions.c
+++ b/daemons/clvmd/lvm-functions.c
@@ -17,7 +17,6 @@
#include <pthread.h>
-#include "lvm-types.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
diff --git a/include/.symlinks.in b/include/.symlinks.in
index ced2cb3..48c4d9d 100644
--- a/include/.symlinks.in
+++ b/include/.symlinks.in
@@ -11,7 +11,6 @@
@top_srcdir(a)/lib/config/config_settings.h
@top_srcdir(a)/lib/config/defaults.h
@top_srcdir(a)/lib/datastruct/btree.h
-@top_srcdir(a)/lib/datastruct/lvm-types.h
@top_srcdir(a)/lib/datastruct/str_list.h
@top_srcdir(a)/lib/device/dev-cache.h
@top_srcdir(a)/lib/device/dev-type.h
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 83d561b..d43866d 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -88,17 +88,17 @@ int lvmcache_vgname_is_locked(const char *vgname);
void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd);
-/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
+/* Returns list of struct dm_str_list containing pool-allocated copy of vgnames */
/* If include_internal is not set, return only proper vg names. */
struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
int include_internal);
-/* Returns list of struct str_lists containing pool-allocated copy of vgids */
+/* Returns list of struct dm_str_list containing pool-allocated copy of vgids */
/* If include_internal is not set, return only proper vg ids. */
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
int include_internal);
-/* Returns list of struct str_lists containing pool-allocated copy of pvids */
+/* Returns list of struct dm_str_list containing pool-allocated copy of pvids */
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
const char *vgid);
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 519d36a..cc08747 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -615,7 +615,7 @@ static int _init_lvm_conf(struct cmd_context *cmd)
/* Read any additional config files */
static int _init_tag_configs(struct cmd_context *cmd)
{
- struct str_list *sl;
+ struct dm_str_list *sl;
/* Tag list may grow while inside this loop */
dm_list_iterate_items(sl, &cmd->tags) {
diff --git a/lib/datastruct/lvm-types.h b/lib/datastruct/lvm-types.h
deleted file mode 100644
index b38798f..0000000
--- a/lib/datastruct/lvm-types.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
- *
- * This file is part of LVM2.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _LVM_TYPES_H
-#define _LVM_TYPES_H
-
-#include "libdevmapper.h"
-
-struct str_list {
- struct dm_list list;
- const char *str;
-};
-
-#endif
diff --git a/lib/datastruct/str_list.c b/lib/datastruct/str_list.c
index dfce69c..f519679 100644
--- a/lib/datastruct/str_list.c
+++ b/lib/datastruct/str_list.c
@@ -32,7 +32,7 @@ struct dm_list *str_list_create(struct dm_pool *mem)
int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str)
{
- struct str_list *sln;
+ struct dm_str_list *sln;
if (!str)
return_0;
@@ -55,14 +55,14 @@ void str_list_del(struct dm_list *sll, const char *str)
struct dm_list *slh, *slht;
dm_list_iterate_safe(slh, slht, sll)
- if (!strcmp(str, dm_list_item(slh, struct str_list)->str))
+ if (!strcmp(str, dm_list_item(slh, struct dm_str_list)->str))
dm_list_del(slh);
}
int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew,
const struct dm_list *sllold)
{
- struct str_list *sl;
+ struct dm_str_list *sl;
dm_list_init(sllnew);
@@ -79,7 +79,7 @@ int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew,
*/
int str_list_match_item(const struct dm_list *sll, const char *str)
{
- struct str_list *sl;
+ struct dm_str_list *sl;
dm_list_iterate_items(sl, sll)
if (!strcmp(str, sl->str))
@@ -94,7 +94,7 @@ int str_list_match_item(const struct dm_list *sll, const char *str)
*/
int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, const char **tag_matched)
{
- struct str_list *sl;
+ struct dm_str_list *sl;
dm_list_iterate_items(sl, sll)
if (str_list_match_item(sll2, sl->str)) {
@@ -111,7 +111,7 @@ int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, c
*/
int str_list_lists_equal(const struct dm_list *sll, const struct dm_list *sll2)
{
- struct str_list *sl;
+ struct dm_str_list *sl;
if (dm_list_size(sll) != dm_list_size(sll2))
return 0;
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index f76e527..1d7a517 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -14,7 +14,6 @@
*/
#include "lib.h"
-#include "lvm-types.h"
#include "btree.h"
#include "config.h"
#include "toolcontext.h"
@@ -70,7 +69,7 @@ static void _dev_init(struct device *dev, int max_error_count)
}
struct device *dev_create_file(const char *filename, struct device *dev,
- struct str_list *alias, int use_malloc)
+ struct dm_str_list *alias, int use_malloc)
{
int allocate = !dev;
@@ -81,7 +80,7 @@ struct device *dev_create_file(const char *filename, struct device *dev,
return NULL;
}
if (!(alias = dm_zalloc(sizeof(*alias)))) {
- log_error("struct str_list allocation failed");
+ log_error("struct dm_str_list allocation failed");
dm_free(dev);
return NULL;
}
@@ -97,7 +96,7 @@ struct device *dev_create_file(const char *filename, struct device *dev,
return NULL;
}
if (!(alias = _zalloc(sizeof(*alias)))) {
- log_error("struct str_list allocation failed");
+ log_error("struct dm_str_list allocation failed");
_free(dev);
return NULL;
}
@@ -133,7 +132,7 @@ static struct device *_dev_create(dev_t d)
return dev;
}
-void dev_set_preferred_name(struct str_list *sl, struct device *dev)
+void dev_set_preferred_name(struct dm_str_list *sl, struct device *dev)
{
/*
* Don't interfere with ordering specified in config file.
@@ -308,8 +307,8 @@ static int _compare_paths(const char *path0, const char *path1)
static int _add_alias(struct device *dev, const char *path)
{
- struct str_list *sl = _zalloc(sizeof(*sl));
- struct str_list *strl;
+ struct dm_str_list *sl = _zalloc(sizeof(*sl));
+ struct dm_str_list *strl;
const char *oldpath;
int prefer_old = 1;
@@ -327,7 +326,7 @@ static int _add_alias(struct device *dev, const char *path)
sl->str = path;
if (!dm_list_empty(&dev->aliases)) {
- oldpath = dm_list_item(dev->aliases.n, struct str_list)->str;
+ oldpath = dm_list_item(dev->aliases.n, struct dm_str_list)->str;
prefer_old = _compare_paths(path, oldpath);
log_debug_devs("%s: Aliased to %s in device cache%s",
path, oldpath, prefer_old ? "" : " (preferred name)");
@@ -889,7 +888,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
return dev_name(dev);
while ((r = stat(name = dm_list_item(dev->aliases.n,
- struct str_list)->str, &buf)) ||
+ struct dm_str_list)->str, &buf)) ||
(buf.st_rdev != dev->dev)) {
if (r < 0) {
if (quiet)
@@ -1073,6 +1072,6 @@ int dev_fd(struct device *dev)
const char *dev_name(const struct device *dev)
{
- return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct str_list)->str :
+ return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str :
"unknown device";
}
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index fcc69a5..4fca358 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -54,7 +54,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f);
// TODO
struct device *dev_cache_get_by_devt(dev_t device, struct dev_filter *f);
-void dev_set_preferred_name(struct str_list *sl, struct device *dev);
+void dev_set_preferred_name(struct dm_str_list *sl, struct device *dev);
/*
* Object for iterating through the cache.
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index 6697456..0a75088 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -14,7 +14,6 @@
*/
#include "lib.h"
-#include "lvm-types.h"
#include "device.h"
#include "metadata.h"
#include "lvmcache.h"
@@ -591,7 +590,7 @@ static void _close(struct device *dev)
log_debug_devs("Closed %s", dev_name(dev));
if (dev->flags & DEV_ALLOCED) {
- dm_free((void *) dm_list_item(dev->aliases.n, struct str_list)->
+ dm_free((void *) dm_list_item(dev->aliases.n, struct dm_str_list)->
str);
dm_free(dev->aliases.n);
dm_free(dev);
diff --git a/lib/device/device.h b/lib/device/device.h
index 35d7505..c916a4b 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -17,7 +17,6 @@
#define _LVM_DEVICE_H
#include "uuid.h"
-#include "lvm-types.h"
#include <fcntl.h>
@@ -34,7 +33,7 @@
* pointer comparisons are valid.
*/
struct device {
- struct dm_list aliases; /* struct str_list from lvm-types.h */
+ struct dm_list aliases; /* struct dm_str_list */
dev_t dev;
/* private */
@@ -96,7 +95,7 @@ int dev_set(struct device *dev, uint64_t offset, size_t len, int value);
void dev_flush(struct device *dev);
struct device *dev_create_file(const char *filename, struct device *dev,
- struct str_list *alias, int use_malloc);
+ struct dm_str_list *alias, int use_malloc);
/* Return a valid device name from the alias list; NULL otherwise */
const char *dev_name_confirmed(struct device *dev, int quiet);
diff --git a/lib/display/display.c b/lib/display/display.c
index 3c47aa8..70a4cda 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -833,7 +833,7 @@ void display_segtypes(const struct cmd_context *cmd)
void display_tags(const struct cmd_context *cmd)
{
- const struct str_list *sl;
+ const struct dm_str_list *sl;
dm_list_iterate_items(sl, &cmd->tags) {
log_print("%s", sl->str);
diff --git a/lib/filters/filter-persistent.c b/lib/filters/filter-persistent.c
index 7eaae71..6d406c7 100644
--- a/lib/filters/filter-persistent.c
+++ b/lib/filters/filter-persistent.c
@@ -272,7 +272,7 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
{
struct pfilter *pf = (struct pfilter *) f->private;
void *l = dm_hash_lookup(pf->devices, dev_name(dev));
- struct str_list *sl;
+ struct dm_str_list *sl;
/* Cached BAD? */
if (l == PF_BAD_DEVICE) {
diff --git a/lib/filters/filter-regex.c b/lib/filters/filter-regex.c
index b30290e..f60a47f 100644
--- a/lib/filters/filter-regex.c
+++ b/lib/filters/filter-regex.c
@@ -149,7 +149,7 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
{
int m, first = 1, rejected = 0;
struct rfilter *rf = (struct rfilter *) f->private;
- struct str_list *sl;
+ struct dm_str_list *sl;
dm_list_iterate_items(sl, &dev->aliases) {
m = dm_regex_match(rf->engine, sl->str);
diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h
index 52ee303..43e2e57 100644
--- a/lib/format1/disk-rep.h
+++ b/lib/format1/disk-rep.h
@@ -16,7 +16,6 @@
#ifndef DISK_REP_FORMAT1_H
#define DISK_REP_FORMAT1_H
-#include "lvm-types.h"
#include "metadata.h"
#include "toolcontext.h"
diff --git a/lib/format_text/format-text.h b/lib/format_text/format-text.h
index 7d2543d..39591d1 100644
--- a/lib/format_text/format-text.h
+++ b/lib/format_text/format-text.h
@@ -16,7 +16,6 @@
#ifndef _LVM_FORMAT_TEXT_H
#define _LVM_FORMAT_TEXT_H
-#include "lvm-types.h"
#include "metadata.h"
#define FMT_TEXT_NAME "lvm2"
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index 6fb3e49..4753fde 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -17,7 +17,6 @@
#define _LVM_TEXT_LAYOUT_H
#include "config.h"
-#include "lvm-types.h"
#include "metadata.h"
#include "uuid.h"
diff --git a/lib/format_text/tags.c b/lib/format_text/tags.c
index d0bf2b1..dc138d1 100644
--- a/lib/format_text/tags.c
+++ b/lib/format_text/tags.c
@@ -21,7 +21,7 @@
char *alloc_printed_tags(struct dm_list *tagsl)
{
- struct str_list *sl;
+ struct dm_str_list *sl;
int first = 1;
size_t size = 0;
char *buffer, *buf;
diff --git a/lib/log/log.c b/lib/log/log.c
index a3c0139..83e5be4 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -23,7 +23,7 @@
static FILE *_log_file;
static struct device _log_dev;
-static struct str_list _log_dev_alias;
+static struct dm_str_list _log_dev_alias;
static int _syslog = 0;
static int _log_to_file = 0;
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 76a9103..9fe441d 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -5281,7 +5281,7 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
int r;
char *name;
size_t len;
- struct str_list *sl;
+ struct dm_str_list *sl;
struct logical_volume *layer_lv;
struct segment_type *segtype;
struct lv_segment *mapseg;
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 15f9249..5c0a474 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2322,7 +2322,7 @@ int vg_validate(struct volume_group *vg)
struct pv_list *pvl;
struct lv_list *lvl;
struct lv_segment *seg;
- struct str_list *sl;
+ struct dm_str_list *sl;
char uuid[64] __attribute__((aligned(8)));
int r = 1;
unsigned hidden_lv_count = 0, lv_count = 0, lv_visible_count = 0;
@@ -3571,7 +3571,7 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
const char *vgname;
struct dm_list *vgnames;
struct volume_group *vg;
- struct str_list *strl;
+ struct dm_str_list *strl;
int consistent = 0;
/* Is corresponding vgname already cached? */
@@ -3802,7 +3802,7 @@ struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal)
static int _get_pvs(struct cmd_context *cmd, int warnings,
struct dm_list *pvslist, struct dm_list *vgslist)
{
- struct str_list *strl;
+ struct dm_str_list *strl;
const char *vgname, *vgid;
struct pv_list *pvl, *pvl_copy;
struct dm_list *vgids;
@@ -4712,7 +4712,7 @@ int pv_change_metadataignore(struct physical_volume *pv, uint32_t mda_ignored)
char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tagsl)
{
- struct str_list *sl;
+ struct dm_str_list *sl;
if (!dm_pool_begin_object(mem, 256)) {
log_error("dm_pool_begin_object failed");
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 9a413e8..b03cdbe 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -281,7 +281,7 @@ static int _init_mirror_log(struct cmd_context *cmd,
struct logical_volume *log_lv, int in_sync,
struct dm_list *tagsl, int remove_on_failure)
{
- struct str_list *sl;
+ struct dm_str_list *sl;
uint64_t orig_status = log_lv->status;
int was_active = 0;
@@ -420,7 +420,7 @@ static int _activate_lv_like_model(struct logical_volume *model,
static int _delete_lv(struct logical_volume *mirror_lv, struct logical_volume *lv)
{
struct cmd_context *cmd = mirror_lv->vg->cmd;
- struct str_list *sl;
+ struct dm_str_list *sl;
/* Inherit tags - maybe needed for activation */
if (!str_list_match_list(&mirror_lv->tags, &lv->tags, NULL)) {
diff --git a/lib/misc/lib.h b/lib/misc/lib.h
index 5bd968a..3a35c22 100644
--- a/lib/misc/lib.h
+++ b/lib/misc/lib.h
@@ -40,7 +40,6 @@
# include "lvm-logging.h"
# include "lvm-globals.h"
# include "lvm-wrappers.h"
-# include "lvm-types.h"
#endif
#include <unistd.h>
diff --git a/lib/report/properties.h b/lib/report/properties.h
index 4e8bf86..14e65ed 100644
--- a/lib/report/properties.h
+++ b/lib/report/properties.h
@@ -15,7 +15,6 @@
#define _LVM_PROPERTIES_H
#include "libdevmapper.h"
-#include "lvm-types.h"
#include "metadata.h"
#include "report.h"
#include "prop_common.h"
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 319b07c..f3e2b92 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1179,6 +1179,14 @@ struct dm_list {
};
/*
+ * String list.
+ */
+struct dm_str_list {
+ struct dm_list list;
+ const char *str;
+};
+
+/*
* Initialise a list before use.
* The list head's next and previous pointers point back to itself.
*/
diff --git a/liblvm/lvm_misc.c b/liblvm/lvm_misc.c
index d9b4323..ff26cdf 100644
--- a/liblvm/lvm_misc.c
+++ b/liblvm/lvm_misc.c
@@ -22,7 +22,7 @@ struct dm_list *tag_list_copy(struct dm_pool *p, struct dm_list *tag_list)
{
struct dm_list *list;
lvm_str_list_t *lsl;
- struct str_list *sl;
+ struct dm_str_list *sl;
if (!(list = dm_pool_zalloc(p, sizeof(*list)))) {
log_errno(ENOMEM, "Memory allocation fail for dm_list.");
diff --git a/liblvm/lvm_prop.c b/liblvm/lvm_prop.c
index cbbd6f5..79ed113 100644
--- a/liblvm/lvm_prop.c
+++ b/liblvm/lvm_prop.c
@@ -14,7 +14,6 @@
#include "lvm_prop.h"
#include "libdevmapper.h"
-#include "lvm-types.h"
#include "metadata.h"
/* lv create parameters */
diff --git a/old-tests/device/dev_cache_t.c b/old-tests/device/dev_cache_t.c
index f19a56f..26895b8 100644
--- a/old-tests/device/dev_cache_t.c
+++ b/old-tests/device/dev_cache_t.c
@@ -24,7 +24,7 @@ int main(int argc, char **argv)
struct device *dev;
struct dev_iter *iter;
struct list_head *tmp;
- struct str_list *sl;
+ struct dm_str_list *sl;
if (argc < 2) {
fprintf(stderr, "usage: %s <dir>\n", argv[0]);
@@ -55,7 +55,7 @@ int main(int argc, char **argv)
printf("%s", dev->name);
list_for_each(tmp, &dev->aliases) {
- sl = list_entry(tmp, struct str_list, list);
+ sl = list_entry(tmp, struct dm_str_list, list);
printf(", %s", sl->str);
}
printf("\n");
diff --git a/old-tests/device/random.h b/old-tests/device/random.h
index abcbda6..9e3783b 100644
--- a/old-tests/device/random.h
+++ b/old-tests/device/random.h
@@ -21,8 +21,6 @@
#ifndef _LVM_RANDOM_H
#define _LVM_RANDOM_H
-#include "lvm-types.h"
-
void rand_init(int32_t seed);
int32_t rand_get(void);
diff --git a/tools/lvrename.c b/tools/lvrename.c
index 0fea039..3bf4793 100644
--- a/tools/lvrename.c
+++ b/tools/lvrename.c
@@ -14,7 +14,6 @@
*/
#include "tools.h"
-#include "lvm-types.h"
/*
* lvrename command implementation.
diff --git a/tools/pvchange.c b/tools/pvchange.c
index afa6829..c2adc34 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -161,7 +161,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
struct pv_list *pvl;
struct dm_list *vgnames;
- struct str_list *sll;
+ struct dm_str_list *sll;
if (!(arg_count(cmd, allocatable_ARG) + arg_is_set(cmd, addtag_ARG) +
arg_is_set(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) +
diff --git a/tools/toollib.c b/tools/toollib.c
index c619d9b..d4c915d 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -293,7 +293,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
struct dm_list *tags_arg;
struct dm_list *vgnames; /* VGs to process */
- struct str_list *sll, *strl;
+ struct dm_str_list *sll, *strl;
struct cmd_vg *cvl_vg;
struct dm_list cmd_vgs;
struct dm_list failed_lvnames;
@@ -621,7 +621,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
int opt = 0;
int ret_max = ECMD_PROCESSED;
- struct str_list *sl;
+ struct dm_str_list *sl;
struct dm_list *vgnames, *vgids;
struct dm_list arg_vgnames, tagsl;
@@ -803,7 +803,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
struct physical_volume *pv;
struct dm_list *pvslist = NULL, *vgnames;
struct dm_list tagsl;
- struct str_list *sll;
+ struct dm_str_list *sll;
char *at_sign, *tagname;
struct device *dev;
diff --git a/tools/tools.h b/tools/tools.h
index 11111cb..2b09f37 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -23,7 +23,6 @@
#include <assert.h>
#include "libdevmapper.h"
-#include "lvm-types.h"
#include "lvm-logging.h"
#include "activate.h"
#include "archiver.h"
diff --git a/tools/vgrename.c b/tools/vgrename.c
index d97b871..860ccf1 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -62,7 +62,7 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
int match = 0;
int found_id = 0;
struct dm_list *vgids;
- struct str_list *sl;
+ struct dm_str_list *sl;
const char *vg_name_new;
const char *vgid = NULL, *vg_name, *vg_name_old;
char old_path[NAME_LEN], new_path[NAME_LEN];
8 years, 9 months