Exemplo n.º 1
0
/* Server run loop till shutdown */
void rdb_r_s_server_run(struct server_data *server_data)
{
    int i;

    /* default xio supplied main loop */
    if (xio_context_run_loop(server_data->ctx, XIO_INFINITE) != 0) {
        for (i = 0; i < server_data->nworkers; i++) {
            xio_context_stop_loop(server_data->wdata[i].ctx);
        }
        fprintf(stderr, "failed to run event loop for server listner. reason %d - (%s)\n",
                xio_errno(), xio_strerror(xio_errno()));
    }

    /* join the worker threads */
    for (i = 0; i < server_data->nworkers; i++) {
        pthread_join(server_data->wdata[i].thread_id, NULL);
    }

    /* free the server */
    if (server_data->server)
        xio_unbind(server_data->server);

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

    xio_shutdown();

    if (server_data)
        free(server_data);
}
Exemplo n.º 2
0
/*---------------------------------------------------------------------------*/
static int on_message_delivered(struct xio_session *session,
				struct xio_msg *msg,
				int last_in_rxq,
				void *cb_user_context)
{
	struct ow_test_params *ow_params =
				(struct ow_test_params *)cb_user_context;
	struct xio_msg *new_msg;

	process_tx_message(ow_params, msg);
	ow_params->ndelivered++;

	/* can be safely returned to pool */
	msg_pool_put(ow_params->pool, msg);

	if (ow_params->finite_run) {
		if (ow_params->ndelivered == ow_params->disconnect_nr) {
			xio_disconnect(ow_params->conn);
			return 0;
		}

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

	/* peek message from the pool */
	new_msg = msg_pool_get(ow_params->pool);
	if (new_msg == NULL) {
		printf("pool is empty\n");
		return 0;
	}

	/* assign buffers to the message */
	msg_write(&ow_params->msg_params, new_msg,
		  test_config.hdr_len,
		  1, test_config.data_len);

	/*
	 * ask for receipt since we need to put the message back
	 * to pool
	 */
	 new_msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT;

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

	return 0;
}
Exemplo n.º 3
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
		       struct xio_msg *msg,
		       int last_in_rxq,
		       void *cb_user_context)
{
	/* struct scatterlist	*sgl; */

	process_response(msg);

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

	nrecv++;

	msg_pool_put(pool, msg);

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

		if (nrecv > disconnect_nr)
			return 0;
	}

	/* reset message */
	msg->in.header.iov_base = NULL;
	msg->in.header.iov_len = 0;
	msg->in.data_tbl.nents = 0;

	/*
	sgl = msg->in.data_tbl.sgl;
	xio_tbl_set_nents(&msg->in.data_tbl, test_config.in_iov_len);
	sg_set_buf(sgl, NULL, ONE_MB);
	*/

	msg->sn = 0;

	/* recycle the message and fill new request */
	msg_build_out_sgl(&msg_params, msg,
		  test_config.hdr_len,
		  1, test_config.data_len);

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

	return 0;
}
Exemplo n.º 4
0
/*---------------------------------------------------------------------------*/
static int on_new_session(struct xio_session *session,
			struct xio_new_session_req *session_data,
			void *cb_prv_data)
{
	struct xio_msg	*req;
	int		i = 0;

	printf("**** [%p] on_new_session :%s:%d\n", session,
	       get_ip((struct sockaddr *)&session_data->src_addr),
	       get_port((struct sockaddr *)&session_data->src_addr));

	xio_accept(session, NULL, 0, NULL, 0);

	msg_pool_reset(pool);
	conn = xio_get_connection(session, ctx);

	printf("**** starting ...\n");
	while (1) {
		/* create transaction */
		req = msg_pool_get(pool);
		if (req == NULL)
			break;

		/* get pointers to internal buffers */
		req->in.header.iov_base = NULL;
		req->in.header.iov_len = 0;
		req->in.data_iovlen = 1;
		req->in.data_iov[0].iov_base = NULL;
		req->in.data_iov[0].iov_len  = ONE_MB;
		req->in.data_iov[0].mr = NULL;

		/* recycle the message and fill new request */
		msg_set(req, 1,
			test_config.hdr_len,
			test_config.data_len);

		/* try to send it */
		if (xio_send_request(conn, req) == -1) {
			printf("**** sent %d messages\n", i);
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_msg " \
				       "failed. %s\n",
					session,
					xio_strerror(xio_errno()));
			msg_pool_put(pool, req);
			return 0;
		}
		i++;
		if (i == 256)
			break;
	}

	return 0;
}
Exemplo n.º 5
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.º 6
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.º 7
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
			struct xio_msg *msg,
			int more_in_batch,
			void *cb_user_context)
{
	process_response(msg);

	if (msg->status)
		printf("**** message completed with error. [%s]\n",
				xio_strerror(msg->status));

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


	/* reset message */
	msg->in.header.iov_base = NULL;
	msg->in.header.iov_len = 0;
	msg->in.data_iovlen = 1;
	msg->in.data_iov[0].iov_base = NULL;
	msg->in.data_iov[0].iov_len  = ONE_MB;
	msg->in.data_iov[0].mr = NULL;

	msg->sn = 0;
	msg->more_in_batch = 0;

	do {
		/* recycle the message and fill new request */
		msg_write(msg,
			  "hello world request header",
			  test_config.hdr_len,
			  "hello world request data",
			  test_config.data_len);

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



	return 0;
}
Exemplo n.º 8
0
/*---------------------------------------------------------------------------*/
static int on_new_session(struct xio_session *session,
                          struct xio_new_session_req *req,
                          void *cb_user_context)
{
    int			i = 0;
    struct ow_test_params	*ow_params = cb_user_context;
    struct xio_msg		*msg;

    printf("**** [%p] on_new_session :%s:%d\n", session,
           get_ip((struct sockaddr *)&req->src_addr),
           get_port((struct sockaddr *)&req->src_addr));

    xio_accept(session, NULL, 0, NULL, 0);

    if (ow_params->connection == NULL)
        ow_params->connection = xio_get_connection(session,
                                ow_params->ctx);

    for (i = 0; i < MAX_OUTSTANDING_REQS; i++) {
        /* pick message from the pool */
        msg = msg_pool_get(ow_params->pool);
        if (msg == NULL)
            break;

        /* assign buffers to the message */
        msg_write(&ow_params->msg_params, msg,
                  NULL, test_config.hdr_len,
                  NULL, test_config.data_len);

        /* ask for read receipt since the message needed to be
         * recycled to the pool */
        msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT;

        /* send the message */
        if (xio_send_msg(ow_params->connection, msg) == -1) {
            printf("**** sent %d messages\n", i);
            if (xio_errno() != EAGAIN)
                printf("**** [%p] Error - xio_send_msg " \
                       "failed. %s\n",
                       session,
                       xio_strerror(xio_errno()));
            msg_pool_put(ow_params->pool, msg);
            return 0;
        }
        ow_params->nsent++;
    }
    return 0;
}
Exemplo n.º 9
0
/*---------------------------------------------------------------------------*/
static int on_request(struct xio_session *session, struct xio_msg *req,
		      int more_in_batch, void *cb_user_context)
{
	struct xio_msg	*rsp;

	/* process request */
	process_request(req);

	/* alloc transaction */
	rsp	= msg_pool_get(pool);
	rsp->request		= req;
	rsp->more_in_batch	= 0;

	/* fill response */
	msg_write(&msg_params, rsp,
		  test_config.hdr_len,
		  1, test_config.data_len);

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

	return 0;
}
void
NetworkXioIOHandler::update_fs_client_info(const std::string& volume_name)
{
    uint16_t port = 0;
    std::string host;

    xio_connection_attr xcon_peer;
    int ret = xio_query_connection(cd_->conn,
                                   &xcon_peer,
                                   XIO_CONNECTION_ATTR_USER_CTX |
                                   XIO_CONNECTION_ATTR_PEER_ADDR);
    if (ret < 0)
    {
        LOG_ERROR(volume_name << ": failed to query the xio connection: " <<
                  xio_strerror(xio_errno()));
    }
    else
    {
        const yt::SocketAddress sa(xcon_peer.peer_addr);
        port = sa.get_port();
        host = sa.get_ip_address();
    }

    const FrontendPath volume_path(make_volume_path(volume_name));
    cd_->tag = fs_.register_client(ClientInfo(fs_.find_id(volume_path),
                                              std::move(host),
                                              port));
}
Exemplo n.º 11
0
/*---------------------------------------------------------------------------*/
static int on_request(struct xio_session *session, struct xio_msg *req,
		      int last_in_rxq, void *cb_prv_data)
{
	struct xio_msg	*rsp;

	/* process request */
	process_request(req);

	/* alloc transaction */
	rsp	= msg_pool_get(pool);

	rsp->request		= req;

	/* fill response */
	msg_build_out_sgl(&msg_params, rsp,
		  test_config.hdr_len,
		  1, test_config.data_len);

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

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

    /* process request */
    process_request(tdata, req);

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

    rsp->request		= req;

    /* fill response */
    msg_build_out_sgl(&msg_prms, rsp,
                      test_config.hdr_len,
                      1, test_config.data_len);

    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);

        /* better to do disconnect */
        /*xio_disconnect(tdata->conn);*/
        xio_assert(0);
    }
    tdata->nsent++;

    return 0;
}
Exemplo n.º 13
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;

	if (req->status)
		printf("**** request completed with error. [%s]\n",
		       xio_strerror(req->status));

	/* process request */
	process_request(req);

	/* alloc transaction */
	rsp	= msg_pool_get(pool);

	rsp->request		= req;
	rsp->more_in_batch	= 0;

	/* fill response */
	msg_set(rsp, 0,
		test_config.hdr_len,
		test_config.data_len);

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

	return 0;
}
Exemplo n.º 14
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.º 15
0
/* Server I/O manager */
void *rdb_r_s_io_worker(void *data)
{
    struct io_worker_data *worker_data;
    struct xio_server *server = NULL;
    cpu_set_t cpuset;

    worker_data = (struct io_worker_data *) data;

    /* set affinity to thread */
    CPU_ZERO(&cpuset);
    CPU_SET(worker_data->affinity, &cpuset);
    pthread_setaffinity_np(worker_data->thread_id, sizeof(cpu_set_t), &cpuset);

    worker_data->ctx = xio_context_create(NULL, POLLING_TIMEOUT,
                                            worker_data->affinity);
    if (!worker_data->ctx) {
        fprintf(stderr, "failed to create context for thread %s. reason %d - (%s)\n",
                worker_data->portal, xio_errno(), xio_strerror(xio_errno()));
        goto out;
    }
    server = xio_bind(worker_data->ctx, &io_worker_ops,
                worker_data->portal, NULL, 0, worker_data);
    if (!server) {
        fprintf(stderr, "failed to bind context for thread %s. reason %d - (%s)\n",
                worker_data->portal, xio_errno(), xio_strerror(xio_errno()));
        goto out;
    }

    xio_mem_alloc(MAX_VALUE_SIZE, &worker_data->reg_mem);
    if (!worker_data->reg_mem.addr) {
        fprintf(stderr, "failed to allocate accelio transfer buffer for thread %s. reason %d - (%s)\n",
                worker_data->portal, xio_errno(), xio_strerror(xio_errno()));
        goto out;
    }

    /* the default xio supplied main loop */
    if (xio_context_run_loop(worker_data->ctx, XIO_INFINITE) != 0) {
        fprintf(stderr, "failed to run event loop for thread %s. reason %d - (%s)\n",
                worker_data->portal, xio_errno(), xio_strerror(xio_errno()));
    }

out:
    /* detach the worker */
    if (server)
        xio_unbind(server);

    if (worker_data->reg_mem.addr)
        xio_mem_free(&worker_data->reg_mem);

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

    return NULL;
}
Exemplo n.º 16
0
/*---------------------------------------------------------------------------*/
static void *portal_server_cb(void *data)
{
    struct thread_data	*tdata = (struct thread_data *)data;
    cpu_set_t		cpuset;
    struct xio_server	*server;
    int			retval = 0;

    /* 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(MAX_POOL_SIZE, 0, 1);
    if (tdata->pool == NULL) {
        retval = -1;
        goto exit;
    }

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

    /* bind a listener server to a portal/url */
    printf("thread [%d] - listen:%s\n", tdata->affinity, tdata->portal);
    server = xio_bind(tdata->ctx, &portal_server_ops, tdata->portal,
                      NULL, 0, tdata);
    if (server == NULL) {
        printf("**** Error - xio_bind failed. %s\n",
               xio_strerror(xio_errno()));
        retval = -1;
        goto cleanup;
    }

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

    /* normal exit phase */
    fprintf(stdout, "thread [%d] - exit signaled\n", tdata->affinity);

    /* detach the server */
    xio_unbind(server);

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

    if (tdata->reg_mem.addr)
        xio_mem_free(&tdata->reg_mem);

cleanup:
    /* free the context */
    xio_context_destroy(tdata->ctx);
exit:
    pthread_exit((void *)(unsigned long)retval);
}
Exemplo n.º 17
0
/* Reads a ID3v1 tag from the input file and stores them in
   the given structure. Returns 0 if it successfully reads the
   tag or if the input file don't have a ID3v1 tag. A nonzero
   return value indicates an error. */
