1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
/*
* (C) 2010 Christophe Varoqui
* (C) 2009 Dembach Goo Infromatik GmbH & Co KG
* Manon Goo <manon.goo@dg-i.net>
*
* datacore.c
* Version 0.9
*
* This program was inspired by work from
* Matthias Rudolph <matthias.rudolph@hds.com>
*
* This work is made available on the basis of the
* GPLv2 for detials see <http://www.gnu.org/licenses/>.
*
* Manon Goo 2009
*
*
*/
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sg_include.h>
#include <debug.h>
#include <prio.h>
#define INQ_REPLY_LEN 255
#define INQ_CMD_CODE 0x12
#define INQ_CMD_LEN 6
#define dc_log(prio, msg) condlog(prio, "%s: datacore prio: " msg, dev)
int datacore_prio (const char *dev, int sg_fd, char * args)
{
int k;
char vendor[8];
char product[32];
char luname[32];
char wwpn[32];
char sdsname[32];
unsigned char inqCmdBlk[INQ_CMD_LEN] = { INQ_CMD_CODE, 0, 0, 0, INQ_REPLY_LEN, 0 };
unsigned char inqBuff[INQ_REPLY_LEN];
unsigned char *inqBuffp = inqBuff;
unsigned char sense_buffer[32];
sg_io_hdr_t io_hdr;
int timeout = 2000;
char preferredsds_buff[255] = "";
char * preferredsds = &preferredsds_buff[0];
if (!args) {
dc_log(0, "need prio_args with preferredsds set");
return 0;
}
if (sscanf(args, "timeout=%i preferredsds=%s",
&timeout, preferredsds) == 2) {}
else if (sscanf(args, "preferredsds=%s timeout=%i",
preferredsds, &timeout) == 2) {}
else if (sscanf(args, "preferredsds=%s",
preferredsds) == 1) {}
else {
dc_log(0, "unexpected prio_args format");
return 0;
}
// on error just return prio 0
if (strlen(preferredsds) <= 1) {
dc_log(0, "prio args: preferredsds too short (1 character min)");
return 0;
}
if ((timeout < 500) || (timeout > 20000)) {
dc_log(0, "prio args: timeout out of bounds [500:20000]");
return 0;
}
if ((ioctl(sg_fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000))
return 0;
memset (&io_hdr, 0, sizeof (sg_io_hdr_t));
io_hdr.interface_id = 'S';
io_hdr.cmd_len = sizeof (inqCmdBlk);
io_hdr.mx_sb_len = sizeof (sense_buffer);
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.dxfer_len = INQ_REPLY_LEN;
io_hdr.dxferp = inqBuff;
io_hdr.cmdp = inqCmdBlk;
io_hdr.sbp = sense_buffer;
io_hdr.timeout = timeout;
// on error just return prio 0
if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
return 0;
if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK)
return 0;
snprintf(vendor, 9, "%.8s\n", inqBuffp + 8);
snprintf(product, 17, "%.16s", inqBuffp + 16);
snprintf(luname, 21, "%.19s", inqBuffp + 36);
snprintf(wwpn, 17, "%.16s", inqBuffp + 96);
snprintf(sdsname, 17, "%.16s", inqBuffp + 112);
if (strstr(sdsname , preferredsds))
return 1;
return 0;
}
int getprio (struct path * pp, char * args)
{
return datacore_prio(pp->dev, pp->fd, args);
}
|