From 28fca04eb990f11608187252ca8949d7df22ce9d Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Sat, 17 Jul 2021 08:28:38 +0200 Subject: [PATCH] qrap: Skip pci.2 bus for pc-q35, add proper error reporting for probing On pc-q35, pci.2 is usually configured by libvirt as a hotplug bus, so we can't use address 0x0 there. Look for free busses starting from pci.3 instead. While at it, add proper error reporting for passt probing, and add some comments to structs that were previously missing. Signed-off-by: Stefano Brivio --- qrap.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/qrap.c b/qrap.c index 5c535ff..b1a8f03 100644 --- a/qrap.c +++ b/qrap.c @@ -27,8 +27,8 @@ #include #include -#include "passt.h" #include "util.h" +#include "passt.h" #include "arp.h" static char *qemu_names[] = { @@ -41,6 +41,11 @@ static char *qemu_names[] = { NULL, }; +/** + * struct drop_arg - Drop matching arguments on command line + * @name: Option name + * @val: Substring in option value, NULL matches any value + */ static const struct drop_arg { char *name; char *val; @@ -55,6 +60,15 @@ static const struct drop_arg { { 0 }, }; +/** + * struct pci_dev - PCI devices to add on command line depending on machine name + * @mach: Machine name + * @name: Device ("-device") name to insert + * @template: Prefix for device specification (first part of address) + * @template_post: Suffix for device specification (last part of address) + * @first: First usable PCI address + * @last: Last usable PCI address + */ static const struct pci_dev { char *mach; char *name; @@ -64,7 +78,7 @@ static const struct pci_dev { int last; } pci_devs[] = { { "pc-q35", "virtio-net-pci", - "bus=pci.", ",addr=0x0", 1, 16 }, + "bus=pci.", ",addr=0x0", 3, /* 2: hotplug bus */ 16 }, { "pc-", "virtio-net-pci", "bus=pci.0,addr=0x", "", 2, /* 1: ISA bridge */ 16 }, { "s390-ccw", "virtio-net-ccw", @@ -98,8 +112,9 @@ void usage(const char *name) */ int main(int argc, char **argv) { - char *qemu_argv[ARG_MAX], dev_str[ARG_MAX]; + struct timeval tv = { .tv_sec = 0, .tv_usec = 100 * 1000 }; int i, s, qemu_argc = 0, addr_map = 0, has_dev = 0; + char *qemu_argv[ARG_MAX], dev_str[ARG_MAX]; struct sockaddr_un addr = { .sun_family = AF_UNIX, }; @@ -130,6 +145,7 @@ int main(int argc, char **argv) char probe_r; if (argc >= 3) { + errno = 0; fd = strtol(argv[1], NULL, 0); if (fd >= 3 && fd < INT_MAX && !errno) { char env_path[ARG_MAX + 1], *p, command[ARG_MAX]; @@ -217,8 +233,6 @@ int main(int argc, char **argv) valid_args: for (i = 1; i < UNIX_SOCK_MAX; i++) { - struct timeval tv = { .tv_sec = 0, .tv_usec = 100 * 1000 }; - s = socket(AF_UNIX, SOCK_STREAM, 0); setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); @@ -228,15 +242,16 @@ valid_args: } snprintf(addr.sun_path, UNIX_PATH_MAX, UNIX_SOCK_PATH, i); - if (!connect(s, (const struct sockaddr *)&addr, sizeof(addr)) && - send(s, &probe, sizeof(probe), 0) == sizeof(probe) && - recv(s, &probe_r, 1, MSG_PEEK) > 0) { - tv.tv_usec = 0; - setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + if (connect(s, (const struct sockaddr *)&addr, sizeof(addr))) + perror("connect"); + else if (send(s, &probe, sizeof(probe), 0) != sizeof(probe)) + perror("send"); + else if (recv(s, &probe_r, 1, MSG_PEEK) <= 0) + perror("recv"); + else break; - } - perror("send"); + fprintf(stderr, "Probe of %s failed\n", addr.sun_path); close(s); } @@ -246,6 +261,10 @@ valid_args: exit(EXIT_FAILURE); } + tv.tv_usec = 0; + setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + fprintf(stderr, "Connected to %s\n", addr.sun_path); + if (dup2(s, (int)fd) < 0) { perror("dup"); exit(EXIT_FAILURE);