Gitweb:
https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=15eaf703fcfc548ff68...
Commit: 15eaf703fcfc548ff687a07002f35b06f9fd8c7d
Parent: 54726a4950756b8f0c3e19c4c7d5feb6fb838e00
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Apr 28 16:27:19 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon May 1 15:27:14 2017 -0500
commands: fix memory debug for cmd defs
Clean up the handling of memory used for cmd defs
so it doesn't trip up memory debugging.
Allocate memory for commands[] from libmem.
Free temporary memory used by define_commands()
at the end of the function.
Clear all the command def state in in lvm_fin().
---
tools/command.c | 97 +++++++++++++++++++++++++++++++--------------------
tools/command.h | 2 +-
tools/lvm2cmdline.h | 2 +-
tools/lvmcmdlib.c | 2 +-
tools/lvmcmdline.c | 17 +++++++--
5 files changed, 76 insertions(+), 44 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index 816901b..347475b 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -40,14 +40,18 @@
*/
#ifdef MAN_PAGE_GENERATOR
+struct cmd_context {
+ void *libmem;
+};
+
#define log_error(fmt, args...) \
do { \
printf(fmt "\n", ##args); \
} while (0)
#define dm_malloc malloc
-#define dm_free free
#define dm_strdup strdup
+#define dm_free free
#define dm_snprintf snprintf
static int dm_strncpy(char *dest, const char *src, size_t n)
@@ -61,6 +65,16 @@ static int dm_strncpy(char *dest, const char *src, size_t n)
return 0;
}
+static char *dm_pool_strdup(void *p, const char *str)
+{
+ return strdup(str);
+}
+
+static void *dm_pool_alloc(void *p, size_t size)
+{
+ return malloc(size);
+}
+
/* needed to include args.h */
#define ARG_COUNTABLE 0x00000001
#define ARG_GROUPABLE 0x00000002
@@ -281,7 +295,7 @@ static struct oo_line oo_lines[MAX_OO_LINES];
*/
#include "command-lines-input.h"
-static void add_optional_opt_line(struct command *cmd, int argc, char *argv[]);
+static void add_optional_opt_line(struct cmd_context *cmdtool, struct command *cmd, int
argc, char *argv[]);
/*
* modifies buf, replacing the sep characters with \0
@@ -648,7 +662,7 @@ static void set_pos_def(struct command *cmd, char *str, struct arg_def
*def)
* Parse str for anything that can follow --option.
*/
-static void set_opt_def(struct command *cmd, char *str, struct arg_def *def)
+static void set_opt_def(struct cmd_context *cmdtool, struct command *cmd, char *str,
struct arg_def *def)
{
char *argv[MAX_LINE_ARGC];
int argc;
@@ -686,7 +700,7 @@ static void set_opt_def(struct command *cmd, char *str, struct arg_def
*def)
def->num = (uint64_t)atoi(name);
if (val_enum == conststr_VAL)
- def->str = dm_strdup(name);
+ def->str = dm_pool_strdup(cmdtool->libmem, name);
if (val_enum == lv_VAL) {
if (strchr(name, '_'))
@@ -789,7 +803,7 @@ static char *get_oo_line(const char *str)
* i.e. include common options from an OO_FOO definition.
*/
-static void include_optional_opt_args(struct command *cmd, const char *str)
+static void include_optional_opt_args(struct cmd_context *cmdtool, struct command *cmd,
const char *str)
{
char *oo_line;
char *line;
@@ -808,7 +822,7 @@ static void include_optional_opt_args(struct command *cmd, const char
*str)
}
split_line(line, &line_argc, line_argv, ' ');
- add_optional_opt_line(cmd, line_argc, line_argv);
+ add_optional_opt_line(cmdtool, cmd, line_argc, line_argv);
dm_free(line);
}
@@ -873,7 +887,7 @@ skip:
* for the value that appears after --option.
*/
-static void update_prev_opt_arg(struct command *cmd, char *str, int required)
+static void update_prev_opt_arg(struct cmd_context *cmdtool, struct command *cmd, char
*str, int required)
{
struct arg_def def = { 0 };
char *comma;
@@ -890,7 +904,7 @@ static void update_prev_opt_arg(struct command *cmd, char *str, int
required)
if ((comma = strchr(str, ',')))
*comma = '\0';
- set_opt_def(cmd, str, &def);
+ set_opt_def(cmdtool, cmd, str, &def);
if (required > 0)
cmd->required_opt_args[cmd->ro_count-1].def = def;
@@ -948,7 +962,7 @@ static void update_prev_pos_arg(struct command *cmd, char *str, int
required)
/* Process what follows OO:, which are the optional opt args for the cmd def. */
-static void add_optional_opt_line(struct command *cmd, int argc, char *argv[])
+static void add_optional_opt_line(struct cmd_context *cmdtool, struct command *cmd, int
argc, char *argv[])
{
int takes_arg = 0;
int already;
@@ -963,9 +977,9 @@ static void add_optional_opt_line(struct command *cmd, int argc, char
*argv[])
if (is_opt_name(argv[i]))
add_opt_arg(cmd, argv[i], &takes_arg, &already, OPTIONAL);
else if (!strncmp(argv[i], "OO_", 3))
- include_optional_opt_args(cmd, argv[i]);
+ include_optional_opt_args(cmdtool, cmd, argv[i]);
else if (takes_arg)
- update_prev_opt_arg(cmd, argv[i], OPTIONAL);
+ update_prev_opt_arg(cmdtool, cmd, argv[i], OPTIONAL);
else {
log_error("Parsing command defs: can't parse argc %d argv %s prev %s.",
i, argv[i], argv[i-1]);
@@ -980,7 +994,7 @@ static void add_optional_opt_line(struct command *cmd, int argc, char
*argv[])
/* Process what follows IO:, which are the ignore options for the cmd def. */
-static void add_ignore_opt_line(struct command *cmd, int argc, char *argv[])
+static void add_ignore_opt_line(struct cmd_context *cmdtool, struct command *cmd, int
argc, char *argv[])
{
int takes_arg = 0;
int i;
@@ -991,7 +1005,7 @@ static void add_ignore_opt_line(struct command *cmd, int argc, char
*argv[])
if (is_opt_name(argv[i]))
add_opt_arg(cmd, argv[i], &takes_arg, NULL, IGNORE);
else if (takes_arg)
- update_prev_opt_arg(cmd, argv[i], IGNORE);
+ update_prev_opt_arg(cmdtool, cmd, argv[i], IGNORE);
else {
log_error("Parsing command defs: can't parse argc %d argv %s prev %s.",
i, argv[i], argv[i-1]);
@@ -1017,7 +1031,7 @@ static void add_optional_pos_line(struct command *cmd, int argc,
char *argv[])
}
}
-static void add_required_opt_line(struct command *cmd, int argc, char *argv[])
+static void add_required_opt_line(struct cmd_context *cmdtool, struct command *cmd, int
argc, char *argv[])
{
int takes_arg = 0;
int i;
@@ -1026,7 +1040,7 @@ static void add_required_opt_line(struct command *cmd, int argc,
char *argv[])
if (is_opt_name(argv[i]))
add_opt_arg(cmd, argv[i], &takes_arg, NULL, REQUIRED);
else if (takes_arg)
- update_prev_opt_arg(cmd, argv[i], REQUIRED);
+ update_prev_opt_arg(cmdtool, cmd, argv[i], REQUIRED);
else {
log_error("Parsing command defs: can't parse argc %d argv %s prev %s.",
i, argv[i], argv[i-1]);
@@ -1045,7 +1059,7 @@ static void add_required_opt_line(struct command *cmd, int argc,
char *argv[])
* this special case.
*/
-static void include_required_opt_args(struct command *cmd, char *str)
+static void include_required_opt_args(struct cmd_context *cmdtool, struct command *cmd,
char *str)
{
char *oo_line;
char *line;
@@ -1064,13 +1078,13 @@ static void include_required_opt_args(struct command *cmd, char
*str)
}
split_line(line, &line_argc, line_argv, ' ');
- add_required_opt_line(cmd, line_argc, line_argv);
+ add_required_opt_line(cmdtool, cmd, line_argc, line_argv);
dm_free(line);
}
/* Process what follows command_name, which are required opt/pos args. */
-static void add_required_line(struct command *cmd, int argc, char *argv[])
+static void add_required_line(struct cmd_context *cmdtool, struct command *cmd, int argc,
char *argv[])
{
int i;
int takes_arg;
@@ -1088,7 +1102,7 @@ static void add_required_line(struct command *cmd, int argc, char
*argv[])
} else if (prev_was_opt && takes_arg) {
/* set value for previous required_opt_arg */
- update_prev_opt_arg(cmd, argv[i], REQUIRED);
+ update_prev_opt_arg(cmdtool, cmd, argv[i], REQUIRED);
prev_was_opt = 0;
prev_was_pos = 0;
@@ -1101,7 +1115,7 @@ static void add_required_line(struct command *cmd, int argc, char
*argv[])
} else if (!strncmp(argv[i], "OO_", 3)) {
/* one required_opt_arg is required, special case lv/vgchange */
cmd->cmd_flags |= CMD_FLAG_ONE_REQUIRED_OPT;
- include_required_opt_args(cmd, argv[i]);
+ include_required_opt_args(cmdtool, cmd, argv[i]);
} else if (prev_was_pos) {
/* set property for previous required_pos_arg */
@@ -1125,7 +1139,7 @@ static void add_flags(struct command *cmd, char *line)
#define MAX_RULE_OPTS 64
-static void add_rule(struct command *cmd, char *line)
+static void add_rule(struct cmd_context *cmdtool, struct command *cmd, char *line)
{
struct cmd_rule *rule;
char *line_argv[MAX_LINE_ARGC];
@@ -1164,7 +1178,7 @@ static void add_rule(struct command *cmd, char *line)
else if (!strncmp(arg, "--", 2)) {
if (!rule->opts) {
- if (!(rule->opts = dm_malloc(MAX_RULE_OPTS * sizeof(int)))) {
+ if (!(rule->opts = dm_pool_alloc(cmdtool->libmem, MAX_RULE_OPTS *
sizeof(int)))) {
log_error("Parsing command defs: no mem.");
cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
return;
@@ -1173,7 +1187,7 @@ static void add_rule(struct command *cmd, char *line)
}
if (!rule->check_opts) {
- if (!(rule->check_opts = dm_malloc(MAX_RULE_OPTS * sizeof(int)))) {
+ if (!(rule->check_opts = dm_pool_alloc(cmdtool->libmem, MAX_RULE_OPTS *
sizeof(int)))) {
log_error("Parsing command defs: no mem.");
cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
return;
@@ -1348,7 +1362,7 @@ static int copy_line(char *line, int max_line, int *position)
return 1;
}
-int define_commands(const char *run_name)
+int define_commands(struct cmd_context *cmdtool, const char *run_name)
{
struct command *cmd = NULL;
char line[MAX_LINE];
@@ -1400,7 +1414,7 @@ int define_commands(const char *run_name)
cmd = &commands[cmd_count];
cmd->command_index = cmd_count;
cmd_count++;
- cmd->name = dm_strdup(name);
+ cmd->name = dm_pool_strdup(cmdtool->libmem, name);
if (run_name && strcmp(run_name, name)) {
skip = 1;
@@ -1412,10 +1426,10 @@ int define_commands(const char *run_name)
skip = 0;
cmd->pos_count = 1;
- add_required_line(cmd, line_argc, line_argv);
+ add_required_line(cmdtool, cmd, line_argc, line_argv);
/* Every cmd gets the OO_ALL options */
- include_optional_opt_args(cmd, "OO_ALL:");
+ include_optional_opt_args(cmdtool, cmd, "OO_ALL:");
continue;
}
@@ -1425,15 +1439,13 @@ int define_commands(const char *run_name)
*/
if (is_desc_line(line_argv[0]) && !skip && cmd) {
- char *desc = dm_strdup(line_orig);
+ char *desc = dm_pool_strdup(cmdtool->libmem, line_orig);
if (cmd->desc) {
int newlen = strlen(cmd->desc) + strlen(desc) + 2;
- char *newdesc = dm_malloc(newlen);
+ char *newdesc = dm_pool_alloc(cmdtool->libmem, newlen);
if (newdesc) {
memset(newdesc, 0, newlen);
snprintf(newdesc, newlen, "%s %s", cmd->desc, desc);
- dm_free((char *)cmd->desc);
- dm_free(desc);
cmd->desc = newdesc;
}
} else
@@ -1447,12 +1459,12 @@ int define_commands(const char *run_name)
}
if (is_rule_line(line_argv[0]) && !skip && cmd) {
- add_rule(cmd, line_orig);
+ add_rule(cmdtool, cmd, line_orig);
continue;
}
if (is_id_line(line_argv[0]) && cmd) {
- cmd->command_id = dm_strdup(line_argv[1]);
+ cmd->command_id = dm_pool_strdup(cmdtool->libmem, line_argv[1]);
continue;
}
@@ -1467,7 +1479,7 @@ int define_commands(const char *run_name)
/* OO: ... */
if (is_oo_line(line_argv[0]) && !skip && cmd) {
- add_optional_opt_line(cmd, line_argc, line_argv);
+ add_optional_opt_line(cmdtool, cmd, line_argc, line_argv);
prev_was_oo_def = 0;
prev_was_oo = 1;
prev_was_op = 0;
@@ -1485,7 +1497,7 @@ int define_commands(const char *run_name)
/* IO: ... */
if (is_io_line(line_argv[0]) && !skip && cmd) {
- add_ignore_opt_line(cmd, line_argc, line_argv);
+ add_ignore_opt_line(cmdtool, cmd, line_argc, line_argv);
prev_was_oo = 0;
prev_was_op = 0;
continue;
@@ -1499,7 +1511,7 @@ int define_commands(const char *run_name)
}
if (prev_was_oo && cmd) {
- add_optional_opt_line(cmd, line_argc, line_argv);
+ add_optional_opt_line(cmdtool, cmd, line_argc, line_argv);
continue;
}
@@ -1517,7 +1529,15 @@ int define_commands(const char *run_name)
return 0;
}
- include_optional_opt_args(&lvm_all, "OO_ALL");
+ include_optional_opt_args(cmdtool, &lvm_all, "OO_ALL");
+
+ for (i = 0; i < oo_line_count; i++) {
+ struct oo_line *oo = &oo_lines[i];
+ dm_free(oo->name);
+ dm_free(oo->line);
+ }
+ memset(&oo_lines, 0, sizeof(oo_lines));
+ oo_line_count = 0;
return 1;
}
@@ -3422,6 +3442,7 @@ static void _print_man_secondary(char *name)
int main(int argc, char *argv[])
{
+ struct cmd_context cmdtool;
char *cmdname = NULL;
char *desfile = NULL;
char *stdout_buf;
@@ -3478,7 +3499,7 @@ int main(int argc, char *argv[])
if (optind < argc)
desfile = argv[optind++];
- define_commands(NULL);
+ define_commands(&cmdtool, NULL);
configure_command_option_values(cmdname);
diff --git a/tools/command.h b/tools/command.h
index 339863c..a84e374 100644
--- a/tools/command.h
+++ b/tools/command.h
@@ -255,7 +255,7 @@ struct lv_type {
};
-int define_commands(const char *run_name);
+int define_commands(struct cmd_context *cmdtool, const char *run_name);
int command_id_to_enum(const char *str);
void print_usage(struct command *cmd, int longhelp, int desc_first);
void print_usage_common_cmd(struct command_name *cname, struct command *cmd);
diff --git a/tools/lvm2cmdline.h b/tools/lvm2cmdline.h
index 48c2c37..0073f90 100644
--- a/tools/lvm2cmdline.h
+++ b/tools/lvm2cmdline.h
@@ -32,7 +32,7 @@ void *cmdlib_lvm2_init(unsigned static_compile);
void lvm_fin(struct cmd_context *cmd);
struct cmd_context *init_lvm(unsigned set_connections, unsigned set_filters);
-int lvm_register_commands(const char *name);
+int lvm_register_commands(struct cmd_context *cmdtool, const char *name);
int lvm_split(char *str, int *argc, char **argv, int max);
int lvm_run_command(struct cmd_context *cmd, int argc, char **argv);
int lvm_return_code(int ret);
diff --git a/tools/lvmcmdlib.c b/tools/lvmcmdlib.c
index 8f15c1f..5944576 100644
--- a/tools/lvmcmdlib.c
+++ b/tools/lvmcmdlib.c
@@ -34,7 +34,7 @@ void *cmdlib_lvm2_init(unsigned static_compile)
if (!(cmd = init_lvm(1, 1)))
return NULL;
- if (!lvm_register_commands(NULL))
+ if (!lvm_register_commands(cmd, NULL))
return NULL;
return (void *) cmd;
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 29ec06b..9e77d48 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1241,7 +1241,16 @@ static const struct command_function *_find_command_id_function(int
command_enum
return NULL;
}
-int lvm_register_commands(const char *run_name)
+static void _unregister_commands(void)
+{
+ _cmdline.commands = NULL;
+ _cmdline.num_commands = 0;
+ _cmdline.command_names = NULL;
+ _cmdline.num_command_names = 0;
+ memset(&commands, 0, sizeof(commands));
+}
+
+int lvm_register_commands(struct cmd_context *cmd, const char *run_name)
{
int i;
@@ -1255,7 +1264,7 @@ int lvm_register_commands(const char *run_name)
* populate commands[] array with command definitions
* by parsing command-lines.in/command-lines-input.h
*/
- if (!define_commands(run_name)) {
+ if (!define_commands(cmd, run_name)) {
log_error(INTERNAL_ERROR "Failed to parse command definitions.");
return 0;
}
@@ -1285,6 +1294,7 @@ int lvm_register_commands(const char *run_name)
}
_cmdline.command_names = command_names;
+ _cmdline.num_command_names = 0;
for (i = 0; i < MAX_COMMAND_NAMES; i++) {
if (!command_names[i].name)
@@ -3268,6 +3278,7 @@ struct cmd_context *init_lvm(unsigned set_connections, unsigned
set_filters)
void lvm_fin(struct cmd_context *cmd)
{
+ _unregister_commands();
destroy_toolcontext(cmd);
udev_fin_library_context();
}
@@ -3448,7 +3459,7 @@ int lvm2_main(int argc, char **argv)
if (run_name && !find_command_name(run_name))
run_name = NULL;
- if (!lvm_register_commands(run_name)) {
+ if (!lvm_register_commands(cmd, run_name)) {
ret = ECMD_FAILED;
goto out;
}