Esempio n. 1
0
struct xio_session *sd_xio_gw_create_session(struct xio_context *ctx,
					     const struct node_id *nid,
					     void *user_ctx)
{
	struct xio_session *session;
	char url[256];
	struct xio_session_params params;

	if (nid->io_transport_type == IO_TRANSPORT_TYPE_RDMA)
		snprintf(url, 256, "rdma://%s",
			 addr_to_str(nid->io_addr, nid->io_port));
	else
		snprintf(url, 256, "tcp://%s",
			 addr_to_str(nid->io_addr, nid->io_port));

	memset(&params, 0, sizeof(params));
	params.type = XIO_SESSION_CLIENT;
	params.ses_ops = &gw_client_ses_ops;
	params.uri = url;
	params.user_context = user_ctx;

	session = xio_session_create(&params);

	return session;
}
Esempio n. 2
0
/*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
	struct xio_session	*session;
	char			url[256];
	struct session_data	session_data;
	int			i = 0;
	struct xio_session_params params;

	if (argc < 3) {
		printf("Usage: %s <host> <port> <transport:optional>\n",
		       argv[0]);
		exit(1);
	}
	memset(&session_data, 0, sizeof(session_data));
	memset(&params, 0, sizeof(params));

	/* initialize library */
	xio_init();

	/* create thread context for the client */
	session_data.ctx = xio_context_create(NULL, 0, -1);


	/* create url to connect to */
	if (argc > 3)
		sprintf(url, "%s://%s:%s", argv[3], argv[1], argv[2]);
	else
		sprintf(url, "rdma://%s:%s", argv[1], argv[2]);

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

	session = xio_session_create(&params);

	/* connect the session  */
	session_data.conn = xio_connect(session, session_data.ctx,
					0, NULL, &session_data);

	/* create "hello world" message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		memset(&session_data.req[i], 0, sizeof(session_data.req[i]));
		/* header */
		session_data.req[i].out.header.iov_base =
			strdup("hello world header request");
		session_data.req[i].out.header.iov_len =
			strlen(session_data.req[i].out.header.iov_base) + 1;
		/* iovec[0]*/
		session_data.req[i].in.sgl_type		  = XIO_SGL_TYPE_IOV;
		session_data.req[i].in.data_iov.max_nents = XIO_IOVLEN;

		session_data.req[i].out.sgl_type	   = XIO_SGL_TYPE_IOV;
		session_data.req[i].out.data_iov.max_nents = XIO_IOVLEN;

		session_data.req[i].out.data_iov.sglist[0].iov_base =
			strdup("hello world data request");

		session_data.req[i].out.data_iov.sglist[0].iov_len =
			strlen(session_data.req[i].out.data_iov.sglist[0].iov_base) + 1;

		session_data.req[i].out.data_iov.nents = 1;
	}
	/* send first message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		xio_send_request(session_data.conn, &session_data.req[i]);
		session_data.nsent++;
	}

	/* event dispatcher is now running */
	xio_context_run_loop(session_data.ctx, XIO_INFINITE);

	/* normal exit phase */
	fprintf(stdout, "exit signaled\n");

	/* free the message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		free(session_data.req[i].out.header.iov_base);
		free(session_data.req[i].out.data_iov.sglist[0].iov_base);
	}

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

	xio_shutdown();

	printf("good bye\n");
	return 0;
}
Esempio n. 3
0
/*---------------------------------------------------------------------------*/
int main(int argc, char *const argv[])
{
	struct xio_session	*session;
	char			url[256];
	int			i;
	struct sigaction	sa;
	int			c;
	char			*addr = NULL;
	char			*port = NULL;
	char			*trans = NULL;
	struct xio_session_params params;
	struct xio_connection_params cparams;

	while (1) {
		c = getopt_long(argc, argv, "a:p:r:hdnV", longopts, NULL);
		if (c == -1)
			break;

		switch (c) {
		case 'a':
			addr = optarg;
			break;
		case 'p':
			port = optarg;
			break;
		case 'r':
			trans = optarg;
			break;
		case 'h':
			usage(argv[0], 0);
		case 'd':
			debug_flag++;
			nofork_flag++;
			break;
		case 'n':
			nofork_flag++;
			break;
		case 'V':
			printf("%s\n", PACKAGE_STRING);
			exit(0);
			break;
		default:
			usage(argv[0], 1);
			break;
		}
	}

	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = signal_handler;
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGQUIT, &sa, NULL);
	sigaction(SIGHUP, &sa, NULL);

	sa.sa_handler = SIG_IGN;
	sa.sa_flags = SA_RESTART;
	sigaction(SIGPIPE, &sa, NULL);


	if (!nofork_flag && daemon(0, 0)) {
		logerr("daemon() failed");
		exit(1);
	}

	if (!debug_flag) {
		openlog("xioclntd", LOG_PID, LOG_DAEMON);
		use_syslog = 1;
	}

	/* Create the process PID file */
	if (create_pidfile(pid_file) != 0)
		exit(EXIT_FAILURE);

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

	/* initialize library */
	xio_init();

	/* create "hello world" message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		memset(&session_data.req[i], 0, sizeof(session_data.req[i]));
		/* header */
		session_data.req[i].out.header.iov_base =
			strdup("hello world header request");
		session_data.req[i].out.header.iov_len =
			strlen((const char *)
				session_data.req[i].out.header.iov_base) + 1;
		/* iovec[0]*/
		session_data.req[i].out.sgl_type	   = XIO_SGL_TYPE_IOV;
		session_data.req[i].out.data_iov.max_nents = XIO_IOVLEN;

		session_data.req[i].out.data_iov.sglist[0].iov_base =
			strdup("hello world iovec request");

		session_data.req[i].out.data_iov.sglist[0].iov_len =
			strlen((const char *)
				session_data.req[i].out.data_iov.sglist[0].iov_base) + 1;

		session_data.req[i].out.data_iov.nents = 1;
	}
	/* create thread context for the client */
	session_data.ctx = xio_context_create(NULL, 0, -1);

	/* create url to connect to */
	if (trans)
		sprintf(url, "%s://%s:%s", trans, addr, port);
	else
		sprintf(url, "rdma://%s:%s", addr, port);

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


