[PATCH 1/6] mgmt and concat_buf: split mtask.buf into req_buf and rsp_buf

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxx>
---
 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@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux