[Stgt-devel] Re: SCSI Target framework configuration

Mike Christie michaelc at cs.wisc.edu
Tue Aug 23 02:54:59 CEST 2005


This is a multi-part message in MIME format.
--------------070807090906020204030007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

grr, still cannot seem to use ssh to checkout so I cannot checkin too.
I can ssh directly to the server though

FUJITA Tomonori wrote:
> Really sorry for novice questions again.
> 

no problem

> How do 'iscsi_target_class' (similar to scsi_transport_iscsi.c) and
> 'scsi_target_class' work together?
> 
> scsi_target_class can handle LU stuff, which are common for all target
> drivers (FC and iSCSI at present).

> 
> iscsi_target_class can handle connections (iSCSI specific) and sessions
> and targets, which some of thier informations are protocol specific.
> 
> 
> My first impression is that stgt.c has 'struct scsi_target_internal'
> like 'struct iscsi_internal' and stgt_iscsi.c and stgt_fc.c have
> protocol specific functions (e.g., exporting attributes). That is,
> target drivers call scsi_target_register (similar to
> iscsi_register_transport) and use helper functions in stgt_iscsi.c or
> stgt_fc.c to simplify their implementations.


Attached (sorry christoph will inline from now on), is a first pass at
adding stgt_target level attributes. There are attrs that are common
to all targets and have nothing to do with transport specific like
iSCSI sessions.

I will send a stgt_device patch next (need to use driver model interface
to support different types of scsi devices like st, sg, sg osd, etc though).


I am thinking most of the transport stuff will be kept seperate like
the iscsi_session or fc rport. I mean there will not be a driver
model transport register call in stgt core). This is like scsi-ml
where it allows the LLD to notify the transport when it has a
i_t_nexus becuase it looks like there are not too many transport
level target or device attributes (for stgt stgt_session seems useful
though).

This patch is not really tested so do not apply yet.

--------------070807090906020204030007
Content-Type: text/x-patch;
 name="add-target-sysfs.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="add-target-sysfs.patch"

