mpath_prout_common() will only try sending the prout command to one
path. If that fails, it will give up. There are a number of cases where
it is reasonable to assume that sending the command down another path
could succeed. Keep trying other available paths in these cases.

Do do this, this patch adds a new error code, MPATH_PR_RETRYABLE_ERROR.
libmpathpersist will not return this error to users. It will change it
to MPATH_PR_OTHER if it fails trying on all the paths.

Signed-off-by: Benjamin Marzinski <bmarz...@redhat.com>
---
 libmpathpersist/mpath_persist.h     |  3 +++
 libmpathpersist/mpath_persist_int.c | 13 +++++++++----
 libmpathpersist/mpath_pr_ioctl.c    | 24 +++++++++++++-----------
 3 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h
index d94205f0..32aa7ffe 100644
--- a/libmpathpersist/mpath_persist.h
+++ b/libmpathpersist/mpath_persist.h
@@ -62,6 +62,9 @@ extern "C" {
 #define MPATH_PR_THREAD_ERROR          14  /* pthreads error (e.g. unable to 
create new thread) */
 #define MPATH_PR_OTHER                 15  /*other error/warning has 
occurred(transport
                                              or driver error) */
+#define MPATH_PR_RETRYABLE_ERROR       16  /* error that might be succeed
+                                              down another path. Internal
+                                              only. */
 
 /* PR MASK */
 #define MPATH_F_APTPL_MASK             0x01    /* APTPL MASK*/
diff --git a/libmpathpersist/mpath_persist_int.c 
b/libmpathpersist/mpath_persist_int.c
index 7a6992c2..b838a014 100644
--- a/libmpathpersist/mpath_persist_int.c
+++ b/libmpathpersist/mpath_persist_int.c
@@ -92,7 +92,7 @@ static int mpath_prin_activepath (struct multipath *mpp, int 
rq_servact,
                        }
                }
        }
-       return ret;
+       return (ret == MPATH_PR_RETRYABLE_ERROR) ? MPATH_PR_OTHER : ret;
 }
 
 void *mpath_alloc_prin_response(int prin_sa)
@@ -372,7 +372,7 @@ static int mpath_prout_reg(struct multipath *mpp,int 
rq_servact, int rq_scope,
        }
 
        pthread_attr_destroy(&attr);
-       return (status);
+       return (status == MPATH_PR_RETRYABLE_ERROR) ? MPATH_PR_OTHER : status;
 }
 
 static int send_prout_activepath(char *dev, int rq_servact, int rq_scope,
@@ -416,6 +416,7 @@ static int mpath_prout_common(struct multipath *mpp,int 
rq_servact, int rq_scope
        int i,j, ret;
        struct pathgroup *pgp = NULL;
        struct path *pp = NULL;
+       bool found = false;
 
        vector_foreach_slot (mpp->pg, pgp, j){
                vector_foreach_slot (pgp->paths, pp, i){
@@ -426,12 +427,16 @@ static int mpath_prout_common(struct multipath *mpp,int 
rq_servact, int rq_scope
                        }
 
                        condlog (3, "%s: sending pr out command to %s", 
mpp->wwid, pp->dev);
+                       found = true;
                        ret = send_prout_activepath(pp->dev, rq_servact,
                                                    rq_scope, rq_type,
                                                    paramp, noisy);
-                       return ret ;
+                       if (ret != MPATH_PR_RETRYABLE_ERROR)
+                               return ret ;
                }
        }
+       if (found)
+               return MPATH_PR_OTHER;
        condlog (0, "%s: no path available", mpp->wwid);
        return MPATH_PR_DMMP_ERROR;
 }
@@ -635,7 +640,7 @@ out1:
        free (pamp);
 out:
        free (pr_buff);
-       return (status);
+       return (status == MPATH_PR_RETRYABLE_ERROR) ? MPATH_PR_OTHER : status;
 }
 
 int do_mpath_persistent_reserve_out(vector curmp, vector pathvec, int fd,
diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c
index 093ec71b..bf3a817d 100644
--- a/libmpathpersist/mpath_pr_ioctl.c
+++ b/libmpathpersist/mpath_pr_ioctl.c
@@ -52,7 +52,7 @@ int prout_do_scsi_ioctl(char * dev, int rq_servact, int 
rq_scope,
        fd = open(devname, O_RDONLY);
        if(fd < 0){
                condlog (1, "%s: unable to open device.", dev);
-               return MPATH_PR_FILE_ERROR;
+               return MPATH_PR_RETRYABLE_ERROR;
        }
 
        unsigned char cdb[MPATH_PROUT_CMDLEN] =
@@ -123,14 +123,16 @@ retry :
                goto retry;
        }
 
-       if (((status == MPATH_PR_SENSE_NOT_READY )&& (Sensedata.ASC == 0x04)&&
-                               (Sensedata.ASCQ == 0x07))&& (retry > 0))
-       {
-               usleep(1000);
-               --retry;
-               condlog(3, "%s: retrying for sense 02/04/07."
-                       " Remaining retries = %d", dev, retry);
-               goto retry;
+       if (status == MPATH_PR_SENSE_NOT_READY) {
+               if (Sensedata.ASC == 0x04 && Sensedata.ASCQ == 0x07 &&
+                   retry > 0) {
+                               usleep(1000);
+                               --retry;
+                               condlog(3, "%s: retrying for sense 02/04/07."
+                                       " Remaining retries = %d", dev, retry);
+                               goto retry;
+               } else
+                       status = MPATH_PR_RETRYABLE_ERROR;
        }
 
        close(fd);
@@ -342,7 +344,7 @@ int prin_do_scsi_ioctl(char * dev, int rq_servact, struct 
prin_resp * resp, int
        fd = open(devname, O_RDONLY);
        if(fd < 0){
                condlog(0, "%s: Unable to open device ", dev);
-               return MPATH_PR_FILE_ERROR;
+               return MPATH_PR_RETRYABLE_ERROR;
        }
 
        if (mpath_mx_alloc_len)
@@ -488,7 +490,7 @@ int mpath_translate_response (char * dev, struct sg_io_hdr 
io_hdr,
        case DID_OK :
                break;
        default :
-               return MPATH_PR_OTHER;
+               return MPATH_PR_RETRYABLE_ERROR;
        }
        switch(io_hdr.driver_status)
        {
-- 
2.48.1


Reply via email to