Merging hwentries with identical vendor/product/revision is still useful,
although it's not strictly necessary any more. But such identical entries
should always be merged, not only if they appear in different configuration
files. This requires changing the logic of factorize_hwtable.

By setting -DCHECK_BUILTIN_HWTABLE at compile time, the built-in hwtable
can be checked against duplicates as well.

Signed-off-by: Martin Wilck <[email protected]>
---
 libmultipath/config.c | 43 +++++++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/libmultipath/config.c b/libmultipath/config.c
index 713ac7f3..fb41d620 100644
--- a/libmultipath/config.c
+++ b/libmultipath/config.c
@@ -452,7 +452,7 @@ out:
 }
 
 static void
-factorize_hwtable (vector hw, int n)
+factorize_hwtable (vector hw, int n, const char *table_desc)
 {
        struct hwentry *hwe1, *hwe2;
        int i, j;
@@ -462,22 +462,26 @@ restart:
                if (i == n)
                        break;
                j = n;
+               /* drop invalid device configs */
+               if (i >= n && (!hwe1->vendor || !hwe1->product)) {
+                       condlog(0, "device config in %s missing vendor or 
product parameter",
+                               table_desc);
+                       vector_del_slot(hw, i--);
+                       free_hwe(hwe1);
+                       continue;
+               }
+               j = n > i + 1 ? n : i + 1;
                vector_foreach_slot_after(hw, hwe2, j) {
-                       /* drop invalid device configs */
-                       if (!hwe2->vendor || !hwe2->product) {
-                               condlog(0, "device config missing vendor or 
product parameter");
-                               vector_del_slot(hw, j--);
-                               free_hwe(hwe2);
-                               continue;
-                       }
                        if (hwe_strmatch(hwe2, hwe1) == 0) {
-                               condlog(4, "%s: removing hwentry %s:%s:%s",
+                               condlog(i >= n ? 1 : 3,
+                                       "%s: duplicate device section for 
%s:%s:%s in %s",
                                        __func__, hwe1->vendor, hwe1->product,
-                                       hwe1->revision);
+                                       hwe1->revision, table_desc);
                                vector_del_slot(hw, i);
                                merge_hwe(hwe2, hwe1);
                                free_hwe(hwe1);
-                               n -= 1;
+                               if (i < n)
+                                       n -= 1;
                                /*
                                 * Play safe here; we have modified
                                 * the original vector so the outer
@@ -605,9 +609,8 @@ process_config_dir(struct config *conf, vector keywords, 
char *dir)
                snprintf(path, LINE_MAX, "%s/%s", dir, namelist[i]->d_name);
                path[LINE_MAX-1] = '\0';
                process_file(conf, path);
-               if (VECTOR_SIZE(conf->hwtable) > old_hwtable_size)
-                       factorize_hwtable(conf->hwtable, old_hwtable_size);
-
+               factorize_hwtable(conf->hwtable, old_hwtable_size,
+                                 namelist[i]->d_name);
        }
        pthread_cleanup_pop(1);
 }
@@ -655,6 +658,9 @@ load_config (char * file)
        if (setup_default_hwtable(conf->hwtable))
                goto out;
 
+#ifdef CHECK_BUILTIN_HWTABLE
+       factorize_hwtable(conf->hwtable, 0, "builtin");
+#endif
        /*
         * read the config file
         */
@@ -668,14 +674,7 @@ load_config (char * file)
                        condlog(0, "error parsing config file");
                        goto out;
                }
-               if (VECTOR_SIZE(conf->hwtable) > builtin_hwtable_size) {
-                       /*
-                        * remove duplica in hwtable. config file
-                        * takes precedence over build-in hwtable
-                        */
-                       factorize_hwtable(conf->hwtable, builtin_hwtable_size);
-               }
-
+               factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
        }
 
        conf->processed_main_config = 1;
-- 
2.17.0

--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to