sock: Add impl_name parameter in spdk_sock_listen/connect.

Purpose: With this patch,

(1)We can support using different sock implementations in
one application together.

(2)For one IP address managed by kernel, we can use different method
to listen/connect, e.g., posix, or uring. With this patch, we can
designate the specified sock implementation if impl_name is not NULL
and valid. Otherwise, spdk_sock_listen/connect will try to use the sock
implementations in the list by order if impl_name is NULL.

Without this patch, the app will always use the same type of sock implementation
if the order is fixed. For example, if we have posix and uring together,
the first one will always be uring.

Signed-off-by: Ziye Yang <ziye.yang@intel.com>
Change-Id: Ic49563f5025085471d356798e522ff7ab748f586
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/478140
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Ziye Yang 2019-12-17 21:57:10 +08:00 committed by Tomasz Zawadzki
parent 738b9569f0
commit 0bfaaace8f
9 changed files with 55 additions and 31 deletions

View File

@ -25,6 +25,10 @@ never return EAGAIN, instead queueing internally until the data has all been sen
simplify many code flows that create pollers to continue attempting to flush writes
on sockets.
Added `impl_name` parameter in spdk_sock_listen and spdk_sock_connect functions. Users may now
specify the sock layer implementation they'd prefer to use. Valid implementations are currently
"vpp" and "posix" and NULL, where NULL results in the previous behavior of the functions.
### isa-l
Updated ISA-L submodule to commit f3993f5c0b6911 which includes implementation and

View File

