summaryrefslogtreecommitdiffstats
path: root/0069-UPBZ-1033791-improve-rdac-checker.patch
diff options
context:
space:
mode:
Diffstat (limited to '0069-UPBZ-1033791-improve-rdac-checker.patch')
-rw-r--r--0069-UPBZ-1033791-improve-rdac-checker.patch153
1 files changed, 153 insertions, 0 deletions
diff --git a/0069-UPBZ-1033791-improve-rdac-checker.patch b/0069-UPBZ-1033791-improve-rdac-checker.patch
new file mode 100644
index 0000000..c838f29
--- /dev/null
+++ b/0069-UPBZ-1033791-improve-rdac-checker.patch
@@ -0,0 +1,153 @@
+---
+ libmultipath/checkers/rdac.c | 91 ++++++++++++++++++++++++++++++++++++++-----
+ libmultipath/discovery.c | 2
+ 2 files changed, 81 insertions(+), 12 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/checkers/rdac.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/checkers/rdac.c
++++ multipath-tools-130222/libmultipath/checkers/rdac.c
+@@ -34,6 +34,18 @@
+ #define MSG_RDAC_UP "rdac checker reports path is up"
+ #define MSG_RDAC_DOWN "rdac checker reports path is down"
+ #define MSG_RDAC_GHOST "rdac checker reports path is ghost"
++#define MSG_RDAC_DOWN_TYPE(STR) MSG_RDAC_DOWN": "STR
++
++#define RTPG_UNAVAILABLE 0x3
++#define RTPG_OFFLINE 0xE
++#define RTPG_TRANSITIONING 0xF
++
++#define RTPG_UNAVAIL_NON_RESPONSIVE 0x2
++#define RTPG_UNAVAIL_IN_RESET 0x3
++#define RTPG_UNAVAIL_CFW_DL1 0x4
++#define RTPG_UNAVAIL_CFW_DL2 0x5
++#define RTPG_UNAVAIL_QUIESCED 0x6
++#define RTPG_UNAVAIL_SERVICE_MODE 0x7
+
+ struct control_mode_page {
+ unsigned char header[8];
+@@ -199,22 +211,64 @@ struct volume_access_inq
+ char PQ_PDT;
+ char dontcare0[7];
+ char avtcvp;
+- char dontcare1;
+- char asym_access_state_cur;
++ char vol_ppp;
++ char aas_cur;
+ char vendor_specific_cur;
+- char dontcare2[36];
++ char aas_alt;
++ char vendor_specific_alt;
++ char dontcare1[34];
+ };
+
++const char
++*checker_msg_string(struct volume_access_inq *inq)
++{
++ /* lun not connected */
++ if (((inq->PQ_PDT & 0xE0) == 0x20) || (inq->PQ_PDT & 0x7f))
++ return MSG_RDAC_DOWN_TYPE("lun not connected");
++
++ /* if no tpg data is available, give the generic path down message */
++ if (!(inq->avtcvp & 0x10))
++ return MSG_RDAC_DOWN;
++
++ /* controller is booting up */
++ if (((inq->aas_cur & 0x0F) == RTPG_TRANSITIONING) &&
++ (inq->aas_alt & 0x0F) != RTPG_TRANSITIONING)
++ return MSG_RDAC_DOWN_TYPE("ctlr is in startup sequence");
++
++ /* if not unavailable, give generic message */
++ if ((inq->aas_cur & 0x0F) != RTPG_UNAVAILABLE)
++ return MSG_RDAC_DOWN;
++
++ /* target port group unavailable */
++ switch (inq->vendor_specific_cur) {
++ case RTPG_UNAVAIL_NON_RESPONSIVE:
++ return MSG_RDAC_DOWN_TYPE("non-responsive to queries");
++ case RTPG_UNAVAIL_IN_RESET:
++ return MSG_RDAC_DOWN_TYPE("ctlr held in reset");
++ case RTPG_UNAVAIL_CFW_DL1:
++ case RTPG_UNAVAIL_CFW_DL2:
++ return MSG_RDAC_DOWN_TYPE("ctlr firmware downloading");
++ case RTPG_UNAVAIL_QUIESCED:
++ return MSG_RDAC_DOWN_TYPE("ctlr quiesced by admin request");
++ case RTPG_UNAVAIL_SERVICE_MODE:
++ return MSG_RDAC_DOWN_TYPE("ctlr is in service mode");
++ default:
++ return MSG_RDAC_DOWN_TYPE("ctlr is unavailable");
++ }
++}
++
+ extern int
+ libcheck_check (struct checker * c)
+ {
+ struct volume_access_inq inq;
+- int ret;
++ int ret, inqfail;
+
++ inqfail = 0;
+ memset(&inq, 0, sizeof(struct volume_access_inq));
+ if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq),
+ c->timeout)) {
+ ret = PATH_DOWN;
++ inqfail = 1;
+ goto done;
+ } else if (((inq.PQ_PDT & 0xE0) == 0x20) || (inq.PQ_PDT & 0x7f)) {
+ /* LUN not connected*/
+@@ -222,11 +276,27 @@ libcheck_check (struct checker * c)
+ goto done;
+ }
+
+- /* check if controller is reporting asymmetric access state of unavailable */
+- if ((inq.avtcvp & 0x10) &&
+- ((inq.asym_access_state_cur & 0x0F) == 0x3)) {
+- ret = PATH_DOWN;
+- goto done;
++ /* If TPGDE bit set, evaluate TPG information */
++ if ((inq.avtcvp & 0x10)) {
++ switch (inq.aas_cur & 0x0F) {
++ /* Never use the path if it reports unavailable */
++ case RTPG_UNAVAILABLE:
++ ret = PATH_DOWN;
++ goto done;
++ /*
++ * If both controllers report transitioning, it
++ * means mode select or STPG is being processed.
++ *
++ * If this controller alone is transitioning, it's
++ * booting and we shouldn't use it yet.
++ */
++ case RTPG_TRANSITIONING:
++ if ((inq.aas_alt & 0xF) != RTPG_TRANSITIONING) {
++ ret = PATH_DOWN;
++ goto done;
++ }
++ break;
++ }
+ }
+
+ /* If owner set or ioship mode is enabled return PATH_UP always */
+@@ -238,7 +308,8 @@ libcheck_check (struct checker * c)
+ done:
+ switch (ret) {
+ case PATH_DOWN:
+- MSG(c, MSG_RDAC_DOWN);
++ MSG(c, (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
++ checker_msg_string(&inq));
+ break;
+ case PATH_UP:
+ MSG(c, MSG_RDAC_UP);
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -1116,8 +1116,6 @@ pathinfo (struct path *pp, vector hwtabl
+ if (!strlen(pp->wwid))
+ get_uid(pp);
+ get_prio(pp);
+- } else {
+- pp->priority = PRIO_UNDEF;
+ }
+ }
+