diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 38045d681..5e1f25fec 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,9 @@ Version 1.02.101 - ================================= + Add dm_report_value_cache_{set,get} to support caching during report/select. + Add dm_report_reserved_handler to handle report reserved value actions. + Support dynamic value in select: DM_REPORT_FIELD_RESERVED_VALUE_DYNAMIC_VALUE. + Support fuzzy names in select: DM_REPORT_FIELD_RESERVED_VALUE_FUZZY_NAMES. Thin pool trace messages show a device name and major:minor. Version 1.02.100 - 30th June 2015 diff --git a/lib/report/report.c b/lib/report/report.c index 40f947f24..2e9a5d392 100644 --- a/lib/report/report.c +++ b/lib/report/report.c @@ -99,6 +99,8 @@ static const int32_t _reserved_num_undef_32 = INT32_C(-1); #define NOFLAG 0 #define NAMED DM_REPORT_FIELD_RESERVED_VALUE_NAMED #define RANGE DM_REPORT_FIELD_RESERVED_VALUE_RANGE +#define FUZZY DM_REPORT_FIELD_RESERVED_VALUE_FUZZY_NAMES +#define DYNAMIC DM_REPORT_FIELD_RESERVED_VALUE_DYNAMIC_VALUE #define TYPE_RESERVED_VALUE(type, flags, id, desc, value, ...) \ static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__, NULL}; \ @@ -121,6 +123,8 @@ static const int32_t _reserved_num_undef_32 = INT32_C(-1); #undef TYPE_RESERVED_VALUE #undef FIELD_RESERVED_VALUE #undef FIELD_RESERVED_BINARY_VALUE +#undef FUZZY +#undef DYNAMIC /* * Create array of reserved values to be registered with reporting code via @@ -133,6 +137,8 @@ static const int32_t _reserved_num_undef_32 = INT32_C(-1); #define NOFLAG 0 #define NAMED DM_REPORT_FIELD_RESERVED_VALUE_NAMED #define RANGE DM_REPORT_FIELD_RESERVED_VALUE_RANGE +#define FUZZY DM_REPORT_FIELD_RESERVED_VALUE_FUZZY_NAMES +#define DYNAMIC DM_REPORT_FIELD_RESERVED_VALUE_DYNAMIC_VALUE #define TYPE_RESERVED_VALUE(type, flags, id, desc, value, ...) {type | flags, &_reserved_ ## id, _reserved_ ## id ## _names, desc}, @@ -151,6 +157,8 @@ static const struct dm_report_reserved_value _report_reserved_values[] = { #undef NOFLAG #undef NAMED #undef RANGE +#undef FUZZY +#undef DYNAMIC #undef TYPE_RESERVED_VALUE #undef FIELD_RESERVED_VALUE #undef FIELD_RESERVED_BINARY_VALUE diff --git a/libdm/.exported_symbols.DM_1_02_101 b/libdm/.exported_symbols.DM_1_02_101 new file mode 100644 index 000000000..75089ba8b --- /dev/null +++ b/libdm/.exported_symbols.DM_1_02_101 @@ -0,0 +1,2 @@ +dm_report_value_cache_set +dm_report_value_cache_get diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h index 7e30d8eb9..4ce2e6be9 100644 --- a/libdm/libdevmapper.h +++ b/libdm/libdevmapper.h @@ -1688,6 +1688,8 @@ struct dm_report_field; #define DM_REPORT_FIELD_RESERVED_VALUE_MASK 0x0000000F #define DM_REPORT_FIELD_RESERVED_VALUE_NAMED 0x00000001 /* only named value, less strict form of reservation */ #define DM_REPORT_FIELD_RESERVED_VALUE_RANGE 0x00000002 /* value is range - low and high value defined */ +#define DM_REPORT_FIELD_RESERVED_VALUE_DYNAMIC_VALUE 0x00000004 /* value is computed in runtime */ +#define DM_REPORT_FIELD_RESERVED_VALUE_FUZZY_NAMES 0x00000008 /* value names are recognized in runtime */ #define DM_REPORT_FIELD_TYPE_ID_LEN 32 #define DM_REPORT_FIELD_TYPE_HEADING_LEN 32 @@ -1721,7 +1723,8 @@ struct dm_report_field_reserved_value { }; /* - * Reserved value is a 'value' that is used directly if any of the 'names' is hit. + * Reserved value is a 'value' that is used directly if any of the 'names' is hit + * or in case of fuzzy names, if such fuzzy name matches. * * If type is any of DM_REPORT_FIELD_TYPE_*, the reserved value is recognized * for all fields of that type. @@ -1736,15 +1739,58 @@ struct dm_report_field_reserved_value { struct dm_report_reserved_value { const uint32_t type; /* DM_REPORT_FIELD_RESERVED_VALUE_* and DM_REPORT_FIELD_TYPE_* */ const void *value; /* reserved value: - struct dm_report_field_reserved_value for DM_REPORT_FIELD_TYPE_NONE uint64_t for DM_REPORT_FIELD_TYPE_NUMBER uint64_t for DM_REPORT_FIELD_TYPE_SIZE (number of 512-byte sectors) uint64_t for DM_REPORT_FIELD_TYPE_PERCENT - const char * for DM_REPORT_FIELD_TYPE_STRING */ - const char **names; /* null-terminated array of names for this reserved value */ + const char* for DM_REPORT_FIELD_TYPE_STRING + struct dm_report_field_reserved_value for DM_REPORT_FIELD_TYPE_NONE + dm_report_reserved_handler* if DM_REPORT_FIELD_RESERVED_VALUE_{DYNAMIC_VALUE,FUZZY_NAMES} is used */ + const char **names; /* null-terminated array of static names for this reserved value */ const char *description; /* description of the reserved value */ }; +/* + * Available actions for dm_report_reserved_value_handler. + */ +typedef enum { + DM_REPORT_RESERVED_PARSE_FUZZY_NAME, + DM_REPORT_RESERVED_GET_DYNAMIC_VALUE, +} dm_report_reserved_action_t; + +/* + * Generic reserved value handler to process reserved value names and/or values. + * + * Actions and their input/output: + * + * DM_REPORT_RESERVED_PARSE_FUZZY_NAME + * data_in: const char *fuzzy_name + * data_out: const char *canonical_name, NULL if fuzzy_name not recognized + * + * DM_REPORT_RESERVED_GET_DYNAMIC_VALUE + * data_in: const char *canonical_name + * data_out: void *value, NULL if canonical_name not recognized + * + * All actions return: + * + * -1 if action not implemented + * 0 on error + * 1 on success + */ +typedef int (*dm_report_reserved_handler) (struct dm_report *rh, + struct dm_pool *mem, + uint32_t field_num, + dm_report_reserved_action_t action, + const void *data_in, + const void **data_out); + +/* + * The dm_report_value_cache_{set,get} are helper functions to store and retrieve + * various values used during reporting (dm_report_field_type.report_fn) and/or + * selection processing (dm_report_reserved_handler instances) to avoid + * recalculation of these values or to share values among calls. + */ +int dm_report_value_cache_set(struct dm_report *rh, const char *name, const void *data); +const void *dm_report_value_cache_get(struct dm_report *rh, const char *name); /* * dm_report_init output_flags */ diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c index f8bd58188..559d46307 100644 --- a/libdm/libdm-report.c +++ b/libdm/libdm-report.c @@ -63,6 +63,7 @@ struct dm_report { /* Null-terminated array of reserved values */ const struct dm_report_reserved_value *reserved_values; + struct dm_hash_table *value_cache; }; /* @@ -1222,6 +1223,8 @@ void dm_report_free(struct dm_report *rh) { if (rh->selection) dm_pool_destroy(rh->selection->mem); + if (rh->value_cache) + dm_hash_destroy(rh->value_cache); dm_pool_destroy(rh->mem); dm_free(rh); } @@ -2205,6 +2208,21 @@ dm_percent_t dm_make_percent(uint64_t numerator, uint64_t denominator) } } +int dm_report_value_cache_set(struct dm_report *rh, const char *name, const void *data) +{ + if (!rh->value_cache && (!(rh->value_cache = dm_hash_create(64)))) { + log_error("Failed to create cache for values used during reporting."); + return 0; + } + + return dm_hash_insert(rh->value_cache, name, (void *) data); +} + +const void *dm_report_value_cache_get(struct dm_report *rh, const char *name) +{ + return (rh->value_cache) ? dm_hash_lookup(rh->value_cache, name) : NULL; +} + /* * Used to check whether the reserved_values definition passed to * dm_report_init_with_selection contains only supported reserved value types.