libmultipath: use vector for for pp->hwe and mp->hwe
authorMartin Wilck <mwilck@suse.com>
Fri, 8 Jun 2018 10:20:25 +0000 (12:20 +0200)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 21 Jun 2018 07:49:07 +0000 (09:49 +0200)
Change the data structure of "struct path" and "struct multipath"
such that the "hwe" entry is a vector of hwentry structures rather
than a single hwentry structure. Add respective code to the
constructors and destructors (note that mp->hwe is never allocated,
it's always a pointer to a path hwe).

Change find_hwe() to fill in the passed vector rather than returning
a hwentry pointer. Change the propsel code to look through vectors
of hwentries to determine a given property.

This patch just creates the new data structure and the functions to
deal with them, it doesn't introduce semantic changes.

Signed-off-by: Martin Wilck <mwilck@suse.com>
libmultipath/config.c
libmultipath/config.h
libmultipath/discovery.c
libmultipath/propsel.c
libmultipath/structs.c
libmultipath/structs.h

index 7123da8..2a7fa1f 100644 (file)
@@ -113,27 +113,34 @@ static void _log_match(const char *fn, const struct hwentry *h,
 }
 #define log_match(h, v, p, r) _log_match(__func__, (h), (v), (p), (r))
 
-struct hwentry *
+int
 find_hwe (const struct _vector *hwtable,
-         const char * vendor, const char * product, const char * revision)
+         const char * vendor, const char * product, const char * revision,
+         vector result)
 {
-       int i;
-       struct hwentry *tmp, *ret = NULL;
+       int i, n = 0;
+       struct hwentry *tmp;
 
        /*
-        * Search backwards here.
+        * Search backwards here, and add forward.
         * User modified entries are attached at the end of
         * the list, so we have to check them first before
         * continuing to the generic entries
         */
+       vector_reset(result);
        vector_foreach_slot_backwards (hwtable, tmp, i) {
                if (hwe_regmatch(tmp, vendor, product, revision))
                        continue;
-               ret = tmp;
+               if (vector_alloc_slot(result) != NULL) {
+                       vector_set_slot(result, tmp);
+                       n++;
+               }
                log_match(tmp, vendor, product, revision);
                break;
        }
-       return ret;
+       condlog(n > 1 ? 3 : 4, "%s: found %d hwtable matches for %s:%s:%s",
+               __func__, n, vendor, product, revision);
+       return n;
 }
 
 struct mpentry *find_mpe(vector mptable, char *wwid)
index e10618a..8739bde 100644 (file)
@@ -217,9 +217,9 @@ struct config {
 
 extern struct udev * udev;
 
-struct hwentry * find_hwe (const struct _vector *hwtable,
-                          const char * vendor, const char * product,
-                          const char *revision);
+int find_hwe (const struct _vector *hwtable,
+             const char * vendor, const char * product, const char *revision,
+             vector result);
 struct mpentry * find_mpe (vector mptable, char * wwid);
 char * get_mpe_wwid (vector mptable, char * alias);
 
index 18ad0e2..573d98b 100644 (file)
@@ -1176,7 +1176,7 @@ scsi_sysfs_pathinfo (struct path * pp, vector hwtable)
        /*
         * set the hwe configlet pointer
         */
-       pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, pp->rev);
+       find_hwe(hwtable, pp->vendor_id, pp->product_id, pp->rev, pp->hwe);
 
        /*
         * host / bus / target / lun
@@ -1240,7 +1240,7 @@ nvme_sysfs_pathinfo (struct path * pp, vector hwtable)
        condlog(3, "%s: serial = %s", pp->dev, pp->serial);
        condlog(3, "%s: rev = %s", pp->dev, pp->rev);
 
-       pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL);
+       find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL, pp->hwe);
 
        return 0;
 }
@@ -1282,7 +1282,7 @@ ccw_sysfs_pathinfo (struct path * pp, vector hwtable)
        /*
         * set the hwe configlet pointer
         */
-       pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL);
+       find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL, pp->hwe);
 
        /*
         * host / bus / target / lun
@@ -1345,7 +1345,7 @@ cciss_sysfs_pathinfo (struct path * pp, vector hwtable)
        /*
         * set the hwe configlet pointer
         */
