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