reconnect:
	session = xio_session_create(&params);

	cparams.session			= session;
	cparams.ctx			= session_data.ctx;
	cparams.conn_user_context	= &session_data;

	/* connect the session  */
	session_data.conn = xio_connect(&cparams);

	/* event dispatcher is now running */
	xio_context_run_loop(session_data.ctx, XIO_INFINITE);

	if (reconnect_flag || reload_flag) {
		session_data.cnt = 0;
		if (reconnect_flag)
			sleep(1);
		reload_flag = 0;
		reconnect_flag = 0;
		goto reconnect;
	}

	/* normal exit phase */
	logit(LOG_INFO, "exit signaled\n");

	/* free the message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		free(session_data.req[i].out.header.iov_base);
		free(session_data.req[i].out.data_iov.sglist[0].iov_base);
	}

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

	xio_shutdown();

	remove_pidfile();

	if (use_syslog)
		closelog();

	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;
}
Esempio n. 5
0
/*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
	struct xio_session	*session;
	char			url[256];
	struct session_data	session_data;
	int			i = 0;

	/* client session attributes */
	struct xio_session_attr attr = {
		&ses_ops, /* callbacks structure */
		NULL,	  /* no need to pass the server private data */
		0
	};
	memset(&session_data, 0, sizeof(session_data));

	/* initialize library */
	xio_init();

	/* create thread context for the client */
	session_data.ctx = xio_context_create(NULL, 0);


	/* create url to connect to */
	sprintf(url, "rdma://%s:%s", argv[1], argv[2]);
	session = xio_session_create(XIO_SESSION_CLIENT,
				   &attr, url, 0, 0, &session_data);

	/* connect the session  */
	session_data.conn = xio_connect(session, session_data.ctx,
					0, NULL, &session_data);

	/* create "hello world" message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		memset(&session_data.req[i], 0, sizeof(session_data.req[i]));
		session_data.req[i].out.header.iov_base =
			strdup("hello world header request");
		session_data.req[i].out.header.iov_len =
			strlen(session_data.req[i].out.header.iov_base) + 1;
	}
	/* send first message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		xio_send_request(session_data.conn, &session_data.req[i]);
		session_data.nsent++;
	}

	/* event dispatcher is now running */
	xio_context_run_loop(session_data.ctx, XIO_INFINITE);

	/* normal exit phase */
	fprintf(stdout, "exit signaled\n");

	/* free the message */
	for (i = 0; i < QUEUE_DEPTH; i++)
		free(session_data.req[i].out.header.iov_base);

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

	xio_shutdown();

	printf("good bye\n");
	return 0;
}
Esempio n. 6
0
/*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
	struct xio_session	*session;
	char			url[256];
	struct session_data	session_data;
	int			i = 0;
	struct event		timeout;
	struct event		xio_event;
	struct timeval		tv;
	struct xio_poll_params  poll_params;
	struct xio_session_params params;

	if (argc < 3) {
		printf("Usage: %s <host> <port> <transport:optional>\n",
		       argv[0]);
		exit(1);
	}
	memset(&session_data, 0, sizeof(session_data));
	memset(&params, 0, sizeof(params));

	/* initialize library */
	xio_init();

	/* create thread context for the client */
	session_data.ctx = xio_context_create(NULL, 0, -1);

	/* get poll parameters for libevent */
	xio_context_get_poll_params(session_data.ctx, &poll_params);

	/* create url to connect to */
	if (argc > 3)
		sprintf(url, "%s://%s:%s", argv[3], argv[1], argv[2]);
	else
		sprintf(url, "rdma://%s:%s", argv[1], argv[2]);
	params.type		= XIO_SESSION_CLIENT;
	params.ses_ops		= &ses_ops;
	params.user_context	= &session_data;
	params.uri		= url;

	session = xio_session_create(&params);

	/* connect the session  */
	session_data.conn = xio_connect(session, session_data.ctx,
					0, NULL, &session_data);

	/* create "hello world" message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		memset(&session_data.req[i], 0, sizeof(session_data.req[i]));
		/* header */
		session_data.req[i].out.header.iov_base =
			strdup("hello world header request");
		session_data.req[i].out.header.iov_len =
			strlen(session_data.req[i].out.header.iov_base) + 1;
		/* iovec[0]*/
		session_data.req[i].out.sgl_type	   = XIO_SGL_TYPE_IOV;
		session_data.req[i].out.data_iov.max_nents = XIO_IOVLEN;

		session_data.req[i].out.data_iov.sglist[0].iov_base =
			strdup("hello world iovec request");
		session_data.req[i].out.data_iov.sglist[0].iov_len =
			strlen(session_data.req[i].out.data_iov.sglist[0].iov_base) + 1;
		session_data.req[i].out.data_iov.nents = 1;
	}
	/* send first message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		xio_send_request(session_data.conn, &session_data.req[i]);
		session_data.nsent++;
	}

	/* Initialize the event library */
	session_data.evbase = event_base_new();

	/* Initialize one timer event */
	event_assign(&timeout, session_data.evbase, -1,
		     EV_PERSIST, timeout_cb, (void *)&timeout);

	evutil_timerclear(&tv);
	tv.tv_sec = 2;
	event_add(&timeout, &tv);

	event_assign(&xio_event, session_data.evbase, poll_params.fd,
		     EV_READ|EV_PERSIST, xio_event_handler,
		     (void *)&poll_params);

	/* Add it to the active events, without a timeout */
	event_add(&xio_event, NULL);

	event_base_dispatch(session_data.evbase);

	fprintf(stdout, "exit signaled\n");

	event_base_free(session_data.evbase);

	/* free the message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		free(session_data.req[i].out.header.iov_base);
		free(session_data.req[i].out.data_iov.sglist[0].iov_base);
	}

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

	xio_shutdown();

	printf("good bye\n");
	return 0;
}
Esempio n. 7
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;
}
Esempio n. 8
0
/* first message after new connection are going trough the server */
static int xio_on_new_message(struct xio_server *server,
			      struct xio_nexus *nexus,
			      int event,
			      union xio_nexus_event_data *event_data)
{
	struct xio_session		*session = NULL;
	struct xio_connection		*connection = NULL;
	struct xio_connection		*connection1 = NULL;
	struct xio_task			*task;
	uint32_t			tlv_type;
	struct xio_session_params	params;
	int				locked = 0;

