qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

sockets: pull code for testing IP availability out of specific test

The test-io-channel-socket.c file has some useful helper functions for
checking if a specific IP protocol is available. Other tests need to
perform similar kinds of checks to avoid running tests that will fail
due to missing IP protocols.

Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

+145 -71
+1 -1
tests/Makefile.include
··· 715 715 tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y) 716 716 tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y) 717 717 tests/test-io-channel-socket$(EXESUF): tests/test-io-channel-socket.o \ 718 - tests/io-channel-helpers.o $(test-io-obj-y) 718 + tests/io-channel-helpers.o tests/socket-helpers.o $(test-io-obj-y) 719 719 tests/tpm-crb-test$(EXESUF): tests/tpm-crb-test.o tests/tpm-emu.o $(test-io-obj-y) 720 720 tests/tpm-tis-test$(EXESUF): tests/tpm-tis-test.o tests/tpm-emu.o $(test-io-obj-y) 721 721 tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \
+100
tests/socket-helpers.c
··· 1 + /* 2 + * Helper functions for tests using sockets 3 + * 4 + * Copyright 2015-2018 Red Hat, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License as 8 + * published by the Free Software Foundation; either version 2 or 9 + * (at your option) version 3 of the License. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 + * 19 + */ 20 + 21 + #include "qemu/osdep.h" 22 + #include "qemu-common.h" 23 + #include "qemu/sockets.h" 24 + #include "socket-helpers.h" 25 + 26 + #ifndef AI_ADDRCONFIG 27 + # define AI_ADDRCONFIG 0 28 + #endif 29 + #ifndef EAI_ADDRFAMILY 30 + # define EAI_ADDRFAMILY 0 31 + #endif 32 + 33 + int socket_can_bind(const char *hostname) 34 + { 35 + int fd = -1; 36 + struct addrinfo ai, *res = NULL; 37 + int rc; 38 + int ret = -1; 39 + 40 + memset(&ai, 0, sizeof(ai)); 41 + ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; 42 + ai.ai_family = AF_UNSPEC; 43 + ai.ai_socktype = SOCK_STREAM; 44 + 45 + /* lookup */ 46 + rc = getaddrinfo(hostname, NULL, &ai, &res); 47 + if (rc != 0) { 48 + if (rc == EAI_ADDRFAMILY || 49 + rc == EAI_FAMILY) { 50 + errno = EADDRNOTAVAIL; 51 + } else { 52 + errno = EINVAL; 53 + } 54 + goto cleanup; 55 + } 56 + 57 + fd = qemu_socket(res->ai_family, res->ai_socktype, res->ai_protocol); 58 + if (fd < 0) { 59 + goto cleanup; 60 + } 61 + 62 + if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) { 63 + goto cleanup; 64 + } 65 + 66 + ret = 0; 67 + 68 + cleanup: 69 + if (fd != -1) { 70 + close(fd); 71 + } 72 + if (res) { 73 + freeaddrinfo(res); 74 + } 75 + return ret; 76 + } 77 + 78 + 79 + int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6) 80 + { 81 + *has_ipv4 = *has_ipv6 = false; 82 + 83 + if (socket_can_bind("127.0.0.1") < 0) { 84 + if (errno != EADDRNOTAVAIL) { 85 + return -1; 86 + } 87 + } else { 88 + *has_ipv4 = true; 89 + } 90 + 91 + if (socket_can_bind("::1") < 0) { 92 + if (errno != EADDRNOTAVAIL) { 93 + return -1; 94 + } 95 + } else { 96 + *has_ipv6 = true; 97 + } 98 + 99 + return 0; 100 + }
+42
tests/socket-helpers.h
··· 1 + /* 2 + * Helper functions for tests using sockets 3 + * 4 + * Copyright 2015-2018 Red Hat, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License as 8 + * published by the Free Software Foundation; either version 2 or 9 + * (at your option) version 3 of the License. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 + * 19 + */ 20 + 21 + /* 22 + * @hostname: a DNS name or numeric IP address 23 + * 24 + * Check whether it is possible to bind to ports 25 + * on the DNS name or IP address @hostname. If an IP address 26 + * is used, it must not be a wildcard address. 27 + * 28 + * Returns 0 on success, -1 on error with errno set 29 + */ 30 + int socket_can_bind(const char *hostname); 31 + 32 + /* 33 + * @has_ipv4: set to true on return if IPv4 is available 34 + * @has_ipv6: set to true on return if IPv6 is available 35 + * 36 + * Check whether IPv4 and/or IPv6 are available for use. 37 + * On success, @has_ipv4 and @has_ipv6 will be set to 38 + * indicate whether the respective protocols are available. 39 + * 40 + * Returns 0 on success, -1 on fatal error 41 + */ 42 + int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6);
+2 -70
tests/test-io-channel-socket.c
··· 22 22 #include "io/channel-socket.h" 23 23 #include "io/channel-util.h" 24 24 #include "io-channel-helpers.h" 25 + #include "socket-helpers.h" 25 26 #include "qapi/error.h" 26 - 27 - #ifndef AI_ADDRCONFIG 28 - # define AI_ADDRCONFIG 0 29 - #endif 30 - #ifndef EAI_ADDRFAMILY 31 - # define EAI_ADDRFAMILY 0 32 - #endif 33 - 34 - static int check_bind(const char *hostname, bool *has_proto) 35 - { 36 - int fd = -1; 37 - struct addrinfo ai, *res = NULL; 38 - int rc; 39 - int ret = -1; 40 - 41 - memset(&ai, 0, sizeof(ai)); 42 - ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; 43 - ai.ai_family = AF_UNSPEC; 44 - ai.ai_socktype = SOCK_STREAM; 45 - 46 - /* lookup */ 47 - rc = getaddrinfo(hostname, NULL, &ai, &res); 48 - if (rc != 0) { 49 - if (rc == EAI_ADDRFAMILY || 50 - rc == EAI_FAMILY) { 51 - *has_proto = false; 52 - goto done; 53 - } 54 - goto cleanup; 55 - } 56 - 57 - fd = qemu_socket(res->ai_family, res->ai_socktype, res->ai_protocol); 58 - if (fd < 0) { 59 - goto cleanup; 60 - } 61 - 62 - if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) { 63 - if (errno == EADDRNOTAVAIL) { 64 - *has_proto = false; 65 - goto done; 66 - } 67 - goto cleanup; 68 - } 69 - 70 - *has_proto = true; 71 - done: 72 - ret = 0; 73 - 74 - cleanup: 75 - if (fd != -1) { 76 - close(fd); 77 - } 78 - if (res) { 79 - freeaddrinfo(res); 80 - } 81 - return ret; 82 - } 83 - 84 - static int check_protocol_support(bool *has_ipv4, bool *has_ipv6) 85 - { 86 - if (check_bind("127.0.0.1", has_ipv4) < 0) { 87 - return -1; 88 - } 89 - if (check_bind("::1", has_ipv6) < 0) { 90 - return -1; 91 - } 92 - 93 - return 0; 94 - } 95 27 96 28 97 29 static void test_io_channel_set_socket_bufs(QIOChannel *src, ··· 566 498 * each protocol to avoid breaking tests on machines 567 499 * with either IPv4 or IPv6 disabled. 568 500 */ 569 - if (check_protocol_support(&has_ipv4, &has_ipv6) < 0) { 501 + if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { 570 502 return 1; 571 503 } 572 504