device-mapper-multipath/0096-RHBZ-683616-ioship-support.patch

152 lines
4.0 KiB
Diff
Raw Normal View History

---
libmultipath/checkers/rdac.c | 92 ++++++++++++++++++++++++++++++++++++++-
libmultipath/prioritizers/rdac.c | 4 +
2 files changed, 95 insertions(+), 1 deletion(-)
Index: multipath-tools/libmultipath/checkers/rdac.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/rdac.c
+++ multipath-tools/libmultipath/checkers/rdac.c
@@ -12,27 +12,113 @@
#include <errno.h>
#include "checkers.h"
+#include "debug.h"
#include "../libmultipath/sg_include.h"
#define INQUIRY_CMDLEN 6
#define INQUIRY_CMD 0x12
+#define MODE_SENSE_CMD 0x5a
+#define MODE_SELECT_CMD 0x55
+#define MODE_SEN_SEL_CMDLEN 10
#define SENSE_BUFF_LEN 32
#define SCSI_CHECK_CONDITION 0x2
#define SCSI_COMMAND_TERMINATED 0x22
#define SG_ERR_DRIVER_SENSE 0x08
#define RECOVERED_ERROR 0x01
+
+#define CURRENT_PAGE_CODE_VALUES 0
+#define CHANGEABLE_PAGE_CODE_VALUES 1
+
#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"
+struct control_mode_page {
+ unsigned char header[8];
+ unsigned char page_code;
+ unsigned char page_len;
+ unsigned char dontcare0[3];
+ unsigned char tas_bit;
+ unsigned char dontcare1[6];
+};
+
struct rdac_checker_context {
void * dummy;
};
int libcheck_init (struct checker * c)
{
+ unsigned char cmd[MODE_SEN_SEL_CMDLEN];
+ unsigned char sense_b[SENSE_BUFF_LEN];
+ struct sg_io_hdr io_hdr;
+ struct control_mode_page current, changeable;
+ int set = 0;
+
+ memset(cmd, 0, MODE_SEN_SEL_CMDLEN);
+ cmd[0] = MODE_SENSE_CMD;
+ cmd[1] = 0x08; /* DBD bit on */
+ cmd[2] = 0xA + (CURRENT_PAGE_CODE_VALUES << 6);
+ cmd[8] = (sizeof(struct control_mode_page) & 0xff);
+
+ memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+ memset(sense_b, 0, SENSE_BUFF_LEN);
+ memset(&current, 0, sizeof(struct control_mode_page));
+
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = MODE_SEN_SEL_CMDLEN;
+ io_hdr.mx_sb_len = sizeof(sense_b);
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr.dxfer_len = (sizeof(struct control_mode_page) & 0xff);
+ io_hdr.dxferp = &current;
+ io_hdr.cmdp = cmd;
+ io_hdr.sbp = sense_b;
+ io_hdr.timeout = c->timeout;
+
+ if (ioctl(c->fd, SG_IO, &io_hdr) < 0)
+ goto out;
+
+ /* check the TAS bit to see if it is already set */
+ if ((current.tas_bit >> 6) & 0x1) {
+ set = 1;
+ goto out;
+ }
+
+ /* get the changeble values */
+ cmd[2] = 0xA + (CHANGEABLE_PAGE_CODE_VALUES << 6);
+ io_hdr.dxferp = &changeable;
+ memset(&changeable, 0, sizeof(struct control_mode_page));
+
+ if (ioctl(c->fd, SG_IO, &io_hdr) < 0)
+ goto out;
+
+ /* if TAS bit is not settable exit */
+ if (((changeable.tas_bit >> 6) & 0x1) == 0)
+ goto out;
+
+ /* Now go ahead and set it */
+ memset(cmd, 0, MODE_SEN_SEL_CMDLEN);
+ cmd[0] = MODE_SELECT_CMD;
+ cmd[1] = 0x1; /* set SP bit on */
+ cmd[8] = (sizeof(struct control_mode_page) & 0xff);
+
+ /* use the same buffer as current, only set the tas bit */
+ current.page_code = 0xA;
+ current.page_len = 0xA;
+ current.tas_bit |= (1 << 6);
+
+ io_hdr.dxfer_direction = SG_DXFER_TO_DEV;
+ io_hdr.dxferp = &current;
+
+ if (ioctl(c->fd, SG_IO, &io_hdr) < 0)
+ goto out;
+
+ /* Success */
+ set = 1;
+out:
+ if (set == 0)
+ condlog(0, "rdac checker failed to set TAS bit");
return 0;
}
@@ -132,7 +218,11 @@ libcheck_check (struct checker * c)
goto done;
}
- ret = ((inq.avtcvp & 0x1) ? PATH_UP : PATH_GHOST);
+ /* If owner set or ioship mode is enabled return PATH_UP always */
+ if ((inq.avtcvp & 0x1) || ((inq.avtcvp >> 5) & 0x1))
+ ret = PATH_UP;
+ else
+ ret = PATH_GHOST;
done:
switch (ret) {
Index: multipath-tools/libmultipath/prioritizers/rdac.c
===================================================================
--- multipath-tools.orig/libmultipath/prioritizers/rdac.c
+++ multipath-tools/libmultipath/prioritizers/rdac.c
@@ -81,6 +81,10 @@ int rdac_prio(const char *dev, int fd)
break;
}
+ /* For ioship mode set the bit 3 (00001000) */
+ if ((sense_buffer[8] >> 5) & 0x01)
+ ret |= 0x08;
+
out:
return(ret);
}