You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.6 KiB
153 lines
4.6 KiB
--- |
|
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; |
|
} |
|
} |
|
|
|
|