[stgt] [PATCH V3 3/8] tgt-admin: add option to restart llds
Roi Dayan
roid at mellanox.com
Sun Jul 29 10:52:23 CEST 2012
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 at mellanox.com>
---
usr/mgmt.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
usr/target.c | 17 +++++++++++++++++
usr/tgtadm.c | 25 +++++++++++++++++++++++++
usr/tgtadm.h | 3 +++
usr/tgtd.c | 37 ++++++++++++++++++++++---------------
usr/tgtd.h | 3 +++
6 files changed, 117 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 14d82f7..41e4f05 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -2338,6 +2338,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..0a4b9be 100644
--- a/usr/tgtadm.c
+++ b/usr/tgtadm.c
@@ -405,6 +405,8 @@ static int str_to_mode(char *str)
return MODE_CONNECTION;
else if (!strcmp("account", str))
return MODE_ACCOUNT;
+ 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_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 +870,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 at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list