--- libmultipath/dict.c | 16 +++++------ libmultipath/parser.c | 69 +++++++++++++++++++++++++++++++++++++++++++++----- libmultipath/parser.h | 9 ++++-- 3 files changed, 77 insertions(+), 17 deletions(-) Index: multipath-tools/libmultipath/dict.c =================================================================== --- multipath-tools.orig/libmultipath/dict.c +++ multipath-tools/libmultipath/dict.c @@ -2218,17 +2218,17 @@ init_keywords(void) __deprecated install_keyword("default_path_checker", &def_path_checker_handler, NULL); install_keyword_root("blacklist", &blacklist_handler); - install_keyword("devnode", &ble_devnode_handler, &snprint_ble_simple); - install_keyword("wwid", &ble_wwid_handler, &snprint_ble_simple); - install_keyword("device", &ble_device_handler, NULL); + install_keyword_multi("devnode", &ble_devnode_handler, &snprint_ble_simple); + install_keyword_multi("wwid", &ble_wwid_handler, &snprint_ble_simple); + install_keyword_multi("device", &ble_device_handler, NULL); install_sublevel(); install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor); install_keyword("product", &ble_product_handler, &snprint_bled_product); install_sublevel_end(); install_keyword_root("blacklist_exceptions", &blacklist_exceptions_handler); - install_keyword("devnode", &ble_except_devnode_handler, &snprint_ble_simple); - install_keyword("wwid", &ble_except_wwid_handler, &snprint_ble_simple); - install_keyword("device", &ble_except_device_handler, NULL); + install_keyword_multi("devnode", &ble_except_devnode_handler, &snprint_ble_simple); + install_keyword_multi("wwid", &ble_except_wwid_handler, &snprint_ble_simple); + install_keyword_multi("device", &ble_except_device_handler, NULL); install_sublevel(); install_keyword("vendor", &ble_except_vendor_handler, &snprint_bled_vendor); install_keyword("product", &ble_except_product_handler, &snprint_bled_product); @@ -2246,7 +2246,7 @@ init_keywords(void) #endif install_keyword_root("devices", &devices_handler); - install_keyword("device", &device_handler, NULL); + install_keyword_multi("device", &device_handler, NULL); install_sublevel(); install_keyword("vendor", &vendor_handler, &snprint_hw_vendor); install_keyword("product", &product_handler, &snprint_hw_product); @@ -2271,7 +2271,7 @@ init_keywords(void) install_sublevel_end(); install_keyword_root("multipaths", &multipaths_handler); - install_keyword("multipath", &multipath_handler, NULL); + install_keyword_multi("multipath", &multipath_handler, NULL); install_sublevel(); install_keyword("wwid", &wwid_handler, &snprint_mp_wwid); install_keyword("alias", &alias_handler, &snprint_mp_alias); Index: multipath-tools/libmultipath/parser.c =================================================================== --- multipath-tools.orig/libmultipath/parser.c +++ multipath-tools/libmultipath/parser.c @@ -21,11 +21,13 @@ #include "parser.h" #include "memory.h" +#include "debug.h" /* local vars */ static int sublevel = 0; vector keywords = NULL; vector *keywords_addr = NULL; +static int line_nr; void set_current_keywords (vector *k) { @@ -35,7 +37,7 @@ void set_current_keywords (vector *k) int keyword_alloc(vector keywords, char *string, int (*handler) (vector), - int (*print) (char *, int, void *)) + int (*print) (char *, int, void *), int unique) { struct keyword *keyword; @@ -51,6 +53,7 @@ keyword_alloc(vector keywords, char *str keyword->string = string; keyword->handler = handler; keyword->print = print; + keyword->unique = unique; vector_set_slot(keywords, keyword); @@ -60,7 +63,7 @@ keyword_alloc(vector keywords, char *str int install_keyword_root(char *string, int (*handler) (vector)) { - int r = keyword_alloc(keywords, string, handler, NULL); + int r = keyword_alloc(keywords, string, handler, NULL, 1); if (!r) *keywords_addr = keywords; return r; @@ -79,8 +82,8 @@ install_sublevel_end(void) } int -install_keyword(char *string, int (*handler) (vector), - int (*print) (char *, int, void *)) +_install_keyword(char *string, int (*handler) (vector), + int (*print) (char *, int, void *), int unique) { int i = 0; struct keyword *keyword; @@ -101,7 +104,7 @@ install_keyword(char *string, int (*hand return 1; /* add new sub keyword */ - return keyword_alloc(keyword->sub, string, handler, print); + return keyword_alloc(keyword->sub, string, handler, print, unique); } void @@ -419,6 +422,39 @@ set_value(vector strvec) /* non-recursive configuration stream handler */ static int kw_level = 0; + +int warn_on_duplicates(vector uniques, char *str) +{ + char *tmp; + int i; + + vector_foreach_slot(uniques, tmp, i) { + if (!strcmp(str, tmp)) { + condlog(1, "multipath.conf line %d, duplicate keyword: %s", line_nr, str); + return 0; + } + } + tmp = strdup(str); + if (!tmp) + return 1; + if (!vector_alloc_slot(uniques)) { + free(tmp); + return 1; + } + vector_set_slot(uniques, tmp); + return 0; +} + +void free_uniques(vector uniques) +{ + char *tmp; + int i; + + vector_foreach_slot(uniques, tmp, i) + free(tmp); + vector_free(uniques); +} + int process_stream(vector keywords) { @@ -428,13 +464,21 @@ process_stream(vector keywords) char *str; char *buf; vector strvec; + vector uniques; + + uniques = vector_alloc(); + if (!uniques) + return 1; buf = MALLOC(MAXBUF); - if (!buf) + if (!buf) { + vector_free(uniques); return 1; + } while (read_line(buf, MAXBUF)) { + line_nr++; strvec = alloc_strvec(buf); memset(buf,0, MAXBUF); @@ -452,6 +496,12 @@ process_stream(vector keywords) keyword = VECTOR_SLOT(keywords, i); if (!strcmp(keyword->string, str)) { + if (keyword->unique && + warn_on_duplicates(uniques, str)) { + r = 1; + free_strvec(strvec); + goto out; + } if (keyword->handler) r += (*keyword->handler) (strvec); @@ -463,11 +513,17 @@ process_stream(vector keywords) break; } } + if (i >= VECTOR_SIZE(keywords)) + condlog(1, + "multipath.conf line %d, invalid keyword: %s", + line_nr, str); free_strvec(strvec); } +out: FREE(buf); + free_uniques(uniques); return r; } @@ -496,6 +552,7 @@ init_data(char *conf_file, void (*init_k */ /* Stream handling */ + line_nr = 0; r = process_stream(keywords); fclose(stream); //free_keywords(keywords); Index: multipath-tools/libmultipath/parser.h =================================================================== --- multipath-tools.orig/libmultipath/parser.h +++ multipath-tools/libmultipath/parser.h @@ -44,6 +44,7 @@ struct keyword { int (*handler) (vector); int (*print) (char *, int, void *); vector sub; + int unique; }; /* global var exported */ @@ -60,12 +61,14 @@ FILE *stream; /* Prototypes */ extern int keyword_alloc(vector keywords, char *string, int (*handler) (vector), - int (*print) (char *, int, void *)); + int (*print) (char *, int, void *), int unique); extern int install_keyword_root(char *string, int (*handler) (vector)); extern void install_sublevel(void); extern void install_sublevel_end(void); -extern int install_keyword(char *string, int (*handler) (vector), - int (*print) (char *, int, void *)); +extern int _install_keyword(char *string, int (*handler) (vector), + int (*print) (char *, int, void *), int unique); +#define install_keyword(str, vec, pri) _install_keyword(str, vec, pri, 1) +#define install_keyword_multi(str, vec, pri) _install_keyword(str, vec, pri, 0) extern void dump_keywords(vector keydump, int level); extern void free_keywords(vector keywords); extern vector alloc_strvec(char *string);