diff options
author | Peter Rajnoha <prajnoha@redhat.com> | 2013-07-08 15:34:27 +0200 |
---|---|---|
committer | Peter Rajnoha <prajnoha@redhat.com> | 2013-07-08 16:05:56 +0200 |
commit | 5ed7d0cf1de4ebea6be8cb67759da40cb61c3913 (patch) | |
tree | 1955dd52d8023e577dc9acb46db02c9bf3c009f3 /tools/dumpconfig.c | |
parent | f1e289001286f978630f5e6423acca1af322ebd7 (diff) | |
download | lvm2-5ed7d0cf1de4ebea6be8cb67759da40cb61c3913.tar.gz |
dumpconfig: add --mergedconfig option
Normally, the lvm dumpconfig processes only the configuration tree
that is at the top of the cascade. Considering the cascade is:
CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_MERGED_FILES/CONFIG_FILE
...then:
(dumpconfig of lvm.conf only)
raw/~ $ lvm dumpconfig allocation
allocation {
maximise_cling=1
mirror_logs_require_separate_pvs=0
thin_pool_metadata_require_separate_pvs=0
thin_pool_chunk_size=64
}
(dumpconfig of selected profile configuration only)
raw/~ $ lvm dumpconfig --profile test allocation
allocation {
thin_pool_chunk_size=8
thin_pool_discards="passdown"
thin_pool_zero=1
}
(dumpconfig of given --config configuration only)
raw/~ $ lvm dumpconfig --config 'allocation{thin_pool_chunk_size=16}' allocation
allocation {
thin_pool_chunk_size=16
}
The --mergedconfig option causes the configuration cascade to be
merged before processing it with dumpconfig:
(dumpconfig of merged selected profile and lvm.conf)
raw/~ $ lvm dumpconfig --profile test allocation --mergedconfig
allocation {
maximise_cling=1
thin_pool_zero=1
thin_pool_discards="passdown"
mirror_logs_require_separate_pvs=0
thin_pool_metadata_require_separate_pvs=0
thin_pool_chunk_size=8
}
(dumpconfig merged given --config and selected profile and lvm.conf)
raw/~ $ lvm dumpconfig --profile test --config 'allocation{thin_pool_chunk_size=16}' allocation --mergedconfig
allocation {
maximise_cling=1
thin_pool_zero=1
thin_pool_discards="passdown"
mirror_logs_require_separate_pvs=0
thin_pool_metadata_require_separate_pvs=0
thin_pool_chunk_size=16
}
Hence with the --mergedconfig, we are able to see the
configuration that is actually used when processing any
LVM command while using any combination of --config/--profile
options together with lvm.conf file.
Diffstat (limited to 'tools/dumpconfig.c')
-rw-r--r-- | tools/dumpconfig.c | 87 |
1 files changed, 65 insertions, 22 deletions
diff --git a/tools/dumpconfig.c b/tools/dumpconfig.c index 3839defab..08f996a88 100644 --- a/tools/dumpconfig.c +++ b/tools/dumpconfig.c @@ -15,7 +15,7 @@ #include "tools.h" -static int _get_vsn(struct cmd_context *cmd, uint16_t *version) +static int _get_vsn(struct cmd_context *cmd, uint16_t *version_int) { const char *atversion = arg_str_value(cmd, atversion_ARG, LVM_VERSION); unsigned int major, minor, patchlevel; @@ -25,31 +25,42 @@ static int _get_vsn(struct cmd_context *cmd, uint16_t *version) return 0; } - *version = vsn(major, minor, patchlevel); + *version_int = vsn(major, minor, patchlevel); return 1; } -static struct cft_check_handle *_get_cft_check_handle(struct cmd_context *cmd) +static struct cft_check_handle *_get_cft_check_handle(struct cmd_context *cmd, struct dm_config_tree *cft) { - struct cft_check_handle *handle = cmd->cft_check_handle; + struct cft_check_handle *handle; + struct dm_pool *mem; + + if (cft == cmd->cft) { + mem = cmd->libmem; + handle = cmd->cft_check_handle; + } else { + mem = cft->mem; + handle = NULL; + } if (!handle) { - if (!(handle = dm_pool_zalloc(cmd->libmem, sizeof(*cmd->cft_check_handle)))) { + if (!(handle = dm_pool_zalloc(mem, sizeof(struct cft_check_handle)))) { log_error("Configuration check handle allocation failed."); return NULL; } - handle->cft = cmd->cft; - cmd->cft_check_handle = handle; + handle->cft = cft; + if (cft == cmd->cft) + cmd->cft_check_handle = handle; } return handle; } -static int _do_def_check(struct cmd_context *cmd, struct cft_check_handle **cft_check_handle) +static int _do_def_check(struct cmd_context *cmd, struct dm_config_tree *cft, + struct cft_check_handle **cft_check_handle) { struct cft_check_handle *handle; - if (!(handle = _get_cft_check_handle(cmd))) + if (!(handle = _get_cft_check_handle(cmd, cft))) return 0; handle->force_check = 1; @@ -62,6 +73,21 @@ static int _do_def_check(struct cmd_context *cmd, struct cft_check_handle **cft_ return 1; } +static int _merge_config_cascade(struct cmd_context *cmd, struct dm_config_tree *cft_cascaded, + struct dm_config_tree **cft_merged) +{ + if (!cft_cascaded) + return 1; + + if (!*cft_merged && !(*cft_merged = config_open(CONFIG_MERGED_FILES, NULL, 0))) + return_0; + + if (!_merge_config_cascade(cmd, cft_cascaded->cascade, cft_merged)) + return_0; + + return merge_config_tree(cmd, *cft_merged, cft_cascaded, CONFIG_MERGE_TYPE_RAW); +} + int dumpconfig(struct cmd_context *cmd, int argc, char **argv) { const char *file = arg_str_value(cmd, file_ARG, NULL); @@ -103,8 +129,21 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) if (!_get_vsn(cmd, &tree_spec.version)) return EINVALID_CMD_LINE; + /* + * Set the 'cft' to work with based on whether we need the plain + * config tree or merged config tree cascade if --mergedconfig is used. + */ + if (arg_count(cmd, mergedconfig_ARG) && cmd->cft->cascade) { + if (!_merge_config_cascade(cmd, cmd->cft, &cft)) { + log_error("Failed to merge configuration."); + r = ECMD_FAILED; + goto out; + } + } else + cft = cmd->cft; + if (arg_count(cmd, validate_ARG)) { - if (!(cft_check_handle = _get_cft_check_handle(cmd))) + if (!(cft_check_handle = _get_cft_check_handle(cmd, cft))) return ECMD_FAILED; cft_check_handle->force_check = 1; @@ -113,22 +152,27 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) if (config_def_check(cmd, cft_check_handle)) { log_print("LVM configuration valid."); - return ECMD_PROCESSED; + goto out; } else { log_error("LVM configuration invalid."); - return ECMD_FAILED; + r = ECMD_FAILED; + goto out; } } if (!strcmp(type, "current")) { tree_spec.type = CFG_DEF_TREE_CURRENT; - if (!_do_def_check(cmd, &cft_check_handle)) - return ECMD_FAILED; + if (!_do_def_check(cmd, cft, &cft_check_handle)) { + r = ECMD_FAILED; + goto_out; + } } else if (!strcmp(type, "missing")) { tree_spec.type = CFG_DEF_TREE_MISSING; - if (!_do_def_check(cmd, &cft_check_handle)) - return ECMD_FAILED; + if (!_do_def_check(cmd, cft, &cft_check_handle)) { + r = ECMD_FAILED; + goto_out; + } } else if (!strcmp(type, "default")) { tree_spec.type = CFG_DEF_TREE_DEFAULT; @@ -141,15 +185,14 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) else { log_error("Incorrect type of configuration specified. " "Expected one of: current, default, missing, new."); - return EINVALID_CMD_LINE; + r = EINVALID_CMD_LINE; + goto out; } if (cft_check_handle) tree_spec.check_status = cft_check_handle->status; - if (tree_spec.type == CFG_DEF_TREE_CURRENT) - cft = cmd->cft; - else + if (tree_spec.type != CFG_DEF_TREE_CURRENT) cft = config_def_create_tree(&tree_spec); if (!config_write(cft, arg_count(cmd, withcomments_ARG), @@ -158,8 +201,8 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) stack; r = ECMD_FAILED; } - - if (cft != cmd->cft) +out: + if (cft && (cft != cmd->cft)) dm_pool_destroy(cft->mem); /* |