[dm-devel] [PATCH] libmultipath/checkers/rdac.c: Use RTPG data in RDAC checker
Christophe Varoqui
christophe.varoqui at opensvc.com
Thu Nov 14 21:09:43 UTC 2013
Applied.
Thanks.
Christophe Varoqui
www.opensvc.com
On Thu, Nov 14, 2013 at 1:09 AM, Sean Stewart <sean.stewart at netapp.com>wrote:
> Make the RDAC checker utilize the RTPG data given in the 0xC9 inquiry
> page to make intelligent decisions about path status, and print more
> descriptive path down messages.
>
> Signed-off-by: Sean Stewart <sean.stewart at netapp.com>
> ---
> libmultipath/checkers/rdac.c | 92
> ++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 81 insertions(+), 11 deletions(-)
>
> diff --git a/libmultipath/checkers/rdac.c b/libmultipath/checkers/rdac.c
> index 2e64dd3..e0b2ea4 100644
> --- a/libmultipath/checkers/rdac.c
> +++ b/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,12 +276,27 @@ libcheck_check (struct checker * c)
> goto done;
> }
>
> - /* check if controller is in service mode */
> - if ((inq.avtcvp & 0x10) &&
> - ((inq.asym_access_state_cur & 0x0F) == 0x3) &&
> - (inq.vendor_specific_cur == 0x7)) {
> - 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 */
> @@ -239,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);
> --
> 1.8.3.1
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/dm-devel/attachments/20131114/800b074a/attachment.htm>
More information about the dm-devel
mailing list