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