	if (!server || !nexus || !event_data || !event_data->msg.task) {
		ERROR_LOG("server [new session]: failed " \
			  "invalid parameter\n");
		return -1;
	}
	task			= event_data->msg.task;

	params.type		= XIO_SESSION_SERVER;
	params.initial_sn	= 0;
	params.ses_ops		= &server->ops;
	params.uri		= server->uri;
	params.private_data	= NULL;
	params.private_data_len = 0;
	params.user_context	= server->cb_private_data;

	/* read the first message  type */
	tlv_type = xio_read_tlv_type(&event_data->msg.task->mbuf);

	if (tlv_type == XIO_SESSION_SETUP_REQ) {
		/* create new session */
		session = xio_session_create(&params);
		if (!session) {
			ERROR_LOG("server [new session]: failed " \
				"  allocating session failed\n");
			return -1;
		}
		DEBUG_LOG("server [new session]: server:%p, " \
			  "session:%p, nexus:%p ,session_id:%d\n",
			  server, session, nexus, session->session_id);

		/* get transport class routines */
		session->validators_cls = xio_nexus_get_validators_cls(nexus);

		connection =
			xio_session_alloc_connection(session,
						     server->ctx, 0,
						     server->cb_private_data);
		if (!connection) {
			ERROR_LOG("server failed to allocate new connection\n");
			goto cleanup;
		}
		connection1 = xio_session_assign_nexus(session, nexus);
		if (!connection1) {
			ERROR_LOG("server failed to assign new connection\n");
			goto cleanup1;
		}
		connection = connection1;

		xio_idr_add_uobj(usr_idr, session, "xio_session");
		xio_idr_add_uobj(usr_idr, connection, "xio_connection");
		xio_connection_set_state(connection,
					 XIO_CONNECTION_STATE_ONLINE);

		xio_connection_keepalive_start(connection);

		task->session		= session;
		task->connection	= connection;
	} else if (tlv_type == XIO_CONNECTION_HELLO_REQ) {
		struct xio_session *session1;
		/* find the old session without lock */
		session = xio_find_session(event_data->msg.task);
		if (!session) {
			ERROR_LOG("server [new connection]: failed " \
				  "session not found. server:%p\n",
				  server);
			xio_nexus_close(nexus, NULL);
			return -1;
		}
		/* lock it and retry find */
		mutex_lock(&session->lock);
		/* session before destruction - try to lock before continue */
		session1 = xio_find_session(event_data->msg.task);
		if (!session1) {
			ERROR_LOG("server [new connection]: failed " \
				  "session not found. server:%p\n",
				  server);
			xio_nexus_close(nexus, NULL);
			mutex_unlock(&session->lock);
			return -1;
		}
		locked = 1;
		task->session = session;

		DEBUG_LOG("server [new connection]: server:%p, " \
			  "session:%p, nexus:%p, session_id:%d\n",
			   server, session, nexus, session->session_id);

		connection = xio_session_alloc_connection(
				task->session,
				server->ctx, 0,
				server->cb_private_data);

		if (!connection) {
			ERROR_LOG("server failed to allocate new connection\n");
			goto cleanup;
		}
		connection1 = xio_session_assign_nexus(task->session, nexus);
		if (!connection1) {
			ERROR_LOG("server failed to assign new connection\n");
			goto cleanup1;
		}
		connection = connection1;

		/* copy the server attributes to the connection */
		xio_connection_set_ops(connection, &server->ops);

		task->connection = connection;

		/* This in a multiple-portal situation */
		session->state = XIO_SESSION_STATE_ONLINE;
		xio_connection_set_state(connection,
					 XIO_CONNECTION_STATE_ONLINE);

		xio_connection_keepalive_start(connection);

		xio_idr_add_uobj(usr_idr, connection, "xio_connection");
	} else {
		ERROR_LOG("server unexpected message\n");
		return -1;
	}

