diff --git a/WHATS_NEW b/WHATS_NEW index b57a1c3c1..51249ed71 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.107 - ================================== + Add dumpconfig --type profilable-{metadata,command} to select profile type. Exit immediately with error if command profile is found invalid. Separate --profile cmd line arg into --commandprofile and --metadataprofile. Strictly separate command profiles and per-VG/LV profiles referenced in mda. diff --git a/lib/config/config.c b/lib/config/config.c index 4fbee665e..ecb674e5f 100644 --- a/lib/config/config.c +++ b/lib/config/config.c @@ -1622,6 +1622,7 @@ static struct dm_config_node *_add_def_node(struct dm_config_tree *cft, 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); + uint16_t flags; if ((def->parent != section_id) || (spec->ignoreadvanced && def->flags & CFG_ADVANCED) || @@ -1645,9 +1646,19 @@ static int _should_skip_def_node(struct config_def_tree_spec *spec, int section_ return 1; break; case CFG_DEF_TREE_PROFILABLE: + case CFG_DEF_TREE_PROFILABLE_CMD: + case CFG_DEF_TREE_PROFILABLE_MDA: if (!(def->flags & CFG_PROFILABLE) || (def->since_version > spec->version)) return 1; + flags = def->flags & ~CFG_PROFILABLE; + if (spec->type == CFG_DEF_TREE_PROFILABLE_CMD) { + if (flags & CFG_PROFILABLE_METADATA) + return 1; + } else if (spec->type == CFG_DEF_TREE_PROFILABLE_MDA) { + if (!(flags & CFG_PROFILABLE_METADATA)) + return 1; + } break; default: if (def->since_version > spec->version) diff --git a/lib/config/config.h b/lib/config/config.h index 0618045b5..7b1d5b6d8 100644 --- a/lib/config/config.h +++ b/lib/config/config.h @@ -129,6 +129,8 @@ typedef enum { CFG_DEF_TREE_DEFAULT, /* tree of all possible config nodes with default values */ CFG_DEF_TREE_NEW, /* tree of all new nodes that appeared in given version */ CFG_DEF_TREE_PROFILABLE, /* tree of all nodes that are customizable by profiles */ + CFG_DEF_TREE_PROFILABLE_CMD, /* tree of all nodes that are customizable by command profiles (subset of PROFILABLE) */ + CFG_DEF_TREE_PROFILABLE_MDA, /* tree of all nodes that are customizable by metadata profiles (subset of PROFILABLE) */ CFG_DEF_TREE_DIFF, /* tree of all nodes that differ from defaults */ } cfg_def_tree_t; diff --git a/tools/commands.h b/tools/commands.h index 6ed4f8ddb..50db8eb59 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -59,18 +59,22 @@ xx(dumpconfig, "dumpconfig\n" "\t[--commandprofile ProfileName]\n" "\t[-f|--file filename] \n" - "\t[--type {current|default|diff|missing|new|profilable} \n" + "\t[--type {current|default|diff|missing|new|profilable|profilable-command|profilable-metadata} \n" "\t[--atversion version]] \n" "\t[--ignoreadvanced] \n" "\t[--ignoreunsupported] \n" + "\t[--config ConfigurationString] \n" + "\t[--commandprofile ProfileName] \n" + "\t[--profile ProfileName] \n" + "\t[--metadataprofile ProfileName] \n" "\t[--mergedconfig] \n" "\t[--validate]\n" "\t[--withcomments] \n" "\t[--withversions] \n" "\t[ConfigurationNode...]\n", atversion_ARG, configtype_ARG, file_ARG, ignoreadvanced_ARG, - ignoreunsupported_ARG, mergedconfig_ARG, validate_ARG, - withcomments_ARG, withversions_ARG) + ignoreunsupported_ARG, mergedconfig_ARG, metadataprofile_ARG, + validate_ARG, withcomments_ARG, withversions_ARG) xx(formats, "List available metadata formats", diff --git a/tools/dumpconfig.c b/tools/dumpconfig.c index 141a03041..09f2119e5 100644 --- a/tools/dumpconfig.c +++ b/tools/dumpconfig.c @@ -92,6 +92,7 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) struct config_def_tree_spec tree_spec = {0}; struct dm_config_tree *cft = NULL; struct cft_check_handle *cft_check_handle = NULL; + struct profile *profile = NULL; int r = ECMD_PROCESSED; tree_spec.cmd = cmd; @@ -131,6 +132,18 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) if (!_get_vsn(cmd, &tree_spec.version)) return EINVALID_CMD_LINE; + /* + * The profile specified by --profile cmd arg is like --commandprofile, + * but it is used just for dumping the profile content and not for + * application. + */ + if (arg_count(cmd, profile_ARG) && + (!(profile = add_profile(cmd, arg_str_value(cmd, profile_ARG, NULL), CONFIG_PROFILE_COMMAND)) || + !override_config_tree_from_profile(cmd, profile))) { + log_error("Failed to load profile %s.", arg_str_value(cmd, profile_ARG, NULL)); + return ECMD_FAILED; + } + /* * Set the 'cft' to work with based on whether we need the plain * config tree or merged config tree cascade if --mergedconfig is used. @@ -188,9 +201,18 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) tree_spec.type = CFG_DEF_TREE_PROFILABLE; /* profilable type does not require check status */ } + else if (!strcmp(type, "profilable-command")) { + tree_spec.type = CFG_DEF_TREE_PROFILABLE_CMD; + /* profilable-command type does not require check status */ + } + else if (!strcmp(type, "profilable-metadata")) { + tree_spec.type = CFG_DEF_TREE_PROFILABLE_MDA; + /* profilable-metadata type does not require check status */ + } else { log_error("Incorrect type of configuration specified. " - "Expected one of: current, default, missing, new, profilable."); + "Expected one of: current, default, missing, new, " + "profilable, profilable-command, profilable-metadata."); r = EINVALID_CMD_LINE; goto out; } @@ -218,6 +240,8 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) out: if (cft && (cft != cmd->cft)) dm_pool_destroy(cft->mem); + else if (profile) + remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND); /* * The cmd->cft (the "current" tree) is destroyed