[stgt] [Patch 1/1] Add support for passthrough LUNs
ronnie sahlberg
ronniesahlberg at gmail.com
Mon Aug 18 08:11:13 CEST 2008
List,
This patch adds support for passthrough devices to tgtd.
Please review/apply.
>From 7b9518e0cd6ad4b2051c0bdbba2f5ea4aca324d0 Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date: Mon, 18 Aug 2008 15:59:59 +1000
Subject: [PATCH] add support for passthrough luns
Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
---
usr/Makefile | 7 +-
usr/bs_pt.c | 90 ++++++++++++++++++++++++++
usr/pt.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
usr/target.c | 9 +--
usr/tgtd.h | 2 +-
5 files changed, 298 insertions(+), 9 deletions(-)
create mode 100644 usr/bs_pt.c
create mode 100644 usr/pt.c
diff --git a/usr/Makefile b/usr/Makefile
index 4245709..b7c7517 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -11,7 +11,7 @@ CFLAGS += -DISCSI
TGTD_OBJS += $(addprefix iscsi/, conn.o param.o session.o \
iscsid.o target.o chap.o transport.o iscsi_tcp.o \
isns.o libcrc32c.o)
-TGTD_OBJS += bs_rdwr.o bs_aio.o
+TGTD_OBJS += bs_rdwr.o bs_aio.o bs_pt.o
LIBS += -lcrypto
ifneq ($(ISCSI_RDMA),)
@@ -43,7 +43,7 @@ TGTD_OBJS += $(addprefix fcoe/,\
fcoe_if.o fcoe_dev.o \
sa_event.o sa_timer.o sa_hash_kern.o sa_state.o\
crc32_le.o crc32_le_tab.o)
-TGTD_OBJS += bs_rdwr.o
+TGTD_OBJS += bs_rdwr.o bs_pt.o
endif
INCLUDES += -I. -I../include -I$(KERNELSRC)/include
@@ -57,7 +57,8 @@ LIBS += -lpthread
PROGRAMS += tgtd tgtadm
SCRIPTS += ../scripts/tgt-setup-lun
TGTD_OBJS += tgtd.o mgmt.o target.o scsi.o log.o driver.o util.o work.o \
- parser.o spc.o sbc.o mmc.o osd.o scc.o smc.o ssc.o bs_ssc.o bs.o
+ parser.o spc.o sbc.o mmc.o osd.o pt.o scc.o \
+ smc.o ssc.o bs_ssc.o bs.o
MANPAGES = ../doc/manpages/tgtadm.8 ../doc/manpages/tgt-setup-lun.8
TGTD_DEP = $(TGTD_OBJS:.o=.d)
diff --git a/usr/bs_pt.c b/usr/bs_pt.c
new file mode 100644
index 0000000..299ba2c
--- /dev/null
+++ b/usr/bs_pt.c
@@ -0,0 +1,90 @@
+/*
+ * Backing store for passthrough devices
+ *
+ * Copyright (C) 2008 Ronnie Sahlberg <ronniesahlberg at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#define _XOPEN_SOURCE 500
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <linux/fs.h>
+#include <sys/epoll.h>
+#include <sys/ioctl.h>
+#include <scsi/sg.h>
+
+#include "list.h"
+#include "util.h"
+#include "tgtd.h"
+#include "scsi.h"
+#include "bs_thread.h"
+
+
+
+static int open_scsi_device(const char *dev)
+{
+ int fd, vers;
+
+ fd = open(dev, O_RDWR);
+ if (fd < 0) {
+ dprintf("ERROR could not open device %s\n", dev);
+ return -1;
+ }
+ if ((ioctl(fd, SG_GET_VERSION_NUM, &vers) < 0) || (vers < 30000)) {
+ dprintf("/dev is not an sg device, or old sg driver\n");
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+
+static int bs_passthrough_open(struct scsi_lu *lu, char *path, int *fd,
+ uint64_t *size)
+{
+ *fd = open_scsi_device(path);
+
+ return 0;
+}
+
+static void bs_passthrough_close(struct scsi_lu *lu)
+{
+ close(lu->fd);
+}
+
+static int bs_passthrough_cmd_done(struct scsi_cmd *cmd)
+{
+ return 0;
+}
+
+static struct backingstore_template passthrough_bst = {
+ .bs_name = "pt",
+ .bs_open = bs_passthrough_open,
+ .bs_close = bs_passthrough_close,
+};
+
+__attribute__((constructor)) static void bs_passthrough_constructor(void)
+{
+ register_backingstore_template(&passthrough_bst);
+}
diff --git a/usr/pt.c b/usr/pt.c
new file mode 100644
index 0000000..480b4d7
--- /dev/null
+++ b/usr/pt.c
@@ -0,0 +1,199 @@
+/*
+ * SCSI passthrough module
+ *
+ * Copyright (C) 2008 Ronnie Sahlberg <ronniesahlberg at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <linux/fs.h>
+#include <sys/stat.h>
+
+#include "list.h"
+#include "util.h"
+#include "tgtd.h"
+#include <fcntl.h>
+#include "target.h"
+#include "tgtadm_error.h"
+#include "driver.h"
+#include "scsi.h"
+#include "spc.h"
+#include "tgtadm_error.h"
+#include <sys/ioctl.h>
+#include <scsi/sg.h>
+
+
+static unsigned char scsi_command_size[8] = {6, 10, 10, 12, 16, 12, 10, 10};
+
+#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
+#define CDB_SIZE(cmd) (((((cmd)->scb[0] >> 5) & 7) < 6) ? \
+ COMMAND_SIZE((cmd)->scb[0]) : (cmd)->scb_len)
+
+#define SCSI_TIMEOUT 5000 /* ms */
+
+
+int scsi_io(int fd, unsigned char *cdb, unsigned char cdb_size,
+ int xfer_dir, unsigned char *data, int *data_size,
+ unsigned char *sense, unsigned int *sense_len)
+{
+ sg_io_hdr_t io_hdr;
+
+ memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
+ io_hdr.interface_id = 'S';
+
+ /* CDB */
+ io_hdr.cmdp = cdb;
+ io_hdr.cmd_len = cdb_size;
+
+ /* Where to store the sense_data, if there was an error */
+ io_hdr.sbp = sense;
+ io_hdr.mx_sb_len = *sense_len;
+ *sense_len = 0;
+
+ /* Transfer direction, either in or out. Linux does not yet
+ support bidirectional SCSI transfers ?
+ */
+ io_hdr.dxfer_direction = xfer_dir;
+
+ /* Where to store the DATA IN/OUT from the device and how big the
+ buffer is
+ */
+ io_hdr.dxferp = data;
+ io_hdr.dxfer_len = *data_size;
+
+ /* SCSI timeout in ms */
+ io_hdr.timeout = SCSI_TIMEOUT;
+
+
+ if (ioctl(fd, SG_IO, &io_hdr) < 0)
+ return -1;
+
+ /* now for the error processing */
+ if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
+ if (io_hdr.sb_len_wr > 0) {
+ *sense_len = io_hdr.sb_len_wr;
+ return 0;
+ }
+ }
+ if (io_hdr.masked_status)
+ return -2;
+
+ if (io_hdr.host_status)
+ return -3;
+
+ if (io_hdr.driver_status)
+ return -4;
+
+ return 0;
+}
+
+
+
+
+static int scsi_passthrough(int host_no, struct scsi_cmd *cmd)
+{
+ unsigned int sense_len = 32;
+ unsigned char sense[sense_len];
+ int alloc_len;
+ uint8_t *data;
+ int direction;
+
+ alloc_len = scsi_get_in_length(cmd);
+ if (alloc_len > 0) {
+ direction = SG_DXFER_FROM_DEV;
+ data = scsi_get_in_buffer(cmd);
+ } else {
+ alloc_len = scsi_get_out_length(cmd);
+ if (alloc_len > 0) {
+ direction = SG_DXFER_TO_DEV;
+ data = scsi_get_out_buffer(cmd);
+ } else {
+ direction = SG_DXFER_NONE;
+ data = NULL;
+ }
+ }
+
+ scsi_io(cmd->dev->fd,
+ cmd->scb,
+ COMMAND_SIZE(cmd->scb[0]),
+ direction,
+ data, &alloc_len, sense, &sense_len);
+ if (sense_len) {
+ scsi_set_in_resid_by_actual(cmd, 0);
+ sense_data_build(cmd, sense[2], sense[12]<<8);
+ return SAM_STAT_CHECK_CONDITION;
+ }
+
+ if (direction == SG_DXFER_FROM_DEV)
+ scsi_set_in_resid_by_actual(cmd, alloc_len);
+
+ return SAM_STAT_GOOD;
+}
+
+static int passthrough_lu_init(struct scsi_lu *lu)
+{
+ struct backingstore_template *bst;
+
+ /* passthrough devices always use passthrough backingstore */
+ bst = get_backingstore_template("pt");
+ if (!bst) {
+ eprintf("failed to find bstype, pt\n");
+ return TGTADM_INVALID_REQUEST;
+ }
+ lu->bst = bst;
+
+ lu->attrs.device_type = TYPE_SPT;
+
+ return 0;
+}
+
+static int passthrough_lu_online(struct scsi_lu *lu)
+{
+ lu->attrs.online = 1;
+
+ return 0;
+}
+
+static int passthrough_lu_offline(struct scsi_lu *lu)
+{
+ lu->attrs.online = 0;
+ return 0;
+}
+
+static struct device_type_template passthrough_template = {
+ .type = TYPE_SPT,
+ .lu_init = passthrough_lu_init,
+ .lu_config = spc_lu_config,
+ .lu_online = passthrough_lu_online,
+ .lu_offline = passthrough_lu_offline,
+ .lu_exit = spc_lu_exit,
+ .ops = {
+ [0x00 ... 0x9F] = {scsi_passthrough,},
+ /* 0xA0 */
+ {spc_report_luns,},
+ [0xA1 ... 0xFF] = {scsi_passthrough,},
+ }
+};
+
+__attribute__((constructor)) static void passthrough_init(void)
+{
+ device_type_register(&passthrough_template);
+}
diff --git a/usr/target.c b/usr/target.c
index 70bf72a..e200471 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -1524,21 +1524,20 @@ static struct {
{TYPE_ENCLOSURE, "enclosure"},
{TYPE_RBC, "rbc"},
{TYPE_OSD, "osd"},
- {TYPE_NO_LUN, "No LUN"}
+ {TYPE_NO_LUN, "No LUN"},
+ {TYPE_SPT, "passthrough"}
};
static char *print_type(int type)
{
int i;
- char *name = NULL;
for (i = 0; i < ARRAY_SIZE(disk_type_names); i++) {
if (disk_type_names[i].value == type) {
- name = disk_type_names[i].name;
- break;
+ return disk_type_names[i].name;
}
}
- return name;
+ return "Unknown type";
}
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 4febcd3..a649129 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -60,7 +60,7 @@ struct lu_phy_attr {
uint16_t version_desc[VERSION_DESCRIPTOR_LEN];
- char device_type; /* Peripheral device type */
+ unsigned char device_type;/* Peripheral device type */
char qualifier; /* Peripheral Qualifier */
char removable; /* Removable media */
char online; /* Logical Unit online */
--
1.5.5
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-add-support-for-passthrough-luns.patch.gz
Type: application/x-gzip
Size: 3540 bytes
Desc: not available
URL: <http://lists.wpkg.org/pipermail/stgt/attachments/20080818/dfe964c2/attachment-0001.bin>
More information about the stgt
mailing list