libmultipath: implement and use blacklist merging
authorMartin Wilck <mwilck@suse.com>
Fri, 8 Jun 2018 10:20:39 +0000 (12:20 +0200)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 21 Jun 2018 07:50:00 +0000 (09:50 +0200)
Implement removal of invalid and duplicate entries in blacklists.

With this fix, we can fully enable the config dump/reload test,
which doesn't fail any more.

Signed-off-by: Martin Wilck <mwilck@suse.com>
libmultipath/blacklist.c
libmultipath/blacklist.h
libmultipath/config.c
tests/hwtable.c

index 91ed7dd..361c603 100644 (file)
@@ -416,6 +416,15 @@ filter_property(struct config * conf, struct udev_device * udev)
        return MATCH_PROPERTY_BLIST_MISSING;
 }
 
+static void free_ble(struct blentry *ble)
+{
+       if (!ble)
+               return;
+       regfree(&ble->regex);
+       FREE(ble->str);
+       FREE(ble);
+}
+
 void
 free_blacklist (vector blist)
 {
@@ -426,15 +435,45 @@ free_blacklist (vector blist)
                return;
 
        vector_foreach_slot (blist, ble, i) {
-               if (ble) {
-                       regfree(&ble->regex);
-                       FREE(ble->str);
-                       FREE(ble);
-               }
+               free_ble(ble);
        }
        vector_free(blist);
 }
 
+void merge_blacklist(vector blist)
+{
+       struct blentry *bl1, *bl2;
+       int i, j;
+
+       vector_foreach_slot(blist, bl1, i) {
+               j = i + 1;
+               vector_foreach_slot_after(blist, bl2, j) {
+                       if (!bl1->str || !bl2->str || strcmp(bl1->str, bl2->str))
+                               continue;
+                       condlog(3, "%s: duplicate blist entry section for %s",
+                               __func__, bl1->str);
+                       free_ble(bl2);
+                       vector_del_slot(blist, j);
+                       j--;
+               }
+       }
+}
+
+static void free_ble_device(struct blentry_device *ble)
+{
+       if (ble) {
+               if (ble->vendor) {
+                       regfree(&ble->vendor_reg);
+                       FREE(ble->vendor);
+               }
+               if (ble->product) {
+                       regfree(&ble->product_reg);
+                       FREE(ble->product);
+               }
+               FREE(ble);
+       }
+}
+
 void
 free_blacklist_device (vector blist)
 {
@@ -445,17 +484,42 @@ free_blacklist_device (vector blist)
                return;
 
        vector_foreach_slot (blist, ble, i) {
-               if (ble) {
-                       if (ble->vendor) {
-                               regfree(&ble->vendor_reg);
-                               FREE(ble->vendor);
-                       }
-                       if (ble->product) {
-                               regfree(&ble->product_reg);
-                               FREE(ble->product);
-                       }
-                       FREE(ble);
-               }
+               free_ble_device(ble);
        }
        vector_free(blist);
 }
+
+void merge_blacklist_device(vector blist)
+{
+       struct blentry_device *bl1, *bl2;
+       int i, j;
+
+       vector_foreach_slot(blist, bl1, i) {
+               if (!bl1->vendor && !bl1->product) {
+                       free_ble_device(bl1);
+                       vector_del_slot(blist, i);
+                       i--;
+               }
+       }
+
+       vector_foreach_slot(blist, bl1, i) {
+               j = i + 1;
+               vector_foreach_slot_after(blist, bl2, j) {
+                       if ((!bl1->vendor && bl2->vendor) ||
+                           (bl1->vendor && !bl2->vendor) ||
+                           (bl1->vendor && bl2->vendor &&
+                            strcmp(bl1->vendor, bl2->vendor)))
+                               continue;
+                       if ((!bl1->product && bl2->product) ||
+                           (bl1->product && !bl2->product) ||
+                           (bl1->product && bl2->product &&
+                            strcmp(bl1->product, bl2->product)))
+                               continue;
+                       condlog(3, "%s: duplicate blist entry section for %s:%s",
+                               __func__, bl1->vendor, bl1->product);
+                       free_ble_device(bl2);
+                       vector_del_slot(blist, j);
+                       j--;
+               }
+       }
+}
index 443025d..0b028d4 100644 (file)
@@ -40,5 +40,7 @@ int store_ble (vector, char *, int);
 int set_ble_device (vector, char *, char *, int);
 void free_blacklist (vector);
 void free_blacklist_device (vector);
+void merge_blacklist(vector);
+void merge_blacklist_device(vector);
 
 #endif /* _BLACKLIST_H */
index 55f48f1..a34a43c 100644 (file)
@@ -819,6 +819,15 @@ load_config (char * file)
        }
 
        merge_mptable(conf->mptable);
+       merge_blacklist(conf->blist_devnode);
+       merge_blacklist(conf->blist_property);
+       merge_blacklist(conf->blist_wwid);
+       merge_blacklist_device(conf->blist_device);
+       merge_blacklist(conf->elist_devnode);
+       merge_blacklist(conf->elist_property);
+       merge_blacklist(conf->elist_wwid);
+       merge_blacklist_device(conf->elist_device);
+
        if (conf->bindings_file == NULL)
                conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
 
index f6fba14..7daf71e 100644 (file)
@@ -499,13 +499,8 @@ static void replicate_config(const struct hwt_state *hwt, bool local)
        DUMP_CFG_STR(cfg2);
 #endif
 
-#if BROKEN
-       condlog(1, "%s: WARNING: skipping tests for same configuration after dump/reload on %d",
-               __func__, __LINE__);
-#else
        assert_int_equal(strlen(cfg2), strlen(cfg1));
        assert_string_equal(cfg2, cfg1);
-#endif
        free(cfg1);
        free(cfg2);
 }