Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Konstantin Shkolnyy <kshk@linux.ibm.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Konstantin Shkolnyy and committed by
Paolo Abeni
86814d8f 3f36ee29

+181 -53
+3 -6
tools/testing/vsock/control.c
··· 27 27 28 28 #include "timeout.h" 29 29 #include "control.h" 30 + #include "util.h" 30 31 31 32 static int control_fd = -1; 32 33 ··· 51 50 52 51 for (ai = result; ai; ai = ai->ai_next) { 53 52 int fd; 54 - int val = 1; 55 53 56 54 fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 57 55 if (fd < 0) ··· 65 65 break; 66 66 } 67 67 68 - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 69 - &val, sizeof(val)) < 0) { 70 - perror("setsockopt"); 71 - exit(EXIT_FAILURE); 72 - } 68 + setsockopt_int_check(fd, SOL_SOCKET, SO_REUSEADDR, 1, 69 + "setsockopt SO_REUSEADDR"); 73 70 74 71 if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) 75 72 goto next;
-10
tools/testing/vsock/msg_zerocopy_common.c
··· 14 14 15 15 #include "msg_zerocopy_common.h" 16 16 17 - void enable_so_zerocopy(int fd) 18 - { 19 - int val = 1; 20 - 21 - if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) { 22 - perror("setsockopt"); 23 - exit(EXIT_FAILURE); 24 - } 25 - } 26 - 27 17 void vsock_recv_completion(int fd, const bool *zerocopied) 28 18 { 29 19 struct sock_extended_err *serr;
-1
tools/testing/vsock/msg_zerocopy_common.h
··· 12 12 #define VSOCK_RECVERR 1 13 13 #endif 14 14 15 - void enable_so_zerocopy(int fd); 16 15 void vsock_recv_completion(int fd, const bool *zerocopied); 17 16 18 17 #endif /* MSG_ZEROCOPY_COMMON_H */
+142
tools/testing/vsock/util.c
··· 651 651 652 652 free(iovec); 653 653 } 654 + 655 + /* Set "unsigned long long" socket option and check that it's indeed set */ 656 + void setsockopt_ull_check(int fd, int level, int optname, 657 + unsigned long long val, char const *errmsg) 658 + { 659 + unsigned long long chkval; 660 + socklen_t chklen; 661 + int err; 662 + 663 + err = setsockopt(fd, level, optname, &val, sizeof(val)); 664 + if (err) { 665 + fprintf(stderr, "setsockopt err: %s (%d)\n", 666 + strerror(errno), errno); 667 + goto fail; 668 + } 669 + 670 + chkval = ~val; /* just make storage != val */ 671 + chklen = sizeof(chkval); 672 + 673 + err = getsockopt(fd, level, optname, &chkval, &chklen); 674 + if (err) { 675 + fprintf(stderr, "getsockopt err: %s (%d)\n", 676 + strerror(errno), errno); 677 + goto fail; 678 + } 679 + 680 + if (chklen != sizeof(chkval)) { 681 + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), 682 + chklen); 683 + goto fail; 684 + } 685 + 686 + if (chkval != val) { 687 + fprintf(stderr, "value mismatch: set %llu got %llu\n", val, 688 + chkval); 689 + goto fail; 690 + } 691 + return; 692 + fail: 693 + fprintf(stderr, "%s val %llu\n", errmsg, val); 694 + exit(EXIT_FAILURE); 695 + ; 696 + } 697 + 698 + /* Set "int" socket option and check that it's indeed set */ 699 + void setsockopt_int_check(int fd, int level, int optname, int val, 700 + char const *errmsg) 701 + { 702 + int chkval; 703 + socklen_t chklen; 704 + int err; 705 + 706 + err = setsockopt(fd, level, optname, &val, sizeof(val)); 707 + if (err) { 708 + fprintf(stderr, "setsockopt err: %s (%d)\n", 709 + strerror(errno), errno); 710 + goto fail; 711 + } 712 + 713 + chkval = ~val; /* just make storage != val */ 714 + chklen = sizeof(chkval); 715 + 716 + err = getsockopt(fd, level, optname, &chkval, &chklen); 717 + if (err) { 718 + fprintf(stderr, "getsockopt err: %s (%d)\n", 719 + strerror(errno), errno); 720 + goto fail; 721 + } 722 + 723 + if (chklen != sizeof(chkval)) { 724 + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), 725 + chklen); 726 + goto fail; 727 + } 728 + 729 + if (chkval != val) { 730 + fprintf(stderr, "value mismatch: set %d got %d\n", val, chkval); 731 + goto fail; 732 + } 733 + return; 734 + fail: 735 + fprintf(stderr, "%s val %d\n", errmsg, val); 736 + exit(EXIT_FAILURE); 737 + } 738 + 739 + static void mem_invert(unsigned char *mem, size_t size) 740 + { 741 + size_t i; 742 + 743 + for (i = 0; i < size; i++) 744 + mem[i] = ~mem[i]; 745 + } 746 + 747 + /* Set "timeval" socket option and check that it's indeed set */ 748 + void setsockopt_timeval_check(int fd, int level, int optname, 749 + struct timeval val, char const *errmsg) 750 + { 751 + struct timeval chkval; 752 + socklen_t chklen; 753 + int err; 754 + 755 + err = setsockopt(fd, level, optname, &val, sizeof(val)); 756 + if (err) { 757 + fprintf(stderr, "setsockopt err: %s (%d)\n", 758 + strerror(errno), errno); 759 + goto fail; 760 + } 761 + 762 + /* just make storage != val */ 763 + chkval = val; 764 + mem_invert((unsigned char *)&chkval, sizeof(chkval)); 765 + chklen = sizeof(chkval); 766 + 767 + err = getsockopt(fd, level, optname, &chkval, &chklen); 768 + if (err) { 769 + fprintf(stderr, "getsockopt err: %s (%d)\n", 770 + strerror(errno), errno); 771 + goto fail; 772 + } 773 + 774 + if (chklen != sizeof(chkval)) { 775 + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), 776 + chklen); 777 + goto fail; 778 + } 779 + 780 + if (memcmp(&chkval, &val, sizeof(val)) != 0) { 781 + fprintf(stderr, "value mismatch: set %ld:%ld got %ld:%ld\n", 782 + val.tv_sec, val.tv_usec, chkval.tv_sec, chkval.tv_usec); 783 + goto fail; 784 + } 785 + return; 786 + fail: 787 + fprintf(stderr, "%s val %ld:%ld\n", errmsg, val.tv_sec, val.tv_usec); 788 + exit(EXIT_FAILURE); 789 + } 790 + 791 + void enable_so_zerocopy_check(int fd) 792 + { 793 + setsockopt_int_check(fd, SOL_SOCKET, SO_ZEROCOPY, 1, 794 + "setsockopt SO_ZEROCOPY"); 795 + }
+7
tools/testing/vsock/util.h
··· 68 68 struct iovec *alloc_test_iovec(const struct iovec *test_iovec, int iovnum); 69 69 void free_test_iovec(const struct iovec *test_iovec, 70 70 struct iovec *iovec, int iovnum); 71 + void setsockopt_ull_check(int fd, int level, int optname, 72 + unsigned long long val, char const *errmsg); 73 + void setsockopt_int_check(int fd, int level, int optname, int val, 74 + char const *errmsg); 75 + void setsockopt_timeval_check(int fd, int level, int optname, 76 + struct timeval val, char const *errmsg); 77 + void enable_so_zerocopy_check(int fd); 71 78 #endif /* UTIL_H */
+10
tools/testing/vsock/vsock_perf.c
··· 251 251 close(fd); 252 252 } 253 253 254 + static void enable_so_zerocopy(int fd) 255 + { 256 + int val = 1; 257 + 258 + if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) { 259 + perror("setsockopt"); 260 + exit(EXIT_FAILURE); 261 + } 262 + } 263 + 254 264 static void run_sender(int peer_cid, unsigned long to_send_bytes) 255 265 { 256 266 time_t tx_begin_ns;
+17 -34
tools/testing/vsock/vsock_test.c
··· 444 444 445 445 sock_buf_size = SOCK_BUF_SIZE; 446 446 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); 451 - } 447 + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE, 448 + sock_buf_size, 449 + "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)"); 452 450 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); 457 - } 451 + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, 452 + sock_buf_size, 453 + "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); 458 454 459 455 /* Ready to receive data. */ 460 456 control_writeln("SRVREADY"); ··· 582 586 tv.tv_sec = RCVTIMEO_TIMEOUT_SEC; 583 587 tv.tv_usec = 0; 584 588 585 - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) { 586 - perror("setsockopt(SO_RCVTIMEO)"); 587 - exit(EXIT_FAILURE); 588 - } 589 + setsockopt_timeval_check(fd, SOL_SOCKET, SO_RCVTIMEO, tv, 590 + "setsockopt(SO_RCVTIMEO)"); 589 591 590 592 read_enter_ns = current_nsec(); 591 593 ··· 849 855 exit(EXIT_FAILURE); 850 856 } 851 857 852 - if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, 853 - &lowat_val, sizeof(lowat_val))) { 854 - perror("setsockopt(SO_RCVLOWAT)"); 855 - exit(EXIT_FAILURE); 856 - } 858 + setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, 859 + lowat_val, "setsockopt(SO_RCVLOWAT)"); 857 860 858 861 control_expectln("SRVSENT"); 859 862 ··· 1374 1383 /* size_t can be < unsigned long long */ 1375 1384 sock_buf_size = buf_size; 1376 1385 1377 - if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, 1378 - &sock_buf_size, sizeof(sock_buf_size))) { 1379 - perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); 1380 - exit(EXIT_FAILURE); 1381 - } 1386 + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, 1387 + sock_buf_size, 1388 + "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); 1382 1389 1383 1390 if (low_rx_bytes_test) { 1384 1391 /* Set new SO_RCVLOWAT here. This enables sending credit ··· 1385 1396 */ 1386 1397 recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE; 1387 1398 1388 - if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, 1389 - &recv_buf_size, sizeof(recv_buf_size))) { 1390 - perror("setsockopt(SO_RCVLOWAT)"); 1391 - exit(EXIT_FAILURE); 1392 - } 1399 + setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, 1400 + recv_buf_size, "setsockopt(SO_RCVLOWAT)"); 1393 1401 } 1394 1402 1395 1403 /* Send one dummy byte here, because 'setsockopt()' above also ··· 1428 1442 recv_buf_size++; 1429 1443 1430 1444 /* Updating SO_RCVLOWAT will send credit update. */ 1431 - if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, 1432 - &recv_buf_size, sizeof(recv_buf_size))) { 1433 - perror("setsockopt(SO_RCVLOWAT)"); 1434 - exit(EXIT_FAILURE); 1435 - } 1445 + setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, 1446 + recv_buf_size, "setsockopt(SO_RCVLOWAT)"); 1436 1447 } 1437 1448 1438 1449 fds.fd = fd;
+1 -1
tools/testing/vsock/vsock_test_zerocopy.c
··· 162 162 } 163 163 164 164 if (test_data->so_zerocopy) 165 - enable_so_zerocopy(fd); 165 + enable_so_zerocopy_check(fd); 166 166 167 167 iovec = alloc_test_iovec(test_data->vecs, test_data->vecs_cnt); 168 168
+1 -1
tools/testing/vsock/vsock_uring_test.c
··· 73 73 } 74 74 75 75 if (msg_zerocopy) 76 - enable_so_zerocopy(fd); 76 + enable_so_zerocopy_check(fd); 77 77 78 78 iovec = alloc_test_iovec(test_data->vecs, test_data->vecs_cnt); 79 79