summaryrefslogtreecommitdiff
path: root/extras/multipath-tools/multipathd/devinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'extras/multipath-tools/multipathd/devinfo.c')
-rw-r--r--extras/multipath-tools/multipathd/devinfo.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/extras/multipath-tools/multipathd/devinfo.c b/extras/multipath-tools/multipathd/devinfo.c
new file mode 100644
index 0000000000..46505470f4
--- /dev/null
+++ b/extras/multipath-tools/multipathd/devinfo.c
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "devinfo.h"
+#include "sg_include.h"
+
+#define FILE_NAME_SIZE 255
+
+static int
+do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
+ void *resp, int mx_resp_len, int noisy)
+{
+ unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
+ { INQUIRY_CMD, 0, 0, 0, 0, 0 };
+ unsigned char sense_b[SENSE_BUFF_LEN];
+ struct sg_io_hdr io_hdr;
+
+ if (cmddt)
+ inqCmdBlk[1] |= 2;
+ if (evpd)
+ inqCmdBlk[1] |= 1;
+ inqCmdBlk[2] = (unsigned char) pg_op;
+ inqCmdBlk[4] = (unsigned char) mx_resp_len;
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = sizeof (inqCmdBlk);
+ io_hdr.mx_sb_len = sizeof (sense_b);
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr.dxfer_len = mx_resp_len;
+ io_hdr.dxferp = resp;
+ io_hdr.cmdp = inqCmdBlk;
+ io_hdr.sbp = sense_b;
+ io_hdr.timeout = DEF_TIMEOUT;
+
+ if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
+ perror("SG_IO (inquiry) error");
+ return -1;
+ }
+
+ /* treat SG_ERR here to get rid of sg_err.[ch] */
+ io_hdr.status &= 0x7e;
+ if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
+ (0 == io_hdr.driver_status))
+ return 0;
+ if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
+ (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
+ (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
+ if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
+ int sense_key;
+ unsigned char * sense_buffer = io_hdr.sbp;
+ if (sense_buffer[0] & 0x2)
+ sense_key = sense_buffer[1] & 0xf;
+ else
+ sense_key = sense_buffer[2] & 0xf;
+ if(RECOVERED_ERROR == sense_key)
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int
+get_lun_strings(char * vendor_id, char * product_id, char * rev, char * devname)
+{
+ int fd;
+ char buff[36];
+
+ /* ioctl style */
+ if ((fd = open(devname, O_RDONLY)) < 0)
+ return 1;
+ if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1))
+ return 1;
+ memcpy(vendor_id, &buff[8], 8);
+ memcpy(product_id, &buff[16], 16);
+ memcpy(rev, &buff[32], 4);
+ close(fd);
+
+ return 0;
+}