	/* route the message to the session */
	if (session)
		xio_nexus_notify_observer(nexus, &session->observer,
					  event, event_data);
	if (locked)
		mutex_unlock(&session->lock);

	return 0;

cleanup1:
	if (connection)
		xio_session_free_connection(connection);

cleanup:
	if (session)
		xio_session_destroy(session);

	return -1;
}
Esempio n. 9
0
/*---------------------------------------------------------------------------*/
static int xio_client_main(void *data)
{
	char **argv = (char **)data;

	struct xio_session	*session;
	struct xio_session_params params;
	struct xio_context_params ctx_params;
	struct xio_connection_params cparams;
	char			url[256];
	struct xio_context	*ctx;
	struct session_data	*session_data;
	int			i = 0;

	atomic_add(2, &module_state);

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

	/* create thread context for the client */
	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(session_data);
		pr_err("context open filed\n");
		return 0;
	}

	session_data->ctx = ctx;

	/* create url to connect to */
	sprintf(url, "rdma://%s:%s", argv[1], argv[2]);

	memset(&params, 0, sizeof(params));
	params.type		= XIO_SESSION_CLIENT;
	params.ses_ops		= &ses_ops;
	params.user_context	= session_data;
	params.uri		= url;

	session = xio_session_create(&params);

	memset(&cparams, 0, sizeof(cparams));
	cparams.session			= session;
	cparams.ctx			= ctx;
	cparams.conn_user_context	= session_data;

	/* connect the session  */
	session_data->session = session;
	session_data->connection = xio_connect(&cparams);

	/* create "hello world" message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		struct xio_vmsg *omsg;
		void *buf;

		omsg = &session_data->req[i].out;

		memset(&session_data->req[i], 0, sizeof(session_data->req[i]));

		/* header */
		buf = kstrdup("hello world header request", GFP_KERNEL);
		session_data->req[i].out.header.iov_base = buf;
		session_data->req[i].out.header.iov_len = strlen(buf) + 1;
		/* iovec[0]*/
		omsg->sgl_type = XIO_SGL_TYPE_SCATTERLIST;
		sg_alloc_table(&omsg->data_tbl, SG_TBL_LEN, GFP_KERNEL);

		/* currently only one entry */
		buf = kstrdup("hello world iovec request", GFP_KERNEL);
		sg_init_one(omsg->data_tbl.sgl, buf, strlen(buf) + 1);
		/* orig_nents is XIO_IOVLEN */
		omsg->data_tbl.nents = 1;
	}

	/* send first message */
	for (i = 0; i < QUEUE_DEPTH; i++)
		xio_send_request(session_data->connection,
				 &session_data->req[i]);

	g_session_data = session_data;

	/* the default xio supplied main loop */
	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 message */
	for (i = 0; i < QUEUE_DEPTH; i++) {
		kfree(session_data->req[i].out.header.iov_base);
		/* Currently need to release only one entry */
		kfree(sg_virt(session_data->req[i].out.data_tbl.sgl));
		sg_free_table(&session_data->req[i].out.data_tbl);
	}

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

	vfree(session_data);

	pr_info("good bye\n");

	complete_and_exit(&cleanup_complete, 0);

	return 0;
}