mirror of
git://sourceware.org/git/lvm2.git
synced 2025-08-03 08:22:00 +03:00
config: make it possible to run several instances of configuration check at once
Before, the status of the configuration check (config_def_check fn call) was saved directly in global configuration definitinion array (as part of the cfg_def_item_t/flags) This patch introduces the "struct cft_check_handle" that defines configuration check parameters as well as separate place to store the status (status here means CFG_USED and CFG_VALID flags, formerly saved in cfg_def_item_t/flags). This struct can hold config check parameters as well as the status for each config tree separately, thus making it possible to run several instances of config_def_check without interference.
This commit is contained in:
@ -263,6 +263,29 @@ static int _check_disable_udev(const char *msg) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _check_config(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
if (!find_config_tree_bool(cmd, config_checks_CFG, NULL))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!cmd->cft_check_handle) {
|
||||||
|
if (!(cmd->cft_check_handle = dm_pool_zalloc(cmd->libmem, sizeof(*cmd->cft_check_handle)))) {
|
||||||
|
log_error("Configuration check handle allocation failed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->cft_check_handle->cft = cmd->cft;
|
||||||
|
|
||||||
|
if (!config_def_check(cmd, cmd->cft_check_handle) &&
|
||||||
|
find_config_tree_bool(cmd, config_abort_on_errors_CFG, NULL)) {
|
||||||
|
log_error("LVM configuration invalid.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int _process_config(struct cmd_context *cmd)
|
static int _process_config(struct cmd_context *cmd)
|
||||||
{
|
{
|
||||||
mode_t old_umask;
|
mode_t old_umask;
|
||||||
@ -275,10 +298,8 @@ static int _process_config(struct cmd_context *cmd)
|
|||||||
int udev_disabled = 0;
|
int udev_disabled = 0;
|
||||||
char sysfs_dir[PATH_MAX];
|
char sysfs_dir[PATH_MAX];
|
||||||
|
|
||||||
if (!config_def_check(cmd, 0, 0, 0) && find_config_tree_bool(cmd, config_abort_on_errors_CFG, NULL)) {
|
if (!_check_config(cmd))
|
||||||
log_error("LVM configuration invalid.");
|
return_0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* umask */
|
/* umask */
|
||||||
cmd->default_settings.umask = find_config_tree_int(cmd, global_umask_CFG, NULL);
|
cmd->default_settings.umask = find_config_tree_int(cmd, global_umask_CFG, NULL);
|
||||||
|
@ -102,7 +102,9 @@ struct cmd_context {
|
|||||||
struct profile_params *profile_params; /* profile handling params including loaded profile configs */
|
struct profile_params *profile_params; /* profile handling params including loaded profile configs */
|
||||||
struct dm_config_tree *cft; /* the whole cascade: CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_FILE/CONFIG_MERGED_FILES */
|
struct dm_config_tree *cft; /* the whole cascade: CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_FILE/CONFIG_MERGED_FILES */
|
||||||
int config_initialized; /* used to reinitialize config if previous init was not successful */
|
int config_initialized; /* used to reinitialize config if previous init was not successful */
|
||||||
|
|
||||||
struct dm_hash_table *cft_def_hash; /* config definition hash used for validity check (item type + item recognized) */
|
struct dm_hash_table *cft_def_hash; /* config definition hash used for validity check (item type + item recognized) */
|
||||||
|
struct cft_check_handle *cft_check_handle;
|
||||||
|
|
||||||
/* selected settings with original default/configured value which can be changed during cmd processing */
|
/* selected settings with original default/configured value which can be changed during cmd processing */
|
||||||
struct config_info default_settings;
|
struct config_info default_settings;
|
||||||
|
@ -584,12 +584,13 @@ static int _config_def_check_node_single_value(const char *rp, const struct dm_c
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _config_def_check_node_value(const char *rp, const struct dm_config_value *v,
|
static int _config_def_check_node_value(struct cft_check_handle *handle,
|
||||||
const cfg_def_item_t *def, int suppress_messages)
|
const char *rp, const struct dm_config_value *v,
|
||||||
|
const cfg_def_item_t *def)
|
||||||
{
|
{
|
||||||
if (!v) {
|
if (!v) {
|
||||||
if (def->type != CFG_TYPE_SECTION) {
|
if (def->type != CFG_TYPE_SECTION) {
|
||||||
_log_type_error(rp, CFG_TYPE_SECTION, def->type, suppress_messages);
|
_log_type_error(rp, CFG_TYPE_SECTION, def->type, handle->suppress_messages);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -597,13 +598,13 @@ static int _config_def_check_node_value(const char *rp, const struct dm_config_v
|
|||||||
|
|
||||||
if (v->next) {
|
if (v->next) {
|
||||||
if (!(def->type & CFG_TYPE_ARRAY)) {
|
if (!(def->type & CFG_TYPE_ARRAY)) {
|
||||||
_log_type_error(rp, CFG_TYPE_ARRAY, def->type, suppress_messages);
|
_log_type_error(rp, CFG_TYPE_ARRAY, def->type, handle->suppress_messages);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!_config_def_check_node_single_value(rp, v, def, suppress_messages))
|
if (!_config_def_check_node_single_value(rp, v, def, handle->suppress_messages))
|
||||||
return 0;
|
return 0;
|
||||||
v = v->next;
|
v = v->next;
|
||||||
} while (v);
|
} while (v);
|
||||||
@ -611,9 +612,10 @@ static int _config_def_check_node_value(const char *rp, const struct dm_config_v
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _config_def_check_node(const char *vp, char *pvp, char *rp, char *prp,
|
static int _config_def_check_node(struct cft_check_handle *handle,
|
||||||
|
const char *vp, char *pvp, char *rp, char *prp,
|
||||||
size_t buf_size, struct dm_config_node *cn,
|
size_t buf_size, struct dm_config_node *cn,
|
||||||
struct dm_hash_table *ht, int suppress_messages)
|
struct dm_hash_table *ht)
|
||||||
{
|
{
|
||||||
cfg_def_item_t *def;
|
cfg_def_item_t *def;
|
||||||
int sep = vp != pvp; /* don't use '/' separator for top-level node */
|
int sep = vp != pvp; /* don't use '/' separator for top-level node */
|
||||||
@ -628,7 +630,7 @@ static int _config_def_check_node(const char *vp, char *pvp, char *rp, char *prp
|
|||||||
if (!(def = (cfg_def_item_t *) dm_hash_lookup(ht, vp))) {
|
if (!(def = (cfg_def_item_t *) dm_hash_lookup(ht, vp))) {
|
||||||
/* If the node is not a section but a setting, fail now. */
|
/* If the node is not a section but a setting, fail now. */
|
||||||
if (cn->v) {
|
if (cn->v) {
|
||||||
log_warn_suppress(suppress_messages,
|
log_warn_suppress(handle->suppress_messages,
|
||||||
"Configuration setting \"%s\" unknown.", rp);
|
"Configuration setting \"%s\" unknown.", rp);
|
||||||
cn->id = -1;
|
cn->id = -1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -639,38 +641,38 @@ static int _config_def_check_node(const char *vp, char *pvp, char *rp, char *prp
|
|||||||
/* The real path without '#' is still stored in rp variable. */
|
/* The real path without '#' is still stored in rp variable. */
|
||||||
pvp[sep] = '#', pvp[sep + 1] = '\0';
|
pvp[sep] = '#', pvp[sep + 1] = '\0';
|
||||||
if (!(def = (cfg_def_item_t *) dm_hash_lookup(ht, vp))) {
|
if (!(def = (cfg_def_item_t *) dm_hash_lookup(ht, vp))) {
|
||||||
log_warn_suppress(suppress_messages,
|
log_warn_suppress(handle->suppress_messages,
|
||||||
"Configuration section \"%s\" unknown.", rp);
|
"Configuration section \"%s\" unknown.", rp);
|
||||||
cn->id = -1;
|
cn->id = -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def->flags |= CFG_USED;
|
handle->status[def->id] |= CFG_USED;
|
||||||
cn->id = def->id;
|
cn->id = def->id;
|
||||||
|
|
||||||
if (!_config_def_check_node_value(rp, cn->v, def, suppress_messages))
|
if (!_config_def_check_node_value(handle, rp, cn->v, def))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
def->flags |= CFG_VALID;
|
handle->status[def->id] |= CFG_VALID;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _config_def_check_tree(const char *vp, char *pvp, char *rp, char *prp,
|
static int _config_def_check_tree(struct cft_check_handle *handle,
|
||||||
|
const char *vp, char *pvp, char *rp, char *prp,
|
||||||
size_t buf_size, struct dm_config_node *root,
|
size_t buf_size, struct dm_config_node *root,
|
||||||
struct dm_hash_table *ht, int suppress_messages)
|
struct dm_hash_table *ht)
|
||||||
{
|
{
|
||||||
struct dm_config_node *cn;
|
struct dm_config_node *cn;
|
||||||
int valid, r = 1;
|
int valid, r = 1;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
for (cn = root->child; cn; cn = cn->sib) {
|
for (cn = root->child; cn; cn = cn->sib) {
|
||||||
if ((valid = _config_def_check_node(vp, pvp, rp, prp, buf_size,
|
if ((valid = _config_def_check_node(handle, vp, pvp, rp, prp,
|
||||||
cn, ht, suppress_messages)) && !cn->v) {
|
buf_size, cn, ht)) && !cn->v) {
|
||||||
len = strlen(rp);
|
len = strlen(rp);
|
||||||
valid = _config_def_check_tree(vp, pvp + strlen(pvp),
|
valid = _config_def_check_tree(handle, vp, pvp + strlen(pvp),
|
||||||
rp, prp + len, buf_size - len, cn, ht,
|
rp, prp + len, buf_size - len, cn, ht);
|
||||||
suppress_messages);
|
|
||||||
}
|
}
|
||||||
if (!valid)
|
if (!valid)
|
||||||
r = 0;
|
r = 0;
|
||||||
@ -679,7 +681,7 @@ static int _config_def_check_tree(const char *vp, char *pvp, char *rp, char *prp
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_def_check(struct cmd_context *cmd, int force, int skip, int suppress_messages)
|
int config_def_check(struct cmd_context *cmd, struct cft_check_handle *handle)
|
||||||
{
|
{
|
||||||
cfg_def_item_t *def;
|
cfg_def_item_t *def;
|
||||||
struct dm_config_node *cn;
|
struct dm_config_node *cn;
|
||||||
@ -695,28 +697,21 @@ int config_def_check(struct cmd_context *cmd, int force, int skip, int suppress_
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the check has already been done and 'skip' is set,
|
* If the check has already been done and 'skip_if_checked' is set,
|
||||||
* skip the actual check and use last result if available.
|
* skip the actual check and use last result if available.
|
||||||
* If not available, we must do the check. The global status
|
* If not available, we must do the check. The global status
|
||||||
* is stored in root node.
|
* is stored in root node.
|
||||||
*/
|
*/
|
||||||
def = cfg_def_get_item_p(root_CFG_SECTION);
|
if (handle->skip_if_checked && (handle->status[root_CFG_SECTION] & CFG_USED))
|
||||||
if (skip && (def->flags & CFG_USED))
|
return handle->status[root_CFG_SECTION] & CFG_VALID;
|
||||||
return def->flags & CFG_VALID;
|
|
||||||
|
/* Nothing to do if checks are disabled and also not forced. */
|
||||||
|
if (!handle->force_check && !find_config_tree_bool(cmd, config_checks_CFG, NULL))
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* Clear 'used' and 'valid' status flags. */
|
/* Clear 'used' and 'valid' status flags. */
|
||||||
for (id = 0; id < CFG_COUNT; id++) {
|
for (id = 0; id < CFG_COUNT; id++)
|
||||||
def = cfg_def_get_item_p(id);
|
handle->status[id] &= ~(CFG_USED | CFG_VALID);
|
||||||
def->flags &= ~(CFG_USED | CFG_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!force && !find_config_tree_bool(cmd, config_checks_CFG, NULL)) {
|
|
||||||
if (cmd->cft_def_hash) {
|
|
||||||
dm_hash_destroy(cmd->cft_def_hash);
|
|
||||||
cmd->cft_def_hash = NULL;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a hash of all possible configuration
|
* Create a hash of all possible configuration
|
||||||
@ -743,44 +738,46 @@ int config_def_check(struct cmd_context *cmd, int force, int skip, int suppress_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_def_get_item_p(root_CFG_SECTION)->flags |= CFG_USED;
|
/*
|
||||||
|
* Mark this handle as used so next time we know that the check
|
||||||
|
* has already been done and so we can just reuse the previous
|
||||||
|
* status instead of running this whole check again.
|
||||||
|
*/
|
||||||
|
handle->status[root_CFG_SECTION] |= CFG_USED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow only sections as top-level elements.
|
* Allow only sections as top-level elements.
|
||||||
* Iterate top-level sections and dive deeper.
|
* Iterate top-level sections and dive deeper.
|
||||||
* If any of subsequent checks fails, the whole check fails.
|
* If any of subsequent checks fails, the whole check fails.
|
||||||
*/
|
*/
|
||||||
for (cn = cmd->cft->root; cn; cn = cn->sib) {
|
for (cn = handle->cft->root; cn; cn = cn->sib) {
|
||||||
if (!cn->v) {
|
if (!cn->v) {
|
||||||
/* top level node: vp=vp, rp=rp */
|
/* top level node: vp=vp, rp=rp */
|
||||||
if (!_config_def_check_node(vp, vp, rp, rp,
|
if (!_config_def_check_node(handle, vp, vp, rp, rp,
|
||||||
CFG_PATH_MAX_LEN,
|
CFG_PATH_MAX_LEN,
|
||||||
cn, cmd->cft_def_hash,
|
cn, cmd->cft_def_hash)) {
|
||||||
suppress_messages)) {
|
|
||||||
r = 0; continue;
|
r = 0; continue;
|
||||||
}
|
}
|
||||||
rplen = strlen(rp);
|
rplen = strlen(rp);
|
||||||
if (!_config_def_check_tree(vp, vp + strlen(vp),
|
if (!_config_def_check_tree(handle,
|
||||||
|
vp, vp + strlen(vp),
|
||||||
rp, rp + rplen,
|
rp, rp + rplen,
|
||||||
CFG_PATH_MAX_LEN - rplen,
|
CFG_PATH_MAX_LEN - rplen,
|
||||||
cn, cmd->cft_def_hash,
|
cn, cmd->cft_def_hash))
|
||||||
suppress_messages))
|
|
||||||
r = 0;
|
r = 0;
|
||||||
} else {
|
} else {
|
||||||
log_error_suppress(suppress_messages,
|
log_error_suppress(handle->suppress_messages,
|
||||||
"Configuration setting \"%s\" invalid. "
|
"Configuration setting \"%s\" invalid. "
|
||||||
"It's not part of any section.", cn->key);
|
"It's not part of any section.", cn->key);
|
||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (r) {
|
if (r)
|
||||||
cfg_def_get_item_p(root_CFG_SECTION)->flags |= CFG_VALID;
|
handle->status[root_CFG_SECTION] |= CFG_VALID;
|
||||||
def->flags |= CFG_VALID;
|
else
|
||||||
} else {
|
handle->status[root_CFG_SECTION] &= ~CFG_VALID;
|
||||||
cfg_def_get_item_p(root_CFG_SECTION)->flags &= ~CFG_VALID;
|
|
||||||
def->flags &= ~CFG_VALID;
|
|
||||||
}
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,10 +80,6 @@ typedef union {
|
|||||||
#define CFG_ADVANCED 0x04
|
#define CFG_ADVANCED 0x04
|
||||||
/* whether the configuraton item is not officially supported */
|
/* whether the configuraton item is not officially supported */
|
||||||
#define CFG_UNSUPPORTED 0x08
|
#define CFG_UNSUPPORTED 0x08
|
||||||
/* helper flag to mark the item as used in a config tree instance */
|
|
||||||
#define CFG_USED 0x10
|
|
||||||
/* helper flag to mark the item as valid in a config tree instance */
|
|
||||||
#define CFG_VALID 0x20
|
|
||||||
|
|
||||||
/* configuration definition item structure */
|
/* configuration definition item structure */
|
||||||
typedef struct cfg_def_item {
|
typedef struct cfg_def_item {
|
||||||
@ -114,6 +110,12 @@ struct config_def_tree_spec {
|
|||||||
int ignoreunsupported; /* do not include unsupported configs */
|
int ignoreunsupported; /* do not include unsupported configs */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* flag to mark the item as used in a config tree instance during validation */
|
||||||
|
#define CFG_USED 0x01
|
||||||
|
/* flag to mark the item as valid in a config tree instance during validation */
|
||||||
|
#define CFG_VALID 0x02
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register ID for each possible item in the configuration tree.
|
* Register ID for each possible item in the configuration tree.
|
||||||
*/
|
*/
|
||||||
@ -131,8 +133,17 @@ struct profile *add_profile(struct cmd_context *cmd, const char *profile_name);
|
|||||||
int load_profile(struct cmd_context *cmd, struct profile *profile);
|
int load_profile(struct cmd_context *cmd, struct profile *profile);
|
||||||
int load_pending_profiles(struct cmd_context *cmd);
|
int load_pending_profiles(struct cmd_context *cmd);
|
||||||
|
|
||||||
|
/* configuration check handle for each instance of the validation check */
|
||||||
|
struct cft_check_handle {
|
||||||
|
struct dm_config_tree *cft; /* the tree for which the check is done */
|
||||||
|
unsigned force_check:1; /* force check even if disabled by config/checks setting */
|
||||||
|
unsigned skip_if_checked:1; /* skip the check if already done before - return last state */
|
||||||
|
unsigned suppress_messages:1; /* suppress messages during the check if config item is found invalid */
|
||||||
|
uint8_t status[CFG_COUNT]; /* flags for each configuration item - the result of the check */
|
||||||
|
};
|
||||||
|
|
||||||
int config_def_get_path(char *buf, size_t buf_size, int id);
|
int config_def_get_path(char *buf, size_t buf_size, int id);
|
||||||
int config_def_check(struct cmd_context *cmd, int force, int skip, int suppress_messages);
|
int config_def_check(struct cmd_context *cmd, struct cft_check_handle *handle);
|
||||||
|
|
||||||
int override_config_tree_from_string(struct cmd_context *cmd, const char *config_settings);
|
int override_config_tree_from_string(struct cmd_context *cmd, const char *config_settings);
|
||||||
int override_config_tree_from_profile(struct cmd_context *cmd, struct profile *profile);
|
int override_config_tree_from_profile(struct cmd_context *cmd, struct profile *profile);
|
||||||
|
@ -31,6 +31,22 @@ static int _get_vsn(struct cmd_context *cmd, unsigned int *major,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct cft_check_handle *_get_cft_check_handle(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
struct cft_check_handle *handle = cmd->cft_check_handle;
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
if (!(handle = dm_pool_zalloc(cmd->libmem, sizeof(*cmd->cft_check_handle)))) {
|
||||||
|
log_error("Configuration check handle allocation failed.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
handle->cft = cmd->cft;
|
||||||
|
cmd->cft_check_handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -38,6 +54,7 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
unsigned int major, minor, patchlevel;
|
unsigned int major, minor, patchlevel;
|
||||||
struct config_def_tree_spec tree_spec = {0};
|
struct config_def_tree_spec tree_spec = {0};
|
||||||
struct dm_config_tree *cft = cmd->cft;
|
struct dm_config_tree *cft = cmd->cft;
|
||||||
|
struct cft_check_handle *cft_check_handle;
|
||||||
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)) {
|
||||||
@ -57,7 +74,14 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
tree_spec.ignoreunsupported = 1;
|
tree_spec.ignoreunsupported = 1;
|
||||||
|
|
||||||
if (arg_count(cmd, validate_ARG)) {
|
if (arg_count(cmd, validate_ARG)) {
|
||||||
if (config_def_check(cmd, 1, 1, 0)) {
|
if (!(cft_check_handle = _get_cft_check_handle(cmd)))
|
||||||
|
return ECMD_FAILED;
|
||||||
|
|
||||||
|
cft_check_handle->force_check = 1;
|
||||||
|
cft_check_handle->skip_if_checked = 1;
|
||||||
|
cft_check_handle->suppress_messages = 0;
|
||||||
|
|
||||||
|
if (config_def_check(cmd, cft_check_handle)) {
|
||||||
log_print("LVM configuration valid.");
|
log_print("LVM configuration valid.");
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
} else {
|
} else {
|
||||||
@ -72,7 +96,15 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
return EINVALID_CMD_LINE;
|
return EINVALID_CMD_LINE;
|
||||||
}
|
}
|
||||||
tree_spec.type = CFG_DEF_TREE_CURRENT;
|
tree_spec.type = CFG_DEF_TREE_CURRENT;
|
||||||
config_def_check(cmd, 1, 1, 1);
|
|
||||||
|
if (!(cft_check_handle = _get_cft_check_handle(cmd)))
|
||||||
|
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, "default"))
|
else if (!strcmp(type, "default"))
|
||||||
|
Reference in New Issue
Block a user