int ID3V1_TAG::ReadTag(XFILE* x)
{ if ( xio_fseek(x, -128, XIO_SEEK_END) != -1
    && xio_fread(this, 1, 128, x) == 128 )
  { if (!IsValid())
      Clean();
    return 0;
  }
  Clean();
  return xio_errno();
}
Exemplo n.º 18
0
/*---------------------------------------------------------------------------*/
static int on_message_delivered(struct xio_session *session,
			struct xio_msg *msg,
			int more_in_batch,
			void *cb_user_context)
{
	struct xio_msg *new_msg;

	process_tx_message(msg);

	/* can be safely returned to pool */
	msg_pool_put(pool, msg);


	/* peek message from the pool */
	new_msg = msg_pool_get(pool);
	if (new_msg == NULL) {
		printf("pool is empty\n");
		return 0;
	}

	/* assign buffers to the message */
	msg_write(new_msg,
		  NULL, test_config.hdr_len,
		  NULL, test_config.data_len);

	/*
	 * ask for receipt since we need to put the message back
	 * to pool
	 */
	 new_msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT;

	/* send it */
	if (xio_send_msg(conn, new_msg) == -1) {
		if (xio_errno() != EAGAIN)
			printf("**** [%p] Error - xio_send_msg " \
					"failed. %s\n",
					session,
					xio_strerror(xio_errno()));
		msg_pool_put(pool, new_msg);
		return 0;
	}
	return 0;
}
Exemplo n.º 19
0
/*---------------------------------------------------------------------------*/
static int on_connection_established(struct xio_connection *conn)
{
	struct xio_msg			*msg;

	pr_info("**** starting ...\n");

	/* create transaction */
	msg = msg_pool_get(pool);
	if (!msg)
		return 0;

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

	/*
	   sglist = vmsg_sglist(&msg->in);
	   sglist[0].iov_base = NULL;
	   sglist[0].iov_len  = ONE_MB;
	   sglist[0].mr = NULL;
	   vmsg_sglist_set_nents(&msg->in, 1);
	   */

	/* recycle the message and fill new request */
	msg_build_out_sgl(&msg_params, msg, test_config.hdr_len, 1,
		  test_config.data_len);

	/* try to send it */
	if (xio_send_request(conn, msg) == -1) {
		pr_info("**** sent %d messages\n", 1);
		if (xio_errno() != EAGAIN)
			pr_info("**** [%p] Error - xio_send_msg " \
					"failed. %s\n",
					conn,
					xio_strerror(xio_errno()));
		msg_pool_put(pool, msg);
		xio_assert(0);
	}

	return 0;
}
Exemplo n.º 20
0
/* Server session manager */
struct server_data* rdb_r_s_server_create(const char *host, const int *port)
{
    struct server_data *server_data = NULL;
    char url[NAME_LEN];

