Commit 86814d8f authored by Konstantin Shkolnyy's avatar Konstantin Shkolnyy Committed by Paolo Abeni
Browse files

vsock/test: verify socket options after setting them



Replace setsockopt() calls with calls to functions that follow
setsockopt() with getsockopt() and check that the returned value and its
size are the same as have been set. (Except in vsock_perf.)

Signed-off-by: default avatarKonstantin Shkolnyy <kshk@linux.ibm.com>
Reviewed-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 3f36ee29
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include "timeout.h"
#include "control.h"
#include "util.h"

static int control_fd = -1;

@@ -50,7 +51,6 @@ void control_init(const char *control_host,

	for (ai = result; ai; ai = ai->ai_next) {
		int fd;
		int val = 1;

		fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (fd < 0)
@@ -65,11 +65,8 @@ void control_init(const char *control_host,
			break;
		}

		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
			       &val, sizeof(val)) < 0) {
			perror("setsockopt");
			exit(EXIT_FAILURE);
		}
		setsockopt_int_check(fd, SOL_SOCKET, SO_REUSEADDR, 1,
				     "setsockopt SO_REUSEADDR");

		if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0)
			goto next;
+0 −10
Original line number Diff line number Diff line
@@ -14,16 +14,6 @@

#include "msg_zerocopy_common.h"

void enable_so_zerocopy(int fd)
{
	int val = 1;

	if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) {
		perror("setsockopt");
		exit(EXIT_FAILURE);
	}
}

void vsock_recv_completion(int fd, const bool *zerocopied)
{
	struct sock_extended_err *serr;
+0 −1
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@
#define VSOCK_RECVERR	1
#endif

void enable_so_zerocopy(int fd);
void vsock_recv_completion(int fd, const bool *zerocopied);

#endif /* MSG_ZEROCOPY_COMMON_H */
+142 −0
Original line number Diff line number Diff line
@@ -651,3 +651,145 @@ void free_test_iovec(const struct iovec *test_iovec,

	free(iovec);
}

/* Set "unsigned long long" socket option and check that it's indeed set */
void setsockopt_ull_check(int fd, int level, int optname,
			  unsigned long long val, char const *errmsg)
{
	unsigned long long chkval;
	socklen_t chklen;
	int err;

	err = setsockopt(fd, level, optname, &val, sizeof(val));
	if (err) {
		fprintf(stderr, "setsockopt err: %s (%d)\n",
			strerror(errno), errno);
		goto fail;
	}

	chkval = ~val; /* just make storage != val */
	chklen = sizeof(chkval);

	err = getsockopt(fd, level, optname, &chkval, &chklen);
	if (err) {
		fprintf(stderr, "getsockopt err: %s (%d)\n",
			strerror(errno), errno);
		goto fail;
	}

	if (chklen != sizeof(chkval)) {
		fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val),
			chklen);
		goto fail;
	}

	if (chkval != val) {
		fprintf(stderr, "value mismatch: set %llu got %llu\n", val,
			chkval);
		goto fail;
	}
	return;
fail:
	fprintf(stderr, "%s  val %llu\n", errmsg, val);
	exit(EXIT_FAILURE);
;
}

/* Set "int" socket option and check that it's indeed set */
void setsockopt_int_check(int fd, int level, int optname, int val,
			  char const *errmsg)
{
	int chkval;
	socklen_t chklen;
	int err;

	err = setsockopt(fd, level, optname, &val, sizeof(val));
	if (err) {
		fprintf(stderr, "setsockopt err: %s (%d)\n",
			strerror(errno), errno);
		goto fail;
	}

	chkval = ~val; /* just make storage != val */
	chklen = sizeof(chkval);

	err = getsockopt(fd, level, optname, &chkval, &chklen);
	if (err) {
		fprintf(stderr, "getsockopt err: %s (%d)\n",
			strerror(errno), errno);
		goto fail;
	}

	if (chklen != sizeof(chkval)) {
		fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val),
			chklen);
		goto fail;
	}

	if (chkval != val) {
		fprintf(stderr, "value mismatch: set %d got %d\n", val, chkval);
		goto fail;
	}
	return;
fail:
	fprintf(stderr, "%s val %d\n", errmsg, val);
	exit(EXIT_FAILURE);
}

static void mem_invert(unsigned char *mem, size_t size)
{
	size_t i;

	for (i = 0; i < size; i++)
		mem[i] = ~mem[i];
}

/* Set "timeval" socket option and check that it's indeed set */
void setsockopt_timeval_check(int fd, int level, int optname,
			      struct timeval val, char const *errmsg)
{
	struct timeval chkval;
	socklen_t chklen;
	int err;

	err = setsockopt(fd, level, optname, &val, sizeof(val));
	if (err) {
		fprintf(stderr, "setsockopt err: %s (%d)\n",
			strerror(errno), errno);
		goto fail;
	}

	 /* just make storage != val */
	chkval = val;
	mem_invert((unsigned char *)&chkval, sizeof(chkval));
	chklen = sizeof(chkval);

	err = getsockopt(fd, level, optname, &chkval, &chklen);
	if (err) {
		fprintf(stderr, "getsockopt err: %s (%d)\n",
			strerror(errno), errno);
		goto fail;
	}

	if (chklen != sizeof(chkval)) {
		fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val),
			chklen);
		goto fail;
	}

	if (memcmp(&chkval, &val, sizeof(val)) != 0) {
		fprintf(stderr, "value mismatch: set %ld:%ld got %ld:%ld\n",
			val.tv_sec, val.tv_usec, chkval.tv_sec, chkval.tv_usec);
		goto fail;
	}
	return;
fail:
	fprintf(stderr, "%s val %ld:%ld\n", errmsg, val.tv_sec, val.tv_usec);
	exit(EXIT_FAILURE);
}

void enable_so_zerocopy_check(int fd)
{
	setsockopt_int_check(fd, SOL_SOCKET, SO_ZEROCOPY, 1,
			     "setsockopt SO_ZEROCOPY");
}
+7 −0
Original line number Diff line number Diff line
@@ -68,4 +68,11 @@ unsigned long iovec_hash_djb2(const struct iovec *iov, size_t iovnum);
struct iovec *alloc_test_iovec(const struct iovec *test_iovec, int iovnum);
void free_test_iovec(const struct iovec *test_iovec,
		     struct iovec *iovec, int iovnum);
void setsockopt_ull_check(int fd, int level, int optname,
			  unsigned long long val, char const *errmsg);
void setsockopt_int_check(int fd, int level, int optname, int val,
			  char const *errmsg);
void setsockopt_timeval_check(int fd, int level, int optname,
			      struct timeval val, char const *errmsg);
void enable_so_zerocopy_check(int fd);
#endif /* UTIL_H */
Loading