[PATCH 1/3] tgt-admin: add option to restart llds

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


This patch allows to stop and start lld without restarting tgtd.
Example:
tgtadm --mode lld --lld iser --op start

Signed-off-by: Roi Dayan <roid@xxxxxxxxxxxx>
---
 usr/mgmt.c   |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 usr/target.c |   13 +++++++++++++
 usr/tgtadm.c |   25 +++++++++++++++++++++++++
 usr/tgtadm.h |    3 +++
 usr/tgtd.c   |   35 ++++++++++++++++++++++-------------
 usr/tgtd.h   |    3 +++
 6 files changed, 110 insertions(+), 14 deletions(-)

diff --git a/usr/mgmt.c b/usr/mgmt.c
index ef1b265..1a86333 100644
--- a/usr/mgmt.c
+++ b/usr/mgmt.c
@@ -371,6 +371,43 @@ static tgtadm_err connection_mgmt(int lld_no, struct mgmt_task *mtask)
 	return adm_err;
 }
 
+static tgtadm_err lld_mgmt(int lld_no, struct mgmt_task *mtask)
+{
+	struct tgtadm_req *req = &mtask->req;
+	tgtadm_err adm_err = TGTADM_INVALID_REQUEST;
+
+	switch (req->op) {
+	case OP_START:
+		if (tgt_drivers[lld_no]->drv_state != DRIVER_INIT) {
+			if (lld_init_one(lld_no))
+				adm_err = TGTADM_NO_DRIVER;
+			else
+				adm_err = TGTADM_SUCCESS;
+		} else {
+			adm_err = TGTADM_SUCCESS;
+		}
+		break;
+	case OP_STOP:
+		if (tgt_drivers[lld_no]->drv_state == DRIVER_INIT) {
+			if (tgt_drivers[lld_no]->exit) {
+				tgt_drivers[lld_no]->exit();
+				tgt_drivers[lld_no]->drv_state = DRIVER_EXIT;
+			}
+		}
+		adm_err = TGTADM_SUCCESS;
+		break;
+	case OP_SHOW:
+		concat_buf_init(&mtask->rsp_concat);
+		adm_err = lld_show(&mtask->rsp_concat);
+		concat_buf_finish(&mtask->rsp_concat);
+		break;
+	default:
+		break;
+	}
+
+	return adm_err;
+}
+
 static tgtadm_err mtask_execute(struct mgmt_task *mtask)
 {
 	struct tgtadm_req *req = &mtask->req;
@@ -381,7 +418,10 @@ static tgtadm_err mtask_execute(struct mgmt_task *mtask)
 		lld_no = 0;
 	else {
 		lld_no = get_driver_index(req->lld);
-		if (lld_no < 0 || tgt_drivers[lld_no]->drv_state != DRIVER_INIT) {
+		if (lld_no < 0 ||
+		   (tgt_drivers[lld_no]->drv_state != DRIVER_INIT &&
+		    req->mode != MODE_LLD))
+		{
 			if (lld_no < 0)
 				eprintf("can't find the driver %s\n", req->lld);
 			else
@@ -414,6 +454,9 @@ static tgtadm_err mtask_execute(struct mgmt_task *mtask)
 	case MODE_CONNECTION:
 		adm_err = connection_mgmt(lld_no, mtask);
 		break;
+	case MODE_LLD:
+		adm_err = lld_mgmt(lld_no, mtask);
+		break;
 	default:
 		if (req->op == OP_SHOW && tgt_drivers[lld_no]->show) {
 			concat_buf_init(&mtask->rsp_concat);
diff --git a/usr/target.c b/usr/target.c
index 68222a0..470ea44 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -2213,6 +2213,19 @@ tgtadm_err system_show(int mode, struct concat_buf *b)
 	return TGTADM_SUCCESS;
 }
 
+tgtadm_err lld_show(struct concat_buf *b)
+{
+	int i;
+
+	concat_printf(b, "LLDs:\n");
+	for (i = 0; tgt_drivers[i]; i++) {
+		concat_printf(b, _TAB1 "%s: %s\n", tgt_drivers[i]->name,
+				  driver_state_name(tgt_drivers[i]));
+	}
+
+	return TGTADM_SUCCESS;
+}
+
 void update_lbppbe(struct scsi_lu *lu, int blksize)
 {
 	lu->attrs.lbppbe = 0;
diff --git a/usr/tgtadm.c b/usr/tgtadm.c
index 92f2dc7..93b92a8 100644
--- a/usr/tgtadm.c
+++ b/usr/tgtadm.c
@@ -407,6 +407,8 @@ static int str_to_mode(char *str)
 		return MODE_ACCOUNT;
 	else if (!strcmp("stats", str))
 		return MODE_STATS;
+	else if (!strcmp("lld", str))
+		return MODE_LLD;
 	else {
 		eprintf("unknown mode: %s\n", str);
 		exit(1);
@@ -427,6 +429,10 @@ static int str_to_op(char *str)
 		return OP_SHOW;
 	else if (!strcmp("update", str))
 		return OP_UPDATE;
+	else if (!strcmp("start", str))
+		return OP_START;
+	else if (!strcmp("stop", str))
+		return OP_STOP;
 	else {
 		eprintf("unknown operation: %s\n", str);
 		exit(1);
@@ -861,6 +867,25 @@ int main(int argc, char **argv)
 		}
 	}
 
+	if (mode == MODE_LLD) {
+		switch (op) {
+		case OP_START:
+		case OP_STOP:
+		case OP_SHOW:
+			rc = verify_mode_params(argc, argv, "LmoC");
+			if (rc) {
+				eprintf("system mode: option '-%c' is not "
+					"allowed/supported\n", rc);
+				exit(EINVAL);
+			}
+			break;
+		default:
+			eprintf("option %d not supported in lld mode\n", op);
+			exit(EINVAL);
+			break;
+		}
+	}
+
 	req->op = op;
 	req->tid = tid;
 	req->sid = sid;
diff --git a/usr/tgtadm.h b/usr/tgtadm.h
index eedcf60..8a80a24 100644
--- a/usr/tgtadm.h
+++ b/usr/tgtadm.h
@@ -15,6 +15,8 @@ enum tgtadm_op {
 	OP_BIND,
 	OP_UNBIND,
 	OP_UPDATE,
+	OP_START,
+	OP_STOP,
 };
 
 enum tgtadm_mode {
@@ -22,6 +24,7 @@ enum tgtadm_mode {
 	MODE_TARGET,
 	MODE_DEVICE,
 	MODE_PORTAL,
+	MODE_LLD,
 
 	MODE_SESSION,
 	MODE_CONNECTION,
diff --git a/usr/tgtd.c b/usr/tgtd.c
index cba2b66..3111215 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -63,6 +63,8 @@ static struct option const long_options[] =
 
 static char *short_options = "fC:d:t:Vh";
 
+static char *spare_args;
+
 static void usage(int status)
 {
 	if (status)
@@ -416,20 +418,28 @@ retry:
 		goto retry;
 }
 
-static int lld_init(char *args)
+int lld_init_one(int lld_index)
 {
-	int i, err, nr;
+	int err;
 
-	for (i = nr = 0; tgt_drivers[i]; i++) {
-		if (tgt_drivers[i]->init) {
-			err = tgt_drivers[i]->init(i, args);
-			if (err) {
-				tgt_drivers[i]->drv_state = DRIVER_ERR;
-				continue;
-			}
-			tgt_drivers[i]->drv_state = DRIVER_INIT;
+	if (tgt_drivers[lld_index]->init) {
+		err = tgt_drivers[lld_index]->init(lld_index, spare_args);
+		if (err) {
+			tgt_drivers[lld_index]->drv_state = DRIVER_ERR;
+			return err;
 		}
-		nr++;
+		tgt_drivers[lld_index]->drv_state = DRIVER_INIT;
+	}
+	return 0;
+}
+
+static int lld_init(void)
+{
+	int i, nr;
+
+	for (i = nr = 0; tgt_drivers[i]; i++) {
+		if (!lld_init_one(i))
+			nr++;
 	}
 	return nr;
 }
@@ -487,7 +497,6 @@ int main(int argc, char **argv)
 {
 	struct sigaction sa_old;
 	struct sigaction sa_new;
-	char *spare_args;
 	int err, ch, longindex, nr_lld = 0;
 	int is_daemon = 1, is_debug = 0;
 	int ret;
@@ -552,7 +561,7 @@ int main(int argc, char **argv)
 
 	spare_args = optind < argc ? argv[optind] : NULL;
 
-	nr_lld = lld_init(spare_args);
+	nr_lld = lld_init();
 	if (!nr_lld) {
 		fprintf(stderr, "No available low level driver!\n");
 		exit(1);
diff --git a/usr/tgtd.h b/usr/tgtd.h
index b303e21..13a8c88 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -245,6 +245,7 @@ extern char *tgt_targetname(int tid);
 extern tgtadm_err tgt_target_show_all(struct concat_buf *b);
 tgtadm_err system_set_state(char *str);
 tgtadm_err system_show(int mode, struct concat_buf *b);
+tgtadm_err lld_show(struct concat_buf *b);
 int is_system_available(void);
 int is_system_inactive(void);
 
@@ -330,6 +331,8 @@ extern tgtadm_err dtd_check_removable(int tid, uint64_t lun);
 extern int register_backingstore_template(struct backingstore_template *bst);
 extern struct backingstore_template *get_backingstore_template(const char *name);
 
+extern int lld_init_one(int lld_index);
+
 extern int setup_param(char *name, int (*parser)(char *));
 
 extern int bs_init(void);
-- 
1.7.8.2

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Free Online Dating]     [Linux Kernel]     [XFree86]     [Video Devices]

Add to Google Powered by Linux