[Stgt-devel] [Scst-devel] Integration of SCST in themainstreamLinux kernel

FUJITA Tomonori fujita.tomonori
Thu Mar 13 13:40:24 CET 2008


On Thu, 13 Mar 2008 12:44:18 +0100
Tomasz Chmielewski <mangoo at wpkg.org> wrote:

> FUJITA Tomonori schrieb:
> > On Thu, 13 Mar 2008 12:24:33 +0100
> > Tomasz Chmielewski <mangoo at wpkg.a.org> wrote:
> 
> (...)
> 
> >> If the patch is finally integrated, I guess README files need updating, 
> >> too to reflect the change.
> > 
> > Well, I really don't like to set the default state to 'offline'.
> > 
> > I'm sure that many people say that initiators can connect to tgtd if I
> > do that.
> 
> You meant "can't connect" I guess.
> Yes, this changes the default behaviour.

Yeah.


> > I could make it as the startup (boot) option though I don't like it
> > either but I think that it's less problematic to set the default state
> > to 'offline'.
> 
> Either default to offline (bad for existing users) or give a startup 

Not only for existing users. People dislike extra operations.

I've used several commercial iSCSI target systems. All I need to do are
setting up security (which initiators can connect) and luns with them.


> option to tgtd (better). There is no other way, I guess (other than 
> making it compile-time option, which is really bad).

There is another option. If tgtd has no targets, then tgtd closes a
connection instead of sending a response. So you can change the state
to offline, configure targets and then change the state to running.

Try this patch (against the current git head).


diff --git a/usr/iscsi/iscsi_tcp.c b/usr/iscsi/iscsi_tcp.c
index 09ed0e5..ed7879a 100644
--- a/usr/iscsi/iscsi_tcp.c
+++ b/usr/iscsi/iscsi_tcp.c
@@ -104,6 +104,12 @@ static void accept_connection(int afd, int events, void *data)
 		return;
 	}
 
+	if (!is_system_available())
+		goto out;
+
+	if (list_empty(&iscsi_targets_list))
+		goto out;
+
 	ret = set_keepalive(fd);
 	if (ret)
 		goto out;
diff --git a/usr/iscsi/isns.c b/usr/iscsi/isns.c
index 81b2874..7bbf875 100644
--- a/usr/iscsi/isns.c
+++ b/usr/iscsi/isns.c
@@ -982,7 +982,7 @@ overflow:
 }
 
 enum {
-	Opt_isns, Opt_ip, Opt_port, Opt_ac, Opt_err,
+	Opt_isns, Opt_ip, Opt_port, Opt_ac, Opt_state, Opt_err,
 };
 
 static match_table_t tokens = {
@@ -990,6 +990,7 @@ static match_table_t tokens = {
 	{Opt_ip, "iSNSServerIP=%s"},
 	{Opt_port, "iSNSServerPort=%d"},
 	{Opt_ac, "iSNSAccessControl=%s"},
+	{Opt_state, "state=%s"},
 	{Opt_err, NULL},
 };
 
@@ -1001,7 +1002,7 @@ int isns_update(char *params)
 	while ((p = strsep(&params, ",")) != NULL) {
 		substring_t args[MAX_OPT_ARGS];
 		int token;
-		char tmp[8];
+		char tmp[16];
 
 		if (!*p)
 			continue;
@@ -1030,6 +1031,10 @@ int isns_update(char *params)
 			match_strncpy(tmp, &args[0], sizeof(tmp));
 			use_isns_ac = !strcmp(tmp, "On");
 			break;
+		case Opt_state:
+			match_strncpy(tmp, &args[0], sizeof(tmp));
+			system_set_state(tmp);
+			break;
 		default:
 			ret = TGTADM_INVALID_REQUEST;
 		}
diff --git a/usr/mgmt.c b/usr/mgmt.c
index 041f0ff..711c7f4 100644
--- a/usr/mgmt.c
+++ b/usr/mgmt.c
@@ -262,13 +262,14 @@ static int sys_mgmt(int lld_no, struct mgmt_task *mtask)
 		rsp->len = sizeof(*rsp);
 		break;
 	case OP_SHOW:
-		if (tgt_drivers[lld_no]->show) {
-			err = tgt_drivers[lld_no]->show(req->mode,
-							req->tid, req->sid,
-							req->cid, req->lun,
-							mtask->buf, len);
-			set_show_results(rsp, &err);
+		err = system_show(req->mode, mtask->buf, len);
+		if (err >= 0 && tgt_drivers[lld_no]->show) {
+			err += tgt_drivers[lld_no]->show(req->mode,
+							 req->tid, req->sid,
+							 req->cid, req->lun,
+							 mtask->buf + err, len - err);
 		}
+		set_show_results(rsp, &err);
 		break;
 	default:
 		break;
diff --git a/usr/target.c b/usr/target.c
index 50769f6..937e32e 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -1716,3 +1716,63 @@ int account_show(char *buf, int rest)
 overflow:
 	return max;
 }
+
+static struct {
+	enum tgt_system_state value;
+	char *name;
+} system_state[] = {
+	{TGT_SYSTEM_OFFLINE, "offline"},
+	{TGT_SYSTEM_RUNNING, "running"},
+};
+
+static char *system_state_name(enum scsi_target_state state)
+{
+	int i;
+	char *name = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(system_state); i++) {
+		if (system_state[i].value == state) {
+			name = system_state[i].name;
+			break;
+		}
+	}
+	return name;
+}
+
+static enum tgt_system_state sys_state = TGT_SYSTEM_RUNNING;
+
+int system_set_state(char *str)
+{
+	int i, err = TGTADM_INVALID_REQUEST;
+
+	for (i = 0; i < ARRAY_SIZE(target_state); i++) {
+		if (!strcmp(system_state[i].name, str)) {
+			sys_state = system_state[i].value;
+			err = 0;
+			break;
+		}
+	}
+	return err;
+}
+
+int system_show(int mode, char *buf, int rest)
+{
+	int total = 0, max = rest;
+
+	/* FIXME: too hacky */
+	if (mode != MODE_SYSTEM)
+		return 0;
+
+	shprintf(total, buf, rest, "System:\n");
+	shprintf(total, buf, rest, _TAB1 "Status=%s\n",
+		 system_state_name(sys_state));
+
+	return total;
+overflow:
+	return max;
+}
+
+int is_system_available(void)
+{
+	return (sys_state == TGT_SYSTEM_RUNNING);
+}
diff --git a/usr/tgtd.h b/usr/tgtd.h
index c083fbe..c0b8a0c 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -24,6 +24,11 @@
 #define _TAB3 _TAB1 _TAB1 _TAB1
 #define _TAB4 _TAB2 _TAB2
 
+enum tgt_system_state {
+	TGT_SYSTEM_OFFLINE = 1,
+	TGT_SYSTEM_RUNNING,
+};
+
 enum scsi_target_state {
 	SCSI_TARGET_OFFLINE = 1,
 	SCSI_TARGET_RUNNING,
@@ -183,6 +188,9 @@ extern int tgt_target_create(int lld, int tid, char *args);
 extern int tgt_target_destroy(int lld, int tid);
 extern char *tgt_targetname(int tid);
 extern int tgt_target_show_all(char *buf, int rest);
+int system_set_state(char *str);
+int system_show(int mode, char *buf, int rest);
+int is_system_available(void);
 
 extern int tgt_bind_host_to_target(int tid, int host_no);
 extern int tgt_unbind_host_to_target(int tid, int host_no);



More information about the stgt mailing list