Exemplo n.º 1
0
/*---------------------------------------------------------------------------*/
static int on_request(struct xio_session *session,
			struct xio_msg *req,
			int more_in_batch,
			void *cb_prv_data)
{
	struct xio_msg		*rsp;
	struct thread_data	*tdata = cb_prv_data;

	/* alloc transaction */
	rsp	= msg_pool_get(tdata->pool);

	/* fill response */
	rsp->request		= req;
	rsp->more_in_batch	= more_in_batch;
	rsp->in.header.iov_len	= 0;
	rsp->out.header.iov_len = 0;
	vmsg_sglist_set_nents(&rsp->in, 0);

	if (tdata->user_param->verb == READ)
		vmsg_sglist_set_nents(&rsp->out, 0);

	if (xio_send_response(rsp) == -1) {
		printf("**** [%p] Error - xio_send_msg failed. %s\n",
		       session, xio_strerror(xio_errno()));
		msg_pool_put(tdata->pool, req);
	}


	return 0;
}
Exemplo n.º 2
0
static void msg_prep_for_send(struct sd_req *hdr, struct sd_rsp *rsp,
			      void *data, struct xio_msg *msg)
{
	struct xio_vmsg *pomsg = &msg->out;
	struct xio_iovec_ex *osglist = vmsg_sglist(pomsg);
	struct xio_vmsg *pimsg = &msg->in;
	struct xio_iovec_ex *isglist = vmsg_sglist(pimsg);

	vmsg_sglist_set_nents(pomsg, 0);
	pomsg->header.iov_len = sizeof(*hdr);
	pomsg->header.iov_base = hdr;

	if (hdr->flags & SD_FLAG_CMD_WRITE) {
		vmsg_sglist_set_nents(pomsg, 1);

		osglist[0].iov_base = data;
		osglist[0].iov_len = hdr->data_length;
		osglist[0].mr = NULL;
	}

	vmsg_sglist_set_nents(pimsg, 1);
	isglist[0].iov_base = rsp;
	isglist[0].iov_len = sizeof(*rsp);
	isglist[0].mr = NULL;

	if (hdr->data_length) {
		vmsg_sglist_set_nents(pimsg, 2);
		isglist[1].iov_base = xzalloc(hdr->data_length);
		isglist[1].iov_len = hdr->data_length;
		isglist[1].mr = NULL;
	}
}
Exemplo n.º 3
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
		       struct xio_msg *rsp,
		       int more_in_batch,
		       void *cb_user_context)
{
	struct session_data *session_data = cb_user_context;
	int i = rsp->request->sn % QUEUE_DEPTH;

	session_data->nrecv++;
	/* process the incoming message */
	process_response(session_data, rsp);

	/* acknowledge xio that response is no longer needed */
	xio_release_response(rsp);

#if  TEST_DISCONNECT
	if (session_data->nrecv == DISCONNECT_NR) {
		xio_disconnect(session_data->conn);
		return 0;
	}
	if (session_data->nsent == DISCONNECT_NR)
		return 0;
#endif

	session_data->req[i].in.header.iov_base	  = NULL;
	session_data->req[i].in.header.iov_len	  = 0;
	vmsg_sglist_set_nents(&session_data->req[i].in, 0);

	/* resend the message */
	xio_send_request(session_data->conn, &session_data->req[i]);
	session_data->nsent++;

	return 0;
}
Exemplo n.º 4
0
static int server_on_request(struct xio_session *session,
			     struct xio_msg *xio_req,
			     int last_in_rxq,
			     void *cb_user_conext)
{
	struct client_info *ci = (struct client_info *)cb_user_conext;
	struct sd_req *hdr;
	struct request *req;

	struct xio_iovec_ex *sglist = vmsg_sglist(&xio_req->in);
	int nents = vmsg_sglist_nents(&xio_req->in);

	sd_debug("on request: %p, %p, nents: %d", session, xio_req, nents);
	hdr = xio_req->in.header.iov_base;

	req = alloc_request(ci, hdr->data_length);
	memcpy(&req->rq, hdr, sizeof(req->rq));

	if (hdr->data_length && hdr->flags & SD_FLAG_CMD_WRITE) {
		sd_assert(nents == 1);
		req->data = sglist[0].iov_base;
	}

	xio_req->in.header.iov_base  = NULL;
	xio_req->in.header.iov_len  = 0;
	vmsg_sglist_set_nents(&xio_req->in, 0);

	ci->xio_req = xio_req;

	queue_request(req);

	xio_context_stop_loop(xio_get_main_ctx());
	return 0;
}
Exemplo n.º 5
0
static void msg_prep_for_reply(struct sd_rsp *rsp,
			       void *data, struct xio_msg *msg)
{
	struct xio_vmsg *pomsg = &msg->out;
	struct xio_iovec_ex *sglist = vmsg_sglist(pomsg);

	vmsg_sglist_set_nents(pomsg, 0);
	pomsg->header.iov_len = sizeof(*rsp);
	pomsg->header.iov_base = rsp;

	if (rsp->data_length != 0) {
		vmsg_sglist_set_nents(pomsg, 1);

		sglist[0].iov_base = data;
		sglist[0].iov_len = rsp->data_length;
		sglist[0].mr = NULL;
	}
}
Exemplo n.º 6
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session, struct xio_msg *rsp,
		       int more_in_batch, void *cb_user_context)
{
	struct xio_iovec_ex	*sglist;

	process_response(rsp);

	/* message is no longer needed */
	xio_release_response(rsp);

	nrecv++;
	if (test_config.finite_run) {
		if (nrecv == disconnect_nr) {
			xio_disconnect(conn);
			return 0;
		}

		if (nrecv > disconnect_nr || nsent == disconnect_nr)
			return 0;
	}

	/* reset message */
	rsp->in.header.iov_base = NULL;
	rsp->in.header.iov_len = 0;
	sglist = vmsg_sglist(&rsp->in);
	vmsg_sglist_set_nents(&rsp->in, 1);

	sglist[0].iov_base = NULL;
	sglist[0].iov_len  = ONE_MB;
	sglist[0].mr = NULL;

	rsp->sn = 0;
	rsp->more_in_batch = 0;
	do {
		/* recycle the message and fill new request */
		msg_write(&msg_params, rsp,
			  test_config.hdr_len,
			  1, test_config.data_len);

		/* try to send it */
		if (xio_send_request(conn, rsp) == -1) {
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_msg " \
				       "failed %s\n",
				       session,
				       xio_strerror(xio_errno()));
			msg_pool_put(pool, rsp);
			xio_assert(0);
		}
		nsent++;
	} while (0);

	return 0;
}
Exemplo n.º 7
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
			struct xio_msg *msg,
			int last_in_rxq,
			void *cb_user_context)
{
	struct thread_data  *tdata = (struct thread_data *)cb_user_context;

	cycles_t rtt = (get_cycles()-(cycles_t)msg->user_context);

	if (tdata->do_stat) {
		if (rtt > tdata->stat.max_rtt)
			tdata->stat.max_rtt = rtt;
		if (rtt < tdata->stat.min_rtt)
			tdata->stat.min_rtt = rtt;
		tdata->stat.tot_rtt += rtt;
		tdata->stat.ccnt++;
	}

	tdata->rx_nr++;

	/* message is no longer needed */
	xio_release_response(msg);

	if (tdata->disconnect) {
		if (tdata->rx_nr == tdata->tx_nr)
			xio_disconnect(tdata->conn);
		else
			msg_pool_put(tdata->pool, msg);
		return 0;
	}

	/* reset message */
	msg->in.header.iov_len = 0;
	vmsg_sglist_set_nents(&msg->in, 0);

	msg->user_context = (void *)get_cycles();
	if (xio_send_request(tdata->conn, msg) == -1) {
		if (xio_errno() != EAGAIN)
			printf("**** [%p] Error - xio_send_request " \
					"failed %s\n",
					session,
					xio_strerror(xio_errno()));
		msg_pool_put(tdata->pool, msg);
		return 0;
	}
	if (tdata->do_stat)
		tdata->stat.scnt++;

	tdata->tx_nr++;

	return 0;
}
Exemplo n.º 8
0
/*---------------------------------------------------------------------------*/
static void process_response(struct session_data *session_data,
			     struct xio_msg *rsp)
{
	if (++session_data->cnt == PRINT_COUNTER) {
		((char *)(rsp->in.header.iov_base))[rsp->in.header.iov_len] = 0;
		logit(LOG_INFO, "message: [%lu] - %s\n",
		      (rsp->request->sn + 1), (char *)rsp->in.header.iov_base);
		session_data->cnt = 0;
	}
	rsp->in.header.iov_base	  = NULL;
	rsp->in.header.iov_len	  = 0;
	vmsg_sglist_set_nents(&rsp->in, 0);
}
Exemplo n.º 9
0
/*---------------------------------------------------------------------------*/
int assign_data_in_buf(struct xio_msg *msg, void *cb_user_context)
{
	struct xio_iovec_ex	*sglist = vmsg_sglist(&msg->in);

	vmsg_sglist_set_nents(&msg->in, 1);
	if (reg_mem.addr == NULL)
		xio_mem_alloc(XIO_READ_BUF_LEN, &reg_mem);

	sglist[0].iov_base = reg_mem.addr;
	sglist[0].mr =	reg_mem.mr;
	sglist[0].iov_len = XIO_READ_BUF_LEN;

	return 0;
}
Exemplo n.º 10
0
/*---------------------------------------------------------------------------*/
static int assign_data_in_buf(struct xio_msg *msg, void *cb_user_context)
{
	struct xio_iovec_ex	*sglist = vmsg_sglist(&msg->in);

	vmsg_sglist_set_nents(&msg->in, 1);
	if (xbuf == NULL)
		xbuf = xio_alloc(XIO_READ_BUF_LEN);

	sglist[0].iov_base = xbuf->addr;
	sglist[0].mr = xbuf->mr;
	sglist[0].iov_len = XIO_READ_BUF_LEN;

	return 0;
}
Exemplo n.º 11
0
/*---------------------------------------------------------------------------*/
static void process_request(struct server_data *server_data,
			    struct xio_msg *req)
{
	struct xio_iovec_ex	*sglist = vmsg_sglist(&req->in);
	char			*str;
	int			nents = vmsg_sglist_nents(&req->in);
	int			len, i;
	char			tmp;

