[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