@ -213,7 +213,7 @@ hello_sock_connect(struct hello_context_t *ctx)
SPDK_NOTICELOG("Connecting to the server on %s:%d\n", ctx->host, ctx->port);
ctx->sock = spdk_sock_connect(ctx->host, ctx->port);
ctx->sock = spdk_sock_connect(ctx->host, ctx->port, NULL);
if (ctx->sock == NULL) {
SPDK_ERRLOG("connect error(%d): %s\n", errno, spdk_strerror(errno));
return -1;
@ -340,7 +340,7 @@ hello_sock_group_poll(void *arg)
static int
hello_sock_listen(struct hello_context_t *ctx)
{
ctx->sock = spdk_sock_listen(ctx->host, ctx->port);
ctx->sock = spdk_sock_listen(ctx->host, ctx->port, NULL);
if (ctx->sock == NULL) {
SPDK_ERRLOG("Cannot create server socket\n");
return -1;

View File

@ -96,26 +96,36 @@ int spdk_sock_getaddr(struct spdk_sock *sock, char *saddr, int slen, uint16_t *s
char *caddr, int clen, uint16_t *cport);
/**
* Create a socket, connect the socket to the specified address and port (of the
* server), and then return the socket. This function is used by client.
* Create a socket using the specific sock implementation, connect the socket
* to the specified address and port (of the server), and then return the socket.
* This function is used by client.
*
* \param ip IP address of the server.
* \param port Port number of the server.
* \param impl_name The sock_implementation to use, such as "posix". If impl_name is
* specified, it will *only* try to listen on that impl. If it is NULL, it will try
* all the sock implementations in order and uses the first sock implementation which
* can connect. For example, it will try vpp, posix as an example.
*
* \return a pointer to the connected socket on success, or NULL on failure.
*/
struct spdk_sock *spdk_sock_connect(const char *ip, int port);
struct spdk_sock *spdk_sock_connect(const char *ip, int port, char *impl_name);
/**
* Create a socket, bind the socket to the specified address and port and listen
* on the socket, and then return the socket. This function is used by server.
* Create a socket using the specific sock implementation, bind the socket to
* the specified address and port and listen on the socket, and then return the socket.
* This function is used by server.
*
* \param ip IP address to listen on.
* \param port Port number.
* \param impl_name The sock_implementation to use, such as "posix". If impl_name is
* specified, it will *only* try to listen on that impl. If it is NULL, it will try
* all the sock implementations in order and uses the first sock implementation which
* can listen. For example, it will try vpp, posix as an example.
*
* \return a pointer to the listened socket on success, or NULL on failure.
*/
struct spdk_sock *spdk_sock_listen(const char *ip, int port);
struct spdk_sock *spdk_sock_listen(const char *ip, int port, char *impl_name);
/**
* Accept a new connection from a client on the specified socket and return a

View File

@ -207,7 +207,7 @@ iscsi_portal_open(struct spdk_iscsi_portal *p)
}
port = (int)strtol(p->port, NULL, 0);
sock = spdk_sock_listen(p->host, port);
sock = spdk_sock_listen(p->host, port, NULL);
if (sock == NULL) {
SPDK_ERRLOG("listen error %.64s.%d\n", p->host, port);
return -1;

View File

@ -1574,7 +1574,7 @@ nvme_tcp_ctrlr_connect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpa
return -1;
}
tqpair->sock = spdk_sock_connect(ctrlr->trid.traddr, port);
tqpair->sock = spdk_sock_connect(ctrlr->trid.traddr, port, NULL);
if (!tqpair->sock) {
SPDK_ERRLOG("sock connection error of tqpair=%p with addr=%s, port=%ld\n",
tqpair, ctrlr->trid.traddr, port);

View File

@ -691,7 +691,7 @@ spdk_nvmf_tcp_listen(struct spdk_nvmf_transport *transport,
return -ENOMEM;
}
port->listen_sock = spdk_sock_listen(trid->traddr, trsvcid_int);
port->listen_sock = spdk_sock_listen(trid->traddr, trsvcid_int, NULL);
if (port->listen_sock == NULL) {
SPDK_ERRLOG("spdk_sock_listen(%s, %d) failed: %s (%d)\n",
trid->traddr, trsvcid_int,

View File

@ -169,12 +169,16 @@ spdk_sock_getaddr(struct spdk_sock *sock, char *saddr, int slen, uint16_t *sport
}
struct spdk_sock *
spdk_sock_connect(const char *ip, int port)
spdk_sock_connect(const char *ip, int port, char *impl_name)
{
struct spdk_net_impl *impl = NULL;
struct spdk_sock *sock;
STAILQ_FOREACH_FROM(impl, &g_net_impls, link) {
if (impl_name && strncmp(impl_name, impl->name, strlen(impl->name) + 1)) {
continue;
}
sock = impl->connect(ip, port);
if (sock != NULL) {
sock->net_impl = impl;
@ -188,12 +192,16 @@ spdk_sock_connect(const char *ip, int port)
}
struct spdk_sock *
spdk_sock_listen(const char *ip, int port)
spdk_sock_listen(const char *ip, int port, char *impl_name)
{
struct spdk_net_impl *impl = NULL;
struct spdk_sock *sock;
STAILQ_FOREACH_FROM(impl, &g_net_impls, link) {
if (impl_name && strncmp(impl_name, impl->name, strlen(impl->name) + 1)) {
continue;
}
sock = impl->listen(ip, port);
if (sock != NULL) {
sock->net_impl = impl;

View File

@ -38,8 +38,10 @@
DEFINE_STUB(spdk_sock_getaddr, int, (struct spdk_sock *sock, char *saddr, int slen, uint16_t *sport,
char *caddr, int clen, uint16_t *cport), 0);
DEFINE_STUB(spdk_sock_connect, struct spdk_sock *, (const char *ip, int port), NULL);
DEFINE_STUB(spdk_sock_listen, struct spdk_sock *, (const char *ip, int port), NULL);
DEFINE_STUB(spdk_sock_connect, struct spdk_sock *, (const char *ip, int port, char *impl_name),
NULL);
DEFINE_STUB(spdk_sock_listen, struct spdk_sock *, (const char *ip, int port, char *impl_name),
NULL);
DEFINE_STUB(spdk_sock_accept, struct spdk_sock *, (struct spdk_sock *sock), NULL);
DEFINE_STUB(spdk_sock_close, int, (struct spdk_sock **sock), 0);
DEFINE_STUB(spdk_sock_recv, ssize_t, (struct spdk_sock *sock, void *buf, size_t len), 0);

View File

@ -359,7 +359,7 @@ static struct spdk_net_impl g_ut_net_impl = {
SPDK_NET_IMPL_REGISTER(ut, &g_ut_net_impl);
static void
_sock(const char *ip, int port)
_sock(const char *ip, int port, char *impl_name)
{
struct spdk_sock *listen_sock;
struct spdk_sock *server_sock;
@ -370,14 +370,14 @@ _sock(const char *ip, int port)
struct iovec iov;
int rc;
listen_sock = spdk_sock_listen(ip, port);
listen_sock = spdk_sock_listen(ip, port, impl_name);
SPDK_CU_ASSERT_FATAL(listen_sock != NULL);
server_sock = spdk_sock_accept(listen_sock);
CU_ASSERT(server_sock == NULL);
CU_ASSERT(errno == EAGAIN || errno == EWOULDBLOCK);
client_sock = spdk_sock_connect(ip, port);
client_sock = spdk_sock_connect(ip, port, impl_name);
SPDK_CU_ASSERT_FATAL(client_sock != NULL);
/*
@ -456,13 +456,13 @@ _sock(const char *ip, int port)
static void
posix_sock(void)
{
_sock("127.0.0.1", UT_PORT);
_sock("127.0.0.1", UT_PORT, "posix");
}
static void
ut_sock(void)
{
_sock(UT_IP, UT_PORT);
_sock(UT_IP, UT_PORT, "ut");
}
static void
@ -477,7 +477,7 @@ read_data(void *cb_arg, struct spdk_sock_group *group, struct spdk_sock *sock)
}
static void
_sock_group(const char *ip, int port)
_sock_group(const char *ip, int port, char *impl_name)
{
struct spdk_sock_group *group;
struct spdk_sock *listen_sock;
@ -488,14 +488,14 @@ _sock_group(const char *ip, int port)
struct iovec iov;
int rc;
listen_sock = spdk_sock_listen(ip, port);
listen_sock = spdk_sock_listen(ip, port, impl_name);
SPDK_CU_ASSERT_FATAL(listen_sock != NULL);
server_sock = spdk_sock_accept(listen_sock);
CU_ASSERT(server_sock == NULL);
CU_ASSERT(errno == EAGAIN || errno == EWOULDBLOCK);
client_sock = spdk_sock_connect(ip, port);
client_sock = spdk_sock_connect(ip, port, impl_name);
SPDK_CU_ASSERT_FATAL(client_sock != NULL);
usleep(1000);
@ -576,13 +576,13 @@ _sock_group(const char *ip, int port)
static void
posix_sock_group(void)
{
_sock_group("127.0.0.1", UT_PORT);
_sock_group("127.0.0.1", UT_PORT, "posix");
}
static void
ut_sock_group(void)
{
_sock_group(UT_IP, UT_PORT);
_sock_group(UT_IP, UT_PORT, "ut");
}
static void
@ -612,14 +612,14 @@ posix_sock_group_fairness(void)
struct iovec iov;
int i, rc;
listen_sock = spdk_sock_listen("127.0.0.1", UT_PORT);
listen_sock = spdk_sock_listen("127.0.0.1", UT_PORT, "posix");
SPDK_CU_ASSERT_FATAL(listen_sock != NULL);
group = spdk_sock_group_create(NULL);
SPDK_CU_ASSERT_FATAL(group != NULL);
for (i = 0; i < 3; i++) {
client_sock[i] = spdk_sock_connect("127.0.0.1", UT_PORT);
client_sock[i] = spdk_sock_connect("127.0.0.1", UT_PORT, "posix");
SPDK_CU_ASSERT_FATAL(client_sock[i] != NULL);
usleep(1000);
@ -728,7 +728,7 @@ _second_close_cb(void *cb_arg, int err)
}
static void
_sock_close(const char *ip, int port)
_sock_close(const char *ip, int port, char *impl_name)
{
struct spdk_sock_group *group;
struct spdk_sock *listen_sock;
@ -740,10 +740,10 @@ _sock_close(const char *ip, int port)
bool cb_arg2 = false;
int rc;
listen_sock = spdk_sock_listen(ip, port);
listen_sock = spdk_sock_listen(ip, port, impl_name);
SPDK_CU_ASSERT_FATAL(listen_sock != NULL);
client_sock = spdk_sock_connect(ip, port);
client_sock = spdk_sock_connect(ip, port, impl_name);
SPDK_CU_ASSERT_FATAL(client_sock != NULL);
usleep(1000);
@ -807,7 +807,7 @@ _sock_close(const char *ip, int port)
static void
posix_sock_close(void)
{
_sock_close("127.0.0.1", UT_PORT);
_sock_close("127.0.0.1", UT_PORT, "posix");
}
int