diff -Naurp trunk/iscsi/include/iet_u.h trunk.work/iscsi/include/iet_u.h
--- trunk/iscsi/include/iet_u.h	2005-08-22 18:21:41.000000000 -0500
+++ trunk.work/iscsi/include/iet_u.h	2005-08-22 19:29:06.000000000 -0500
@@ -112,7 +112,7 @@ struct iet_event {
 #define	MIN_NR_QUEUED_CMNDS	1
 #define	MAX_NR_QUEUED_CMNDS	256
 
-#define NETLINK_IET	11
+#define NETLINK_IET	21
 
 #define ADD_TARGET _IOW('i', 0, struct target_info)
 #define DEL_TARGET _IOW('i', 1, struct target_info)
diff -Naurp trunk/iscsi/kernel/iscsi.h trunk.work/iscsi/kernel/iscsi.h
--- trunk/iscsi/kernel/iscsi.h	2005-08-22 18:21:41.000000000 -0500
+++ trunk.work/iscsi/kernel/iscsi.h	2005-08-22 19:33:48.000000000 -0500
@@ -56,6 +56,7 @@ struct network_thread_info {
 };
 
 struct iscsi_cmnd;
+struct stgt_target;
 
 enum iscsi_device_state {
 	IDEV_RUNNING,
diff -Naurp trunk/iscsi/kernel/target.c trunk.work/iscsi/kernel/target.c
--- trunk/iscsi/kernel/target.c	2005-08-22 18:21:41.000000000 -0500
+++ trunk.work/iscsi/kernel/target.c	2005-08-22 19:37:03.000000000 -0500
@@ -10,6 +10,7 @@
 #include <digest.h>
 #include <iscsi_dbg.h>
 #include <stgt.h>
+#include <stgt_target.h>
 
 #define	MAX_NR_TARGETS	(1UL << 30)
 
@@ -111,6 +112,11 @@ static void target_thread_stop(struct is
 	nthread_stop(target);
 }
 
+static struct stgt_target_template iet_stgt_target_template = {
+	.name = "iet",
+	.queued_cmnds = DEFAULT_NR_QUEUED_CMNDS,
+};
+
 static int iscsi_target_create(struct target_info *info, u32 tid)
 {
 	int err = -EINVAL, len;
@@ -154,7 +160,7 @@ static int iscsi_target_create(struct ta
 		goto out;
 	}
 
-	target->stt = stgt_target_create();
+	target->stt = stgt_target_create(&iet_stgt_target_template);
 	assert(target->stt);
 
 	return 0;
diff -Naurp trunk/kernel/Makefile trunk.work/kernel/Makefile
--- trunk/kernel/Makefile	2005-08-22 18:21:40.000000000 -0500
+++ trunk.work/kernel/Makefile	2005-08-22 19:28:50.000000000 -0500
@@ -2,7 +2,7 @@
 # Makefile for the Linux kernel device drivers.
 #
 
-EXTRA_CFLAGS += -I$(obj) -I$(obj)/../include -DNETLINK_STGT=12
+EXTRA_CFLAGS += -I$(obj) -I$(obj)/../include -DNETLINK_STGT=20
 
 ifneq ($(KERNELRELEASE),)
 obj-m		+= stgt.o
diff -Naurp trunk/kernel/stgt.c trunk.work/kernel/stgt.c
--- trunk/kernel/stgt.c	2005-08-22 18:21:40.000000000 -0500
+++ trunk.work/kernel/stgt.c	2005-08-22 19:43:53.000000000 -0500
@@ -17,6 +17,7 @@
 #include <scsi/scsi.h>
 
 #include <stgt.h>
+#include <stgt_target.h>
 #include <stgt_if.h>
 
 #define DEBUG_STGT
@@ -127,7 +128,7 @@ static void stgt_queue_work(struct stgt_
 	schedule_work(&target->work);
 }
 
-struct stgt_target *stgt_target_create(void)
+struct stgt_target *stgt_target_create(struct stgt_target_template *stt)
 {
 	struct stgt_target *target;
 
@@ -150,6 +151,13 @@ struct stgt_target *stgt_target_create(v
 	INIT_LIST_HEAD(&target->work_list);
 
 	INIT_WORK(&target->work, stgt_worker, target);
+	target->stt = stt;
+	target->queued_cmnds = stt->queued_cmnds;
+
+	if (stgt_sysfs_interface_register_target(target)) {
+		kfree(target);
+		return NULL;
+	}
 
 	spin_lock(&all_targets_lock);
 	list_add(&target->tlist, &all_targets);
@@ -165,7 +173,7 @@ int stgt_target_destroy(struct stgt_targ
 	list_del(&target->tlist);
 	spin_unlock(&all_targets_lock);
 
-	kfree(target);
+	stgt_sysfs_interface_unregister_target(target);
 
 	return 0;
 }
@@ -693,6 +701,8 @@ static void __exit stgt_exit(void)
 
 	if (nls)
 		sock_release(nls->sk_socket);
+
+	stgt_sysfs_interface_exit();
 }
 
 static int __init stgt_init(void)
@@ -703,6 +713,10 @@ static int __init stgt_init(void)
 	spin_lock_init(&atomic_sessions_lock);
 	spin_lock_init(&cmnd_hash_lock);
 
+	err = stgt_sysfs_interface_init();
+	if (err)
+		return err;
+
 	cmnd_slab = kmem_cache_create("stgt_cmnd", sizeof(struct stgt_cmnd), 0,
 				      SLAB_HWCACHE_ALIGN | SLAB_NO_REAP,
 				      NULL, NULL);
diff -Naurp trunk/kernel/stgt.h trunk.work/kernel/stgt.h
--- trunk/kernel/stgt.h	2005-08-22 18:21:40.000000000 -0500
+++ trunk.work/kernel/stgt.h	2005-08-22 18:36:41.000000000 -0500
@@ -8,19 +8,6 @@
 
 #include <scsi/scsi_cmnd.h>
 
-struct stgt_target {
-	/* Protects session_list, work_list, device_list */
-	spinlock_t lock;
-
-	struct list_head tlist;
-
-	struct list_head device_list;
-	struct list_head session_list;
-
-	struct work_struct work;
-	struct list_head work_list;
-};
-
 struct stgt_session {
 	struct stgt_target *target;
 	struct list_head slist;
@@ -62,9 +49,6 @@ struct stgt_device {
 	struct list_head dlist;
 };
 
-extern struct stgt_target *stgt_target_create(void);
-extern int stgt_target_destroy(struct stgt_target *target);
-
 extern struct stgt_session *
 stgt_session_create(struct stgt_target *target,
 		    int max_cmnds,
diff -Naurp trunk/kernel/stgt_sysfs_interface.c trunk.work/kernel/stgt_sysfs_interface.c
--- trunk/kernel/stgt_sysfs_interface.c	1969-12-31 18:00:00.000000000 -0600
+++ trunk.work/kernel/stgt_sysfs_interface.c	2005-08-22 19:45:28.000000000 -0500
@@ -0,0 +1,134 @@
+/*
+ * STGT core sysfs files
+ */
+#include <stgt_target.h>
+
+/*
+ * Target sysfs files
+ */
+#define stgt_target_show_fn(name, field, format_string)			\
+static ssize_t								\
+show_##field (struct class_device *cdev, char *buf)			\
+{									\
+	struct stgt_target *target = cdev_to_stgt_target(cdev);		\
+	return snprintf (buf, 20, format_string, starget->field);	\
+}
+
+#define stgt_target_rd_attr(field, format_string)		\
+	shost_show_function(field, format_string)		\
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
+
+stgt_target_rd_attr(queued_cmnds, "%u\n")
+
+static struct class_device_attribute *stgt_target_attrs[] = {
+	&class_device_attr_queued_cmnds,
+	NULL
+};
+
+static void stgt_target_class_release(struct class_device *cdev)
+{
+	struct stgt_target *target = cdev_to_stgt_target(cdev);
+	kfree(starget);
+}
+
+static struct class stgt_target_class = {
+	.name = "stgt_target",
+	.release = stgt_target_class_release,
+};
+
+/*
+ * Tmp: used for unique class_id names. For software we could
+ * push the naming to userspace
+ */
+static int stgt_target_num = 0;
+
+static struct class_device_attribute *class_attr_overridden(
+				struct class_device_attribute **attrs,
+				struct class_device_attribute *attr)
+{
+	int i;
+
+	if (!attrs)
+		return NULL;
+
+	for (i = 0; attrs[i]; i++)
+		if (!strcmp(attrs[i]->attr.name, attr->attr.name))
+			return attrs[i];
+	return NULL;
+}
+
+static int class_attr_add(struct class_device *classdev,
+			  struct class_device_attribute *attr)
+{
+	struct class_device_attribute *base_attr;
+
+	/*
+	 * Spare the caller from having to copy things it's not interested in.
+	*/
+	base_attr = class_attr_overridden(stgt_target_attrs, attr);
+	if (base_attr) {
+		/* extend permissions */
+		attr->attr.mode |= base_attr->attr.mode;
+
+		/* override null show/store with default */
+		if (!attr->show)
+			attr->show = base_attr->show;
+		if (!attr->store)
+			attr->store = base_attr->store;
+	}
+
+	return class_device_create_file(classdev, attr);
+}
+
+int stgt_sysfs_interface_register_target(struct stgt_target *target)
+{
+	struct class_device *cdev = &target->cdev;
+	int err, i;
+	
+	cdev.class = &stgt_target_class;
+	snprintf(cdev->class_id, BUS_ID_SIZE, "target%d", stgt_target_num);
+
+	err = class_device_register(&target->cdev);
+	if (err)
+		return err;
+
+	if (target->stt->target_attrs) {
+		for (i = 0; target->stt->target_attrs[i]; i++) {
+			err = class_attr_add(&target->cdev,
+					     target->stt->target_attrs[i]);
+                        if (err)
+                                goto cleanup;
+		}
+	}
+
+	for (i = 0; stgt_target_attrs[i]; i++) {
+		if (!class_attr_overridden(target->stt->target_attrs,
+					   stgt_target_attrs[i])) {
+			err = class_device_create_file(&shost->shost_classdev,
+						       stgt_target_attrs[i]);
+			if (err)
+				goto cleanup;
+		}
+	}
+
+	return 0;
+
+cleanup:
+	class_device_unregister(&target->cdev);
+	return err;
+}
+
+void stgt_sysfs_interface_register_target(struct stgt_target *target)
+{
+	class_device_unregister(&target->cdev);
+}
+
+int stgt_sysfs_interface_init(void)
+{
+	return class_register(&stgt_target_class);
+}
+
+void stgt_sysfs_interface_exit(void)
+{
+	class_unregister(&stgt_target_class);
+}
diff -Naurp trunk/kernel/stgt_target.h trunk.work/kernel/stgt_target.h
--- trunk/kernel/stgt_target.h	1969-12-31 18:00:00.000000000 -0600
+++ trunk.work/kernel/stgt_target.h	2005-08-22 19:44:21.000000000 -0500
@@ -0,0 +1,43 @@
+/*
+ * STGT target definitions
+ */
+#include <linux/device.h>
+#include <linux/list.h>
+
+struct stgt_target_template {
+	const char *name;
+
+	int queued_cmnds;
+	/*
+	 * Pointer to the sysfs class properties for this host, NULL terminated.
+	 */
+	struct class_device_attribute **target_attrs;
+};
+
+struct stgt_target {
+	struct stgt_target_template *stt;
+	struct class_device cdev;
+
+	int queued_cmnds;
+
+	/* Protects session_list, work_list, device_list */
+	spinlock_t lock;
+
+	struct list_head tlist;
+
+	struct list_head device_list;
+	struct list_head session_list;
+
+	struct work_struct work;
+	struct list_head work_list;
+};
+
+#define cdev_to_stgt_target(cdev) \
+	container_of(cdev, struct stgt_target, cdev)
+
+extern struct stgt_target *stgt_target_create(struct stgt_target_template *stt);
+extern int stgt_target_destroy(struct stgt_target *target);
+extern int stgt_sysfs_interface_init(void);
+extern void stgt_sysfs_interface_exit(void);
+extern int stgt_sysfs_interface_register_target(struct stgt_target *target);
+extern void stgt_sysfs_interface_unregister_target(struct stgt_target *target);
diff -Naurp trunk/usr/Makefile trunk.work/usr/Makefile
--- trunk/usr/Makefile	2005-08-22 18:21:40.000000000 -0500
+++ trunk.work/usr/Makefile	2005-08-22 19:28:30.000000000 -0500
@@ -1,4 +1,4 @@
-CFLAGS += -O2 -fno-inline -Wall -Wstrict-prototypes -I../include -DNETLINK_STGT=12
+CFLAGS += -O2 -fno-inline -Wall -Wstrict-prototypes -I../include -DNETLINK_STGT=20
 PROGRAMS = stgtd
 
 all: $(PROGRAMS)

--------------070807090906020204030007--



More information about the stgt mailing list