	/* note all data is packed together so in order to print each
	 * part on its own NULL character is temporarily stuffed
	 * before the print and the original character is restored after
	 * the printf
	 */
	if (++server_data->cnt == PRINT_COUNTER) {
		str = (char *)req->in.header.iov_base;
		len = req->in.header.iov_len;
		if (str) {
			if (((unsigned) len) > 64)
				len = 64;
			tmp = str[len];
			str[len] = '\0';
			logit(LOG_INFO, "message header : [%lu] - %s",
			      (req->sn + 1), str);
			str[len] = tmp;
		}
		for (i = 0; i < nents; i++) {
			str = (char *)sglist[i].iov_base;
			len = sglist[i].iov_len;
			if (str) {
				if (((unsigned)len) > 64)
					len = 64;
				tmp = str[len];
				str[len] = '\0';
				logit(LOG_INFO, "message data: " \
				      "[%lu][%d][%d] - %s",
				      (req->sn + 1), i, len, str);
				str[len] = tmp;
			}
		}
		server_data->cnt = 0;
	}
	req->in.header.iov_base	  = NULL;
	req->in.header.iov_len	  = 0;
	vmsg_sglist_set_nents(&req->in, 0);
}
Exemplo n.º 12
0
/*---------------------------------------------------------------------------*/
static int assign_data_in_buf(struct xio_msg *msg, void *cb_user_context)
{
	struct thread_data	*tdata = cb_user_context;
	struct xio_iovec_ex	*sglist = vmsg_sglist(&msg->in);

	if (!tdata->in_xbuf) {
		tdata->in_xbuf = xio_alloc(sglist[0].iov_len);
	} else if (tdata->in_xbuf->length < sglist[0].iov_len) {
		xio_free(&tdata->in_xbuf);
		tdata->in_xbuf = xio_alloc(sglist[0].iov_len);
	}

	vmsg_sglist_set_nents(&msg->in, 1);

	sglist[0].iov_base	= tdata->in_xbuf->addr;
	sglist[0].iov_len	= tdata->in_xbuf->length;
	sglist[0].mr		= tdata->in_xbuf->mr;

	return 0;
}
Exemplo n.º 13
0
/*---------------------------------------------------------------------------*/
void msg_write(struct msg_params *msg_params,
	       struct xio_msg *msg,
	       size_t hdrlen,
	       size_t data_iovlen, size_t datalen)
{
	struct xio_vmsg		*pmsg = &msg->out;
	struct xio_iovec_ex	*sglist = vmsg_sglist(pmsg);
	int			nents;
	int			i;

	/* don't do the memcpy */
	pmsg->header.iov_len		= hdrlen;
	pmsg->header.iov_base		= msg_params->g_hdr;
	nents				= datalen ? data_iovlen : 0;

	vmsg_sglist_set_nents(pmsg, nents);

	for (i = 0; i < nents; i++) {
		sglist[i].iov_base	= msg_params->g_data;
		sglist[i].iov_len	= datalen;
		sglist[i].mr		= msg_params->g_data_mr;
	}
}
Exemplo n.º 14
0
/*---------------------------------------------------------------------------*/
static int xio_server_main(void *data)
{
	char **argv = (char **)data;
	struct xio_server	*server;	/* server portal */
	struct server_data	*server_data;
	char			url[256];
	struct xio_context_params ctx_params;
	struct xio_context	*ctx;
	int			i;
	struct xio_vmsg 	*omsg;
	void 			*buf = NULL;
	unsigned long           data_len = 0;

	atomic_add(2, &module_state);

	server_data = vzalloc(sizeof(*server_data));
	if (!server_data) {
		/*pr_err("server_data alloc failed\n");*/
		return 0;
	}

	/* create thread context for the server */
	memset(&ctx_params, 0, sizeof(ctx_params));
	ctx_params.flags = XIO_LOOP_GIVEN_THREAD;
	ctx_params.worker = current;

	ctx = xio_context_create(&ctx_params, 0, -1);
	if (!ctx) {
		vfree(server_data);
		pr_err("context open filed\n");
		return 0;
	}
	server_data->ctx = ctx;

	/* create "hello world" message */
	if (argv[3] != NULL && kstrtoul(argv[3], 0, &data_len)) { /* check, convert and assign data_len */
		data_len = 0;
	}
	for (i = 0; i < QUEUE_DEPTH; i++) {
		xio_reinit_msg(&server_data->rsp[i]);
		omsg = &server_data->rsp[i].out;

		/* header */
		server_data->rsp[i].out.header.iov_base = kstrdup("hello world header rsp 1", GFP_KERNEL);
		server_data->rsp[i].out.header.iov_len = strlen((const char *) server_data->rsp[i].out.header.iov_base) + 1;
		/* iovec[0]*/
		sg_alloc_table(&omsg->data_tbl, 64, GFP_KERNEL);
		/* currently only one entry */
		xio_init_vmsg(omsg, 1);     /* one entry (max_nents) */
		if (data_len < max_data_len) { /* small msgs */
			buf = kstrdup("hello world iovec rsp", GFP_KERNEL);
		} else { /* big msgs */
			if (!buf) {
				pr_info("allocating xio memory...\n");
				buf = kmalloc(data_len, GFP_KERNEL);
				memcpy(buf, "hello world iovec rsp", 22);
			}
		}
		sg_init_one(omsg->data_tbl.sgl, buf, strlen(buf) + 1);
		/* orig_nents is 64 */
		vmsg_sglist_set_nents(omsg, 1);
	}

	/* create url to connect to */
	sprintf(url, "%s://%s:%s", argv[4], argv[1], argv[2]);
	/* bind a listener server to a portal/url */
	server = xio_bind(ctx, &server_ops, url, NULL, 0, server_data);
	if (server) {
		pr_info("listen to %s\n", url);

		g_server_data = server_data;
		if (atomic_add_unless(&module_state, 4, 0x83))
			xio_context_run_loop(ctx);
		atomic_sub(4, &module_state);

		/* normal exit phase */
		pr_info("exit signaled\n");

		/* free the server */
		xio_unbind(server);
	}

	/* free the message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		kfree(server_data->rsp[i].out.header.iov_base);
		if (data_len < max_data_len) {
			/* Currently need to release only one entry */
			kfree(sg_virt(server_data->rsp[i].out.data_tbl.sgl));
		}
		xio_fini_vmsg(&server_data->rsp[i].out);
	}

        if (buf){
                pr_info("freeing xio memory...\n");
                kfree(buf);
                buf = NULL;
        }

	/* free the context */
	xio_context_destroy(ctx);

	vfree(server_data);

	complete_and_exit(&cleanup_complete, 0);
	return 0;
}
Exemplo n.º 15
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
		       struct xio_msg *msg,
		       int last_in_rxq,
		       void *cb_user_context)
{
	struct test_params *test_params = (struct test_params *)cb_user_context;
	struct xio_iovec_ex	*sglist;
	static int		chain_messages = CHAIN_MESSAGES;
	size_t			j;

	test_params->nrecv++;

	process_response(test_params, msg);

	/* message is no longer needed */
	xio_release_response(msg);

	msg_pool_put(test_params->pool, msg);

	if (test_params->finite_run) {
		if (test_params->nrecv ==  test_params->disconnect_nr) {
			xio_disconnect(test_params->connection);
			return 0;
		}

		if (test_params->nsent == test_params->disconnect_nr)
			return 0;
	}

	/* peek message from the pool */
	msg = msg_pool_get(test_params->pool);
	if (msg == NULL) {
		printf("pool is empty\n");
		return 0;
	}
	msg->in.header.iov_base = NULL;
	msg->in.header.iov_len = 0;

	sglist = vmsg_sglist(&msg->in);
	vmsg_sglist_set_nents(&msg->in, test_config.in_iov_len);

	/* tell accelio to use 1MB buffer from its internal pool */
	for (j = 0; j < test_config.in_iov_len; j++) {
		sglist[j].iov_base = NULL;
		sglist[j].iov_len  = ONE_MB;
		sglist[j].mr = NULL;
	}

	msg->sn = 0;

	/* assign buffers to the message */
	msg_build_out_sgl(&test_params->msg_params, msg,
		  test_config.hdr_len,
		  test_config.out_iov_len, test_config.data_len);



	if (chain_messages) {
		msg->next = NULL;
		if (test_params->chain.head  == NULL) {
			test_params->chain.head = msg;
			test_params->chain.tail = test_params->chain.head;
		} else {
			test_params->chain.tail->next = msg;
			test_params->chain.tail = test_params->chain.tail->next;
		}
		if (++test_params->chain.sz == MAX_OUTSTANDING_REQS) {
			if (xio_send_request(test_params->connection,
					     test_params->chain.head) == -1) {
				if (xio_errno() != EAGAIN)
					printf("**** [%p] Error - xio_send_request " \
							"failed %s\n",
							session,
							xio_strerror(xio_errno()));
				msg_pool_put(test_params->pool, msg);
				xio_assert(xio_errno() == EAGAIN);
			}
			test_params->nsent += test_params->chain.sz;
			test_params->chain.head = NULL;
			test_params->chain.sz = 0;
		}
	} else {
		/* try to send it */
		/*msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT; */
		/*msg->flags = XIO_MSG_FLAG_PEER_READ_REQ;*/
		if (xio_send_request(test_params->connection, msg) == -1) {
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_request " \
						"failed %s\n",
						session,
						xio_strerror(xio_errno()));
			msg_pool_put(test_params->pool, msg);
			xio_assert(xio_errno() == EAGAIN);
		}
		test_params->nsent++;
	}

	return 0;
}
Exemplo n.º 16
0
/*---------------------------------------------------------------------------*/
static void *worker_thread(void *data)
{
	struct thread_data		*tdata = (struct thread_data *)data;
	struct xio_connection_params	cparams;
	struct xio_iovec_ex		*sglist;
	cpu_set_t			cpuset;
	struct xio_msg			*msg;
	unsigned int			i;

	/* set affinity to thread */

	CPU_ZERO(&cpuset);
	CPU_SET(tdata->affinity, &cpuset);

	pthread_setaffinity_np(tdata->thread_id, sizeof(cpu_set_t), &cpuset);

	/* prepare data for the cuurent thread */
	tdata->pool = msg_pool_alloc(tdata->user_param->queue_depth);

	/* create thread context for the client */
	tdata->ctx = xio_context_create(NULL, tdata->user_param->poll_timeout,
					tdata->affinity);

	memset(&cparams, 0, sizeof(cparams));
	cparams.session			= tdata->session;
	cparams.ctx			= tdata->ctx;
	cparams.conn_idx		= tdata->cid;
	cparams.conn_user_context	= tdata;

	/* connect the session  */
	tdata->conn = xio_connect(&cparams);

	if (tdata->data_len)
		tdata->xbuf = xio_alloc(tdata->data_len);

	for (i = 0;  i < tdata->user_param->queue_depth; i++) {
		/* create transaction */
		msg = msg_pool_get(tdata->pool);
		if (msg == NULL)
			break;

		/* get pointers to internal buffers */
		msg->in.header.iov_len = 0;

		sglist = vmsg_sglist(&msg->in);
		vmsg_sglist_set_nents(&msg->in, 0);

		msg->out.header.iov_len = 0;
		sglist = vmsg_sglist(&msg->out);
		if (tdata->data_len) {
			vmsg_sglist_set_nents(&msg->out, 1);
			sglist[0].iov_base	= tdata->xbuf->addr;
			sglist[0].iov_len	= tdata->xbuf->length;
			sglist[0].mr		= tdata->xbuf->mr;
		} else {
			vmsg_sglist_set_nents(&msg->out, 0);
		}
		msg->user_context = (void *)get_cycles();
		/* send first message */
		if (xio_send_request(tdata->conn, msg) == -1) {
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_request " \
				       "failed. %s\n",
					tdata->session,
					xio_strerror(xio_errno()));
			msg_pool_put(tdata->pool, msg);
			return 0;
		}
		if (tdata->do_stat)
			tdata->stat.scnt++;
		tdata->tx_nr++;
	}

	/* the default xio supplied main loop */
	xio_context_run_loop(tdata->ctx, XIO_INFINITE);

	/* normal exit phase */

	if (tdata->pool)
		msg_pool_free(tdata->pool);

	if (tdata->xbuf)
		xio_free(&tdata->xbuf);


	/* free the context */
	xio_context_destroy(tdata->ctx);

	return NULL;
}
Exemplo n.º 17
0
static int on_request(struct xio_session *session,
            struct xio_msg *req,
            int last_in_rxq,
            void *cb_user_context)
{
    struct xio_msg *rsp;
    struct io_worker_data *wdata;
    struct xio_iovec_ex *in_sglist;
    struct xio_iovec_ex *out_sglist;
    struct rdb_req_hdr *req_hdr;
    void *ptr;
    int *status;
    char *value;
    size_t key_size, value_size;
//    int len;

    wdata = cb_user_context;
    rsp = &wdata->rsp;

    in_sglist = vmsg_sglist(&req->in);
    req_hdr = in_sglist[0].iov_base;
    ptr = in_sglist[0].iov_base;
    ptr += sizeof (*req_hdr);

    switch (req_hdr->rdb_command) {
        case RDB_CMD_PUT:
            {
                struct rdb_put_req_hdr *put_hdr;

                put_hdr = ptr;

                struct __attribute__((__packed__)) rdb_put_req {
                    struct rdb_key {
                        struct  rdb_key_hdr     key_hdr;
                        char                    key_data[put_hdr->key_size];
                    } key;
                    struct rdb_value {
                        struct  rdb_value_hdr   value_hdr;
                        char                    value_data[put_hdr->value_size];
                    } value;
                } *put_req;

                ptr += sizeof (*put_hdr);
                put_req = ptr;
                key_size = sizeof (struct rdb_key);
                value_size = sizeof (struct rdb_value);
                if (!null_mode)
                    if (!rocksdb_server_put(wdata->rdb, (char *)&put_req->key, &key_size,
                            (char *)&put_req->value, &value_size)) {
                        fprintf(stderr, "rocksdb put failed\n");
                    }
//                len = (int) in_sglist[0].iov_len;

                break;
            }
        case RDB_CMD_MPUT:
            {
                struct rdb_mput_req_hdr *mput_hdr;
                char *records;

                mput_hdr = ptr;

                struct __attribute__((__packed__)) rdb_mput_req {
                    struct multi_kv_pairs {
                        struct rdb_key {
                            struct  rdb_key_hdr     key_hdr;
                            char                    key_data[mput_hdr->key_size];
                        } key;
                        struct rdb_value {
                            struct  rdb_value_hdr   value_hdr;
                            char                    value_data[mput_hdr->value_size];
                        } value;
                    } m_kv_pairs[mput_hdr->num_records];
                } *mput_req;

                ptr += sizeof (*mput_hdr);
                mput_req = ptr;
                key_size = sizeof (struct rdb_key);
                value_size = sizeof (struct rdb_value);
                records = (char *)mput_req->m_kv_pairs;

                if (!null_mode)
                    if (!rocksdb_server_mput(wdata->rdb, records, &key_size,
                            &value_size, &mput_hdr->num_records)) {
                        fprintf(stderr, "rocksdb mput failed\n");
                    }
//                len = (int) in_sglist[0].iov_len;

                break;
            }
        case RDB_CMD_GET:
            {
                struct rdb_get_req_hdr *get_hdr;

                get_hdr = ptr;

                struct __attribute__((__packed__)) rdb_get_req {
                    struct rdb_key {
                        struct  rdb_key_hdr     key_hdr;
                        char                    key_data[get_hdr->key_size];
                    } key;
                } *get_req;

                ptr += sizeof (*get_hdr);
                get_req = ptr;
                key_size = sizeof (get_req->key);

                out_sglist = vmsg_sglist(&rsp->out);
                out_sglist[0].iov_base = wdata->reg_mem.addr;
                out_sglist[0].mr = wdata->reg_mem.mr;

                if (!null_mode) {
                    status = wdata->reg_mem.addr;
                    value = wdata->reg_mem.addr + sizeof (*status);
                    *status = rocksdb_server_get(wdata->rdb, (char *)&get_req->key, &key_size,
                                    value, &value_size);
                    if (*status)
                        out_sglist[0].iov_len = value_size + sizeof (*status);
                    else
                        out_sglist[0].iov_len = sizeof (*status);
                } else {
                    status = wdata->reg_mem.addr;
                    *status = 1;
                    out_sglist[0].iov_len = sizeof (*status);
                }
//                len = (int) out_sglist[0].iov_len;

                vmsg_sglist_set_nents(&rsp->out, 1);

                break;
            }
        case RDB_CMD_MGET:
            {
                struct rdb_mget_req_hdr *mget_hdr;
                char *records;

                mget_hdr = ptr;

                struct __attribute__((__packed__)) rdb_mget_req {
                    struct multi_k_pairs {
                        struct rdb_key {
                            struct  rdb_key_hdr     key_hdr;
                            char                    key_data[mget_hdr->key_size];
                        } key;
                    } m_k_pairs[mget_hdr->num_records];
                } *mget_req;

                ptr += sizeof (*mget_hdr);
                mget_req = ptr;
                key_size = sizeof (struct rdb_key);
                records = (char *) mget_req->m_k_pairs;

                out_sglist = vmsg_sglist(&rsp->out);
                out_sglist[0].iov_base = wdata->reg_mem.addr;
                out_sglist[0].mr = wdata->reg_mem.mr;

                if (!null_mode) {
                    status = wdata->reg_mem.addr;
                    value = wdata->reg_mem.addr + sizeof (*status);
                    *status = rocksdb_server_mget(wdata->rdb, records, &key_size,
                                    value, &value_size, &mget_hdr->num_records);
                    if (*status)
                        out_sglist[0].iov_len = value_size + sizeof (*status);
                    else
                        out_sglist[0].iov_len = sizeof (*status);
                } else {
                    status = wdata->reg_mem.addr;
                    *status = 1;
                    out_sglist[0].iov_len = sizeof (*status);
                }
//                len = (int) out_sglist[0].iov_len;

                vmsg_sglist_set_nents(&rsp->out, 1);

                break;
            }
        default:
            break;
    };

    /*printf("thread : portal : %s, command : %d, version : %d, key : %s, value : %s, len : %d\n",
            wdata->portal,
            *payload_cmd,
            *payload_version,
            key,
            value,
            len);*/

    in_sglist[0].iov_base = NULL;
    in_sglist[0].iov_len = 0;
    vmsg_sglist_set_nents(&req->in, 0);

    rsp->request = req;
    if (xio_send_response(rsp) == -1) {
        fprintf(stderr, "failed to send response for thread %s. reason %d - (%s)\n",
                wdata->portal, xio_errno(), xio_strerror(xio_errno()));
    }

    return (0);
}