[stgt] [PATCH 1/6] mgmt and concat_buf: split mtask.buf into req_buf and rsp_buf
Alexander Nezhinsky
alexandern at mellanox.com
Wed Jan 11 14:29:47 CET 2012
mtask.buf is split into req_buf and rsp_buf;
Request buffer is allocated dynamically, response buffer's speculative
static alloc is meanwhile retained;
Some structuring of mtask handler flow.
Signed-off-by: Alexander Nezhinsky <alexandern at mellanox.com>
---
usr/mgmt.c | 217 +++++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 133 insertions(+), 84 deletions(-)
diff --git a/usr/mgmt.c b/usr/mgmt.c
index 26a360d..4397850 100644
--- a/usr/mgmt.c
+++ b/usr/mgmt.c
@@ -51,16 +51,23 @@ struct mgmt_task {
enum mgmt_task_state mtask_state;
int retry;
int done;
- char *buf;
- int bsize;
struct tgtadm_req req;
+ char *req_buf;
+ int req_bsize;
struct tgtadm_rsp rsp;
+ char *rsp_buf;
+ int rsp_bsize;
/* struct tgt_work work; */
};
+#define MAX_MGT_BUFSIZE (8*1024) /* limit incoming mgmt request data size */
+
static int ipc_fd;
char mgmt_path[256];
+static struct mgmt_task *mtask_alloc(void);
+static void mtask_free(struct mgmt_task *mtask);
+
static void set_show_results(struct tgtadm_rsp *rsp, int *err)
{
if (*err < 0)
@@ -80,7 +87,7 @@ static int target_mgmt(int lld_no, struct mgmt_task *mtask)
switch (req->op) {
case OP_NEW:
- err = tgt_target_create(lld_no, req->tid, mtask->buf);
+ err = tgt_target_create(lld_no, req->tid, mtask->req_buf);
break;
case OP_DELETE:
err = tgt_target_destroy(lld_no, req->tid, req->force);
@@ -92,11 +99,11 @@ static int target_mgmt(int lld_no, struct mgmt_task *mtask)
else {
char *p;
- p = strstr(mtask->buf, "initiator-address=");
+ p = strstr(mtask->req_buf, "initiator-address=");
if (p)
err = acl_add(req->tid, p + strlen("initiator-address="));
- p = strstr(mtask->buf, "initiator-name=");
+ p = strstr(mtask->req_buf, "initiator-name=");
if (p)
err = iqn_acl_add(req->tid, p + strlen("initiator-name="));
}
@@ -107,12 +114,12 @@ static int target_mgmt(int lld_no, struct mgmt_task *mtask)
else {
char *p;
- p = strstr(mtask->buf, "initiator-address=");
+ p = strstr(mtask->req_buf, "initiator-address=");
if (p) {
err = acl_del(req->tid, p + strlen("initiator-address="));
}
- p = strstr(mtask->buf, "initiator-name=");
+ p = strstr(mtask->req_buf, "initiator-name=");
if (p) {
err = iqn_acl_del(req->tid, p + strlen("initiator-name="));
}
@@ -123,29 +130,29 @@ static int target_mgmt(int lld_no, struct mgmt_task *mtask)
char *p;
err = TGTADM_UNSUPPORTED_OPERATION;
- p = strchr(mtask->buf, '=');
+ p = strchr(mtask->req_buf, '=');
if (!p)
break;
*p++ = '\0';
- if (!strcmp(mtask->buf, "state"))
+ if (!strcmp(mtask->req_buf, "state"))
err = tgt_set_target_state(req->tid, p);
else if (tgt_drivers[lld_no]->update)
err = tgt_drivers[lld_no]->update(req->mode, req->op, req->tid,
req->sid, req->lun,
- req->cid, mtask->buf);
+ req->cid, mtask->req_buf);
break;
}
case OP_SHOW:
if (req->tid < 0) {
retry:
- err = tgt_target_show_all(mtask->buf, mtask->bsize);
- if (err == mtask->bsize) {
+ err = tgt_target_show_all(mtask->rsp_buf, mtask->rsp_bsize);
+ if (err == mtask->rsp_bsize) {
char *p;
- mtask->bsize <<= 1;
- p = realloc(mtask->buf, mtask->bsize);
+ mtask->rsp_bsize <<= 1;
+ p = realloc(mtask->rsp_buf, mtask->rsp_bsize);
if (p) {
- mtask->buf = p;
+ mtask->rsp_buf = p;
goto retry;
} else {
eprintf("out of memory\n");
@@ -157,7 +164,7 @@ static int target_mgmt(int lld_no, struct mgmt_task *mtask)
req->tid,
req->sid,
req->cid, req->lun,
- mtask->buf, mtask->bsize);
+ mtask->rsp_buf, mtask->rsp_bsize);
break;
default:
break;
@@ -184,18 +191,18 @@ static int portal_mgmt(int lld_no, struct mgmt_task *mtask,
err = tgt_drivers[lld_no]->show(req->mode,
req->tid, req->sid,
req->cid, req->lun,
- mtask->buf,
- mtask->bsize);
+ mtask->rsp_buf,
+ mtask->rsp_bsize);
set_show_results(rsp, &err);
return err;
}
break;
case OP_NEW:
- err = tgt_portal_create(lld_no, mtask->buf);
+ err = tgt_portal_create(lld_no, mtask->req_buf);
break;
case OP_DELETE:
- err = tgt_portal_destroy(lld_no, mtask->buf);
+ err = tgt_portal_destroy(lld_no, mtask->req_buf);
break;
default:
break;
@@ -245,7 +252,7 @@ static int account_mgmt(int lld_no, struct mgmt_task *mtask)
case OP_DELETE:
case OP_BIND:
case OP_UNBIND:
- user = strstr(mtask->buf, "user=");
+ user = strstr(mtask->req_buf, "user=");
if (!user)
goto out;
user += 5;
@@ -269,13 +276,13 @@ static int account_mgmt(int lld_no, struct mgmt_task *mtask)
break;
case OP_SHOW:
retry:
- err = account_show(mtask->buf, mtask->bsize);
- if (err == mtask->bsize) {
+ err = account_show(mtask->rsp_buf, mtask->rsp_bsize);
+ if (err == mtask->rsp_bsize) {
char *p;
- mtask->bsize <<= 1;
- p = realloc(mtask->buf, mtask->bsize);
+ mtask->rsp_bsize <<= 1;
+ p = realloc(mtask->rsp_buf, mtask->rsp_bsize);
if (p) {
- mtask->buf = p;
+ mtask->rsp_buf = p;
goto retry;
} else
err = TGTADM_NOMEM;
@@ -298,15 +305,15 @@ static int sys_mgmt(int lld_no, struct mgmt_task *mtask)
{
struct tgtadm_req *req = &mtask->req;
struct tgtadm_rsp *rsp = &mtask->rsp;
- int err = TGTADM_INVALID_REQUEST, len = mtask->bsize;
+ int err = TGTADM_INVALID_REQUEST;
switch (req->op) {
case OP_UPDATE:
- if (!strncmp(mtask->buf, "debug=", 6)) {
- if (!strncmp(mtask->buf+6, "on", 2)) {
+ if (!strncmp(mtask->req_buf, "debug=", 6)) {
+ if (!strncmp(mtask->req_buf+6, "on", 2)) {
is_debug = 1;
err = 0;
- } else if (!strncmp(mtask->buf+6, "off", 3)) {
+ } else if (!strncmp(mtask->req_buf+6, "off", 3)) {
is_debug = 0;
err = 0;
}
@@ -316,18 +323,19 @@ static int sys_mgmt(int lld_no, struct mgmt_task *mtask)
err = tgt_drivers[lld_no]->update(req->mode, req->op,
req->tid,
req->sid, req->lun,
- req->cid, mtask->buf);
+ req->cid, mtask->req_buf);
rsp->err = err;
rsp->len = sizeof(*rsp);
break;
case OP_SHOW:
- err = system_show(req->mode, mtask->buf, len);
+ err = system_show(req->mode, mtask->rsp_buf, mtask->rsp_bsize);
if (err >= 0 && tgt_drivers[lld_no]->show) {
err += tgt_drivers[lld_no]->show(req->mode,
req->tid, req->sid,
req->cid, req->lun,
- mtask->buf + err, len - err);
+ mtask->rsp_buf + err,
+ mtask->rsp_bsize - err);
}
set_show_results(rsp, &err);
break;
@@ -357,8 +365,8 @@ static int connection_mgmt(int lld_no, struct mgmt_task *mtask,
err = tgt_drivers[lld_no]->show(req->mode,
req->tid, req->sid,
req->cid, req->lun,
- mtask->buf,
- mtask->bsize);
+ mtask->rsp_buf,
+ mtask->rsp_bsize);
set_show_results(rsp, &err);
return err;
}
@@ -368,7 +376,7 @@ static int connection_mgmt(int lld_no, struct mgmt_task *mtask,
err = tgt_drivers[lld_no]->update(req->mode, req->op,
req->tid,
req->sid, req->lun,
- req->cid, mtask->buf);
+ req->cid, mtask->req_buf);
rsp->err = err;
rsp->len = sizeof(*rsp);
break;
@@ -377,11 +385,12 @@ static int connection_mgmt(int lld_no, struct mgmt_task *mtask,
return err;
}
-static int tgt_mgmt(struct mgmt_task *mtask)
+static int mtask_execute(struct mgmt_task *mtask)
{
struct tgtadm_req *req = &mtask->req;
struct tgtadm_rsp *rsp = &mtask->rsp;
- int lld_no, err = TGTADM_INVALID_REQUEST, len = mtask->bsize;
+ int lld_no, err = TGTADM_INVALID_REQUEST;
+ int len;
if (!strlen(req->lld))
lld_no = 0;
@@ -401,7 +410,7 @@ static int tgt_mgmt(struct mgmt_task *mtask)
dprintf("%d %d %d %d %d %" PRIx64 " %" PRIx64 " %s %d\n",
req->len, lld_no, req->mode, req->op,
- req->tid, req->sid, req->lun, mtask->buf, getpid());
+ req->tid, req->sid, req->lun, mtask->req_buf, getpid());
switch (req->mode) {
case MODE_SYSTEM:
@@ -414,7 +423,7 @@ static int tgt_mgmt(struct mgmt_task *mtask)
err = portal_mgmt(lld_no, mtask, req, rsp);
break;
case MODE_DEVICE:
- err = device_mgmt(lld_no, req, mtask->buf, rsp, &len);
+ err = device_mgmt(lld_no, req, mtask->req_buf, rsp, &len);
break;
case MODE_ACCOUNT:
err = account_mgmt(lld_no, mtask);
@@ -427,7 +436,8 @@ static int tgt_mgmt(struct mgmt_task *mtask)
err = tgt_drivers[lld_no]->show(req->mode,
req->tid, req->sid,
req->cid, req->lun,
- mtask->buf, len);
+ mtask->rsp_buf,
+ mtask->rsp_bsize);
set_show_results(rsp, &err);
} else {
@@ -472,6 +482,59 @@ static int ipc_perm(int fd)
return 0;
}
+static struct mgmt_task *mtask_alloc(void)
+{
+ struct mgmt_task *mtask;
+
+ mtask = zalloc(sizeof(*mtask));
+ if (!mtask) {
+ eprintf("can't allocate mtask\n");
+ return NULL;
+ }
+ mtask->mtask_state = MTASK_STATE_HDR_RECV;
+
+ dprintf("mtask:%p\n", mtask);
+ return mtask;
+}
+
+static void mtask_free(struct mgmt_task *mtask)
+{
+ dprintf("mtask:%p\n", mtask);
+
+ if (mtask->req_buf)
+ free(mtask->req_buf);
+ if (mtask->rsp_buf)
+ free(mtask->rsp_buf);
+ free(mtask);
+}
+
+static int mtask_received(struct mgmt_task *mtask, int fd)
+{
+ int err;
+
+ mtask->rsp_buf = zalloc(MAX_MGT_BUFSIZE);
+ if (!mtask->rsp_buf) {
+ eprintf("failed to allocate response data buffer\n");
+ return -ENOMEM;
+ }
+ mtask->rsp_bsize = MAX_MGT_BUFSIZE;
+
+ err = mtask_execute(mtask);
+ if (err) {
+ eprintf("mgmt task processing failed\n");
+ return err;
+ }
+
+ mtask->mtask_state = MTASK_STATE_RSP_SEND;
+ mtask->done = 0;
+ err = tgt_event_modify(fd, EPOLLOUT);
+ if (err) {
+ eprintf("failed to modify mgmt task event out\n");
+ return err;
+ }
+ return 0;
+}
+
static void mtask_handler(int fd, int events, void *data)
{
int err, len;
@@ -487,24 +550,28 @@ static void mtask_handler(int fd, int events, void *data)
if (err > 0) {
mtask->done += err;
if (mtask->done == sizeof(*req)) {
- if (req->len == sizeof(*req)) {
- tgt_mgmt(mtask);
- mtask->mtask_state =
- MTASK_STATE_RSP_SEND;
- if (tgt_event_modify(fd, EPOLLOUT))
- eprintf("failed to modify\n");
-
- mtask->done = 0;
+ mtask->req_bsize = req->len - sizeof(*req);
+ if (!mtask->req_bsize) {
+ err = mtask_received(mtask, fd);
+ if (err)
+ goto out;
} else {
/* the pdu exists */
- mtask->done = 0;
- mtask->mtask_state =
- MTASK_STATE_PDU_RECV;
-
- if (mtask->bsize < req->len) {
- eprintf("FIXME: %d\n", req->len);
+ if (mtask->req_bsize > MAX_MGT_BUFSIZE) {
+ eprintf("mtask buffer len: %d too large\n",
+ mtask->req_bsize);
+ mtask->req_bsize = 0;
+ goto out;
+ }
+ mtask->req_buf = zalloc(mtask->req_bsize);
+ if (!mtask->req_buf) {
+ eprintf("can't allocate mtask buffer len: %d\n",
+ mtask->req_bsize);
+ mtask->req_bsize = 0;
goto out;
}
+ mtask->mtask_state = MTASK_STATE_PDU_RECV;
+ mtask->done = 0;
}
}
} else
@@ -513,17 +580,14 @@ static void mtask_handler(int fd, int events, void *data)
break;
case MTASK_STATE_PDU_RECV:
- len = req->len - (sizeof(*req) + mtask->done);
- err = read(fd, mtask->buf + mtask->done, len);
+ len = mtask->req_bsize - mtask->done;
+ err = read(fd, mtask->req_buf + mtask->done, len);
if (err > 0) {
mtask->done += err;
- if (mtask->done == req->len - (sizeof(*req))) {
- tgt_mgmt(mtask);
- mtask->mtask_state = MTASK_STATE_RSP_SEND;
- if (tgt_event_modify(fd, EPOLLOUT))
- eprintf("failed to modify\n");
-
- mtask->done = 0;
+ if (mtask->done == mtask->req_bsize) {
+ err = mtask_received(mtask, fd);
+ if (err)
+ goto out;
}
} else
if (errno != EAGAIN)
@@ -535,7 +599,7 @@ static void mtask_handler(int fd, int events, void *data)
p = (char *)rsp + mtask->done;
len = sizeof(*rsp) - mtask->done;
} else {
- p = mtask->buf + (mtask->done - sizeof(*rsp));
+ p = mtask->rsp_buf + (mtask->done - sizeof(*rsp));
len = rsp->len - mtask->done;
}
@@ -562,13 +626,10 @@ static void mtask_handler(int fd, int events, void *data)
return;
out:
tgt_event_del(fd);
- free(mtask->buf);
- free(mtask);
close(fd);
+ mtask_free(mtask);
}
-#define BUFSIZE 1024
-
static void mgmt_event_handler(int accept_fd, int events, void *data)
{
int fd, err;
@@ -592,26 +653,14 @@ static void mgmt_event_handler(int accept_fd, int events, void *data)
goto out;
}
- mtask = zalloc(sizeof(*mtask));
- if (!mtask) {
- eprintf("can't allocate mtask\n");
- goto out;
- }
-
- mtask->buf = zalloc(BUFSIZE);
- if (!mtask->buf) {
- eprintf("can't allocate mtask buffer\n");
- free(mtask);
+ mtask = mtask_alloc();
+ if (!mtask)
goto out;
- }
- mtask->bsize = BUFSIZE;
- mtask->mtask_state = MTASK_STATE_HDR_RECV;
err = tgt_event_add(fd, EPOLLIN, mtask_handler, mtask);
if (err) {
eprintf("failed to add a socket to epoll %d\n", fd);
- free(mtask->buf);
- free(mtask);
+ mtask_free(mtask);
goto out;
}
--
1.7.3.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