[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