    server_data = (struct server_data *)calloc(1, sizeof(*server_data));
    if (!server_data) {
        fprintf(stderr, "failed to allocate memory for server_data\n");
        return (NULL);
    }

    /* init the accelio library */
    xio_init();

    /* create thread context */
    server_data->ctx = xio_context_create(NULL, 0, -1);
    if (!server_data->ctx) {
        fprintf(stderr, "failed to create context for server listner. reason %d - (%s)\n",
                xio_errno(), xio_strerror(xio_errno()));
        goto out;
    }

    sprintf(url, "%s://%s:%d", TRANSPORT, host, *port);
    strcpy(server_data->host, host);
    server_data->port = *port;

    /* bind a listner */
    server_data->server = xio_bind(server_data->ctx, &server_ops,
                                    url, NULL, 0, server_data);
    if (!server_data->server) {
        fprintf(stderr, "failed to bind server listner. reason %d - (%s)\n",
                xio_errno(), xio_strerror(xio_errno()));
        goto out;
    }

out:
    return (server_data);
}
Exemplo n.º 21
0
/*---------------------------------------------------------------------------*/
static int on_message_delivered(struct xio_session *session,
                                struct xio_msg *msg,
                                int more_in_batch,
                                void *cb_user_context)
{
    struct xio_msg *new_msg;
    struct ow_test_params *ow_params = cb_user_context;

    ow_params->ndelivered++;

    /* can be safely freed */
    msg_pool_put(ow_params->pool, msg);

#if  TEST_DISCONNECT
    if (ow_params->ndelivered == DISCONNECT_NR) {
        xio_disconnect(ow_params->connection);
        return 0;
    }

    if (ow_params->nsent == DISCONNECT_NR)
        return 0;
#endif

    /* peek new message from the pool */
    new_msg	= msg_pool_get(ow_params->pool);

    new_msg->more_in_batch	= 0;

    /* fill response */
    msg_write(&ow_params->msg_params, new_msg,
              NULL, test_config.hdr_len,
              NULL, test_config.data_len);

    new_msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT;
    if (xio_send_msg(ow_params->connection, new_msg) == -1) {
        printf("**** [%p] Error - xio_send_msg failed. %s\n",
               session, xio_strerror(xio_errno()));
        msg_pool_put(ow_params->pool, new_msg);
    }
    ow_params->nsent++;


    return 0;
}
Exemplo n.º 22
0
/*---------------------------------------------------------------------------*/
static int on_request(struct xio_session *session,
			struct xio_msg *req,
			int more_in_batch,
			void *cb_user_context)
{
	struct xio_msg	*rsp;
	struct test_params *test_params = cb_user_context;

	if (req->status)
		printf("**** request completed with error. [%s]\n",
		       xio_strerror(req->status));

	/* process request */
	process_request(req);


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

	rsp->request		= req;
	rsp->more_in_batch	= 0;

	/* fill response */
	msg_write(&test_params->msg_params, rsp,
		  NULL, test_config.hdr_len,
		  NULL, test_config.data_len);

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


	return 0;
}
Exemplo n.º 23
0
/*---------------------------------------------------------------------------*/
static int xio_client_main(void *data)
{
	char				url[256];
	struct xio_session_params	params;
	struct xio_context_params	ctx_params;
	struct xio_connection_params	cparams;
	int				error;
	int				retval = 0;

	atomic_add(2, &module_state);

	print_counter = PRINT_COUNTER;

	print_test_config(&test_config);

	memset(&params, 0, sizeof(params));
	memset(&cparams, 0, sizeof(cparams));

	/* prepare buffers for this test */
	if (msg_api_init(&msg_params,
			 test_config.hdr_len, test_config.data_len, 0) != 0) {
		pr_err("msg_api_init failed\n");
		return -1;
	}

	pool = msg_pool_alloc(MAX_POOL_SIZE, 1, 1);
	if (!pool) {
		pr_err("msg_pool_alloc failed\n");
		goto cleanup;
	}

	/* 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,
				 POLLING_TIMEOUT, cpu);
	if (!ctx) {
		pr_err("context open failed\n");
		goto cleanup;
	}

	sprintf(url, "%s://%s:%d",
		test_config.transport,
		test_config.server_addr,
		test_config.server_port);

	params.type		= XIO_SESSION_CLIENT;
	params.ses_ops		= &ses_ops;
	params.uri		= url;

	g_session = xio_session_create(&params);
	if (!g_session)
		pr_err("session creation failed\n");

	cparams.session			= g_session;
	cparams.ctx			= ctx;
	cparams.conn_idx		= test_config.conn_idx;

	/* connect the session  */
	g_connection = xio_connect(&cparams);

	/* the default xio supplied main loop */
	if (atomic_add_unless(&module_state, 4, 0x83))
		retval = xio_context_run_loop(ctx);
	atomic_sub(4, &module_state);

	if (retval != 0) {
		error = xio_errno();
		pr_err("running event loop failed. reason %d - (%s)\n",
		       error, xio_strerror(error));
		xio_assert(retval == 0);
	}

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

	xio_context_destroy(ctx);

	msg_pool_free(pool);

cleanup:
	msg_api_free(&msg_params);

	pr_info("exit complete\n");

	complete_and_exit(&cleanup_complete, 0);

	return 0;
}
Exemplo n.º 24
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);
}
Exemplo n.º 25
0
/*---------------------------------------------------------------------------*/
int xio_on_setup_req_recv(struct xio_connection *connection,
			  struct xio_task *task)
{
	struct xio_msg			*msg = &task->imsg;
	struct xio_new_session_req	req;
	uint8_t				*ptr;
	uint16_t			len;
	struct xio_session_hdr		hdr;
	struct xio_session		*session = connection->session;
	int				retval;
	struct xio_session_event_data  error_event = {};

