summaryrefslogtreecommitdiffstats
path: root/0096-RHBZ-683616-ioship-support.patch
diff options
context:
space:
mode:
Diffstat (limited to '0096-RHBZ-683616-ioship-support.patch')
-rw-r--r--0096-RHBZ-683616-ioship-support.patch151
1 files changed, 151 insertions, 0 deletions
diff --git a/0096-RHBZ-683616-ioship-support.patch b/0096-RHBZ-683616-ioship-support.patch
new file mode 100644
index 0000000..42383b5
--- /dev/null
+++ b/0096-RHBZ-683616-ioship-support.patch
@@ -0,0 +1,151 @@
+---
+ 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);
+ }