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> --- Hi Tomo, The patch adds option to stop and start lld without restarting the tgtd process. Then for example if tgtd was started before the rdma modules were loaded then we can later load the modules and call iser init() with: tgtadm --mode lld --lld iser --op start Thanks, Roi 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