Commit 61316568 authored by Xuewei Niu's avatar Xuewei Niu Committed by Jakub Kicinski
Browse files

test/vsock: Add ioctl SIOCINQ tests



Add SIOCINQ ioctl tests for both SOCK_STREAM and SOCK_SEQPACKET.

The client waits for the server to send data, and checks if the SIOCINQ
ioctl value matches the data size. After consuming the data, the client
checks if the SIOCINQ value is 0.

Signed-off-by: default avatarXuewei Niu <niuxuewei.nxw@antgroup.com>
Reviewed-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Tested-by: default avatarLuigi Leonardi <leonardi@redhat.com>
Reviewed-by: default avatarLuigi Leonardi <leonardi@redhat.com>
Link: https://patch.msgid.link/20250708-siocinq-v6-4-3775f9a9e359@antgroup.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 53548d6b
Loading
Loading
Loading
Loading
+79 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/time64.h>
#include <pthread.h>
#include <fcntl.h>
#include <linux/sockios.h>

#include "vsock_test_zerocopy.h"
#include "timeout.h"
@@ -1307,6 +1308,54 @@ static void test_unsent_bytes_client(const struct test_opts *opts, int type)
	close(fd);
}

static void test_unread_bytes_server(const struct test_opts *opts, int type)
{
	unsigned char buf[MSG_BUF_IOCTL_LEN];
	int client_fd;

	client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type);
	if (client_fd < 0) {
		perror("accept");
		exit(EXIT_FAILURE);
	}

	for (int i = 0; i < sizeof(buf); i++)
		buf[i] = rand() & 0xFF;

	send_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf));
	control_writeln("SENT");

	close(client_fd);
}

static void test_unread_bytes_client(const struct test_opts *opts, int type)
{
	unsigned char buf[MSG_BUF_IOCTL_LEN];
	int fd;

	fd = vsock_connect(opts->peer_cid, opts->peer_port, type);
	if (fd < 0) {
		perror("connect");
		exit(EXIT_FAILURE);
	}

	control_expectln("SENT");
	/* The data has arrived but has not been read. The expected is
	 * MSG_BUF_IOCTL_LEN.
	 */
	if (!vsock_ioctl_int(fd, SIOCINQ, MSG_BUF_IOCTL_LEN)) {
		fprintf(stderr, "Test skipped, SIOCINQ not supported.\n");
		goto out;
	}

	recv_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
	/* All data has been consumed, so the expected is 0. */
	vsock_ioctl_int(fd, SIOCINQ, 0);

out:
	close(fd);
}

static void test_stream_unsent_bytes_client(const struct test_opts *opts)
{
	test_unsent_bytes_client(opts, SOCK_STREAM);
@@ -1327,6 +1376,26 @@ static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
	test_unsent_bytes_server(opts, SOCK_SEQPACKET);
}

static void test_stream_unread_bytes_client(const struct test_opts *opts)
{
	test_unread_bytes_client(opts, SOCK_STREAM);
}

static void test_stream_unread_bytes_server(const struct test_opts *opts)
{
	test_unread_bytes_server(opts, SOCK_STREAM);
}

static void test_seqpacket_unread_bytes_client(const struct test_opts *opts)
{
	test_unread_bytes_client(opts, SOCK_SEQPACKET);
}

static void test_seqpacket_unread_bytes_server(const struct test_opts *opts)
{
	test_unread_bytes_server(opts, SOCK_SEQPACKET);
}

#define RCVLOWAT_CREDIT_UPD_BUF_SIZE	(1024 * 128)
/* This define is the same as in 'include/linux/virtio_vsock.h':
 * it is used to decide when to send credit update message during
@@ -2276,6 +2345,16 @@ static struct test_case test_cases[] = {
		.run_client = test_stream_transport_change_client,
		.run_server = test_stream_transport_change_server,
	},
	{
		.name = "SOCK_STREAM ioctl(SIOCINQ) functionality",
		.run_client = test_stream_unread_bytes_client,
		.run_server = test_stream_unread_bytes_server,
	},
	{
		.name = "SOCK_SEQPACKET ioctl(SIOCINQ) functionality",
		.run_client = test_seqpacket_unread_bytes_client,
		.run_server = test_seqpacket_unread_bytes_server,
	},
	{},
};