diff --git a/tools/command.c b/tools/command.c index f880508d7..7778620a7 100644 --- a/tools/command.c +++ b/tools/command.c @@ -1094,8 +1094,6 @@ static void _add_autotype(struct cmd_context *cmdtool, struct command *cmd, cmd->autotype = dm_pool_strdup(cmdtool->libmem, line_argv[1]); } -#define MAX_RULE_OPTS 64 - static void _add_rule(struct cmd_context *cmdtool, struct command *cmd, int line_argc, char *line_argv[]) { @@ -1105,7 +1103,7 @@ static void _add_rule(struct cmd_context *cmdtool, struct command *cmd, int check = 0; if (cmd->rule_count == CMD_MAX_RULES) { - log_error("Parsing command defs: too many rules for cmd."); + log_error("Parsing command defs: too many rules for cmd, increate CMD_MAX_RULES."); cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR; return; } @@ -1131,22 +1129,10 @@ static void _add_rule(struct cmd_context *cmdtool, struct command *cmd, } else if (!strncmp(arg, "--", 2)) { - if (!rule->opts) { - 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; - } - memset(rule->opts, 0, MAX_RULE_OPTS * sizeof(int)); - } - - if (!rule->check_opts) { - 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; - } - memset(rule->check_opts, 0, MAX_RULE_OPTS * sizeof(int)); + if (rule->opts_count >= MAX_RULE_OPTS || rule->check_opts_count >= MAX_RULE_OPTS) { + log_error("Parsing command defs: too many cmd_rule options for cmd, increase MAX_RULE_OPTS."); + cmd->cmd_flags |= CMD_FLAG_PARSE_ERROR; + return; } if (check) diff --git a/tools/command.h b/tools/command.h index b8df18bb7..f4222f214 100644 --- a/tools/command.h +++ b/tools/command.h @@ -131,16 +131,18 @@ struct pos_arg { #define RULE_INVALID 1 #define RULE_REQUIRE 2 +#define MAX_RULE_OPTS 8 struct cmd_rule { - int *opts; /* if any option in this list is set, the check may apply */ uint64_t lvt_bits; /* if LV has one of these types (lvt_enum_to_bit), the check may apply */ uint64_t lvp_bits; /* if LV has all of these properties (lvp_enum_to_bit), the check may apply */ - int *check_opts; /* used options must [not] be in this list */ uint64_t check_lvt_bits; /* LV must [not] have one of these type */ uint64_t check_lvp_bits; /* LV must [not] have all of these properties */ + uint16_t opts[MAX_RULE_OPTS]; /* if any option in this list is set, the check may apply */ + uint16_t check_opts[MAX_RULE_OPTS];/* used options must [not] be in this list */ + uint16_t rule; /* RULE_INVALID, RULE_REQUIRE: check values must [not] be true */ uint16_t opts_count; /* entries in opts[] */ uint16_t check_opts_count; /* entries in check_opts[] */ diff --git a/tools/toollib.c b/tools/toollib.c index 2be9b9ac1..36c307c84 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -2612,7 +2612,7 @@ static struct lv_segment _historical_lv_segment = { .origin_list = DM_LIST_HEAD_INIT(_historical_lv_segment.origin_list), }; -int opt_in_list_is_set(struct cmd_context *cmd, int *opts, int count, +int opt_in_list_is_set(struct cmd_context *cmd, const uint16_t *opts, int count, int *match_count, int *unmatch_count) { int match = 0; @@ -2634,7 +2634,7 @@ int opt_in_list_is_set(struct cmd_context *cmd, int *opts, int count, return match ? 1 : 0; } -void opt_array_to_str(struct cmd_context *cmd, int *opts, int count, +void opt_array_to_str(struct cmd_context *cmd, const uint16_t *opts, int count, char *buf, int len) { int pos = 0; @@ -3105,7 +3105,7 @@ static int _check_lv_rules(struct cmd_context *cmd, struct logical_volume *lv) * Check the options, LV types, LV properties. */ - if (rule->check_opts) + if (rule->check_opts_count) opt_in_list_is_set(cmd, rule->check_opts, rule->check_opts_count, &opts_match_count, &opts_unmatch_count); @@ -3127,7 +3127,7 @@ static int _check_lv_rules(struct cmd_context *cmd, struct logical_volume *lv) /* Fail if any invalid options are set. */ - if (rule->check_opts && (rule->rule == RULE_INVALID) && opts_match_count) { + if (rule->check_opts_count && (rule->rule == RULE_INVALID) && opts_match_count) { memset(buf, 0, sizeof(buf)); opt_array_to_str(cmd, rule->check_opts, rule->check_opts_count, buf, sizeof(buf)); log_warn("WARNING: Command on LV %s has invalid use of option %s.", @@ -3137,7 +3137,7 @@ static int _check_lv_rules(struct cmd_context *cmd, struct logical_volume *lv) /* Fail if any required options are not set. */ - if (rule->check_opts && (rule->rule == RULE_REQUIRE) && opts_unmatch_count) { + if (rule->check_opts_count && (rule->rule == RULE_REQUIRE) && opts_unmatch_count) { memset(buf, 0, sizeof(buf)); opt_array_to_str(cmd, rule->check_opts, rule->check_opts_count, buf, sizeof(buf)); log_warn("WARNING: Command on LV %s requires option %s.", diff --git a/tools/toollib.h b/tools/toollib.h index c1c7c35f1..2ab6ee05f 100644 --- a/tools/toollib.h +++ b/tools/toollib.h @@ -173,10 +173,10 @@ const char *extract_vgname(struct cmd_context *cmd, const char *lv_name); const char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name, unsigned *dev_dir_found); -int opt_in_list_is_set(struct cmd_context *cmd, int *opts, int count, +int opt_in_list_is_set(struct cmd_context *cmd, const uint16_t *opts, int count, int *match_count, int *unmatch_count); -void opt_array_to_str(struct cmd_context *cmd, int *opts, int count, +void opt_array_to_str(struct cmd_context *cmd, const uint16_t *opts, int count, char *buf, int len); int pvcreate_params_from_args(struct cmd_context *cmd, struct pvcreate_params *pp);