	error_event.event = XIO_SESSION_ERROR_EVENT;

	/* read session header */
	xio_session_read_header(task, &hdr);
#ifdef XIO_SESSION_DEBUG
	connection->peer_connection = hdr.connection;
	connection->peer_session = hdr.session;
#endif
	task->imsg.sn = hdr.serial_num;
	task->connection = connection;
	task->session = session;
	connection->session->setup_req = msg;

	/* read the header */
	ptr = (uint8_t *)msg->in.header.iov_base;

	memset(&req, 0, sizeof(req));

	/* session id */
	len = xio_read_uint32(&session->peer_session_id, 0, ptr);
	ptr  = ptr + len;

	/* queue depth bytes */
	len = xio_read_uint64(&session->peer_snd_queue_depth_bytes, 0, ptr);
	ptr = ptr + len;

	len = xio_read_uint64(&session->peer_rcv_queue_depth_bytes, 0, ptr);
	ptr = ptr + len;

	/* queue depth msgs */
	len = xio_read_uint16((uint16_t *)&session->peer_snd_queue_depth_msgs,
			      0, ptr);
	ptr = ptr + len;

	len = xio_read_uint16((uint16_t *)&session->peer_rcv_queue_depth_msgs,
			      0, ptr);
	ptr = ptr + len;

	/* uri length */
	len = xio_read_uint16(&req.uri_len, 0, ptr);
	ptr = ptr + len;

