Fix for bz #560892.
authorBenjamin Marzinski <bmarzins@sourceware.org>
Thu, 2 Sep 2010 07:59:26 +0000 (09:59 +0200)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 2 Sep 2010 07:59:26 +0000 (09:59 +0200)
multipath now prints some warnings if it notices problems
with /etc/multipath.conf.

libmultipath/dict.c
libmultipath/parser.c
libmultipath/parser.h

index 62f0f21..964df9e 100644 (file)
@@ -2189,17 +2189,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);
@@ -2217,7 +2217,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);
@@ -2243,7 +2243,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 eb3815e..b964ce7 100644 (file)
 
 #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 *string, int (*handler) (vector),
        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 *string, int (*handler) (vector),
 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 (*handler) (vector),
                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,16 @@ process_stream(vector keywords)
                                break;
                        }
                }
+               if (i >= VECTOR_SIZE(keywords))
+                       condlog(1, "multipath.conf +%d, invalid keyword: %s",
+                               line_nr, str);
 
                free_strvec(strvec);
        }
 
+out:
        FREE(buf);
+       free_uniques(uniques);
        return r;
 }
 
@@ -496,6 +551,7 @@ init_data(char *conf_file, void (*init_keywords) (void))
 */
 
        /* Stream handling */
+       line_nr = 0;
        r = process_stream(keywords);
        fclose(stream);
        //free_keywords(keywords);
index 95d4e6f..fb182ec 100644 (file)
@@ -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);