-       pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, pp->rev);
+       find_hwe(hwtable, pp->vendor_id, pp->product_id, pp->rev, pp->hwe);
 
        /*
         * host / bus / target / lun
index 62a6893..f0847db 100644 (file)
@@ -44,6 +44,23 @@ do {                                                                 \
        }                                                               \
 } while(0)
 
+#define do_set_from_vec(type, var, src, dest, msg)                     \
+do {                                                                   \
+       type *_p;                                                       \
+       int i;                                                          \
+                                                                       \
+       vector_foreach_slot(src, _p, i) {                               \
+               if (_p->var) {                                          \
+                       dest = _p->var;                                 \
+                       origin = msg;                                   \
+                       goto out;                                       \
+               }                                                       \
+       }                                                               \
+} while (0)
+
+#define do_set_from_hwe(var, src, dest, msg) \
+       do_set_from_vec(struct hwentry, var, src->hwe, dest, msg)
+
 static const char default_origin[] = "(setting: multipath internal)";
 static const char hwe_origin[] =
        "(setting: storage device configuration)";
@@ -67,7 +84,7 @@ do {                                                                  \
 #define mp_set_mpe(var)                                                        \
 do_set(var, mp->mpe, mp->var, multipaths_origin)
 #define mp_set_hwe(var)                                                        \
-do_set(var, mp->hwe, mp->var, hwe_origin)
+do_set_from_hwe(var, mp, mp->var, hwe_origin)
 #define mp_set_ovr(var)                                                        \
 do_set(var, conf->overrides, mp->var, overrides_origin)
 #define mp_set_conf(var)                                               \
@@ -78,7 +95,7 @@ do_default(mp->var, value)
 #define pp_set_mpe(var)                                                        \
 do_set(var, mpe, pp->var, multipaths_origin)
 #define pp_set_hwe(var)                                                        \
-do_set(var, pp->hwe, pp->var, hwe_origin)
+do_set_from_hwe(var, pp, pp->var, hwe_origin)
 #define pp_set_conf(var)                                               \
 do_set(var, conf, pp->var, conf_origin)
 #define pp_set_ovr(var)                                                        \
@@ -251,8 +268,8 @@ want_user_friendly_names(struct config *conf, struct multipath * mp)
               multipaths_origin);
        do_set(user_friendly_names, conf->overrides, user_friendly_names,
               overrides_origin);
-       do_set(user_friendly_names, mp->hwe, user_friendly_names,
-              hwe_origin);
+       do_set_from_hwe(user_friendly_names, mp, user_friendly_names,
+                       hwe_origin);
        do_set(user_friendly_names, conf, user_friendly_names,
               conf_origin);
        do_default(user_friendly_names, DEFAULT_USER_FRIENDLY_NAMES);
@@ -470,9 +487,9 @@ int select_checker(struct config *conf, struct path *pp)
                        checker_name = TUR;
                        goto out;
                }
-       }
+       }
        do_set(checker_name, conf->overrides, checker_name, overrides_origin);
-       do_set(checker_name, pp->hwe, checker_name, hwe_origin);
+       do_set_from_hwe(checker_name, pp, checker_name, hwe_origin);
        do_set(checker_name, conf, checker_name, conf_origin);
        do_default(checker_name, DEFAULT_CHECKER);
 out:
@@ -546,6 +563,25 @@ do {                                                                       \
        }                                                               \
 } while(0)
 
+#define set_prio_from_vec(type, dir, src, msg, p)                      \
+do {                                                                   \
+       type *_p;                                                       \
+       int i;                                                          \
+       char *prio_name = NULL, *prio_args = NULL;                      \
+                                                                       \
+       vector_foreach_slot(src, _p, i) {                               \
+               if (prio_name == NULL && _p->prio_name)         \
+                       prio_name = _p->prio_name;                      \
+               if (prio_args == NULL && _p->prio_args)         \
+                       prio_args = _p->prio_args;                      \
+       }                                                               \
+       if (prio_name != NULL) {                                        \
+               prio_get(dir, p, prio_name, prio_args);                 \
+               origin = msg;                                           \
+               goto out;                                               \
+       }                                                               \
+} while (0)
+
 int select_prio(struct config *conf, struct path *pp)
 {
        const char *origin;
@@ -562,7 +598,8 @@ int select_prio(struct config *conf, struct path *pp)
        mpe = find_mpe(conf->mptable, pp->wwid);
        set_prio(conf->multipath_dir, mpe, multipaths_origin);
        set_prio(conf->multipath_dir, conf->overrides, overrides_origin);
-       set_prio(conf->multipath_dir, pp->hwe, hwe_origin);
+       set_prio_from_vec(struct hwentry, conf->multipath_dir,
+                         pp->hwe, hwe_origin, p);
        set_prio(conf->multipath_dir, conf, conf_origin);
        prio_get(conf->multipath_dir, p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
        origin = default_origin;
@@ -615,7 +652,7 @@ select_minio_rq (struct config *conf, struct multipath * mp)
 
        do_set(minio_rq, mp->mpe, mp->minio, multipaths_origin);
        do_set(minio_rq, conf->overrides, mp->minio, overrides_origin);
-       do_set(minio_rq, mp->hwe, mp->minio, hwe_origin);
+       do_set_from_hwe(minio_rq, mp, mp->minio, hwe_origin);
        do_set(minio_rq, conf, mp->minio, conf_origin);
        do_default(mp->minio, DEFAULT_MINIO_RQ);
 out:
index 6df2f4e..ae847d6 100644 (file)
@@ -102,6 +102,11 @@ alloc_path (void)
                pp->priority = PRIO_UNDEF;
                checker_clear(&pp->checker);
                dm_path_to_gen(pp)->ops = &dm_gen_path_ops;
+               pp->hwe = vector_alloc();
+               if (pp->hwe == NULL) {
+                       free(pp);
+                       return NULL;
+               }
        }
        return pp;
 }
@@ -125,6 +130,7 @@ free_path (struct path * pp)
                udev_device_unref(pp->udev);
                pp->udev = NULL;
        }
+       vector_free(pp->hwe);
 
        FREE(pp);
 }
index e48ec24..ef57867 100644 (file)
@@ -289,7 +289,7 @@ struct path {
        int io_err_pathfail_starttime;
        int find_multipaths_timeout;
        /* configlet pointers */
-       struct hwentry * hwe;
+       vector hwe;
        struct gen_path generic_path;
 };
 
@@ -348,7 +348,7 @@ struct multipath {
        char * features;
        char * hwhandler;
        struct mpentry * mpe;
-       struct hwentry * hwe;
+       vector hwe;
 
        /* threads */
        pthread_t waiter;