	/* private length */
	len = xio_read_uint16(&req.private_data_len, 0, ptr);
	ptr = ptr + len;

	if (req.uri_len) {
		req.uri =
		  (char *)kcalloc(req.uri_len, sizeof(char), GFP_KERNEL);
		if (unlikely(!req.uri)) {
			xio_set_error(ENOMEM);
			ERROR_LOG("uri allocation failed. len:%d\n",
				  req.uri_len);
			goto cleanup1;
		}

		len = xio_read_array((uint8_t *)req.uri,
				     req.uri_len, 0, ptr);
		ptr = ptr + len;
	}
	if (req.private_data_len) {
		req.private_data = kcalloc(req.private_data_len,
					   sizeof(uint8_t), GFP_KERNEL);
		if (unlikely(!req.private_data)) {
			xio_set_error(ENOMEM);
			ERROR_LOG("private data allocation failed. len:%d\n",
				  req.private_data_len);
			goto cleanup2;
		}
		len = xio_read_array((uint8_t *)req.private_data,
				     req.private_data_len,
				     0, ptr);
		ptr = ptr + len;
	}

	req.proto = (enum xio_proto)xio_nexus_get_proto(connection->nexus);
	xio_nexus_get_peer_addr(connection->nexus,
				&req.src_addr, sizeof(req.src_addr));

	/* cache the task in io queue*/
	xio_connection_queue_io_task(connection, task);

	/* notify the upper layer */
	if (connection->ses_ops.on_new_session) {
		retval = connection->ses_ops.on_new_session(
					session, &req,
					connection->cb_user_context);
		if (retval)
			goto cleanup2;
	} else {
		retval = xio_accept(session, NULL, 0, NULL, 0);
		if (retval) {
			ERROR_LOG("failed to auto accept session. session:%p\n",
				  session);
			goto cleanup2;
		}
	}

	/* Don't move session state to ONLINE. In case of multiple portals
	 * the accept moves the state to ACCEPTED until the first "HELLO"
	 * message arrives. Note that the "upper layer" may call redirect or
	 * reject.
	 */

	xio_session_notify_new_connection(session, connection);

	kfree(req.private_data);
	kfree(req.uri);

	return 0;

cleanup2:
	kfree(req.private_data);

cleanup1:
	kfree(req.uri);

