master - commands: use dm_strncpy
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=582a272b3f401e...
Commit: 582a272b3f401e1bb6eafaa52d0ed1d318d04a9f
Parent: 80b717af0c1c0602537a6e4d5fad76e09733f028
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Feb 17 09:59:29 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Feb 17 13:11:33 2017 +0100
commands: use dm_strncpy
Easier code using dm_strncpy() an dm_snprintf().
---
tools/command.c | 13 ++++---------
1 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index f1b9d8e..e5a4640 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -330,13 +330,13 @@ static char *split_line(char *buf, int *argc, char **argv, char sep)
static int val_str_to_num(char *str)
{
- char name[32] = { 0 };
+ char name[32];
char *new;
int i;
/* compare the name before any suffix like _new or _<lvtype> */
- strncpy(name, str, 31);
+ dm_strncpy(name, str, sizeof(name));
if ((new = strstr(name, "_")))
*new = '\0';
@@ -757,12 +757,8 @@ static void append_oo_definition_line(struct command *cmd, const char *new_line)
cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
return;
}
- memset(line, 0, len);
-
- strcat(line, old_line);
- strcat(line, " ");
- strcat(line, new_line);
+ (void) dm_snprintf(line, len, "%s %s", old_line, new_line);
dm_free(oo->line);
oo->line = line;
}
@@ -778,8 +774,7 @@ static char *get_oo_line(const char *str)
char str2[OO_NAME_LEN];
int i;
- memset(str2, 0, sizeof(str2));
- strncpy(str2, str, OO_NAME_LEN-1);
+ dm_strncpy(str2, str, sizeof(str2));
if ((end = strstr(str2, ":")))
*end = '\0';
if ((end = strstr(str2, ",")))
7 years, 3 months
master - commands: cheap optimisation for parser
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=80b717af0c1c06...
Commit: 80b717af0c1c0602537a6e4d5fad76e09733f028
Parent: 298b11aed1f1517329dc6e5ead661855b1abfb05
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Feb 17 11:52:37 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Feb 17 13:00:05 2017 +0100
commands: cheap optimisation for parser
Some low-hanging fruits to cut of signification number of strcmp calls.
---
tools/command.c | 38 ++++++++++++++++++--------------------
1 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index 5b31b4e..f1b9d8e 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -495,31 +495,32 @@ static struct command_name *find_command_name(const char *name)
{
int i;
+ if (!islower(name[0]))
+ return NULL; /* Commands starts with lower-case */
+
for (i = 0; i < MAX_COMMAND_NAMES; i++) {
if (!command_names[i].name)
break;
if (!strcmp(command_names[i].name, name))
return &command_names[i];
}
+
return NULL;
}
static const char *is_command_name(char *str)
{
- int i;
+ const struct command_name *c;
+
+ if ((c = find_command_name(str)))
+ return c->name;
- for (i = 0; i < MAX_COMMAND_NAMES; i++) {
- if (!command_names[i].name)
- break;
- if (!strcmp(command_names[i].name, str))
- return command_names[i].name;
- }
return NULL;
}
static int is_opt_name(char *str)
{
- if (!strncmp(str, "--", 2))
+ if ((str[0] == '-') && (str[1] == '-'))
return 1;
if ((str[0] == '-') && (str[1] != '-'))
@@ -535,18 +536,15 @@ static int is_opt_name(char *str)
static int is_pos_name(char *str)
{
- if (!strncmp(str, "VG", 2))
- return 1;
- if (!strncmp(str, "LV", 2))
- return 1;
- if (!strncmp(str, "PV", 2))
- return 1;
- if (!strncmp(str, "Tag", 3))
- return 1;
- if (!strncmp(str, "String", 6))
- return 1;
- if (!strncmp(str, "Select", 6))
- return 1;
+ switch (str[0]) {
+ case 'V': return (str[1] == 'G'); /* VG */
+ case 'L': return (str[1] == 'V'); /* LV */
+ case 'P': return (str[1] == 'V'); /* PV */
+ case 'T': return (strncmp(str, "Tag", 3) == 0);
+ case 'S': return ((strncmp(str, "String", 6) == 0) ||
+ (strncmp(str, "Select", 6) == 0));
+ }
+
return 0;
}
7 years, 3 months
master - commands: track errors in command def parsing
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=298b11aed1f151...
Commit: 298b11aed1f1517329dc6e5ead661855b1abfb05
Parent: 1cb95fa5a050c5056d882ef9cbb01ce8040df019
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Feb 16 15:26:42 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 16 15:26:42 2017 -0600
commands: track errors in command def parsing
When parsing command defs, track and report all
errors that are found. Add an error return case
from define_commands so the standard error exit
path is used.
---
tools/command.c | 126 +++++++++++++++++++++++++++++++--------------------
tools/command.h | 1 +
tools/lvm2cmdline.h | 2 +-
tools/lvmcmdlib.c | 3 +-
tools/lvmcmdline.c | 22 +++++++--
5 files changed, 97 insertions(+), 57 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index 6814a54..5b31b4e 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -354,7 +354,7 @@ static int val_str_to_num(char *str)
#define MAX_LONG_OPT_NAME_LEN 32
-static int opt_str_to_num(char *str)
+static int opt_str_to_num(struct command *cmd, char *str)
{
char long_name[MAX_LONG_OPT_NAME_LEN];
char *p;
@@ -383,7 +383,8 @@ static int opt_str_to_num(char *str)
}
log_error("Parsing command defs: unknown opt str: %s %s", str, long_name);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return ARG_UNUSED;
}
for (i = 0; i < ARG_COUNT; i++) {
@@ -397,7 +398,8 @@ static int opt_str_to_num(char *str)
}
log_error("Parsing command defs: unknown opt str: \"%s\"", str);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return ARG_UNUSED;
}
/* "foo" string to foo_CMD int */
@@ -410,13 +412,13 @@ int command_id_to_enum(const char *str)
if (!strcmp(str, cmd_names[i].name))
return cmd_names[i].cmd_enum;
}
- log_error("Parsing command defs: unknown cmd name %s", str);
- exit(EXIT_FAILURE);
+
+ return CMD_NONE;
}
/* "lv_is_prop" to is_prop_LVP */
-static int lvp_name_to_enum(char *str)
+static int lvp_name_to_enum(struct command *cmd, char *str)
{
int i;
@@ -424,13 +426,15 @@ static int lvp_name_to_enum(char *str)
if (!strcmp(str, lvp_names[i].name))
return lvp_names[i].lvp_enum;
}
+
log_error("Parsing command defs: unknown lv property %s", str);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return LVP_NONE;
}
/* "type" to type_LVT */
-static int lvt_name_to_enum(char *str)
+static int lvt_name_to_enum(struct command *cmd, char *str)
{
int i;
@@ -438,15 +442,17 @@ static int lvt_name_to_enum(char *str)
if (!strcmp(str, lvt_names[i].name))
return lvt_names[i].lvt_enum;
}
+
log_error("Parsing command defs: unknown lv type %s", str);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return LVT_NONE;
}
/* LV_<type> to <type>_LVT */
-static int lv_to_enum(char *name)
+static int lv_to_enum(struct command *cmd, char *name)
{
- return lvt_name_to_enum(name + 3);
+ return lvt_name_to_enum(cmd, name + 3);
}
/*
@@ -460,7 +466,7 @@ static int lv_to_enum(char *name)
#define LVTYPE_LEN 64
-static uint64_t lv_to_bits(char *name)
+static uint64_t lv_to_bits(struct command *cmd, char *name)
{
char buf[LVTYPE_LEN];
char *argv[MAX_LINE_ARGC];
@@ -478,7 +484,7 @@ static uint64_t lv_to_bits(char *name)
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "new"))
continue;
- lvt_enum = lvt_name_to_enum(argv[i]);
+ lvt_enum = lvt_name_to_enum(cmd, argv[i]);
lvt_bits |= lvt_enum_to_bit(lvt_enum);
}
@@ -516,10 +522,8 @@ static int is_opt_name(char *str)
if (!strncmp(str, "--", 2))
return 1;
- if ((str[0] == '-') && (str[1] != '-')) {
+ if ((str[0] == '-') && (str[1] != '-'))
log_error("Parsing command defs: options must be specified in long form: %s", str);
- exit(EXIT_FAILURE);
- }
return 0;
}
@@ -625,13 +629,14 @@ static void set_pos_def(struct command *cmd, char *str, struct arg_def *def)
if (!val_enum) {
log_error("Parsing command defs: unknown pos arg: %s", name);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
def->val_bits |= val_enum_to_bit(val_enum);
if ((val_enum == lv_VAL) && strstr(name, "_"))
- def->lvt_bits = lv_to_bits(name);
+ def->lvt_bits = lv_to_bits(cmd, name);
if (strstr(name, "_new")) {
if (val_enum == lv_VAL)
@@ -673,7 +678,8 @@ static void set_opt_def(struct command *cmd, char *str, struct arg_def *def)
else {
log_error("Parsing command defs: unknown opt arg: %s", name);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
}
@@ -688,7 +694,7 @@ static void set_opt_def(struct command *cmd, char *str, struct arg_def *def)
if (val_enum == lv_VAL) {
if (strstr(name, "_"))
- def->lvt_bits = lv_to_bits(name);
+ def->lvt_bits = lv_to_bits(cmd, name);
}
if (strstr(name, "_new")) {
@@ -711,7 +717,7 @@ static void set_opt_def(struct command *cmd, char *str, struct arg_def *def)
* oo->line = "--opt1 ...";
*/
-static void add_oo_definition_line(const char *name, const char *line)
+static void add_oo_definition_line(struct command *cmd, const char *name, const char *line)
{
struct oo_line *oo;
char *colon;
@@ -724,7 +730,8 @@ static void add_oo_definition_line(const char *name, const char *line)
*colon = '\0';
else {
log_error("Parsing command defs: invalid OO definition");
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
start = strstr(line, ":") + 2;
@@ -733,7 +740,7 @@ static void add_oo_definition_line(const char *name, const char *line)
/* Support OO_FOO: continuing on multiple lines. */
-static void append_oo_definition_line(const char *new_line)
+static void append_oo_definition_line(struct command *cmd, const char *new_line)
{
struct oo_line *oo;
char *old_line;
@@ -749,7 +756,8 @@ static void append_oo_definition_line(const char *new_line)
line = dm_malloc(len);
if (!line) {
log_error("Parsing command defs: no memory");
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
memset(line, 0, len);
@@ -801,11 +809,14 @@ static void include_optional_opt_args(struct command *cmd, const char *str)
if (!(oo_line = get_oo_line(str))) {
log_error("Parsing command defs: no OO line found for %s", str);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
- if (!(line = dm_strdup(oo_line)))
- exit(EXIT_FAILURE);
+ if (!(line = dm_strdup(oo_line))) {
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
+ }
split_line(line, &line_argc, line_argv, ' ');
add_optional_opt_line(cmd, line_argc, line_argv);
@@ -838,7 +849,7 @@ static void add_opt_arg(struct command *cmd, char *str, int *takes_arg, int requ
goto skip;
}
- opt = opt_str_to_num(str);
+ opt = opt_str_to_num(cmd, str);
skip:
if (required > 0)
cmd->required_opt_args[cmd->ro_count++].opt = opt;
@@ -846,8 +857,6 @@ skip:
cmd->optional_opt_args[cmd->oo_count++].opt = opt;
else if (required < 0)
cmd->ignore_opt_args[cmd->io_count++].opt = opt;
- else
- exit(EXIT_FAILURE);
*takes_arg = opt_names[opt].val_enum ? 1 : 0;
}
@@ -864,7 +873,8 @@ static void update_prev_opt_arg(struct command *cmd, char *str, int required)
if (str[0] == '-') {
log_error("Parsing command defs: option %s must be followed by an arg.", str);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
/* opt_arg.def set here */
@@ -882,7 +892,7 @@ static void update_prev_opt_arg(struct command *cmd, char *str, int required)
else if (required < 0)
cmd->ignore_opt_args[cmd->io_count-1].def = def;
else
- exit(EXIT_FAILURE);
+ return;
}
/*
@@ -926,7 +936,8 @@ static void update_prev_pos_arg(struct command *cmd, char *str, int required)
def->flags |= ARG_DEF_FLAG_MAY_REPEAT;
else {
log_error("Parsing command defs: unknown pos arg: %s", str);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
}
@@ -949,7 +960,8 @@ static void add_optional_opt_line(struct command *cmd, int argc, char *argv[])
else {
log_error("Parsing command defs: can't parse argc %d argv %s prev %s",
i, argv[i], argv[i-1]);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
}
}
@@ -971,7 +983,8 @@ static void add_ignore_opt_line(struct command *cmd, int argc, char *argv[])
else {
log_error("Parsing command defs: can't parse argc %d argv %s prev %s",
i, argv[i], argv[i-1]);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
}
}
@@ -1005,7 +1018,8 @@ static void add_required_opt_line(struct command *cmd, int argc, char *argv[])
else {
log_error("Parsing command defs: can't parse argc %d argv %s prev %s",
i, argv[i], argv[i-1]);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
}
}
@@ -1028,11 +1042,14 @@ static void include_required_opt_args(struct command *cmd, char *str)
if (!(oo_line = get_oo_line(str))) {
log_error("Parsing command defs: no OO line found for %s", str);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
- if (!(line = dm_strdup(oo_line)))
- exit(EXIT_FAILURE);
+ if (!(line = dm_strdup(oo_line))) {
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
+ }
split_line(line, &line_argc, line_argv, ' ');
add_required_opt_line(cmd, line_argc, line_argv);
@@ -1080,9 +1097,9 @@ static void add_required_line(struct command *cmd, int argc, char *argv[])
} else {
log_error("Parsing command defs: can't parse argc %d argv %s prev %s",
i, argv[i], argv[i-1]);
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
-
}
}
@@ -1105,7 +1122,8 @@ static void add_rule(struct command *cmd, char *line)
if (cmd->rule_count == CMD_MAX_RULES) {
log_error("Parsing command defs: too many rules for cmd");
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
rule = &cmd->rules[cmd->rule_count++];
@@ -1134,7 +1152,8 @@ static void add_rule(struct command *cmd, char *line)
if (!rule->opts) {
if (!(rule->opts = dm_malloc(MAX_RULE_OPTS * sizeof(int)))) {
log_error("Parsing command defs: no mem");
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
memset(rule->opts, 0, MAX_RULE_OPTS * sizeof(int));
}
@@ -1142,19 +1161,20 @@ static void add_rule(struct command *cmd, char *line)
if (!rule->check_opts) {
if (!(rule->check_opts = dm_malloc(MAX_RULE_OPTS * sizeof(int)))) {
log_error("Parsing command defs: no mem");
- exit(EXIT_FAILURE);
+ cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR;
+ return;
}
memset(rule->check_opts, 0, MAX_RULE_OPTS * sizeof(int));
}
if (check)
- rule->check_opts[rule->check_opts_count++] = opt_str_to_num(arg);
+ rule->check_opts[rule->check_opts_count++] = opt_str_to_num(cmd, arg);
else
- rule->opts[rule->opts_count++] = opt_str_to_num(arg);
+ rule->opts[rule->opts_count++] = opt_str_to_num(cmd, arg);
}
else if (!strncmp(arg, "LV_", 3)) {
- lvt_enum = lv_to_enum(arg);
+ lvt_enum = lv_to_enum(cmd, arg);
if (check)
rule->check_lvt_bits |= lvt_enum_to_bit(lvt_enum);
@@ -1163,7 +1183,7 @@ static void add_rule(struct command *cmd, char *line)
}
else if (!strncmp(arg, "lv_is_", 6)) {
- lvp_enum = lvp_name_to_enum(arg);
+ lvp_enum = lvp_name_to_enum(cmd, arg);
if (check)
rule->check_lvp_bits |= lvp_enum_to_bit(lvp_enum);
@@ -1315,6 +1335,7 @@ int define_commands(char *run_name)
int prev_was_op = 0;
int copy_pos = 0;
int skip = 0;
+ int i;
if (run_name && !strcmp(run_name, "help"))
run_name = NULL;
@@ -1408,7 +1429,7 @@ int define_commands(char *run_name)
/* OO_FOO: ... */
if (is_oo_definition(line_argv[0])) {
- add_oo_definition_line(line_argv[0], line_orig);
+ add_oo_definition_line(cmd, line_argv[0], line_orig);
prev_was_oo_def = 1;
prev_was_oo = 0;
prev_was_op = 0;
@@ -1444,7 +1465,7 @@ int define_commands(char *run_name)
/* handle OO_FOO:, OO:, OP: continuing on multiple lines */
if (prev_was_oo_def) {
- append_oo_definition_line(line_orig);
+ append_oo_definition_line(cmd, line_orig);
continue;
}
@@ -1459,6 +1480,11 @@ int define_commands(char *run_name)
}
}
+ for (i = 0; i < COMMAND_COUNT; i++) {
+ if (commands[i].cmd_flags & CMD_FLAG_PARSE_ERROR)
+ return 0;
+ }
+
/*
* For usage.
* Predefined string of options common to all commands
diff --git a/tools/command.h b/tools/command.h
index 0c3f9f3..fcf0ccb 100644
--- a/tools/command.h
+++ b/tools/command.h
@@ -166,6 +166,7 @@ struct cmd_rule {
*/
#define CMD_FLAG_ONE_REQUIRED_OPT 1 /* lvchange/vgchage require one item from required_opt_args */
#define CMD_FLAG_SECONDARY_SYNTAX 2 /* allows syntax variants to be suppressed in certain output */
+#define CMD_FLAG_PARSE_ERROR 4 /* error parsing command-lines.in def */
/* a register of the lvm commands */
struct command {
diff --git a/tools/lvm2cmdline.h b/tools/lvm2cmdline.h
index 00162a4..5c5eaee 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);
-void lvm_register_commands(char *name);
+int lvm_register_commands(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 9e50343..8f15c1f 100644
--- a/tools/lvmcmdlib.c
+++ b/tools/lvmcmdlib.c
@@ -34,7 +34,8 @@ void *cmdlib_lvm2_init(unsigned static_compile)
if (!(cmd = init_lvm(1, 1)))
return NULL;
- lvm_register_commands(NULL);
+ if (!lvm_register_commands(NULL))
+ return NULL;
return (void *) cmd;
}
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index e599ded..7e50d05 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1126,13 +1126,13 @@ static struct command_function *_find_command_id_function(int command_enum)
return NULL;
}
-void lvm_register_commands(char *name)
+int lvm_register_commands(char *name)
{
int i;
/* already initialized */
if (_cmdline.commands)
- return;
+ return 1;
memset(&commands, 0, sizeof(commands));
@@ -1141,8 +1141,8 @@ void lvm_register_commands(char *name)
* by parsing command-lines.in/command-lines-input.h
*/
if (!define_commands(name)) {
- log_error("Failed to parse command definitions.");
- return;
+ log_error(INTERNAL_ERROR "Failed to parse command definitions.");
+ return 0;
}
_cmdline.commands = commands;
@@ -1151,6 +1151,13 @@ void lvm_register_commands(char *name)
for (i = 0; i < COMMAND_COUNT; i++) {
commands[i].command_enum = command_id_to_enum(commands[i].command_id);
+ if (!commands[i].command_enum) {
+ log_error(INTERNAL_ERROR "Failed to find command id %s.", commands[i].command_id);
+ _cmdline.commands = NULL;
+ _cmdline.num_commands = 0;
+ return 0;
+ }
+
/* new style */
commands[i].functions = _find_command_id_function(commands[i].command_enum);
@@ -1172,6 +1179,8 @@ void lvm_register_commands(char *name)
for (i = 0; i < _cmdline.num_command_names; i++)
_set_valid_args_for_command_name(i);
+
+ return 1;
}
struct lv_props *get_lv_prop(int lvp_enum)
@@ -3214,7 +3223,10 @@ int lvm2_main(int argc, char **argv)
else
name = argv[1];
- lvm_register_commands(name);
+ if (!lvm_register_commands(name)) {
+ ret = ECMD_FAILED;
+ goto out;
+ }
if (_lvm1_fallback(cmd)) {
/* Attempt to run equivalent LVM1 tool instead */
7 years, 3 months
master - commands: initialize commands[] once
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1cb95fa5a050c5...
Commit: 1cb95fa5a050c5056d882ef9cbb01ce8040df019
Parent: 15f51bc42113494bfb49fbc0d6a1913f68fb80a8
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Feb 16 13:59:52 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 16 13:59:52 2017 -0600
commands: initialize commands[] once
When using liblvm2cmd, a process can do multiple
init/exit calls, i.e.
lvm2_init(); lvm2_run(); lvm2_exit();
lvm2_init(); lvm2_run(); lvm2_exit();
...
define_commands() needs to set up the global commands[]
definitions only the first time.
---
tools/lvmcmdline.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index ed32f1c..e599ded 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1130,6 +1130,10 @@ void lvm_register_commands(char *name)
{
int i;
+ /* already initialized */
+ if (_cmdline.commands)
+ return;
+
memset(&commands, 0, sizeof(commands));
/*
7 years, 3 months
master - commands: avoid factoring options until needed
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=15f51bc4211349...
Commit: 15f51bc42113494bfb49fbc0d6a1913f68fb80a8
Parent: 22bee4fbdbf3cf52ac6a390b3c1ae983b5350760
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Feb 16 09:36:55 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 16 09:37:28 2017 -0600
commands: avoid factoring options until needed
---
tools/command.c | 21 +++++++++++++--------
1 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index 9f2256b..6814a54 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -1197,6 +1197,10 @@ static void factor_common_options(void)
if (!command_names[cn].name)
break;
+ /* already factored */
+ if (command_names[cn].variants)
+ continue;
+
for (ci = 0; ci < COMMAND_COUNT; ci++) {
cmd = &commands[ci];
@@ -1457,17 +1461,10 @@ int define_commands(char *run_name)
/*
* For usage.
- * Looks at all variants of each command name and figures out
- * which options are common to all variants (for compact output)
- */
- factor_common_options();
-
- /*
- * For usage.
* Predefined string of options common to all commands
* (for compact output)
*/
- include_optional_opt_args(&lvm_all, "OO_USAGE_COMMON");
+ include_optional_opt_args(&lvm_all, "OO_USAGE_COMMON");
return 1;
}
@@ -1564,6 +1561,12 @@ void print_usage(struct command *cmd)
int onereq = (cmd->cmd_flags & CMD_FLAG_ONE_REQUIRED_OPT) ? 1 : 0;
int ro, rp, oo, op, opt_enum, first;
+ /*
+ * Looks at all variants of each command name and figures out
+ * which options are common to all variants (for compact output)
+ */
+ factor_common_options();
+
if (cmd->desc)
_print_usage_description(cmd);
@@ -2717,6 +2720,8 @@ int main(int argc, char *argv[])
define_commands(NULL);
+ factor_common_options();
+
print_man(argv[1], (argc > 2) ? argv[2] : NULL, 1, 1);
return 0;
7 years, 3 months
master - help/man: remove commas from list of options
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=22bee4fbdbf3cf...
Commit: 22bee4fbdbf3cf52ac6a390b3c1ae983b5350760
Parent: 81c0ed9fc6d598ef221e2089e1fd125990a7a626
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 15 14:00:09 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 15 15:51:46 2017 -0600
help/man: remove commas from list of options
Using commas between options does not seem to
be done anywhere else, so remove them.
---
tools/command.c | 13 ++++---------
1 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index ac72c49..9f2256b 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -1624,7 +1624,7 @@ void print_usage(struct command *cmd)
if (first)
printf("\n\t[");
else
- printf(",\n\t ");
+ printf("\n\t ");
first = 0;
printf(" %s", opt_names[opt_enum].long_opt);
@@ -1637,7 +1637,7 @@ void print_usage(struct command *cmd)
if (first)
printf("\n\t[");
else
- printf(",\n\t ");
+ printf("\n\t ");
printf(" COMMON_OPTIONS ]");
}
@@ -1687,7 +1687,7 @@ void print_usage_common(struct command_name *cname, struct command *cmd)
if (first)
printf("\n\t[");
else
- printf(",\n\t ");
+ printf("\n\t ");
first = 0;
for (oo = 0; oo < cmd->oo_count; oo++) {
@@ -1712,7 +1712,7 @@ void print_usage_common(struct command_name *cname, struct command *cmd)
if (first)
printf("\n\t[");
else
- printf(",\n\t ");
+ printf("\n\t ");
first = 0;
printf(" %s", opt_names[opt_enum].long_opt);
@@ -2081,7 +2081,6 @@ void print_man_usage(char *lvmname, struct command *cmd)
continue;
if (sep) {
- printf(",");
printf("\n.br\n");
printf(" ");
}
@@ -2112,7 +2111,6 @@ void print_man_usage(char *lvmname, struct command *cmd)
continue;
if (sep) {
- printf(",");
printf("\n.br\n");
printf(" ");
}
@@ -2130,7 +2128,6 @@ void print_man_usage(char *lvmname, struct command *cmd)
}
if (sep) {
- printf(",");
printf("\n.br\n");
printf(" ");
/* space alignment without short opt */
@@ -2209,7 +2206,6 @@ void print_man_usage_common(struct command *cmd)
continue;
if (sep) {
- printf(",");
printf("\n.br\n");
printf(" ");
}
@@ -2246,7 +2242,6 @@ void print_man_usage_common(struct command *cmd)
continue;
if (sep) {
- printf(",");
printf("\n.br\n");
printf(" ");
}
7 years, 3 months
master - commands: use dm wrappers for malloc/free
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=81c0ed9fc6d598...
Commit: 81c0ed9fc6d598ef221e2089e1fd125990a7a626
Parent: 6a5c9ba34902193ac9d03fe30976d259391905b3
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 15 15:49:18 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 15 15:49:18 2017 -0600
commands: use dm wrappers for malloc/free
---
tools/command.c | 38 +++++++++++++++++++++-----------------
1 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index aa33d5c..ac72c49 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -45,6 +45,10 @@ do { \
printf(fmt "\n", ##args); \
} while (0)
+#define dm_malloc malloc
+#define dm_free free
+#define dm_strdup strdup
+
/* needed to include args.h */
#define ARG_COUNTABLE 0x00000001
#define ARG_GROUPABLE 0x00000002
@@ -680,7 +684,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 = strdup(name);
+ def->str = dm_strdup(name);
if (val_enum == lv_VAL) {
if (strstr(name, "_"))
@@ -714,7 +718,7 @@ static void add_oo_definition_line(const char *name, const char *line)
char *start;
oo = &oo_lines[oo_line_count++];
- oo->name = strdup(name);
+ oo->name = dm_strdup(name);
if ((colon = strstr(oo->name, ":")))
*colon = '\0';
@@ -724,7 +728,7 @@ static void add_oo_definition_line(const char *name, const char *line)
}
start = strstr(line, ":") + 2;
- oo->line = strdup(start);
+ oo->line = dm_strdup(start);
}
/* Support OO_FOO: continuing on multiple lines. */
@@ -742,7 +746,7 @@ static void append_oo_definition_line(const char *new_line)
/* +2 = 1 space between old and new + 1 terminating \0 */
len = strlen(old_line) + strlen(new_line) + 2;
- line = malloc(len);
+ line = dm_malloc(len);
if (!line) {
log_error("Parsing command defs: no memory");
exit(EXIT_FAILURE);
@@ -753,7 +757,7 @@ static void append_oo_definition_line(const char *new_line)
strcat(line, " ");
strcat(line, new_line);
- free(oo->line);
+ dm_free(oo->line);
oo->line = line;
}
@@ -800,12 +804,12 @@ static void include_optional_opt_args(struct command *cmd, const char *str)
exit(EXIT_FAILURE);
}
- if (!(line = strdup(oo_line)))
+ if (!(line = dm_strdup(oo_line)))
exit(EXIT_FAILURE);
split_line(line, &line_argc, line_argv, ' ');
add_optional_opt_line(cmd, line_argc, line_argv);
- free(line);
+ dm_free(line);
}
/*
@@ -1027,12 +1031,12 @@ static void include_required_opt_args(struct command *cmd, char *str)
exit(EXIT_FAILURE);
}
- if (!(line = strdup(oo_line)))
+ if (!(line = dm_strdup(oo_line)))
exit(EXIT_FAILURE);
split_line(line, &line_argc, line_argv, ' ');
add_required_opt_line(cmd, line_argc, line_argv);
- free(line);
+ dm_free(line);
}
/* Process what follows command_name, which are required opt/pos args. */
@@ -1128,7 +1132,7 @@ static void add_rule(struct command *cmd, char *line)
else if (!strncmp(arg, "--", 2)) {
if (!rule->opts) {
- if (!(rule->opts = malloc(MAX_RULE_OPTS * sizeof(int)))) {
+ if (!(rule->opts = dm_malloc(MAX_RULE_OPTS * sizeof(int)))) {
log_error("Parsing command defs: no mem");
exit(EXIT_FAILURE);
}
@@ -1136,7 +1140,7 @@ static void add_rule(struct command *cmd, char *line)
}
if (!rule->check_opts) {
- if (!(rule->check_opts = malloc(MAX_RULE_OPTS * sizeof(int)))) {
+ if (!(rule->check_opts = dm_malloc(MAX_RULE_OPTS * sizeof(int)))) {
log_error("Parsing command defs: no mem");
exit(EXIT_FAILURE);
}
@@ -1343,7 +1347,7 @@ int define_commands(char *run_name)
cmd = &commands[cmd_count];
cmd->command_index = cmd_count;
cmd_count++;
- cmd->name = strdup(name);
+ cmd->name = dm_strdup(name);
if (run_name && strcmp(run_name, name)) {
skip = 1;
@@ -1368,15 +1372,15 @@ int define_commands(char *run_name)
*/
if (is_desc_line(line_argv[0]) && !skip) {
- char *desc = strdup(line_orig);
+ char *desc = dm_strdup(line_orig);
if (cmd->desc) {
int newlen = strlen(cmd->desc) + strlen(desc) + 2;
- char *newdesc = malloc(newlen);
+ char *newdesc = dm_malloc(newlen);
if (newdesc) {
memset(newdesc, 0, newlen);
snprintf(newdesc, newlen, "%s %s", cmd->desc, desc);
cmd->desc = newdesc;
- free(desc);
+ dm_free(desc);
}
} else
cmd->desc = desc;
@@ -1394,7 +1398,7 @@ int define_commands(char *run_name)
}
if (is_id_line(line_argv[0])) {
- cmd->command_id = strdup(line_argv[1]);
+ cmd->command_id = dm_strdup(line_argv[1]);
continue;
}
@@ -1757,7 +1761,7 @@ static void print_val_man(const char *str)
if (strstr(str, "|")) {
int len = strlen(str);
- line = strdup(str);
+ line = dm_strdup(str);
split_line(line, &line_argc, line_argv, '|');
for (i = 0; i < line_argc; i++) {
if (i) {
7 years, 3 months
master - commands: use existing vg/lv name parsing functions
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6a5c9ba3490219...
Commit: 6a5c9ba34902193ac9d03fe30976d259391905b3
Parent: 2556498ee191cc9eaa505c611c5570937ff32315
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 15 15:06:52 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 15 15:28:54 2017 -0600
commands: use existing vg/lv name parsing functions
inside the new lv arg parsing function.
This includes getting the VG name from the env var,
and some added checks on the format of the vg/lv string.
---
tools/toollib.c | 45 +++++++++++++++++++++++++++++----------------
1 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 6e0a4f1..842f67c 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3362,10 +3362,10 @@ static int _get_arg_lvnames(struct cmd_context *cmd,
* came up with its own inconsistent approach.
*
* In this case, when the position arg is a single name, it is treated as an LV
- * name (not a VG name). This leaves the VG unknown. So, other option values
- * must be searched for a VG name. If one of those option values contains a
- * vgname/lvname value, then the VG name is extracted and used for the LV
- * position arg.
+ * name (not a VG name). This leaves the VG unknown. So, other option values,
+ * or env var, must be searched for a VG name. If one of the option values
+ * contains a vgname/lvname value, then the VG name is extracted and used for
+ * the LV position arg. Or, if the env var has the VG name, that is used.
*
* Other option values that are searched for a VG name are:
* --thinpool, --cachepool.
@@ -3375,21 +3375,21 @@ static int _get_arg_lvnames(struct cmd_context *cmd,
* . add vg/lv1 to arg_lvnames
*
* command lv1
- * . error: no vg name
+ * . error: no vg name (unless LVM_VG_NAME)
*
- * command --option vg/lv1 vg/lv2
+ * command --option=vg/lv1 vg/lv2
* . verify both vg names match
* . add vg to arg_vgnames
* . add vg/lv2 to arg_lvnames
*
- * command --option lv1 lv2
- * . error: no vg name
+ * command --option=lv1 lv2
+ * . error: no vg name (unless LVM_VG_NAME)
*
- * command --option vg/lv1 lv2
+ * command --option=vg/lv1 lv2
* . add vg to arg_vgnames
* . add vg/lv2 to arg_lvnames
*
- * command --option lv1 vg/lv2
+ * command --option=lv1 vg/lv2
* . add vg to arg_vgnames
* . add vg/lv2 to arg_lvnames
*/
@@ -3405,6 +3405,7 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
const char *pos_vgname = NULL;
const char *opt_vgname = NULL;
const char *pos_lvname = NULL;
+ const char *env_vgname = NULL;
const char *use_vgname = NULL;
char *tmp_name;
char *split;
@@ -3440,9 +3441,12 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
}
if ((split = strchr(pos_name, '/'))) {
- pos_vgname = pos_name;
- pos_lvname = split + 1;
- *split = '\0';
+ /*
+ * This splits pos_name 'x/y' into pos_vgname 'x' and pos_lvname 'y'
+ * It skips repeated '/', e.g. x//y
+ * It also checks and fails for extra '/', e.g. x/y/z
+ */
+ pos_vgname = _extract_vgname(cmd, pos_name, &pos_lvname);
} else {
pos_lvname = pos_name;
pos_vgname = NULL;
@@ -3453,7 +3457,9 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
else if (arg_is_set(cmd, cachepool_ARG))
arg_name = arg_str_value(cmd, cachepool_ARG, NULL);
- if (!pos_vgname && !arg_name) {
+ env_vgname = _default_vgname(cmd);
+
+ if (!pos_vgname && !arg_name && !env_vgname) {
log_error("Cannot find VG name for LV %s.", pos_lvname);
return ECMD_FAILED;
}
@@ -3479,7 +3485,7 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
opt_vgname = NULL;
}
- if (!pos_vgname && !opt_vgname) {
+ if (!pos_vgname && !opt_vgname && !env_vgname) {
log_error("Cannot find VG name for LV %s.", pos_lvname);
return ECMD_FAILED;
}
@@ -3490,7 +3496,14 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
return ECMD_FAILED;
}
- use_vgname = pos_vgname ? pos_vgname : opt_vgname;
+ if (pos_vgname)
+ use_vgname = pos_vgname;
+ else if (opt_vgname)
+ use_vgname = opt_vgname;
+ else if (env_vgname)
+ use_vgname = env_vgname;
+ else
+ return_ECMD_FAILED;
if (!str_list_add(cmd->mem, arg_vgnames, dm_pool_strdup(cmd->mem, use_vgname))) {
log_error("strlist allocation failed.");
7 years, 3 months
master - lvcreate: fix LVM_VG_NAME detection
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2556498ee191cc...
Commit: 2556498ee191cc9eaa505c611c5570937ff32315
Parent: 4a30f5f9b0a3677af6f32260ee84ec5c2a6c8393
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 15 14:09:45 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 15 14:10:46 2017 -0600
lvcreate: fix LVM_VG_NAME detection
Commit d3af0e7528dbba30824379fc98cb4db437559ad5 was
not quite right in testing if the env var was set.
---
tools/lvmcmdline.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 41ae8c4..ed32f1c 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1280,7 +1280,6 @@ check_val:
static int _command_required_pos_matches(struct cmd_context *cmd, int ci, int rp, char **argv)
{
const char *name;
- char *gotenv = NULL;
/*
* rp is the index in required_pos_args[] of the required positional arg.
@@ -1315,9 +1314,9 @@ static int _command_required_pos_matches(struct cmd_context *cmd, int ci, int rp
(arg_is_set(cmd, name_ARG) ||
arg_is_set(cmd, thinpool_ARG) ||
arg_is_set(cmd, cachepool_ARG) ||
- (gotenv = getenv("LVM_VG_NAME")))) {
+ getenv("LVM_VG_NAME"))) {
- if (gotenv)
+ if (getenv("LVM_VG_NAME"))
return 1;
if ((name = arg_str_value(cmd, name_ARG, NULL))) {
7 years, 3 months
master - toollib: skip dev prefix from lv names
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4a30f5f9b0a367...
Commit: 4a30f5f9b0a3677af6f32260ee84ec5c2a6c8393
Parent: 286d39ee3c4334e9ce0609d9136dfd6b5d6bf34a
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Feb 15 13:42:35 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Feb 15 13:42:35 2017 -0600
toollib: skip dev prefix from lv names
_get_arg_lvnames_using_options() was missing skip_dev_dir()
---
tools/toollib.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index a539878..6e0a4f1 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3434,6 +3434,11 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
return ECMD_PROCESSED;
}
+ if (*pos_name == '/') {
+ if (!(pos_name = skip_dev_dir(cmd, pos_name, NULL)))
+ return ECMD_FAILED;
+ }
+
if ((split = strchr(pos_name, '/'))) {
pos_vgname = pos_name;
pos_lvname = split + 1;
7 years, 3 months