Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / testing / vsock / vsock_test.c
blob8d38dbf8f41f04128aef5113ae0e4cf09fc2e631
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * vsock_test - vsock.ko test suite
5 * Copyright (C) 2017 Red Hat, Inc.
7 * Author: Stefan Hajnoczi <stefanha@redhat.com>
8 */
10 #include <getopt.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <unistd.h>
16 #include <linux/kernel.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <time.h>
20 #include <sys/mman.h>
21 #include <poll.h>
22 #include <signal.h>
23 #include <sys/ioctl.h>
24 #include <linux/sockios.h>
26 #include "vsock_test_zerocopy.h"
27 #include "timeout.h"
28 #include "control.h"
29 #include "util.h"
31 static void test_stream_connection_reset(const struct test_opts *opts)
33 union {
34 struct sockaddr sa;
35 struct sockaddr_vm svm;
36 } addr = {
37 .svm = {
38 .svm_family = AF_VSOCK,
39 .svm_port = opts->peer_port,
40 .svm_cid = opts->peer_cid,
43 int ret;
44 int fd;
46 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
48 timeout_begin(TIMEOUT);
49 do {
50 ret = connect(fd, &addr.sa, sizeof(addr.svm));
51 timeout_check("connect");
52 } while (ret < 0 && errno == EINTR);
53 timeout_end();
55 if (ret != -1) {
56 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
57 exit(EXIT_FAILURE);
59 if (errno != ECONNRESET) {
60 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
61 exit(EXIT_FAILURE);
64 close(fd);
67 static void test_stream_bind_only_client(const struct test_opts *opts)
69 union {
70 struct sockaddr sa;
71 struct sockaddr_vm svm;
72 } addr = {
73 .svm = {
74 .svm_family = AF_VSOCK,
75 .svm_port = opts->peer_port,
76 .svm_cid = opts->peer_cid,
79 int ret;
80 int fd;
82 /* Wait for the server to be ready */
83 control_expectln("BIND");
85 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
87 timeout_begin(TIMEOUT);
88 do {
89 ret = connect(fd, &addr.sa, sizeof(addr.svm));
90 timeout_check("connect");
91 } while (ret < 0 && errno == EINTR);
92 timeout_end();
94 if (ret != -1) {
95 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
96 exit(EXIT_FAILURE);
98 if (errno != ECONNRESET) {
99 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
100 exit(EXIT_FAILURE);
103 /* Notify the server that the client has finished */
104 control_writeln("DONE");
106 close(fd);
109 static void test_stream_bind_only_server(const struct test_opts *opts)
111 union {
112 struct sockaddr sa;
113 struct sockaddr_vm svm;
114 } addr = {
115 .svm = {
116 .svm_family = AF_VSOCK,
117 .svm_port = opts->peer_port,
118 .svm_cid = VMADDR_CID_ANY,
121 int fd;
123 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
125 if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
126 perror("bind");
127 exit(EXIT_FAILURE);
130 /* Notify the client that the server is ready */
131 control_writeln("BIND");
133 /* Wait for the client to finish */
134 control_expectln("DONE");
136 close(fd);
139 static void test_stream_client_close_client(const struct test_opts *opts)
141 int fd;
143 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
144 if (fd < 0) {
145 perror("connect");
146 exit(EXIT_FAILURE);
149 send_byte(fd, 1, 0);
150 close(fd);
153 static void test_stream_client_close_server(const struct test_opts *opts)
155 int fd;
157 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
158 if (fd < 0) {
159 perror("accept");
160 exit(EXIT_FAILURE);
163 /* Wait for the remote to close the connection, before check
164 * -EPIPE error on send.
166 vsock_wait_remote_close(fd);
168 send_byte(fd, -EPIPE, 0);
169 recv_byte(fd, 1, 0);
170 recv_byte(fd, 0, 0);
171 close(fd);
174 static void test_stream_server_close_client(const struct test_opts *opts)
176 int fd;
178 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
179 if (fd < 0) {
180 perror("connect");
181 exit(EXIT_FAILURE);
184 /* Wait for the remote to close the connection, before check
185 * -EPIPE error on send.
187 vsock_wait_remote_close(fd);
189 send_byte(fd, -EPIPE, 0);
190 recv_byte(fd, 1, 0);
191 recv_byte(fd, 0, 0);
192 close(fd);
195 static void test_stream_server_close_server(const struct test_opts *opts)
197 int fd;
199 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
200 if (fd < 0) {
201 perror("accept");
202 exit(EXIT_FAILURE);
205 send_byte(fd, 1, 0);
206 close(fd);
209 /* With the standard socket sizes, VMCI is able to support about 100
210 * concurrent stream connections.
212 #define MULTICONN_NFDS 100
214 static void test_stream_multiconn_client(const struct test_opts *opts)
216 int fds[MULTICONN_NFDS];
217 int i;
219 for (i = 0; i < MULTICONN_NFDS; i++) {
220 fds[i] = vsock_stream_connect(opts->peer_cid, opts->peer_port);
221 if (fds[i] < 0) {
222 perror("connect");
223 exit(EXIT_FAILURE);
227 for (i = 0; i < MULTICONN_NFDS; i++) {
228 if (i % 2)
229 recv_byte(fds[i], 1, 0);
230 else
231 send_byte(fds[i], 1, 0);
234 for (i = 0; i < MULTICONN_NFDS; i++)
235 close(fds[i]);
238 static void test_stream_multiconn_server(const struct test_opts *opts)
240 int fds[MULTICONN_NFDS];
241 int i;
243 for (i = 0; i < MULTICONN_NFDS; i++) {
244 fds[i] = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
245 if (fds[i] < 0) {
246 perror("accept");
247 exit(EXIT_FAILURE);
251 for (i = 0; i < MULTICONN_NFDS; i++) {
252 if (i % 2)
253 send_byte(fds[i], 1, 0);
254 else
255 recv_byte(fds[i], 1, 0);
258 for (i = 0; i < MULTICONN_NFDS; i++)
259 close(fds[i]);
262 #define MSG_PEEK_BUF_LEN 64
264 static void test_msg_peek_client(const struct test_opts *opts,
265 bool seqpacket)
267 unsigned char buf[MSG_PEEK_BUF_LEN];
268 int fd;
269 int i;
271 if (seqpacket)
272 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
273 else
274 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
276 if (fd < 0) {
277 perror("connect");
278 exit(EXIT_FAILURE);
281 for (i = 0; i < sizeof(buf); i++)
282 buf[i] = rand() & 0xFF;
284 control_expectln("SRVREADY");
286 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
288 close(fd);
291 static void test_msg_peek_server(const struct test_opts *opts,
292 bool seqpacket)
294 unsigned char buf_half[MSG_PEEK_BUF_LEN / 2];
295 unsigned char buf_normal[MSG_PEEK_BUF_LEN];
296 unsigned char buf_peek[MSG_PEEK_BUF_LEN];
297 int fd;
299 if (seqpacket)
300 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
301 else
302 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
304 if (fd < 0) {
305 perror("accept");
306 exit(EXIT_FAILURE);
309 /* Peek from empty socket. */
310 recv_buf(fd, buf_peek, sizeof(buf_peek), MSG_PEEK | MSG_DONTWAIT,
311 -EAGAIN);
313 control_writeln("SRVREADY");
315 /* Peek part of data. */
316 recv_buf(fd, buf_half, sizeof(buf_half), MSG_PEEK, sizeof(buf_half));
318 /* Peek whole data. */
319 recv_buf(fd, buf_peek, sizeof(buf_peek), MSG_PEEK, sizeof(buf_peek));
321 /* Compare partial and full peek. */
322 if (memcmp(buf_half, buf_peek, sizeof(buf_half))) {
323 fprintf(stderr, "Partial peek data mismatch\n");
324 exit(EXIT_FAILURE);
327 if (seqpacket) {
328 /* This type of socket supports MSG_TRUNC flag,
329 * so check it with MSG_PEEK. We must get length
330 * of the message.
332 recv_buf(fd, buf_half, sizeof(buf_half), MSG_PEEK | MSG_TRUNC,
333 sizeof(buf_peek));
336 recv_buf(fd, buf_normal, sizeof(buf_normal), 0, sizeof(buf_normal));
338 /* Compare full peek and normal read. */
339 if (memcmp(buf_peek, buf_normal, sizeof(buf_peek))) {
340 fprintf(stderr, "Full peek data mismatch\n");
341 exit(EXIT_FAILURE);
344 close(fd);
347 static void test_stream_msg_peek_client(const struct test_opts *opts)
349 return test_msg_peek_client(opts, false);
352 static void test_stream_msg_peek_server(const struct test_opts *opts)
354 return test_msg_peek_server(opts, false);
357 #define SOCK_BUF_SIZE (2 * 1024 * 1024)
358 #define MAX_MSG_PAGES 4
360 static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
362 unsigned long curr_hash;
363 size_t max_msg_size;
364 int page_size;
365 int msg_count;
366 int fd;
368 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
369 if (fd < 0) {
370 perror("connect");
371 exit(EXIT_FAILURE);
374 /* Wait, until receiver sets buffer size. */
375 control_expectln("SRVREADY");
377 curr_hash = 0;
378 page_size = getpagesize();
379 max_msg_size = MAX_MSG_PAGES * page_size;
380 msg_count = SOCK_BUF_SIZE / max_msg_size;
382 for (int i = 0; i < msg_count; i++) {
383 size_t buf_size;
384 int flags;
385 void *buf;
387 /* Use "small" buffers and "big" buffers. */
388 if (i & 1)
389 buf_size = page_size +
390 (rand() % (max_msg_size - page_size));
391 else
392 buf_size = 1 + (rand() % page_size);
394 buf = malloc(buf_size);
396 if (!buf) {
397 perror("malloc");
398 exit(EXIT_FAILURE);
401 memset(buf, rand() & 0xff, buf_size);
402 /* Set at least one MSG_EOR + some random. */
403 if (i == (msg_count / 2) || (rand() & 1)) {
404 flags = MSG_EOR;
405 curr_hash++;
406 } else {
407 flags = 0;
410 send_buf(fd, buf, buf_size, flags, buf_size);
413 * Hash sum is computed at both client and server in
414 * the same way:
415 * H += hash('message data')
416 * Such hash "controls" both data integrity and message
417 * bounds. After data exchange, both sums are compared
418 * using control socket, and if message bounds wasn't
419 * broken - two values must be equal.
421 curr_hash += hash_djb2(buf, buf_size);
422 free(buf);
425 control_writeln("SENDDONE");
426 control_writeulong(curr_hash);
427 close(fd);
430 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
432 unsigned long sock_buf_size;
433 unsigned long remote_hash;
434 unsigned long curr_hash;
435 int fd;
436 struct msghdr msg = {0};
437 struct iovec iov = {0};
439 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
440 if (fd < 0) {
441 perror("accept");
442 exit(EXIT_FAILURE);
445 sock_buf_size = SOCK_BUF_SIZE;
447 if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
448 &sock_buf_size, sizeof(sock_buf_size))) {
449 perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
450 exit(EXIT_FAILURE);
453 if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
454 &sock_buf_size, sizeof(sock_buf_size))) {
455 perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
456 exit(EXIT_FAILURE);
459 /* Ready to receive data. */
460 control_writeln("SRVREADY");
461 /* Wait, until peer sends whole data. */
462 control_expectln("SENDDONE");
463 iov.iov_len = MAX_MSG_PAGES * getpagesize();
464 iov.iov_base = malloc(iov.iov_len);
465 if (!iov.iov_base) {
466 perror("malloc");
467 exit(EXIT_FAILURE);
470 msg.msg_iov = &iov;
471 msg.msg_iovlen = 1;
473 curr_hash = 0;
475 while (1) {
476 ssize_t recv_size;
478 recv_size = recvmsg(fd, &msg, 0);
480 if (!recv_size)
481 break;
483 if (recv_size < 0) {
484 perror("recvmsg");
485 exit(EXIT_FAILURE);
488 if (msg.msg_flags & MSG_EOR)
489 curr_hash++;
491 curr_hash += hash_djb2(msg.msg_iov[0].iov_base, recv_size);
494 free(iov.iov_base);
495 close(fd);
496 remote_hash = control_readulong();
498 if (curr_hash != remote_hash) {
499 fprintf(stderr, "Message bounds broken\n");
500 exit(EXIT_FAILURE);
504 #define MESSAGE_TRUNC_SZ 32
505 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
507 int fd;
508 char buf[MESSAGE_TRUNC_SZ];
510 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
511 if (fd < 0) {
512 perror("connect");
513 exit(EXIT_FAILURE);
516 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
518 control_writeln("SENDDONE");
519 close(fd);
522 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
524 int fd;
525 char buf[MESSAGE_TRUNC_SZ / 2];
526 struct msghdr msg = {0};
527 struct iovec iov = {0};
529 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
530 if (fd < 0) {
531 perror("accept");
532 exit(EXIT_FAILURE);
535 control_expectln("SENDDONE");
536 iov.iov_base = buf;
537 iov.iov_len = sizeof(buf);
538 msg.msg_iov = &iov;
539 msg.msg_iovlen = 1;
541 ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
543 if (ret != MESSAGE_TRUNC_SZ) {
544 printf("%zi\n", ret);
545 perror("MSG_TRUNC doesn't work");
546 exit(EXIT_FAILURE);
549 if (!(msg.msg_flags & MSG_TRUNC)) {
550 fprintf(stderr, "MSG_TRUNC expected\n");
551 exit(EXIT_FAILURE);
554 close(fd);
557 static time_t current_nsec(void)
559 struct timespec ts;
561 if (clock_gettime(CLOCK_REALTIME, &ts)) {
562 perror("clock_gettime(3) failed");
563 exit(EXIT_FAILURE);
566 return (ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
569 #define RCVTIMEO_TIMEOUT_SEC 1
570 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
572 static void test_seqpacket_timeout_client(const struct test_opts *opts)
574 int fd;
575 struct timeval tv;
576 char dummy;
577 time_t read_enter_ns;
578 time_t read_overhead_ns;
580 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
581 if (fd < 0) {
582 perror("connect");
583 exit(EXIT_FAILURE);
586 tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
587 tv.tv_usec = 0;
589 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) {
590 perror("setsockopt(SO_RCVTIMEO)");
591 exit(EXIT_FAILURE);
594 read_enter_ns = current_nsec();
596 if (read(fd, &dummy, sizeof(dummy)) != -1) {
597 fprintf(stderr,
598 "expected 'dummy' read(2) failure\n");
599 exit(EXIT_FAILURE);
602 if (errno != EAGAIN) {
603 perror("EAGAIN expected");
604 exit(EXIT_FAILURE);
607 read_overhead_ns = current_nsec() - read_enter_ns -
608 1000000000ULL * RCVTIMEO_TIMEOUT_SEC;
610 if (read_overhead_ns > READ_OVERHEAD_NSEC) {
611 fprintf(stderr,
612 "too much time in read(2), %lu > %i ns\n",
613 read_overhead_ns, READ_OVERHEAD_NSEC);
614 exit(EXIT_FAILURE);
617 control_writeln("WAITDONE");
618 close(fd);
621 static void test_seqpacket_timeout_server(const struct test_opts *opts)
623 int fd;
625 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
626 if (fd < 0) {
627 perror("accept");
628 exit(EXIT_FAILURE);
631 control_expectln("WAITDONE");
632 close(fd);
635 static void test_seqpacket_bigmsg_client(const struct test_opts *opts)
637 unsigned long sock_buf_size;
638 socklen_t len;
639 void *data;
640 int fd;
642 len = sizeof(sock_buf_size);
644 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
645 if (fd < 0) {
646 perror("connect");
647 exit(EXIT_FAILURE);
650 if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
651 &sock_buf_size, &len)) {
652 perror("getsockopt");
653 exit(EXIT_FAILURE);
656 sock_buf_size++;
658 data = malloc(sock_buf_size);
659 if (!data) {
660 perror("malloc");
661 exit(EXIT_FAILURE);
664 send_buf(fd, data, sock_buf_size, 0, -EMSGSIZE);
666 control_writeln("CLISENT");
668 free(data);
669 close(fd);
672 static void test_seqpacket_bigmsg_server(const struct test_opts *opts)
674 int fd;
676 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
677 if (fd < 0) {
678 perror("accept");
679 exit(EXIT_FAILURE);
682 control_expectln("CLISENT");
684 close(fd);
687 #define BUF_PATTERN_1 'a'
688 #define BUF_PATTERN_2 'b'
690 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
692 int fd;
693 unsigned char *buf1;
694 unsigned char *buf2;
695 int buf_size = getpagesize() * 3;
697 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
698 if (fd < 0) {
699 perror("connect");
700 exit(EXIT_FAILURE);
703 buf1 = malloc(buf_size);
704 if (!buf1) {
705 perror("'malloc()' for 'buf1'");
706 exit(EXIT_FAILURE);
709 buf2 = malloc(buf_size);
710 if (!buf2) {
711 perror("'malloc()' for 'buf2'");
712 exit(EXIT_FAILURE);
715 memset(buf1, BUF_PATTERN_1, buf_size);
716 memset(buf2, BUF_PATTERN_2, buf_size);
718 send_buf(fd, buf1, buf_size, 0, buf_size);
720 send_buf(fd, buf2, buf_size, 0, buf_size);
722 close(fd);
725 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
727 int fd;
728 unsigned char *broken_buf;
729 unsigned char *valid_buf;
730 int page_size = getpagesize();
731 int buf_size = page_size * 3;
732 ssize_t res;
733 int prot = PROT_READ | PROT_WRITE;
734 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
735 int i;
737 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
738 if (fd < 0) {
739 perror("accept");
740 exit(EXIT_FAILURE);
743 /* Setup first buffer. */
744 broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
745 if (broken_buf == MAP_FAILED) {
746 perror("mmap for 'broken_buf'");
747 exit(EXIT_FAILURE);
750 /* Unmap "hole" in buffer. */
751 if (munmap(broken_buf + page_size, page_size)) {
752 perror("'broken_buf' setup");
753 exit(EXIT_FAILURE);
756 valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
757 if (valid_buf == MAP_FAILED) {
758 perror("mmap for 'valid_buf'");
759 exit(EXIT_FAILURE);
762 /* Try to fill buffer with unmapped middle. */
763 res = read(fd, broken_buf, buf_size);
764 if (res != -1) {
765 fprintf(stderr,
766 "expected 'broken_buf' read(2) failure, got %zi\n",
767 res);
768 exit(EXIT_FAILURE);
771 if (errno != EFAULT) {
772 perror("unexpected errno of 'broken_buf'");
773 exit(EXIT_FAILURE);
776 /* Try to fill valid buffer. */
777 res = read(fd, valid_buf, buf_size);
778 if (res < 0) {
779 perror("unexpected 'valid_buf' read(2) failure");
780 exit(EXIT_FAILURE);
783 if (res != buf_size) {
784 fprintf(stderr,
785 "invalid 'valid_buf' read(2), expected %i, got %zi\n",
786 buf_size, res);
787 exit(EXIT_FAILURE);
790 for (i = 0; i < buf_size; i++) {
791 if (valid_buf[i] != BUF_PATTERN_2) {
792 fprintf(stderr,
793 "invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
794 i, BUF_PATTERN_2, valid_buf[i]);
795 exit(EXIT_FAILURE);
799 /* Unmap buffers. */
800 munmap(broken_buf, page_size);
801 munmap(broken_buf + page_size * 2, page_size);
802 munmap(valid_buf, buf_size);
803 close(fd);
806 #define RCVLOWAT_BUF_SIZE 128
808 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
810 int fd;
811 int i;
813 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
814 if (fd < 0) {
815 perror("accept");
816 exit(EXIT_FAILURE);
819 /* Send 1 byte. */
820 send_byte(fd, 1, 0);
822 control_writeln("SRVSENT");
824 /* Wait until client is ready to receive rest of data. */
825 control_expectln("CLNSENT");
827 for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
828 send_byte(fd, 1, 0);
830 /* Keep socket in active state. */
831 control_expectln("POLLDONE");
833 close(fd);
836 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
838 unsigned long lowat_val = RCVLOWAT_BUF_SIZE;
839 char buf[RCVLOWAT_BUF_SIZE];
840 struct pollfd fds;
841 short poll_flags;
842 int fd;
844 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
845 if (fd < 0) {
846 perror("connect");
847 exit(EXIT_FAILURE);
850 if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
851 &lowat_val, sizeof(lowat_val))) {
852 perror("setsockopt(SO_RCVLOWAT)");
853 exit(EXIT_FAILURE);
856 control_expectln("SRVSENT");
858 /* At this point, server sent 1 byte. */
859 fds.fd = fd;
860 poll_flags = POLLIN | POLLRDNORM;
861 fds.events = poll_flags;
863 /* Try to wait for 1 sec. */
864 if (poll(&fds, 1, 1000) < 0) {
865 perror("poll");
866 exit(EXIT_FAILURE);
869 /* poll() must return nothing. */
870 if (fds.revents) {
871 fprintf(stderr, "Unexpected poll result %hx\n",
872 fds.revents);
873 exit(EXIT_FAILURE);
876 /* Tell server to send rest of data. */
877 control_writeln("CLNSENT");
879 /* Poll for data. */
880 if (poll(&fds, 1, 10000) < 0) {
881 perror("poll");
882 exit(EXIT_FAILURE);
885 /* Only these two bits are expected. */
886 if (fds.revents != poll_flags) {
887 fprintf(stderr, "Unexpected poll result %hx\n",
888 fds.revents);
889 exit(EXIT_FAILURE);
892 /* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
893 * will be returned.
895 recv_buf(fd, buf, sizeof(buf), MSG_DONTWAIT, RCVLOWAT_BUF_SIZE);
897 control_writeln("POLLDONE");
899 close(fd);
902 #define INV_BUF_TEST_DATA_LEN 512
904 static void test_inv_buf_client(const struct test_opts *opts, bool stream)
906 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
907 ssize_t expected_ret;
908 int fd;
910 if (stream)
911 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
912 else
913 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
915 if (fd < 0) {
916 perror("connect");
917 exit(EXIT_FAILURE);
920 control_expectln("SENDDONE");
922 /* Use invalid buffer here. */
923 recv_buf(fd, NULL, sizeof(data), 0, -EFAULT);
925 if (stream) {
926 /* For SOCK_STREAM we must continue reading. */
927 expected_ret = sizeof(data);
928 } else {
929 /* For SOCK_SEQPACKET socket's queue must be empty. */
930 expected_ret = -EAGAIN;
933 recv_buf(fd, data, sizeof(data), MSG_DONTWAIT, expected_ret);
935 control_writeln("DONE");
937 close(fd);
940 static void test_inv_buf_server(const struct test_opts *opts, bool stream)
942 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
943 int fd;
945 if (stream)
946 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
947 else
948 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
950 if (fd < 0) {
951 perror("accept");
952 exit(EXIT_FAILURE);
955 send_buf(fd, data, sizeof(data), 0, sizeof(data));
957 control_writeln("SENDDONE");
959 control_expectln("DONE");
961 close(fd);
964 static void test_stream_inv_buf_client(const struct test_opts *opts)
966 test_inv_buf_client(opts, true);
969 static void test_stream_inv_buf_server(const struct test_opts *opts)
971 test_inv_buf_server(opts, true);
974 static void test_seqpacket_inv_buf_client(const struct test_opts *opts)
976 test_inv_buf_client(opts, false);
979 static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
981 test_inv_buf_server(opts, false);
984 #define HELLO_STR "HELLO"
985 #define WORLD_STR "WORLD"
987 static void test_stream_virtio_skb_merge_client(const struct test_opts *opts)
989 int fd;
991 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
992 if (fd < 0) {
993 perror("connect");
994 exit(EXIT_FAILURE);
997 /* Send first skbuff. */
998 send_buf(fd, HELLO_STR, strlen(HELLO_STR), 0, strlen(HELLO_STR));
1000 control_writeln("SEND0");
1001 /* Peer reads part of first skbuff. */
1002 control_expectln("REPLY0");
1004 /* Send second skbuff, it will be appended to the first. */
1005 send_buf(fd, WORLD_STR, strlen(WORLD_STR), 0, strlen(WORLD_STR));
1007 control_writeln("SEND1");
1008 /* Peer reads merged skbuff packet. */
1009 control_expectln("REPLY1");
1011 close(fd);
1014 static void test_stream_virtio_skb_merge_server(const struct test_opts *opts)
1016 size_t read = 0, to_read;
1017 unsigned char buf[64];
1018 int fd;
1020 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1021 if (fd < 0) {
1022 perror("accept");
1023 exit(EXIT_FAILURE);
1026 control_expectln("SEND0");
1028 /* Read skbuff partially. */
1029 to_read = 2;
1030 recv_buf(fd, buf + read, to_read, 0, to_read);
1031 read += to_read;
1033 control_writeln("REPLY0");
1034 control_expectln("SEND1");
1036 /* Read the rest of both buffers */
1037 to_read = strlen(HELLO_STR WORLD_STR) - read;
1038 recv_buf(fd, buf + read, to_read, 0, to_read);
1039 read += to_read;
1041 /* No more bytes should be there */
1042 to_read = sizeof(buf) - read;
1043 recv_buf(fd, buf + read, to_read, MSG_DONTWAIT, -EAGAIN);
1045 if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) {
1046 fprintf(stderr, "pattern mismatch\n");
1047 exit(EXIT_FAILURE);
1050 control_writeln("REPLY1");
1052 close(fd);
1055 static void test_seqpacket_msg_peek_client(const struct test_opts *opts)
1057 return test_msg_peek_client(opts, true);
1060 static void test_seqpacket_msg_peek_server(const struct test_opts *opts)
1062 return test_msg_peek_server(opts, true);
1065 static sig_atomic_t have_sigpipe;
1067 static void sigpipe(int signo)
1069 have_sigpipe = 1;
1072 static void test_stream_check_sigpipe(int fd)
1074 ssize_t res;
1076 have_sigpipe = 0;
1078 res = send(fd, "A", 1, 0);
1079 if (res != -1) {
1080 fprintf(stderr, "expected send(2) failure, got %zi\n", res);
1081 exit(EXIT_FAILURE);
1084 if (!have_sigpipe) {
1085 fprintf(stderr, "SIGPIPE expected\n");
1086 exit(EXIT_FAILURE);
1089 have_sigpipe = 0;
1091 res = send(fd, "A", 1, MSG_NOSIGNAL);
1092 if (res != -1) {
1093 fprintf(stderr, "expected send(2) failure, got %zi\n", res);
1094 exit(EXIT_FAILURE);
1097 if (have_sigpipe) {
1098 fprintf(stderr, "SIGPIPE not expected\n");
1099 exit(EXIT_FAILURE);
1103 static void test_stream_shutwr_client(const struct test_opts *opts)
1105 int fd;
1107 struct sigaction act = {
1108 .sa_handler = sigpipe,
1111 sigaction(SIGPIPE, &act, NULL);
1113 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1114 if (fd < 0) {
1115 perror("connect");
1116 exit(EXIT_FAILURE);
1119 if (shutdown(fd, SHUT_WR)) {
1120 perror("shutdown");
1121 exit(EXIT_FAILURE);
1124 test_stream_check_sigpipe(fd);
1126 control_writeln("CLIENTDONE");
1128 close(fd);
1131 static void test_stream_shutwr_server(const struct test_opts *opts)
1133 int fd;
1135 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1136 if (fd < 0) {
1137 perror("accept");
1138 exit(EXIT_FAILURE);
1141 control_expectln("CLIENTDONE");
1143 close(fd);
1146 static void test_stream_shutrd_client(const struct test_opts *opts)
1148 int fd;
1150 struct sigaction act = {
1151 .sa_handler = sigpipe,
1154 sigaction(SIGPIPE, &act, NULL);
1156 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1157 if (fd < 0) {
1158 perror("connect");
1159 exit(EXIT_FAILURE);
1162 control_expectln("SHUTRDDONE");
1164 test_stream_check_sigpipe(fd);
1166 control_writeln("CLIENTDONE");
1168 close(fd);
1171 static void test_stream_shutrd_server(const struct test_opts *opts)
1173 int fd;
1175 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1176 if (fd < 0) {
1177 perror("accept");
1178 exit(EXIT_FAILURE);
1181 if (shutdown(fd, SHUT_RD)) {
1182 perror("shutdown");
1183 exit(EXIT_FAILURE);
1186 control_writeln("SHUTRDDONE");
1187 control_expectln("CLIENTDONE");
1189 close(fd);
1192 static void test_double_bind_connect_server(const struct test_opts *opts)
1194 int listen_fd, client_fd, i;
1195 struct sockaddr_vm sa_client;
1196 socklen_t socklen_client = sizeof(sa_client);
1198 listen_fd = vsock_stream_listen(VMADDR_CID_ANY, opts->peer_port);
1200 for (i = 0; i < 2; i++) {
1201 control_writeln("LISTENING");
1203 timeout_begin(TIMEOUT);
1204 do {
1205 client_fd = accept(listen_fd, (struct sockaddr *)&sa_client,
1206 &socklen_client);
1207 timeout_check("accept");
1208 } while (client_fd < 0 && errno == EINTR);
1209 timeout_end();
1211 if (client_fd < 0) {
1212 perror("accept");
1213 exit(EXIT_FAILURE);
1216 /* Waiting for remote peer to close connection */
1217 vsock_wait_remote_close(client_fd);
1220 close(listen_fd);
1223 static void test_double_bind_connect_client(const struct test_opts *opts)
1225 int i, client_fd;
1227 for (i = 0; i < 2; i++) {
1228 /* Wait until server is ready to accept a new connection */
1229 control_expectln("LISTENING");
1231 /* We use 'peer_port + 1' as "some" port for the 'bind()'
1232 * call. It is safe for overflow, but must be considered,
1233 * when running multiple test applications simultaneously
1234 * where 'peer-port' argument differs by 1.
1236 client_fd = vsock_bind_connect(opts->peer_cid, opts->peer_port,
1237 opts->peer_port + 1, SOCK_STREAM);
1239 close(client_fd);
1243 #define MSG_BUF_IOCTL_LEN 64
1244 static void test_unsent_bytes_server(const struct test_opts *opts, int type)
1246 unsigned char buf[MSG_BUF_IOCTL_LEN];
1247 int client_fd;
1249 client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type);
1250 if (client_fd < 0) {
1251 perror("accept");
1252 exit(EXIT_FAILURE);
1255 recv_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf));
1256 control_writeln("RECEIVED");
1258 close(client_fd);
1261 static void test_unsent_bytes_client(const struct test_opts *opts, int type)
1263 unsigned char buf[MSG_BUF_IOCTL_LEN];
1264 int ret, fd, sock_bytes_unsent;
1266 fd = vsock_connect(opts->peer_cid, opts->peer_port, type);
1267 if (fd < 0) {
1268 perror("connect");
1269 exit(EXIT_FAILURE);
1272 for (int i = 0; i < sizeof(buf); i++)
1273 buf[i] = rand() & 0xFF;
1275 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
1276 control_expectln("RECEIVED");
1278 ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
1279 if (ret < 0) {
1280 if (errno == EOPNOTSUPP) {
1281 fprintf(stderr, "Test skipped, SIOCOUTQ not supported.\n");
1282 } else {
1283 perror("ioctl");
1284 exit(EXIT_FAILURE);
1286 } else if (ret == 0 && sock_bytes_unsent != 0) {
1287 fprintf(stderr,
1288 "Unexpected 'SIOCOUTQ' value, expected 0, got %i\n",
1289 sock_bytes_unsent);
1290 exit(EXIT_FAILURE);
1293 close(fd);
1296 static void test_stream_unsent_bytes_client(const struct test_opts *opts)
1298 test_unsent_bytes_client(opts, SOCK_STREAM);
1301 static void test_stream_unsent_bytes_server(const struct test_opts *opts)
1303 test_unsent_bytes_server(opts, SOCK_STREAM);
1306 static void test_seqpacket_unsent_bytes_client(const struct test_opts *opts)
1308 test_unsent_bytes_client(opts, SOCK_SEQPACKET);
1311 static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
1313 test_unsent_bytes_server(opts, SOCK_SEQPACKET);
1316 #define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
1317 /* This define is the same as in 'include/linux/virtio_vsock.h':
1318 * it is used to decide when to send credit update message during
1319 * reading from rx queue of a socket. Value and its usage in
1320 * kernel is important for this test.
1322 #define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64)
1324 static void test_stream_rcvlowat_def_cred_upd_client(const struct test_opts *opts)
1326 size_t buf_size;
1327 void *buf;
1328 int fd;
1330 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1331 if (fd < 0) {
1332 perror("connect");
1333 exit(EXIT_FAILURE);
1336 /* Send 1 byte more than peer's buffer size. */
1337 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE + 1;
1339 buf = malloc(buf_size);
1340 if (!buf) {
1341 perror("malloc");
1342 exit(EXIT_FAILURE);
1345 /* Wait until peer sets needed buffer size. */
1346 recv_byte(fd, 1, 0);
1348 if (send(fd, buf, buf_size, 0) != buf_size) {
1349 perror("send failed");
1350 exit(EXIT_FAILURE);
1353 free(buf);
1354 close(fd);
1357 static void test_stream_credit_update_test(const struct test_opts *opts,
1358 bool low_rx_bytes_test)
1360 size_t recv_buf_size;
1361 struct pollfd fds;
1362 size_t buf_size;
1363 void *buf;
1364 int fd;
1366 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1367 if (fd < 0) {
1368 perror("accept");
1369 exit(EXIT_FAILURE);
1372 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE;
1374 if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
1375 &buf_size, sizeof(buf_size))) {
1376 perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
1377 exit(EXIT_FAILURE);
1380 if (low_rx_bytes_test) {
1381 /* Set new SO_RCVLOWAT here. This enables sending credit
1382 * update when number of bytes if our rx queue become <
1383 * SO_RCVLOWAT value.
1385 recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1387 if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
1388 &recv_buf_size, sizeof(recv_buf_size))) {
1389 perror("setsockopt(SO_RCVLOWAT)");
1390 exit(EXIT_FAILURE);
1394 /* Send one dummy byte here, because 'setsockopt()' above also
1395 * sends special packet which tells sender to update our buffer
1396 * size. This 'send_byte()' will serialize such packet with data
1397 * reads in a loop below. Sender starts transmission only when
1398 * it receives this single byte.
1400 send_byte(fd, 1, 0);
1402 buf = malloc(buf_size);
1403 if (!buf) {
1404 perror("malloc");
1405 exit(EXIT_FAILURE);
1408 /* Wait until there will be 128KB of data in rx queue. */
1409 while (1) {
1410 ssize_t res;
1412 res = recv(fd, buf, buf_size, MSG_PEEK);
1413 if (res == buf_size)
1414 break;
1416 if (res <= 0) {
1417 fprintf(stderr, "unexpected 'recv()' return: %zi\n", res);
1418 exit(EXIT_FAILURE);
1422 /* There is 128KB of data in the socket's rx queue, dequeue first
1423 * 64KB, credit update is sent if 'low_rx_bytes_test' == true.
1424 * Otherwise, credit update is sent in 'if (!low_rx_bytes_test)'.
1426 recv_buf_size = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1427 recv_buf(fd, buf, recv_buf_size, 0, recv_buf_size);
1429 if (!low_rx_bytes_test) {
1430 recv_buf_size++;
1432 /* Updating SO_RCVLOWAT will send credit update. */
1433 if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
1434 &recv_buf_size, sizeof(recv_buf_size))) {
1435 perror("setsockopt(SO_RCVLOWAT)");
1436 exit(EXIT_FAILURE);
1440 fds.fd = fd;
1441 fds.events = POLLIN | POLLRDNORM | POLLERR |
1442 POLLRDHUP | POLLHUP;
1444 /* This 'poll()' will return once we receive last byte
1445 * sent by client.
1447 if (poll(&fds, 1, -1) < 0) {
1448 perror("poll");
1449 exit(EXIT_FAILURE);
1452 if (fds.revents & POLLERR) {
1453 fprintf(stderr, "'poll()' error\n");
1454 exit(EXIT_FAILURE);
1457 if (fds.revents & (POLLIN | POLLRDNORM)) {
1458 recv_buf(fd, buf, recv_buf_size, MSG_DONTWAIT, recv_buf_size);
1459 } else {
1460 /* These flags must be set, as there is at
1461 * least 64KB of data ready to read.
1463 fprintf(stderr, "POLLIN | POLLRDNORM expected\n");
1464 exit(EXIT_FAILURE);
1467 free(buf);
1468 close(fd);
1471 static void test_stream_cred_upd_on_low_rx_bytes(const struct test_opts *opts)
1473 test_stream_credit_update_test(opts, true);
1476 static void test_stream_cred_upd_on_set_rcvlowat(const struct test_opts *opts)
1478 test_stream_credit_update_test(opts, false);
1481 static struct test_case test_cases[] = {
1483 .name = "SOCK_STREAM connection reset",
1484 .run_client = test_stream_connection_reset,
1487 .name = "SOCK_STREAM bind only",
1488 .run_client = test_stream_bind_only_client,
1489 .run_server = test_stream_bind_only_server,
1492 .name = "SOCK_STREAM client close",
1493 .run_client = test_stream_client_close_client,
1494 .run_server = test_stream_client_close_server,
1497 .name = "SOCK_STREAM server close",
1498 .run_client = test_stream_server_close_client,
1499 .run_server = test_stream_server_close_server,
1502 .name = "SOCK_STREAM multiple connections",
1503 .run_client = test_stream_multiconn_client,
1504 .run_server = test_stream_multiconn_server,
1507 .name = "SOCK_STREAM MSG_PEEK",
1508 .run_client = test_stream_msg_peek_client,
1509 .run_server = test_stream_msg_peek_server,
1512 .name = "SOCK_SEQPACKET msg bounds",
1513 .run_client = test_seqpacket_msg_bounds_client,
1514 .run_server = test_seqpacket_msg_bounds_server,
1517 .name = "SOCK_SEQPACKET MSG_TRUNC flag",
1518 .run_client = test_seqpacket_msg_trunc_client,
1519 .run_server = test_seqpacket_msg_trunc_server,
1522 .name = "SOCK_SEQPACKET timeout",
1523 .run_client = test_seqpacket_timeout_client,
1524 .run_server = test_seqpacket_timeout_server,
1527 .name = "SOCK_SEQPACKET invalid receive buffer",
1528 .run_client = test_seqpacket_invalid_rec_buffer_client,
1529 .run_server = test_seqpacket_invalid_rec_buffer_server,
1532 .name = "SOCK_STREAM poll() + SO_RCVLOWAT",
1533 .run_client = test_stream_poll_rcvlowat_client,
1534 .run_server = test_stream_poll_rcvlowat_server,
1537 .name = "SOCK_SEQPACKET big message",
1538 .run_client = test_seqpacket_bigmsg_client,
1539 .run_server = test_seqpacket_bigmsg_server,
1542 .name = "SOCK_STREAM test invalid buffer",
1543 .run_client = test_stream_inv_buf_client,
1544 .run_server = test_stream_inv_buf_server,
1547 .name = "SOCK_SEQPACKET test invalid buffer",
1548 .run_client = test_seqpacket_inv_buf_client,
1549 .run_server = test_seqpacket_inv_buf_server,
1552 .name = "SOCK_STREAM virtio skb merge",
1553 .run_client = test_stream_virtio_skb_merge_client,
1554 .run_server = test_stream_virtio_skb_merge_server,
1557 .name = "SOCK_SEQPACKET MSG_PEEK",
1558 .run_client = test_seqpacket_msg_peek_client,
1559 .run_server = test_seqpacket_msg_peek_server,
1562 .name = "SOCK_STREAM SHUT_WR",
1563 .run_client = test_stream_shutwr_client,
1564 .run_server = test_stream_shutwr_server,
1567 .name = "SOCK_STREAM SHUT_RD",
1568 .run_client = test_stream_shutrd_client,
1569 .run_server = test_stream_shutrd_server,
1572 .name = "SOCK_STREAM MSG_ZEROCOPY",
1573 .run_client = test_stream_msgzcopy_client,
1574 .run_server = test_stream_msgzcopy_server,
1577 .name = "SOCK_SEQPACKET MSG_ZEROCOPY",
1578 .run_client = test_seqpacket_msgzcopy_client,
1579 .run_server = test_seqpacket_msgzcopy_server,
1582 .name = "SOCK_STREAM MSG_ZEROCOPY empty MSG_ERRQUEUE",
1583 .run_client = test_stream_msgzcopy_empty_errq_client,
1584 .run_server = test_stream_msgzcopy_empty_errq_server,
1587 .name = "SOCK_STREAM double bind connect",
1588 .run_client = test_double_bind_connect_client,
1589 .run_server = test_double_bind_connect_server,
1592 .name = "SOCK_STREAM virtio credit update + SO_RCVLOWAT",
1593 .run_client = test_stream_rcvlowat_def_cred_upd_client,
1594 .run_server = test_stream_cred_upd_on_set_rcvlowat,
1597 .name = "SOCK_STREAM virtio credit update + low rx_bytes",
1598 .run_client = test_stream_rcvlowat_def_cred_upd_client,
1599 .run_server = test_stream_cred_upd_on_low_rx_bytes,
1602 .name = "SOCK_STREAM ioctl(SIOCOUTQ) 0 unsent bytes",
1603 .run_client = test_stream_unsent_bytes_client,
1604 .run_server = test_stream_unsent_bytes_server,
1607 .name = "SOCK_SEQPACKET ioctl(SIOCOUTQ) 0 unsent bytes",
1608 .run_client = test_seqpacket_unsent_bytes_client,
1609 .run_server = test_seqpacket_unsent_bytes_server,
1614 static const char optstring[] = "";
1615 static const struct option longopts[] = {
1617 .name = "control-host",
1618 .has_arg = required_argument,
1619 .val = 'H',
1622 .name = "control-port",
1623 .has_arg = required_argument,
1624 .val = 'P',
1627 .name = "mode",
1628 .has_arg = required_argument,
1629 .val = 'm',
1632 .name = "peer-cid",
1633 .has_arg = required_argument,
1634 .val = 'p',
1637 .name = "peer-port",
1638 .has_arg = required_argument,
1639 .val = 'q',
1642 .name = "list",
1643 .has_arg = no_argument,
1644 .val = 'l',
1647 .name = "skip",
1648 .has_arg = required_argument,
1649 .val = 's',
1652 .name = "help",
1653 .has_arg = no_argument,
1654 .val = '?',
1659 static void usage(void)
1661 fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--peer-port=<port>] [--list] [--skip=<test_id>]\n"
1662 "\n"
1663 " Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
1664 " Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
1665 "\n"
1666 "Run vsock.ko tests. Must be launched in both guest\n"
1667 "and host. One side must use --mode=client and\n"
1668 "the other side must use --mode=server.\n"
1669 "\n"
1670 "A TCP control socket connection is used to coordinate tests\n"
1671 "between the client and the server. The server requires a\n"
1672 "listen address and the client requires an address to\n"
1673 "connect to.\n"
1674 "\n"
1675 "The CID of the other side must be given with --peer-cid=<cid>.\n"
1676 "During the test, two AF_VSOCK ports will be used: the port\n"
1677 "specified with --peer-port=<port> (or the default port)\n"
1678 "and the next one.\n"
1679 "\n"
1680 "Options:\n"
1681 " --help This help message\n"
1682 " --control-host <host> Server IP address to connect to\n"
1683 " --control-port <port> Server port to listen on/connect to\n"
1684 " --mode client|server Server or client mode\n"
1685 " --peer-cid <cid> CID of the other side\n"
1686 " --peer-port <port> AF_VSOCK port used for the test [default: %d]\n"
1687 " --list List of tests that will be executed\n"
1688 " --skip <test_id> Test ID to skip;\n"
1689 " use multiple --skip options to skip more tests\n",
1690 DEFAULT_PEER_PORT
1692 exit(EXIT_FAILURE);
1695 int main(int argc, char **argv)
1697 const char *control_host = NULL;
1698 const char *control_port = NULL;
1699 struct test_opts opts = {
1700 .mode = TEST_MODE_UNSET,
1701 .peer_cid = VMADDR_CID_ANY,
1702 .peer_port = DEFAULT_PEER_PORT,
1705 srand(time(NULL));
1706 init_signals();
1708 for (;;) {
1709 int opt = getopt_long(argc, argv, optstring, longopts, NULL);
1711 if (opt == -1)
1712 break;
1714 switch (opt) {
1715 case 'H':
1716 control_host = optarg;
1717 break;
1718 case 'm':
1719 if (strcmp(optarg, "client") == 0)
1720 opts.mode = TEST_MODE_CLIENT;
1721 else if (strcmp(optarg, "server") == 0)
1722 opts.mode = TEST_MODE_SERVER;
1723 else {
1724 fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
1725 return EXIT_FAILURE;
1727 break;
1728 case 'p':
1729 opts.peer_cid = parse_cid(optarg);
1730 break;
1731 case 'q':
1732 opts.peer_port = parse_port(optarg);
1733 break;
1734 case 'P':
1735 control_port = optarg;
1736 break;
1737 case 'l':
1738 list_tests(test_cases);
1739 break;
1740 case 's':
1741 skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
1742 optarg);
1743 break;
1744 case '?':
1745 default:
1746 usage();
1750 if (!control_port)
1751 usage();
1752 if (opts.mode == TEST_MODE_UNSET)
1753 usage();
1754 if (opts.peer_cid == VMADDR_CID_ANY)
1755 usage();
1757 if (!control_host) {
1758 if (opts.mode != TEST_MODE_SERVER)
1759 usage();
1760 control_host = "0.0.0.0";
1763 control_init(control_host, control_port,
1764 opts.mode == TEST_MODE_SERVER);
1766 run_tests(test_cases, &opts);
1768 control_cleanup();
1769 return EXIT_SUCCESS;