mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
config: fix use of last config check status if creating CFG_DEF_TREE_MISSING tree
When CFG_DEF_TREE_MISSING is created, it needs to know the status
of the check done on the tree used (the CFG_USED flag).
This bug was introduced with f1c292cc38
"make it possible to run several instances of configuration check at
once". This patch separated the CFG_USED and CFG_VALID flags in
a separate 'status' field in struct cft_check_handle.
However, when creating some trees, like CFG_DEF_TREE_MISSING,
we need this status to do a comparison with full config definition
to determine which items are missing and for which default values
were used. Otherwise, all items would be considered missing.
So, pass this status in a new field called 'check_status' in
struct config_def_tree_spec that defines how the (dumpconfig) tree
should be constructed (and this struct is passed to
config_def_create_tree fn then).
This commit is contained in:
parent
f5584d4203
commit
661406a417
@ -1336,8 +1336,10 @@ static struct dm_config_node *_add_def_node(struct dm_config_tree *cft,
|
|||||||
return cn;
|
return cn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _should_skip_def_node(struct config_def_tree_spec *spec, int section_id, cfg_def_item_t *def)
|
static int _should_skip_def_node(struct config_def_tree_spec *spec, int section_id, int id)
|
||||||
{
|
{
|
||||||
|
cfg_def_item_t *def = cfg_def_get_item_p(id);
|
||||||
|
|
||||||
if ((def->parent != section_id) ||
|
if ((def->parent != section_id) ||
|
||||||
(spec->ignoreadvanced && def->flags & CFG_ADVANCED) ||
|
(spec->ignoreadvanced && def->flags & CFG_ADVANCED) ||
|
||||||
(spec->ignoreunsupported && def->flags & CFG_UNSUPPORTED))
|
(spec->ignoreunsupported && def->flags & CFG_UNSUPPORTED))
|
||||||
@ -1345,7 +1347,12 @@ static int _should_skip_def_node(struct config_def_tree_spec *spec, int section_
|
|||||||
|
|
||||||
switch (spec->type) {
|
switch (spec->type) {
|
||||||
case CFG_DEF_TREE_MISSING:
|
case CFG_DEF_TREE_MISSING:
|
||||||
if ((def->flags & CFG_USED) ||
|
if (!spec->check_status) {
|
||||||
|
log_error_once(INTERNAL_ERROR "couldn't determine missing "
|
||||||
|
"config nodes - unknown status of last config check.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((spec->check_status[id] & CFG_USED) ||
|
||||||
(def->flags & CFG_NAME_VARIABLE) ||
|
(def->flags & CFG_NAME_VARIABLE) ||
|
||||||
(def->since_version > spec->version))
|
(def->since_version > spec->version))
|
||||||
return 1;
|
return 1;
|
||||||
@ -1374,13 +1381,13 @@ static struct dm_config_node *_add_def_section_subtree(struct dm_config_tree *cf
|
|||||||
int id;
|
int id;
|
||||||
|
|
||||||
for (id = 0; id < CFG_COUNT; id++) {
|
for (id = 0; id < CFG_COUNT; id++) {
|
||||||
def = cfg_def_get_item_p(id);
|
if (_should_skip_def_node(spec, section_id, id))
|
||||||
if (_should_skip_def_node(spec, section_id, def))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!cn && !(cn = _add_def_node(cft, spec, parent, relay, cfg_def_get_item_p(section_id))))
|
if (!cn && !(cn = _add_def_node(cft, spec, parent, relay, cfg_def_get_item_p(section_id))))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
|
def = cfg_def_get_item_p(id);
|
||||||
if ((tmp = def->type == CFG_TYPE_SECTION ? _add_def_section_subtree(cft, spec, cn, relay_sub, id)
|
if ((tmp = def->type == CFG_TYPE_SECTION ? _add_def_section_subtree(cft, spec, cn, relay_sub, id)
|
||||||
: _add_def_node(cft, spec, cn, relay_sub, def)))
|
: _add_def_node(cft, spec, cn, relay_sub, def)))
|
||||||
relay_sub = tmp;
|
relay_sub = tmp;
|
||||||
|
@ -110,6 +110,7 @@ struct config_def_tree_spec {
|
|||||||
uint16_t version; /* tree at this LVM2 version */
|
uint16_t version; /* tree at this LVM2 version */
|
||||||
int ignoreadvanced; /* do not include advanced configs */
|
int ignoreadvanced; /* do not include advanced configs */
|
||||||
int ignoreunsupported; /* do not include unsupported configs */
|
int ignoreunsupported; /* do not include unsupported configs */
|
||||||
|
uint8_t *check_status; /* status of last tree check (currently needed for CFG_DEF_TREE_MISSING only) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,13 +45,30 @@ static struct cft_check_handle *_get_cft_check_handle(struct cmd_context *cmd)
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _do_def_check(struct cmd_context *cmd, struct cft_check_handle **cft_check_handle)
|
||||||
|
{
|
||||||
|
struct cft_check_handle *handle;
|
||||||
|
|
||||||
|
if (!(handle = _get_cft_check_handle(cmd)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
handle->force_check = 1;
|
||||||
|
handle->skip_if_checked = 1;
|
||||||
|
handle->suppress_messages = 1;
|
||||||
|
|
||||||
|
config_def_check(cmd, handle);
|
||||||
|
*cft_check_handle = handle;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
|
int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *file = arg_str_value(cmd, file_ARG, NULL);
|
const char *file = arg_str_value(cmd, file_ARG, NULL);
|
||||||
const char *type = arg_str_value(cmd, configtype_ARG, "current");
|
const char *type = arg_str_value(cmd, configtype_ARG, "current");
|
||||||
struct config_def_tree_spec tree_spec = {0};
|
struct config_def_tree_spec tree_spec = {0};
|
||||||
struct dm_config_tree *cft = NULL;
|
struct dm_config_tree *cft = NULL;
|
||||||
struct cft_check_handle *cft_check_handle;
|
struct cft_check_handle *cft_check_handle = NULL;
|
||||||
int r = ECMD_PROCESSED;
|
int r = ECMD_PROCESSED;
|
||||||
|
|
||||||
if (arg_count(cmd, configtype_ARG) && arg_count(cmd, validate_ARG)) {
|
if (arg_count(cmd, configtype_ARG) && arg_count(cmd, validate_ARG)) {
|
||||||
@ -105,29 +122,31 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
|
|
||||||
if (!strcmp(type, "current")) {
|
if (!strcmp(type, "current")) {
|
||||||
tree_spec.type = CFG_DEF_TREE_CURRENT;
|
tree_spec.type = CFG_DEF_TREE_CURRENT;
|
||||||
|
if (!_do_def_check(cmd, &cft_check_handle))
|
||||||
if (!(cft_check_handle = _get_cft_check_handle(cmd)))
|
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
|
|
||||||
cft_check_handle->force_check = 1;
|
|
||||||
cft_check_handle->skip_if_checked = 1;
|
|
||||||
cft_check_handle->suppress_messages = 1;
|
|
||||||
|
|
||||||
config_def_check(cmd, cft_check_handle);
|
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(type, "missing")) {
|
||||||
else if (!strcmp(type, "default"))
|
|
||||||
tree_spec.type = CFG_DEF_TREE_DEFAULT;
|
|
||||||
else if (!strcmp(type, "missing"))
|
|
||||||
tree_spec.type = CFG_DEF_TREE_MISSING;
|
tree_spec.type = CFG_DEF_TREE_MISSING;
|
||||||
else if (!strcmp(type, "new"))
|
if (!_do_def_check(cmd, &cft_check_handle))
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
else if (!strcmp(type, "default")) {
|
||||||
|
tree_spec.type = CFG_DEF_TREE_DEFAULT;
|
||||||
|
/* default type does not require check status */
|
||||||
|
}
|
||||||
|
else if (!strcmp(type, "new")) {
|
||||||
tree_spec.type = CFG_DEF_TREE_NEW;
|
tree_spec.type = CFG_DEF_TREE_NEW;
|
||||||
|
/* new type does not require check status */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
log_error("Incorrect type of configuration specified. "
|
log_error("Incorrect type of configuration specified. "
|
||||||
"Expected one of: current, default, missing, new.");
|
"Expected one of: current, default, missing, new.");
|
||||||
return EINVALID_CMD_LINE;
|
return EINVALID_CMD_LINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cft_check_handle)
|
||||||
|
tree_spec.check_status = cft_check_handle->status;
|
||||||
|
|
||||||
if (tree_spec.type == CFG_DEF_TREE_CURRENT)
|
if (tree_spec.type == CFG_DEF_TREE_CURRENT)
|
||||||
cft = cmd->cft;
|
cft = cmd->cft;
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user