	if (session->ses_ops.on_session_event) {
		error_event.reason = (enum xio_status)xio_errno();
		session->ses_ops.on_session_event(
				session, &error_event,
				session->cb_user_context);
	}
	return 0;
}
/*---------------------------------------------------------------------------*/
int run_client_test(struct perf_parameters *user_param)
{
	struct session_data	sess_data;
	struct perf_comm	*comm;
	struct thread_data	*tdata;
	char			url[256];
	int			i = 0;
	int			max_cpus;
	pthread_t		statistics_thread_id;
	struct perf_command	command;
	int			size_log2;
	int			max_size_log2 = 24;


	/* client session attributes */
	struct xio_session_attr attr = {
		&ses_ops,
		NULL,
		0
	};
	xio_init();

	g_mhz		= get_cpu_mhz(0);
	max_cpus	= sysconf(_SC_NPROCESSORS_ONLN);
	threads_iter	= 1;
	size_log2	= 0;

	tdata = calloc(user_param->threads_num, sizeof(*tdata));
	if (tdata == NULL) {
		fprintf(fd, "malloc failed\n");
		return -1;
	}

	comm = create_comm_struct(user_param);
	if (establish_connection(comm)) {
		fprintf(stderr, "failed to establish connection\n");
		free(tdata);
		destroy_comm_struct(comm);
		return -1;
	}

	if (user_param->output_file) {
		fd = fopen(user_param->output_file, "w");
		if (fd == NULL) {
			fprintf(fd, "file open failed. %s\n",
				user_param->output_file);
			free(sess_data.tdata);
			destroy_comm_struct(comm);
			return -1;
		}
		fprintf(fd, "size, threads, tps, bw[Mbps], lat[usec]\n");
		fflush(fd);
	}


	printf("%s", RESULT_FMT);
	printf("%s", RESULT_LINE);


	while (threads_iter <= user_param->threads_num)  {
		data_len	= (uint64_t)1 << size_log2;

		memset(&sess_data, 0, sizeof(sess_data));
		memset(tdata, 0, user_param->threads_num*sizeof(*tdata));
		sess_data.tdata = tdata;

		command.test_param.machine_type	= user_param->machine_type;
		command.test_param.test_type	= user_param->test_type;
		command.test_param.verb		= user_param->verb;
		command.test_param.data_len	= data_len;
		command.command			= GetTestParams;

		ctx_write_data(comm, &command, sizeof(command));

		sprintf(url, "rdma://%s:%d", user_param->server_addr,
			user_param->server_port);
		sess_data.session = xio_session_create(XIO_SESSION_CLIENT,
				&attr, url, 0, 0, &sess_data);
		if (sess_data.session == NULL) {
			int error = xio_errno();
			fprintf(stderr,
				"session creation failed. reason %d - (%s)\n",
				error, xio_strerror(error));
			goto cleanup;
		}

		pthread_create(&statistics_thread_id, NULL,
			       statistics_thread_cb, &sess_data);

		/* spawn threads to handle connection */
		for (i = 0; i < threads_iter; i++) {
			sess_data.tdata[i].affinity		=
				((user_param->cpu + i) % max_cpus);
			sess_data.tdata[i].cid			= i;
			sess_data.tdata[i].sdata		= &sess_data;
			sess_data.tdata[i].user_param		= user_param;
			sess_data.tdata[i].data_len		= data_len;

			/* all threads are working on the same session */
			sess_data.tdata[i].session	= sess_data.session;
			pthread_create(&sess_data.tdata[i].thread_id, NULL,
				       worker_thread, &sess_data.tdata[i]);
		}

		pthread_join(statistics_thread_id, NULL);

		/* join the threads */
		for (i = 0; i < threads_iter; i++)
			pthread_join(sess_data.tdata[i].thread_id, NULL);

		/* close the session */
		xio_session_destroy(sess_data.session);

		if (sess_data.abort) {
			fprintf(stderr, "program aborted\n");
			goto cleanup;
		}

		/* send result to server */
		command.results.bytes		= data_len;
		command.results.threads		= threads_iter;
		command.results.tps		= sess_data.tps;
		command.results.avg_bw		= sess_data.avg_bw;
		command.results.avg_lat		= sess_data.avg_lat_us;
		command.results.min_lat		= sess_data.min_lat_us;
		command.results.max_lat		= sess_data.max_lat_us;
		command.command			= GetTestResults;

		/* sync point */
		ctx_write_data(comm, &command, sizeof(command));

		printf(REPORT_FMT,
		       data_len,
		       threads_iter,
		       sess_data.tps,
		       sess_data.avg_bw,
		       sess_data.avg_lat_us,
		       sess_data.min_lat_us,
		       sess_data.max_lat_us);
		if (fd)
			fprintf(fd, "%lu, %d, %lu, %.2lf, %.2lf\n",
				data_len,
				threads_iter,
				sess_data.tps,
				sess_data.avg_bw,
				sess_data.avg_lat_us);
		fflush(fd);

		/* sync point */
		ctx_read_data(comm, NULL, 0, NULL);

		if (++size_log2 < max_size_log2)
			continue;

		threads_iter++;
		size_log2 = 0;
	}

	printf("%s", RESULT_LINE);

cleanup:
	if (fd)
		fclose(fd);

	ctx_hand_shake(comm);

	ctx_close_connection(comm);

	destroy_comm_struct(comm);

	free(tdata);

	xio_shutdown();

	return 0;
}
/*---------------------------------------------------------------------------*/
static void *worker_thread(void *data)
{
	struct thread_data	*tdata = data;
	cpu_set_t		cpuset;
	struct xio_msg		*msg;
	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);


	/* connect the session  */
	tdata->conn = xio_connect(tdata->session, tdata->ctx,
				  tdata->cid, NULL, tdata);

	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;
		msg->in.data_iovlen = 0;
		msg->out.header.iov_len = 0;
		if (tdata->data_len) {
			msg->out.data_iovlen		= 1;
			msg->out.data_iov[0].iov_base	= tdata->xbuf->addr;
			msg->out.data_iov[0].iov_len	= tdata->xbuf->length;
			msg->out.data_iov[0].mr		= tdata->xbuf->mr;
		} else {
			msg->out.data_iovlen = 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.º 28
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.º 29
0
/*---------------------------------------------------------------------------*/
static int xio_server_main(void *data)
{
	struct xio_server		*server;
	struct xio_context_params	ctx_params;
	char				url[256];

	atomic_add(2, &module_state);

	print_test_config(&test_config);

	g_test_params.finite_run = test_config.finite_run;
	g_test_params.disconnect_nr = PRINT_COUNTER * DISCONNECT_FACTOR;

	memset(&ctx_params, 0, sizeof(ctx_params));
	ctx_params.flags = XIO_LOOP_GIVEN_THREAD;
	ctx_params.worker = current;

	g_test_params.ctx = xio_context_create(&ctx_params,
					       0, g_test_params.cpu);
	if (!g_test_params.ctx) {
		int error = xio_errno();

		pr_err("context creation failed. reason %d - (%s)\n",
		       error, xio_strerror(error));
		goto cleanup;
	}

	sprintf(url, "%s://%s:%d",
		test_config.transport,
		test_config.server_addr,
		test_config.server_port);

	server = xio_bind(g_test_params.ctx, &server_ops,
			  url, NULL, 0, &g_test_params);
	if (server) {
		pr_info("listen to %s\n", url);

		if (atomic_add_unless(&module_state, 4, 0x83))
			xio_context_run_loop(g_test_params.ctx);
		atomic_sub(4, &module_state);

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

		/* free the server */
		xio_unbind(server);
	} else {
		pr_err("**** Error - xio_bind failed - %s. " \
		       "Did you load a transport module?\n",
		       xio_strerror(xio_errno()));
		/*xio_assert(0);*/
	}

	xio_context_destroy(g_test_params.ctx);

	kfree(g_test_params.xbuf);
	g_test_params.xbuf = NULL;

cleanup:

	complete_and_exit(&cleanup_complete, 0);

	return 0;
}
Exemplo n.º 30
0
/*---------------------------------------------------------------------------*/
int xio_on_setup_req_recv(struct xio_connection *connection,
			  struct xio_task *task)
{
	struct xio_msg			*msg = &task->imsg;
	struct xio_new_session_req	req;
	uint8_t				*ptr;
	uint16_t			len;
	struct xio_session_hdr		hdr;
	struct xio_session		*session = connection->session;
	int				retval;
	struct xio_session_event_data  error_event = {
		.conn = NULL,
		.conn_user_context = NULL,
		.event = XIO_SESSION_ERROR_EVENT,
		.reason = XIO_E_SUCCESS,
		.private_data = NULL,
		.private_data_len = 0,
	};

	/* read session header */
	xio_session_read_header(task, &hdr);
#ifdef XIO_SESSION_DEBUG
	connection->peer_connection = hdr.connection;
	connection->peer_session = hdr.session;
#endif
	task->imsg.sn = hdr.serial_num;
	task->connection = connection;
	task->session = session;
	connection->session->setup_req = msg;
	connection->session->connection_srv_first = connection;

	/* read the header */
	ptr = (uint8_t *)msg->in.header.iov_base;

	memset(&req, 0, sizeof(req));

	/* session id */
	len = xio_read_uint32(&session->peer_session_id, 0, ptr);
	ptr  = ptr + len;

	/* queue depth bytes */
	len = xio_read_uint64(&session->peer_snd_queue_depth_bytes, 0, ptr);
	ptr = ptr + len;

	len = xio_read_uint64(&session->peer_rcv_queue_depth_bytes, 0, ptr);
	ptr = ptr + len;

	/* queue depth msgs */
	len = xio_read_uint16((uint16_t *)&session->peer_snd_queue_depth_msgs,
			      0, ptr);
	ptr = ptr + len;

	len = xio_read_uint16((uint16_t *)&session->peer_rcv_queue_depth_msgs,
			      0, ptr);
	ptr = ptr + len;

	/* uri length */
	len = xio_read_uint16(&req.uri_len, 0, ptr);
	ptr = ptr + len;

	/* private length */
	len = xio_read_uint16(&req.private_data_len, 0, ptr);
	ptr = ptr + len;

	if (req.uri_len) {
		req.uri =
		  (char *)kcalloc(req.uri_len, sizeof(char), GFP_KERNEL);
		if (unlikely(!req.uri)) {
			xio_set_error(ENOMEM);
			ERROR_LOG("uri allocation failed. len:%d\n",
				  req.uri_len);
			goto cleanup1;
		}

		len = xio_read_array((uint8_t *)req.uri,
				     req.uri_len, 0, ptr);
		ptr = ptr + len;
	}
	if (req.private_data_len) {
		req.private_data = kcalloc(req.private_data_len,
					   sizeof(uint8_t), GFP_KERNEL);
		if (unlikely(!req.private_data)) {
			xio_set_error(ENOMEM);
			ERROR_LOG("private data allocation failed. len:%d\n",
				  req.private_data_len);
			goto cleanup2;
		}
		len = xio_read_array((uint8_t *)req.private_data,
				     req.private_data_len,
				     0, ptr);
		ptr = ptr + len;
	}

	req.proto = (enum xio_proto)xio_nexus_get_proto(connection->nexus);
	xio_nexus_get_peer_addr(connection->nexus,
				&req.src_addr, sizeof(req.src_addr));

	/* cache the task in io queue*/
	xio_connection_queue_io_task(connection, task);

	/* notify the upper layer */
	if (connection->ses_ops.on_new_session) {
#ifdef XIO_THREAD_SAFE_DEBUG
		xio_ctx_debug_thread_unlock(connection->ctx);
#endif
		retval = connection->ses_ops.on_new_session(
					session, &req,
					connection->cb_user_context);
#ifdef XIO_THREAD_SAFE_DEBUG
		xio_ctx_debug_thread_lock(connection->ctx);
#endif
		if (retval)
			goto cleanup2;
	} else {
		retval = xio_accept(session, NULL, 0, NULL, 0);
		if (retval) {
			ERROR_LOG("failed to auto accept session. session:%p\n",
				  session);
			goto cleanup2;
		}
	}

	/* Don't move session state to ONLINE. In case of multiple portals
	 * the accept moves the state to ACCEPTED until the first "HELLO"
	 * message arrives. Note that the "upper layer" may call redirect or
	 * reject.
	 */

	xio_session_notify_new_connection(session, connection);

	kfree(req.private_data);
	kfree(req.uri);

	return 0;

cleanup2:
	kfree(req.private_data);

cleanup1:
	kfree(req.uri);

	if (session->ses_ops.on_session_event) {
#ifdef XIO_THREAD_SAFE_DEBUG
		xio_ctx_debug_thread_unlock(connection->ctx);
#endif
		error_event.reason = (enum xio_status)xio_errno();
		session->ses_ops.on_session_event(
				session, &error_event,
				session->cb_user_context);
#ifdef XIO_THREAD_SAFE_DEBUG
		xio_ctx_debug_thread_lock(connection->ctx);
#endif
	}
	return 0;
}

/*---------------------------------------------------------------------------*/
/* xio_session_write_accept_rsp						     */
/*---------------------------------------------------------------------------*/
struct xio_msg *xio_session_write_accept_rsp(struct xio_session *session,
					     uint16_t action,
					     const char **portals_array,
					     uint16_t portals_array_len,
					     void *user_context,
					     uint16_t user_context_len)
{
	struct xio_msg		*msg;
	uint8_t			*buf;
	uint8_t			*ptr;
	uint16_t		len, i, str_len, tot_len;

	/* calculate length */
	tot_len = 5*sizeof(uint16_t) + sizeof(uint32_t) + 2*sizeof(uint64_t);
	for (i = 0; i < portals_array_len; i++)
		tot_len += strlen(portals_array[i]) + sizeof(uint16_t);
	tot_len += user_context_len;

	if (tot_len > SETUP_BUFFER_LEN)  {
		ERROR_LOG("buffer is too small\n");
		xio_set_error(EMSGSIZE);
		return NULL;
	}

	/* allocate message */
	buf = (uint8_t *)kcalloc(SETUP_BUFFER_LEN + sizeof(struct xio_msg),
		      sizeof(uint8_t), GFP_KERNEL);
	if (unlikely(!buf)) {
		ERROR_LOG("message allocation failed\n");
		xio_set_error(ENOMEM);
		return NULL;
	}

	/* fill the message */
	msg = (struct xio_msg *)buf;
	msg->out.header.iov_base = buf + sizeof(struct xio_msg);
	msg->out.header.iov_len = 0;

	ptr = (uint8_t *)msg->out.header.iov_base;
	len = 0;

	/* serialize message into the buffer */

	/* session_id */
	len = xio_write_uint32(session->session_id, 0, ptr);
	ptr  = ptr + len;

	/* action */
	len = xio_write_uint16(action, 0, ptr);
	ptr  = ptr + len;

	if (action == XIO_ACTION_ACCEPT) {
		/* tx queue depth bytes */
		len = xio_write_uint64(session->snd_queue_depth_bytes, 0, ptr);
		ptr  = ptr + len;

		/* rx queue depth bytes */
		len = xio_write_uint64(session->rcv_queue_depth_bytes, 0, ptr);
		ptr  = ptr + len;

		/* tx queue depth msgs */
		len = xio_write_uint16(session->snd_queue_depth_msgs, 0, ptr);
		ptr  = ptr + len;

		/* rx queue depth msgs */
		len = xio_write_uint16(session->rcv_queue_depth_msgs, 0, ptr);
		ptr  = ptr + len;
	}

	/* portals_array_len */
	len = xio_write_uint16(portals_array_len, 0, ptr);
	ptr  = ptr + len;

	/* user_context_len */
	len = xio_write_uint16(user_context_len, 0, ptr);
	ptr  = ptr + len;

	for (i = 0; i < portals_array_len; i++) {
		str_len = strlen(portals_array[i]);

		len = xio_write_uint16(str_len, 0, ptr);
		ptr  = ptr + len;

		len = xio_write_array((uint8_t *)portals_array[i],
				      str_len, 0, ptr);
		ptr  = ptr + len;
	}

	if (user_context_len) {
		len = xio_write_array((const uint8_t *)user_context,
				      user_context_len,
				      0, ptr);
		ptr  = ptr + len;
	}

	msg->out.header.iov_len = ptr - (uint8_t *)msg->out.header.iov_base;

	if (msg->out.header.iov_len != tot_len) {
		ERROR_LOG("calculated length %d != actual length %zd\n",
			  tot_len, msg->out.header.iov_len);
	}

	return msg;
}

/*---------------------------------------------------------------------------*/
/* xio_session_write_reject_rsp						     */
/*---------------------------------------------------------------------------*/
struct xio_msg *xio_session_write_reject_rsp(struct xio_session *session,
					     enum xio_status reason,
					     void *user_context,
					     uint16_t user_context_len)
{
	struct xio_msg	*msg;
	uint8_t			*buf;
	uint8_t			*ptr;
	uint16_t		len,  tot_len;
	uint16_t		action = XIO_ACTION_REJECT;

	/* calclate length */
	tot_len = 2*sizeof(uint16_t) + 2*sizeof(uint32_t);
	tot_len += user_context_len;

	if (tot_len > SETUP_BUFFER_LEN)  {
		ERROR_LOG("buffer is too small\n");
		xio_set_error(EMSGSIZE);
		return NULL;
	}

	/* allocate message */
	buf = (uint8_t *)kcalloc(SETUP_BUFFER_LEN + sizeof(struct xio_msg),
		      sizeof(uint8_t), GFP_KERNEL);
	if (!buf) {
		ERROR_LOG("message allocation failed\n");
		xio_set_error(ENOMEM);
		return NULL;
	}

	/* fill the message */
	msg = (struct xio_msg *)buf;
	msg->out.header.iov_base = buf + sizeof(struct xio_msg);
	msg->out.header.iov_len = 0;

	ptr = (uint8_t *)msg->out.header.iov_base;
	len = 0;

	/* serialize message into the buffer */

	/* session_id */
	len = xio_write_uint32(session->session_id, 0, ptr);
	ptr  = ptr + len;

	/* action */
	len = xio_write_uint16(action, 0, ptr);
	ptr  = ptr + len;

	/* reason */
	len = xio_write_uint32(reason, 0, ptr);
	ptr  = ptr + len;

	/* user_context_len */
	len = xio_write_uint16(user_context_len, 0, ptr);
	ptr  = ptr + len;

	if (user_context_len) {
		len = xio_write_array((const uint8_t *)user_context,
				      user_context_len,
				      0, ptr);
		ptr  = ptr + len;
	}

	msg->out.header.iov_len = ptr - (uint8_t *)msg->out.header.iov_base;

	if (msg->out.header.iov_len != tot_len) {
		ERROR_LOG("calculated length %d != actual length %zd\n",
			  tot_len, msg->out.header.iov_len);
	}

	return msg;
}

/*---------------------------------------------------------------------------*/
/* xio_accept								     */
/*---------------------------------------------------------------------------*/
int xio_accept(struct xio_session *session,
	       const char **portals_array,
	       size_t portals_array_len,
	       void *user_context,
	       size_t user_context_len)
{
	int			retval = 0;
	struct xio_msg		*msg;
	struct xio_task		*task;

	msg = xio_session_write_accept_rsp(session,
					   XIO_ACTION_ACCEPT,
					   portals_array,
					   portals_array_len,
					   user_context,
					   user_context_len);
	if (!msg) {
		ERROR_LOG("setup request creation failed\n");
		return -1;
	}

	msg->request	= session->setup_req;
	msg->type	= (enum xio_msg_type)XIO_SESSION_SETUP_RSP;

	task = container_of(msg->request,
			    struct xio_task, imsg);

	if (portals_array_len != 0) {
		/* server side state is changed to ACCEPT, will be move to
		 * ONLINE state when first "hello" message arrives
		 */
		session->state = XIO_SESSION_STATE_ACCEPTED;
		/* temporary disable teardown */
		session->disable_teardown = 1;
		TRACE_LOG("session state is now ACCEPT. session:%p\n",
			  session);
	} else {
		/* initialize credits */
		task->connection->peer_credits_msgs =
					session->peer_rcv_queue_depth_msgs;
		task->connection->credits_msgs	= 0;
		task->connection->peer_credits_bytes =
					session->peer_rcv_queue_depth_bytes;
		task->connection->credits_bytes	= 0;

		/* server side state is changed to ONLINE, immediately  */
		session->state = XIO_SESSION_STATE_ONLINE;
		TRACE_LOG("session state changed to ONLINE. session:%p\n",
			  session);
	}
	retval = xio_connection_send(task->connection, msg);
	if (retval && retval != -EAGAIN) {
		ERROR_LOG("failed to send message. errno:%d\n", -retval);
		xio_set_error(-retval);
		return -1;
	}

	return 0;
}