Search for correct hwe in update_multipath()
authorHannes Reinecke <hare@suse.de>
Thu, 20 Nov 2008 11:33:39 +0000 (12:33 +0100)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Tue, 21 Apr 2009 22:32:13 +0000 (00:32 +0200)
When updating the multipath structure we only should update the
hardware entry if it doesn't exist anymore. And we should take
care of not selecting invalid entries in the paths vector as
the hardware entry for this is invalid, too.

Signed-off-by: Hannes Reinecke <hare@suse.de>
libmultipath/structs_vec.c

index 0ff7273..11ec58e 100644 (file)
@@ -27,7 +27,7 @@ update_mpp_paths(struct multipath * mpp, vector pathvec)
        struct path * pp;
        int i,j;
 
-       if (!mpp->pg)
+       if (!mpp || !mpp->pg)
                return 0;
 
        if (!mpp->paths &&
@@ -188,13 +188,48 @@ static struct hwentry *
 extract_hwe_from_path(struct multipath * mpp)
 {
        struct path * pp = NULL;
+       int pg_num = -1, p_num = -1, i;
        struct pathgroup * pgp = NULL;
 
-       if (mpp && mpp->pg)
-               pgp = VECTOR_SLOT(mpp->pg, 0);
+       condlog(3, "%s: searching paths for valid hwe", mpp->alias);
 
-       if (pgp && pgp->paths)
-               pp = VECTOR_SLOT(pgp->paths, 0);
+       if (mpp && mpp->pg) {
+               vector_foreach_slot(mpp->pg, pgp, i) {
+                       if (pgp->status == PGSTATE_ACTIVE ||
+                           pgp->status == PGSTATE_ENABLED) {
+                               pg_num = i;
+                               break;
+                       }
+               }
+               if (pg_num >= 0)
+                       pgp = VECTOR_SLOT(mpp->pg, pg_num);
+       }
+
+       if (pgp && pgp->paths) {
+               vector_foreach_slot(pgp->paths, pp, i) {
+                       if (pp->dmstate == PSTATE_FAILED)
+                               continue;
+                       if (strlen(pp->vendor_id) > 0 &&
+                           strlen(pp->product_id) > 0 &&
+                           strlen(pp->rev) > 0) {
+                               p_num = i;
+                               break;
+                       }
+               }
+               if (p_num >= 0)
+                       pp = VECTOR_SLOT(pgp->paths, i);
+       }
+
+       if (pp) {
+               condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
+               condlog(3, "%s: product = %s", pp->dev, pp->product_id);
+               condlog(3, "%s: rev = %s", pp->dev, pp->rev);
+               if (!pp->hwe) {
+                       condlog(3, "searching hwtable");
+                       pp->hwe = find_hwe(conf->hwtable, pp->vendor_id,
+                                          pp->product_id, pp->rev);
+               }
+       }
 
        return pp?pp->hwe:NULL;
 }
@@ -316,7 +351,12 @@ retry:
        }
 
        //adopt_paths(vecs->pathvec, mpp);
-       mpp->hwe = extract_hwe_from_path(mpp);
+       if (!mpp->hwe)
+               mpp->hwe = extract_hwe_from_path(mpp);
+       if (!mpp->hwe) {
+               condlog(3, "%s: no hardware entry found, using defaults",
+                       mpp->alias);
+       }
        select_rr_weight(mpp);
        select_pgfailback(mpp);
        set_no_path_retry(mpp);