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 <sbrivio@redhat.com>
This commit is contained in:
parent
69c8e5b598
commit
28fca04eb9
1 changed files with 31 additions and 12 deletions
45
qrap.c
45
qrap.c
|
@ -27,8 +27,8 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <net/if_arp.h>
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
#include "passt.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "passt.h"
|
||||||
#include "arp.h"
|
#include "arp.h"
|
||||||
|
|
||||||
static char *qemu_names[] = {
|
static char *qemu_names[] = {
|
||||||
|
@ -41,6 +41,11 @@ static char *qemu_names[] = {
|
||||||
NULL,
|
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 {
|
static const struct drop_arg {
|
||||||
char *name;
|
char *name;
|
||||||
char *val;
|
char *val;
|
||||||
|
@ -55,6 +60,15 @@ static const struct drop_arg {
|
||||||
{ 0 },
|
{ 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 {
|
static const struct pci_dev {
|
||||||
char *mach;
|
char *mach;
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -64,7 +78,7 @@ static const struct pci_dev {
|
||||||
int last;
|
int last;
|
||||||
} pci_devs[] = {
|
} pci_devs[] = {
|
||||||
{ "pc-q35", "virtio-net-pci",
|
{ "pc-q35", "virtio-net-pci",
|
||||||
"bus=pci.", ",addr=0x0", 1, 16 },
|
"bus=pci.", ",addr=0x0", 3, /* 2: hotplug bus */ 16 },
|
||||||
{ "pc-", "virtio-net-pci",
|
{ "pc-", "virtio-net-pci",
|
||||||
"bus=pci.0,addr=0x", "", 2, /* 1: ISA bridge */ 16 },
|
"bus=pci.0,addr=0x", "", 2, /* 1: ISA bridge */ 16 },
|
||||||
{ "s390-ccw", "virtio-net-ccw",
|
{ "s390-ccw", "virtio-net-ccw",
|
||||||
|
@ -98,8 +112,9 @@ void usage(const char *name)
|
||||||
*/
|
*/
|
||||||
int main(int argc, char **argv)
|
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;
|
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 = {
|
struct sockaddr_un addr = {
|
||||||
.sun_family = AF_UNIX,
|
.sun_family = AF_UNIX,
|
||||||
};
|
};
|
||||||
|
@ -130,6 +145,7 @@ int main(int argc, char **argv)
|
||||||
char probe_r;
|
char probe_r;
|
||||||
|
|
||||||
if (argc >= 3) {
|
if (argc >= 3) {
|
||||||
|
errno = 0;
|
||||||
fd = strtol(argv[1], NULL, 0);
|
fd = strtol(argv[1], NULL, 0);
|
||||||
if (fd >= 3 && fd < INT_MAX && !errno) {
|
if (fd >= 3 && fd < INT_MAX && !errno) {
|
||||||
char env_path[ARG_MAX + 1], *p, command[ARG_MAX];
|
char env_path[ARG_MAX + 1], *p, command[ARG_MAX];
|
||||||
|
@ -217,8 +233,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
valid_args:
|
valid_args:
|
||||||
for (i = 1; i < UNIX_SOCK_MAX; i++) {
|
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);
|
s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
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);
|
snprintf(addr.sun_path, UNIX_PATH_MAX, UNIX_SOCK_PATH, i);
|
||||||
if (!connect(s, (const struct sockaddr *)&addr, sizeof(addr)) &&
|
if (connect(s, (const struct sockaddr *)&addr, sizeof(addr)))
|
||||||
send(s, &probe, sizeof(probe), 0) == sizeof(probe) &&
|
perror("connect");
|
||||||
recv(s, &probe_r, 1, MSG_PEEK) > 0) {
|
else if (send(s, &probe, sizeof(probe), 0) != sizeof(probe))
|
||||||
tv.tv_usec = 0;
|
|
||||||
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
perror("send");
|
perror("send");
|
||||||
|
else if (recv(s, &probe_r, 1, MSG_PEEK) <= 0)
|
||||||
|
perror("recv");
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
fprintf(stderr, "Probe of %s failed\n", addr.sun_path);
|
||||||
|
|
||||||
close(s);
|
close(s);
|
||||||
}
|
}
|
||||||
|
@ -246,6 +261,10 @@ valid_args:
|
||||||
exit(EXIT_FAILURE);
|
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) {
|
if (dup2(s, (int)fd) < 0) {
|
||||||
perror("dup");
|
perror("dup");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
Loading…
Reference in a new issue