2 * Copyright (c) 2004, 2005 Lars Marowsky-Bree
11 #include <sys/ioctl.h>
14 #include "path_state.h"
17 #include "../libmultipath/sg_include.h"
19 #define INQUIRY_CMD 0x12
20 #define INQUIRY_CMDLEN 6
21 #define HEAVY_CHECK_COUNT 10
23 struct emc_clariion_checker_context {
29 int emc_clariion(int fd, char *msg, void **context)
31 unsigned char sense_buffer[256] = { 0, };
32 unsigned char sb[128] = { 0, };
33 unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0, 0,
35 struct sg_io_hdr io_hdr;
36 struct emc_clariion_checker_context * ctxt = NULL;
40 * caller passed in a context : use its address
43 ctxt = (struct emc_clariion_checker_context *) (*context);
46 * passed in context is uninitialized or volatile context :
50 ctxt = malloc(sizeof(struct emc_clariion_checker_context));
51 memset(ctxt, 0, sizeof(struct emc_clariion_checker_context));
54 MSG("cannot allocate context");
62 if ((ctxt->run_count % HEAVY_CHECK_COUNT) == 0) {
72 memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
73 io_hdr.interface_id = 'S';
74 io_hdr.cmd_len = sizeof (inqCmdBlk);
75 io_hdr.mx_sb_len = sizeof (sb);
76 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
77 io_hdr.dxfer_len = sizeof (sense_buffer);
78 io_hdr.dxferp = sense_buffer;
79 io_hdr.cmdp = inqCmdBlk;
81 io_hdr.timeout = 60000;
83 if (ioctl(fd, SG_IO, &io_hdr) < 0) {
84 MSG("emc_clariion_checker: sending query command failed");
88 if (io_hdr.info & SG_INFO_OK_MASK) {
89 MSG("emc_clariion_checker: query command indicates error");
93 if (/* Verify the code page - right page & revision */
94 sense_buffer[1] != 0xc0 || sense_buffer[9] != 0x00) {
95 MSG("emc_clariion_checker: Path unit report page in unknown format");
100 if ( /* Effective initiator type */
101 sense_buffer[27] != 0x03
102 /* Failover mode should be set to 1 */
103 || (sense_buffer[28] & 0x07) != 0x04
104 /* Arraycommpath should be set to 1 */
105 || (sense_buffer[30] & 0x04) != 0x04) {
106 MSG("emc_clariion_checker: Path not correctly configured for failover");
111 if ( /* LUN operations should indicate normal operations */
112 sense_buffer[48] != 0x00) {
113 MSG("emc_clariion_checker: Path not available for normal operations");
119 /* This is not actually an error as the failover to this group
120 * _would_ bind the path */
121 if ( /* LUN should at least be bound somewhere */
122 sense_buffer[4] != 0x00) {
129 * store the LUN WWN there and compare that it indeed did not
130 * change in between, to protect against the path suddenly
131 * pointing somewhere else.
133 if (context && ctxt->wwn_set) {
134 if (memcmp(ctxt->wwn, &sense_buffer[10], 16) != 0) {
135 MSG("emc_clariion_checker: Logical Unit WWN has changed!");
140 memcpy(ctxt->wwn, &sense_buffer[10], 16);
145 MSG("emc_clariion_checker: Path healthy");
149 * caller told us he doesn't want to keep the context :