mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +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! However overal this patch is not giving major speedup as we are actually going through config_node many times to extract individual pieces.
This commit is contained in:
parent
a953fd9968
commit
785572fb65
@ -375,7 +375,7 @@ static int _read_segment(struct cmd_context *cmd,
|
||||
uint32_t area_count = 0u;
|
||||
struct lv_segment *seg;
|
||||
const struct dm_config_node *sn_child = sn->child;
|
||||
const struct dm_config_value *cv;
|
||||
const struct dm_config_value *cv = NULL;
|
||||
uint32_t area_extents, start_extent, extent_count, reshape_count, data_copies;
|
||||
struct segment_type *segtype;
|
||||
const char *segtype_str;
|
||||
@ -385,7 +385,7 @@ static int _read_segment(struct cmd_context *cmd,
|
||||
log_error("Empty segment section.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!_read_int32(sn_child, "start_extent", &start_extent)) {
|
||||
log_error("Couldn't read 'start_extent' for segment '%s' "
|
||||
"of logical volume %s.", sn->key, lv->name);
|
||||
@ -423,6 +423,41 @@ static int _read_segment(struct cmd_context *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Optional tags */
|
||||
dm_config_get_list(sn_child, "tags", &cv);
|
||||
#else
|
||||
segtype_str = SEG_TYPE_NAME_STRIPED;
|
||||
reshape_count = 0;
|
||||
data_copies = 1;
|
||||
|
||||
struct config_values v[] = {
|
||||
{ "data_copies", CONFIG_VALUE_UINT32, &data_copies },
|
||||
{ "extent_count", CONFIG_VALUE_UINT32, &extent_count, 1 },
|
||||
{ "reshape_count", CONFIG_VALUE_UINT32, &reshape_count },
|
||||
{ "start_extent", CONFIG_VALUE_UINT32, &start_extent, 1 },
|
||||
{ "tags", CONFIG_VALUE_LIST, &cv },
|
||||
{ "type", CONFIG_VALUE_STRING, &segtype_str },
|
||||
};
|
||||
|
||||
if (!text_import_values(sn_child, DM_ARRAY_SIZE(v), v)) {
|
||||
log_error("Could not read segment values for %s.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Locally duplicate to parse out status flag bits */
|
||||
if (!(segtype_with_flags = dm_pool_strdup(mem, segtype_str))) {
|
||||
log_error("Cannot duplicate segtype string.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!read_segtype_lvflags(&lv->status, segtype_with_flags)) {
|
||||
log_error("Couldn't read segtype for logical volume %s.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (!(segtype = get_segtype_from_string(cmd, segtype_with_flags)))
|
||||
return_0;
|
||||
|
||||
@ -447,13 +482,11 @@ static int _read_segment(struct cmd_context *cmd,
|
||||
return_0;
|
||||
|
||||
/* Optional tags */
|
||||
if (dm_config_get_list(sn_child, "tags", &cv) &&
|
||||
!(_read_str_list(mem, &seg->tags, cv))) {
|
||||
if (cv && !(_read_str_list(mem, &seg->tags, cv))) {
|
||||
log_error("Couldn't read tags for a segment of %s/%s.",
|
||||
lv->vg->name, lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert into correct part of segment list.
|
||||
*/
|
||||
@ -540,6 +573,60 @@ int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _compare_config_values_s(const void *a, const void *b)
|
||||
{
|
||||
return strcmp(((const struct config_values*)a)->path,
|
||||
((const struct config_values*)b)->path);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
size_t values_count, struct config_values *values)
|
||||
{
|
||||
struct config_values *found;
|
||||
unsigned i;
|
||||
|
||||
while (cn) {
|
||||
struct config_values findme = { .path = cn->key };
|
||||
|
||||
found = bsearch(&findme, values, values_count,
|
||||
sizeof(struct config_values),
|
||||
_compare_config_values_s);
|
||||
|
||||
if (found) {
|
||||
switch (found->type) {
|
||||
case CONFIG_VALUE_STRING:
|
||||
*(const char**)(found->result) = cn->v->v.str;
|
||||
break;
|
||||
case CONFIG_VALUE_UINT64:
|
||||
*(uint64_t*)(found->result) = (uint64_t)cn->v->v.i;
|
||||
break;
|
||||
case CONFIG_VALUE_UINT32:
|
||||
*(uint32_t*)(found->result) = (uint32_t)cn->v->v.i;
|
||||
break;
|
||||
case CONFIG_VALUE_LIST:
|
||||
*(struct dm_config_value**)(found->result) = cn->v;
|
||||
break;
|
||||
}
|
||||
--(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].path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_segments(struct cmd_context *cmd,
|
||||
struct format_type *fmt,
|
||||
struct format_instance *fid,
|
||||
|
@ -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,21 @@ 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,
|
||||
CONFIG_VALUE_UINT64,
|
||||
CONFIG_VALUE_UINT32,
|
||||
CONFIG_VALUE_LIST,
|
||||
} config_value_t;
|
||||
|
||||
struct config_values {
|
||||
const char *path; /* option name/path to look for */
|
||||
config_value_t type; /* type of resulting value */
|
||||
void *result; /* where to place resulting value of given type */
|
||||
int mandatory; /* If this path is missing in config node, import fails */
|
||||
};
|
||||
|
||||
int text_import_values(const struct dm_config_node *cn,
|
||||
size_t values_count, struct config_values *values);
|
||||
|
||||
#endif
|
||||
|
@ -72,7 +72,28 @@ static int _striped_text_import_area_count(const struct dm_config_node *sn, uint
|
||||
static int _striped_text_import(struct lv_segment *seg, const struct dm_config_node *sn)
|
||||
{
|
||||
const struct dm_config_value *cv;
|
||||
#if 1
|
||||
uint32_t stripe_size = 0;
|
||||
|
||||
struct config_values v[] = {
|
||||
{ "stripe_size", CONFIG_VALUE_UINT32, &stripe_size },
|
||||
{ "stripes", CONFIG_VALUE_LIST, &cv },
|
||||
};
|
||||
|
||||
if (!text_import_values(sn, DM_ARRAY_SIZE(v), v)) {
|
||||
log_error("Could not read segment values for");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (seg->area_count != 1) {
|
||||
if (!stripe_size) {
|
||||
log_error("Couldn't read stripe_size for segment %s "
|
||||
"of logical volume %s.", dm_config_parent_name(sn), seg->lv->name);
|
||||
return 0;
|
||||
}
|
||||
seg->stripe_size = stripe_size;
|
||||
}
|
||||
#else
|
||||
if ((seg->area_count != 1) &&
|
||||
!dm_config_get_uint32(sn, "stripe_size", &seg->stripe_size)) {
|
||||
log_error("Couldn't read stripe_size for segment %s "
|
||||
@ -85,6 +106,7 @@ static int _striped_text_import(struct lv_segment *seg, const struct dm_config_n
|
||||
"of logical volume %s.", dm_config_parent_name(sn), seg->lv->name);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
seg->area_len /= seg->area_count;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "lib/config/config.h"
|
||||
#include "lib/activate/activate.h"
|
||||
#include "lib/datastruct/str_list.h"
|
||||
#include "lib/format_text/text_import.h"
|
||||
|
||||
/* Dm kernel module name for thin provisioning */
|
||||
static const char _thin_pool_module[] = "thin-pool";
|
||||
@ -468,9 +469,46 @@ static void _thin_display(const struct lv_segment *seg)
|
||||
static int _thin_text_import(struct lv_segment *seg,
|
||||
const struct dm_config_node *sn)
|
||||
{
|
||||
const char *lv_name;
|
||||
struct logical_volume *pool_lv, *origin = NULL, *external_lv = NULL, *merge_lv = NULL;
|
||||
const char *pool_name = NULL, *origin_name = NULL, *external_name = NULL, *merge_name = NULL;
|
||||
struct logical_volume *pool_lv, *origin_lv = NULL, *external_lv = NULL, *merge_lv = NULL;
|
||||
struct generic_logical_volume *indirect_origin = NULL;
|
||||
int64_t transaction_id = -1, device_id = -1;
|
||||
|
||||
struct config_values v[] = {
|
||||
{ "device_id", CONFIG_VALUE_UINT64, &device_id, 1 },
|
||||
{ "external_origin", CONFIG_VALUE_STRING, &external_name },
|
||||
{ "merge", CONFIG_VALUE_STRING, &merge_name },
|
||||
{ "origin", CONFIG_VALUE_STRING, &origin_name },
|
||||
{ "thin_pool", CONFIG_VALUE_STRING, &pool_name, 1 },
|
||||
{ "transaction_id", CONFIG_VALUE_UINT64, &transaction_id, 1 },
|
||||
};
|
||||
|
||||
if (!text_import_values(sn, DM_ARRAY_SIZE(v), v))
|
||||
return SEG_LOG_ERROR("Could not read segment values for");
|
||||
|
||||
seg->transaction_id = (uint64_t)transaction_id;
|
||||
seg->device_id = (uint64_t)device_id;
|
||||
if (seg->device_id > DM_THIN_MAX_DEVICE_ID)
|
||||
return SEG_LOG_ERROR("Unsupported value %u for device_id",
|
||||
seg->device_id);
|
||||
if (!pool_name)
|
||||
return SEG_LOG_ERROR("Thin pool must be a string in");
|
||||
|
||||
if (!(pool_lv = find_lv(seg->lv->vg, pool_name)))
|
||||
return SEG_LOG_ERROR("Unknown thin pool %s in", pool_name);
|
||||
|
||||
if (origin_name &&
|
||||
!(origin_lv = find_lv(seg->lv->vg, origin_name)))
|
||||
return SEG_LOG_ERROR("Unknown origin %s in", origin_name);
|
||||
|
||||
if (merge_name &&
|
||||
!(merge_lv = find_lv(seg->lv->vg, merge_name)))
|
||||
return SEG_LOG_ERROR("Unknown merge lv %s in", merge_name);
|
||||
|
||||
if (external_name &&
|
||||
!(external_lv = find_lv(seg->lv->vg, external_name)))
|
||||
return SEG_LOG_ERROR("Unknown external origin %s in", external_name);
|
||||
#if 0
|
||||
|
||||
if (!dm_config_get_str(sn, "thin_pool", &lv_name))
|
||||
return SEG_LOG_ERROR("Thin pool must be a string in");
|
||||
@ -510,8 +548,8 @@ static int _thin_text_import(struct lv_segment *seg,
|
||||
if (!(external_lv = find_lv(seg->lv->vg, lv_name)))
|
||||
return SEG_LOG_ERROR("Unknown external origin %s in", lv_name);
|
||||
}
|
||||
|
||||
if (!attach_pool_lv(seg, pool_lv, origin, indirect_origin, merge_lv))
|
||||
#endif
|
||||
if (!attach_pool_lv(seg, pool_lv, origin_lv, indirect_origin, merge_lv))
|
||||
return_0;
|
||||
|
||||
if (!attach_thin_external_origin(seg, external_lv))
|
||||
|
Loading…
Reference in New Issue
Block a user