sock: Add spdk_sock_readv(sock, iov, iovcnt)
Add an new API spdk_sock_readv(sock, iov, iovcnt) to the sock library. This will be used in SPDK iSCSI target first. Implementation was done based on vcom_socket_readv in VPP. Change-Id: I88a8f2af4856b1035165b78d76b4a4f4587b265d Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/446343 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
e80efe8f61
commit
1ee8deae9c
@ -126,6 +126,17 @@ ssize_t spdk_sock_recv(struct spdk_sock *sock, void *buf, size_t len);
|
||||
*/
|
||||
ssize_t spdk_sock_writev(struct spdk_sock *sock, struct iovec *iov, int iovcnt);
|
||||
|
||||
/**
|
||||
* Read message from the given socket to the I/O vector array.
|
||||
*
|
||||
* \param sock Socket to receive message.
|
||||
* \param iov I/O vector.
|
||||
* \param iovcnt Number of I/O vectors in the array.
|
||||
*
|
||||
* \return the length of the received message on success, -1 on failure.
|
||||
*/
|
||||
ssize_t spdk_sock_readv(struct spdk_sock *sock, struct iovec *iov, int iovcnt);
|
||||
|
||||
/**
|
||||
* Set the value used to specify the low water mark (in bytes) for this socket.
|
||||
*
|
||||
|
@ -75,6 +75,7 @@ struct spdk_net_impl {
|
||||
struct spdk_sock *(*accept)(struct spdk_sock *sock);
|
||||
int (*close)(struct spdk_sock *sock);
|
||||
ssize_t (*recv)(struct spdk_sock *sock, void *buf, size_t len);
|
||||
ssize_t (*readv)(struct spdk_sock *sock, struct iovec *iov, int iovcnt);
|
||||
ssize_t (*writev)(struct spdk_sock *sock, struct iovec *iov, int iovcnt);
|
||||
|
||||
int (*set_recvlowat)(struct spdk_sock *sock, int nbytes);
|
||||
|
@ -372,6 +372,14 @@ spdk_posix_sock_recv(struct spdk_sock *_sock, void *buf, size_t len)
|
||||
return recv(sock->fd, buf, len, MSG_DONTWAIT);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spdk_posix_sock_readv(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
struct spdk_posix_sock *sock = __posix_sock(_sock);
|
||||
|
||||
return readv(sock->fd, iov, iovcnt);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spdk_posix_sock_writev(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
@ -588,6 +596,7 @@ static struct spdk_net_impl g_posix_net_impl = {
|
||||
.accept = spdk_posix_sock_accept,
|
||||
.close = spdk_posix_sock_close,
|
||||
.recv = spdk_posix_sock_recv,
|
||||
.readv = spdk_posix_sock_readv,
|
||||
.writev = spdk_posix_sock_writev,
|
||||
.set_recvlowat = spdk_posix_sock_set_recvlowat,
|
||||
.set_recvbuf = spdk_posix_sock_set_recvbuf,
|
||||
|
@ -129,6 +129,17 @@ spdk_sock_recv(struct spdk_sock *sock, void *buf, size_t len)
|
||||
return sock->net_impl->recv(sock, buf, len);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
spdk_sock_readv(struct spdk_sock *sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
if (sock == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock->net_impl->readv(sock, iov, iovcnt);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
spdk_sock_writev(struct spdk_sock *sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
@ -140,7 +151,6 @@ spdk_sock_writev(struct spdk_sock *sock, struct iovec *iov, int iovcnt)
|
||||
return sock->net_impl->writev(sock, iov, iovcnt);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
spdk_sock_set_recvlowat(struct spdk_sock *sock, int nbytes)
|
||||
{
|
||||
|
@ -385,6 +385,36 @@ spdk_vpp_sock_recv(struct spdk_sock *_sock, void *buf, size_t len)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spdk_vpp_sock_readv(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
struct spdk_vpp_sock *sock = __vpp_sock(_sock);
|
||||
ssize_t total = 0;
|
||||
int i, rc;
|
||||
|
||||
assert(sock != NULL);
|
||||
assert(g_vpp_initialized);
|
||||
|
||||
for (i = 0; i < iovcnt; ++i) {
|
||||
rc = vppcom_session_read(sock->fd, iov[i].iov_base, iov[i].iov_len);
|
||||
if (rc < 0) {
|
||||
if (total > 0) {
|
||||
break;
|
||||
} else {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
total += rc;
|
||||
if (rc < iov[i].iov_len) {
|
||||
/* Read less than buffer provided, no point to continue. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spdk_vpp_sock_writev(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
@ -411,7 +441,6 @@ spdk_vpp_sock_writev(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* TODO: Check if there are similar parameters to configure in VPP
|
||||
* to three below.
|
||||
@ -609,6 +638,7 @@ static struct spdk_net_impl g_vpp_net_impl = {
|
||||
.accept = spdk_vpp_sock_accept,
|
||||
.close = spdk_vpp_sock_close,
|
||||
.recv = spdk_vpp_sock_recv,
|
||||
.readv = spdk_vpp_sock_readv,
|
||||
.writev = spdk_vpp_sock_writev,
|
||||
.set_recvlowat = spdk_vpp_sock_set_recvlowat,
|
||||
.set_recvbuf = spdk_vpp_sock_set_recvbuf,
|
||||
|
@ -171,6 +171,31 @@ spdk_ut_sock_recv(struct spdk_sock *_sock, void *buf, size_t len)
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spdk_ut_sock_readv(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
struct spdk_ut_sock *sock = __ut_sock(_sock);
|
||||
size_t len;
|
||||
char tmp[256];
|
||||
|
||||
/* Test implementation only supports single iov for now. */
|
||||
CU_ASSERT(iovcnt == 1);
|
||||
|
||||
len = spdk_min(iov[0].iov_len, sock->bytes_avail);
|
||||
|
||||
if (len == 0) {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(iov[0].iov_base, sock->buf, len);
|
||||
memcpy(tmp, &sock->buf[len], sock->bytes_avail - len);
|
||||
memcpy(sock->buf, tmp, sock->bytes_avail - len);
|
||||
sock->bytes_avail -= len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spdk_ut_sock_writev(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
@ -285,6 +310,7 @@ static struct spdk_net_impl g_ut_net_impl = {
|
||||
.accept = spdk_ut_sock_accept,
|
||||
.close = spdk_ut_sock_close,
|
||||
.recv = spdk_ut_sock_recv,
|
||||
.readv = spdk_ut_sock_readv,
|
||||
.writev = spdk_ut_sock_writev,
|
||||
.set_recvlowat = spdk_ut_sock_set_recvlowat,
|
||||
.set_recvbuf = spdk_ut_sock_set_recvbuf,
|
||||
@ -331,6 +357,7 @@ _sock(const char *ip, int port)
|
||||
server_sock = spdk_sock_accept(listen_sock);
|
||||
SPDK_CU_ASSERT_FATAL(server_sock != NULL);
|
||||
|
||||
/* Test spdk_sock_recv */
|
||||
iov.iov_base = test_string;
|
||||
iov.iov_len = 7;
|
||||
bytes_written = spdk_sock_writev(client_sock, &iov, 1);
|
||||
@ -348,6 +375,30 @@ _sock(const char *ip, int port)
|
||||
|
||||
CU_ASSERT(strncmp(test_string, buffer, 7) == 0);
|
||||
|
||||
/* Test spdk_sock_readv */
|
||||
iov.iov_base = test_string;
|
||||
iov.iov_len = 7;
|
||||
bytes_written = spdk_sock_writev(client_sock, &iov, 1);
|
||||
CU_ASSERT(bytes_written == 7);
|
||||
|
||||
usleep(1000);
|
||||
|
||||
iov.iov_base = buffer;
|
||||
iov.iov_len = 2;
|
||||
bytes_read = spdk_sock_readv(server_sock, &iov, 1);
|
||||
CU_ASSERT(bytes_read == 2);
|
||||
|
||||
usleep(1000);
|
||||
|
||||
iov.iov_base = buffer + 2;
|
||||
iov.iov_len = 5;
|
||||
bytes_read += spdk_sock_readv(server_sock, &iov, 1);
|
||||
CU_ASSERT(bytes_read == 7);
|
||||
|
||||
usleep(1000);
|
||||
|
||||
CU_ASSERT(strncmp(test_string, buffer, 7) == 0);
|
||||
|
||||
rc = spdk_sock_close(&client_sock);
|
||||
CU_ASSERT(client_sock == NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user