diff --git a/WHATS_NEW b/WHATS_NEW index b67dad9d7..fbfe4ac0d 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,7 @@ Version 2.02.18 - ==================================== + dumpconfig accepts a list of configuration variables to display. + Change dumpconfig to use --file to redirect output to a file. Avoid vgreduce error when mirror code removes the log LV. Remove 3 redundant AC_MSG_RESULTs from configure.in. Free memory in _raw_read_mda_header() error paths. diff --git a/lib/config/config.c b/lib/config/config.c index dd1513371..2efa9c679 100644 --- a/lib/config/config.c +++ b/lib/config/config.c @@ -373,7 +373,8 @@ static void _write_value(FILE *fp, struct config_value *v) } } -static int _write_config(struct config_node *n, FILE *fp, int level) +static int _write_config(struct config_node *n, int only_one, FILE *fp, + int level) { char space[MAX_INDENT + 1]; int l = (level < MAX_INDENT) ? level : MAX_INDENT; @@ -386,12 +387,12 @@ static int _write_config(struct config_node *n, FILE *fp, int level) space[i] = '\t'; space[i] = '\0'; - while (n) { + do { fprintf(fp, "%s%s", space, n->key); if (!n->v) { /* it's a sub section */ fprintf(fp, " {\n"); - _write_config(n->child, fp, level + 1); + _write_config(n->child, 0, fp, level + 1); fprintf(fp, "%s}", space); } else { /* it's a value */ @@ -411,13 +412,15 @@ static int _write_config(struct config_node *n, FILE *fp, int level) } fprintf(fp, "\n"); n = n->sib; - } + } while (n && !only_one); /* FIXME: add error checking */ return 1; } -int write_config_file(struct config_tree *cft, const char *file) +int write_config_file(struct config_tree *cft, const char *file, + int argc, char **argv) { + struct config_node *cn; int r = 1; FILE *fp; @@ -430,9 +433,22 @@ int write_config_file(struct config_tree *cft, const char *file) } log_verbose("Dumping configuration to %s", file); - if (!_write_config(cft->root, fp, 0)) { - log_error("Failure while writing configuration"); - r = 0; + if (!argc) { + if (!_write_config(cft->root, 0, fp, 0)) { + log_error("Failure while writing configuration"); + r = 0; + } + } else while (argc--) { + if ((cn = find_config_node(cft->root, *argv))) { + if (!_write_config(cn, 1, fp, 0)) { + log_error("Failure while writing configuration"); + r = 0; + } + } else { + log_error("Configuration node %s not found", *argv); + r = 0; + } + argv++; } if (fp != stdout) diff --git a/lib/config/config.h b/lib/config/config.h index 55b0907f6..f51190fff 100644 --- a/lib/config/config.h +++ b/lib/config/config.h @@ -65,7 +65,8 @@ int read_config_fd(struct config_tree *cft, struct device *dev, checksum_fn_t checksum_fn, uint32_t checksum); int read_config_file(struct config_tree *cft); -int write_config_file(struct config_tree *cft, const char *file); +int write_config_file(struct config_tree *cft, const char *file, + int argc, char **argv); time_t config_file_timestamp(struct config_tree *cft); int config_file_changed(struct config_tree *cft); int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft, diff --git a/tools/commands.h b/tools/commands.h index 0daa19f4c..26885b723 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -30,7 +30,10 @@ xx(e2fsadm, xx(dumpconfig, "Dump active configuration", - "dumpconfig \n") + "dumpconfig " + "\t[-f|--file filename] " "\n" + "[ConfigurationVariable...]\n", + file_ARG) xx(formats, "List available metadata formats", diff --git a/tools/dumpconfig.c b/tools/dumpconfig.c index fdf49cb2f..d5b7a78c3 100644 --- a/tools/dumpconfig.c +++ b/tools/dumpconfig.c @@ -19,15 +19,10 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv) { const char *file = NULL; - if (argc == 1) - file = argv[0]; + if (arg_count(cmd, file_ARG)) + file = arg_str_value(cmd, file_ARG, ""); - if (argc > 1) { - log_error("Please specify one file for output"); - return EINVALID_CMD_LINE; - } - - if (!write_config_file(cmd->cft, file)) + if (!write_config_file(cmd->cft, file, argc, argv)) return ECMD_FAILED; return ECMD_PROCESSED;