libmultipath/checkers: cciss_tur: use message id
[multipath-tools/.git] / libmultipath / checkers / cciss_tur.c
1 /*
2  *****************************************************************************
3  *                                                                           *
4  *     (C)  Copyright 2007 Hewlett-Packard Development Company, L.P          *
5  *                                                                           *
6  * This program is free software; you can redistribute it and/or modify it   *
7  * under the terms of the GNU General Public License as published by the Free*
8  * Software  Foundation; either version 2 of the License, or (at your option)*
9  * any later version.                                                        *
10  *                                                                           *
11  * This program is distributed in the hope that it will be useful, but       *
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY*
13  * or FITNESS FOR  A PARTICULAR PURPOSE. See the GNU General Public License  *
14  * for more details.                                                         *
15  *                                                                           *
16  * You should have received a copy of the GNU General Public License along   *
17  * with this program.  If not, see <http://www.gnu.org/licenses/>.           *
18  *                                                                           *
19  *****************************************************************************
20 */
21
22 /*
23  *  This program originally derived from and inspired by
24  *  Christophe Varoqui's tur.c, part of libchecker.
25  */
26
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <sys/ioctl.h>
36 #include <errno.h>
37
38 #include "checkers.h"
39
40 #include "cciss.h"
41
42 #define TUR_CMD_LEN 6
43 #define HEAVY_CHECK_COUNT       10
44
45 struct cciss_tur_checker_context {
46         void * dummy;
47 };
48
49 int libcheck_init (struct checker * c)
50 {
51         return 0;
52 }
53
54 void libcheck_free (struct checker * c)
55 {
56         return;
57 }
58
59 int libcheck_check(struct checker * c)
60 {
61         int rc;
62         int ret;
63         unsigned int lun = 0;
64         struct cciss_tur_checker_context * ctxt = NULL;
65         LogvolInfo_struct    lvi;       // logical "volume" info
66         IOCTL_Command_struct cic;       // cciss ioctl command
67
68         if ((c->fd) < 0) {
69                 c->msgid = CHECKER_MSGID_NO_FD;
70                 ret = -1;
71                 goto out;
72         }
73
74         rc = ioctl(c->fd, CCISS_GETLUNINFO, &lvi);
75         if ( rc != 0) {
76                 perror("Error: ");
77                 fprintf(stderr, "cciss TUR  failed in CCISS_GETLUNINFO: %s\n",
78                         strerror(errno));
79                 c->msgid = CHECKER_MSGID_DOWN;
80                 ret = PATH_DOWN;
81                 goto out;
82         } else {
83                 lun = lvi.LunID;
84         }
85
86         memset(&cic, 0, sizeof(cic));
87         cic.LUN_info.LogDev.VolId = lun & 0x3FFFFFFF;
88         cic.LUN_info.LogDev.Mode = 0x01; /* logical volume addressing */
89         cic.Request.CDBLen = 6;  /* need to try just 2 bytes here */
90         cic.Request.Type.Type =  TYPE_CMD; // It is a command.
91         cic.Request.Type.Attribute = ATTR_SIMPLE;
92         cic.Request.Type.Direction = XFER_NONE;
93         cic.Request.Timeout = 0;
94
95         cic.Request.CDB[0] = 0;
96         cic.Request.CDB[1] = 0;
97         cic.Request.CDB[2] = 0;
98         cic.Request.CDB[3] = 0;
99         cic.Request.CDB[4] = 0;
100         cic.Request.CDB[5] = 0;
101
102         rc = ioctl(c->fd, CCISS_PASSTHRU, &cic);
103         if (rc < 0) {
104                 fprintf(stderr, "cciss TUR  failed: %s\n",
105                         strerror(errno));
106                 c->msgid = CHECKER_MSGID_DOWN;
107                 ret = PATH_DOWN;
108                 goto out;
109         }
110
111         if ((cic.error_info.CommandStatus | cic.error_info.ScsiStatus )) {
112                 c->msgid = CHECKER_MSGID_DOWN;
113                 ret = PATH_DOWN;
114                 goto out;
115         }
116
117         c->msgid = CHECKER_MSGID_UP;
118
119         ret = PATH_UP;
120 out:
121         /*
122          * caller told us he doesn't want to keep the context :
123          * free it
124          */
125         if (!c->context)
126                 free(ctxt);
127
128         return(ret);
129 }