[PATCH V2 3/8] 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   |   48 +++++++++++++++++++++++++++++++++++++++++++++++-
 usr/target.c |   17 +++++++++++++++++
 usr/tgtadm.c |   27 +++++++++++++++++++++++++++
 usr/tgtadm.h |    3 +++
 usr/tgtd.c   |   37 ++++++++++++++++++++++---------------
 usr/tgtd.h   |    3 +++
 6 files changed, 119 insertions(+), 16 deletions(-)

diff --git a/usr/mgmt.c b/usr/mgmt.c
index 1c8cc92..2590a29 100644
--- a/usr/mgmt.c
+++ b/usr/mgmt.c
@@ -432,6 +432,46 @@ 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_SUCCESS;
+			else
+				adm_err = TGTADM_UNKNOWN_ERR;
+		} else
+			adm_err = TGTADM_SUCCESS;
+		break;
+	case OP_STOP:
+		if (tgt_drivers[lld_no]->drv_state == DRIVER_INIT) {
+			if (list_empty(&tgt_drivers[lld_no]->target_list)) {
+				if (tgt_drivers[lld_no]->exit) {
+					tgt_drivers[lld_no]->exit();
+					tgt_drivers[lld_no]->drv_state = DRIVER_EXIT;
+				}
+				adm_err = TGTADM_SUCCESS;
+			} else
+				adm_err = TGTADM_TARGET_ACTIVE;
+		} else
+			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;
@@ -442,7 +482,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
@@ -478,6 +521,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 a54106e..706e4d1 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -2337,6 +2337,23 @@ tgtadm_err system_show(int mode, struct concat_buf *b)
 	return TGTADM_SUCCESS;
 }
 
+tgtadm_err lld_show(struct concat_buf *b)
+{
+	struct target *target;
+	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]));
+		list_for_each_entry(target, &tgt_drivers[i]->target_list, lld_siblings) {
+			concat_printf(b, _TAB2 "Target %d: %s\n", target->tid, target->name);
+		}
+	}
+
+	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 55e539b..edbd568 100644
--- a/usr/tgtadm.c
+++ b/usr/tgtadm.c
@@ -405,6 +405,10 @@ static int str_to_mode(char *str)
 		return MODE_CONNECTION;
 	else if (!strcmp("account", 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 +431,10 @@ static int str_to_op(char *str)
 		return OP_UPDATE;
 	else if (!strcmp("stat", str))
 		return OP_STATS;
+	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);
@@ -864,6 +872,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 18e7d58..4e239c4 100644
--- a/usr/tgtadm.h
+++ b/usr/tgtadm.h
@@ -16,6 +16,8 @@ enum tgtadm_op {
 	OP_UNBIND,
 	OP_UPDATE,
 	OP_STATS,
+	OP_START,
+	OP_STOP,
 };
 
 enum tgtadm_mode {
@@ -23,6 +25,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 67cd2e9..6199926 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -62,6 +62,7 @@ static struct option const long_options[] =
 };
 
 static char *short_options = "fC:d:t:Vh";
+static char *spare_args;
 
 static void usage(int status)
 {
@@ -416,22 +417,29 @@ retry:
 		goto retry;
 }
 
-static int lld_init(char *args)
+int lld_init_one(int lld_index)
 {
-	int i, err, nr;
-
-	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;
-			}
+	int err;
 
-			INIT_LIST_HEAD(&tgt_drivers[i]->target_list);
-			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++;
+		INIT_LIST_HEAD(&tgt_drivers[lld_index]->target_list);
+		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;
 }
@@ -489,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;
@@ -565,7 +572,7 @@ int main(int argc, char **argv)
 	if (err)
 		exit(1);
 
-	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 8bee2e3..91517f9 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -269,6 +269,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);
 
@@ -364,6 +365,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


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux