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 <mwi...@suse.com>
---
 libmultipath/config.c    | 21 ++++++++++------
 libmultipath/config.h    |  6 ++---
 libmultipath/discovery.c | 10 ++++----
 libmultipath/propsel.c   | 53 ++++++++++++++++++++++++++++++++++------
 libmultipath/structs.c   |  6 +++++
 libmultipath/structs.h   |  4 +--
 6 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/libmultipath/config.c b/libmultipath/config.c
index 9e2f166f..95a71447 100644
--- a/libmultipath/config.c
+++ b/libmultipath/config.c
@@ -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)
diff --git a/libmultipath/config.h b/libmultipath/config.h
index 83eaf62f..e1cbd59b 100644
--- a/libmultipath/config.h
+++ b/libmultipath/config.h
@@ -213,9 +213,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);
 
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 1ef1dfa7..b974d6cd 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -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;
 }
@@ -1256,7 +1256,7 @@ rbd_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);
        return 0;
 }
 
@@ -1297,7 +1297,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
@@ -1360,7 +1360,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
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
index 018f4879..d645507e 100644
--- a/libmultipath/propsel.c
+++ b/libmultipath/propsel.c
@@ -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)                                                        
\
@@ -250,8 +267,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);
@@ -471,9 +488,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:
@@ -547,6 +564,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;
@@ -563,7 +599,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;
@@ -616,7 +653,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:
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
index 6df2f4ec..ae847d61 100644
--- a/libmultipath/structs.c
+++ b/libmultipath/structs.c
@@ -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);
 }
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index fef416b4..a801cd92 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -283,7 +283,7 @@ struct path {
        int io_err_pathfail_starttime;
        int find_multipaths_timeout;
        /* configlet pointers */
-       struct hwentry * hwe;
+       vector hwe;
        struct gen_path generic_path;
 };
 
@@ -342,7 +342,7 @@ struct multipath {
        char * features;
        char * hwhandler;
        struct mpentry * mpe;
-       struct hwentry * hwe;
+       vector hwe;
 
        /* threads */
        pthread_t waiter;
-- 
2.17.0

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to