1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

text_import: introduce text_import_values

When reading values out of tree node, we can look for them with
help of binary search.

For this bsearch functionality however config values must be
alphabetically sorted!
This commit is contained in:
Zdenek Kabelac 2024-10-28 18:35:18 +01:00
parent f0ebdf0da1
commit 6819c6ffd4
2 changed files with 116 additions and 1 deletions

View File

@ -547,6 +547,96 @@ int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn,
return 1;
}
/* Ensure config_value has matching type before copy */
static int _copy_config_value(const struct dm_config_node *cn,
const struct config_value *cv)
{
const char *err = "list";
if (cn->v) {
switch (cv->type) {
case CONFIG_VALUE_STRING:
if (cn->v->type != DM_CFG_STRING) {
err = "string";
break;
}
*(const char**)(cv->result) = cn->v->v.str;
return 1;
case CONFIG_VALUE_UINT64:
if (cn->v->type != DM_CFG_INT) {
err = "number";
break;
}
*(uint64_t*)(cv->result) = (uint64_t)cn->v->v.i;
return 1;
case CONFIG_VALUE_UINT32:
if (cn->v->type != DM_CFG_INT) {
err = "number";
break;
}
*(uint32_t*)(cv->result) = (uint32_t)cn->v->v.i;
return 1;
case CONFIG_VALUE_LIST:
*(struct dm_config_value**)(cv->result) = cn->v;
return 1;
}
}
if (cv->mandatory) {
/* For mandatory value mismatching type fails parsing. */
log_error("Value for %s is not a %s.", cv->name, err);
return 0;
}
/* For non-mandatory value warn user and continue with parsing. */
log_warn("WARNING: Ignoring non %s value for %s.", err, cv->name);
return -1;
}
static int _compare_config_values_s(const void *a, const void *b)
{
return strcmp(((const struct config_value*)a)->name,
((const struct config_value*)b)->name);
}
/*
* Read set of values out of config tree nodes
*
* config_values are expected to be in Alphabetic order for use with bsearch!!
*/
int text_import_values(const struct dm_config_node *cn,
struct config_value *values, size_t values_count)
{
struct config_value *found;
struct config_value findme;
unsigned i;
int ret = 1;
while (cn) {
findme.name = cn->key;
if ((found = bsearch(&findme, values, values_count,
sizeof(*found),
_compare_config_values_s))) {
if (!_copy_config_value(cn, found))
return_0;
--(found->mandatory);
}
cn = cn->sib;
}
for (i = 0 ; i < values_count; ++i)
if (values[i].mandatory > 0) {
log_error("Required option %s is missing!", values[i].name);
ret = 0;
}
return ret;
}
static int _read_segments(struct cmd_context *cmd,
struct format_type *fmt,
struct format_instance *fid,

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2024 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -25,4 +25,29 @@ struct dm_config_node;
int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn,
const struct dm_config_value *cv, uint64_t status);
typedef enum {
CONFIG_VALUE_STRING, /* const char * */
CONFIG_VALUE_UINT64, /* uint64_t * */
CONFIG_VALUE_UINT32, /* uint32_t * */
CONFIG_VALUE_LIST, /* struct dm_config_value * */
} config_value_t;
struct config_value {
const char *name; /* config value name/path to look for */
void *result; /* where to store resulting value of expected type */
config_value_t type; /* expected value type */
int mandatory; /* fail import if this value is missing in config node */
};
/*
* Parses config values out of config node out of sorted array like this
*
* struct config_value values[] = {
* { "value1", &uint_value1, CONFIG_VALUE_UINT32, 1 },
* { "value2", &list_value2, CONFIG_VALUE_LIST, },
* };
*/
int text_import_values(const struct dm_config_node *cn,
struct config_value *values, size_t values_count);
#endif