vhost, pc: fixes for 2.5

Minor vhost fixes.  HW version tweak for PC.
 Documentation and test updates.
 
 Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJWVzX5AAoJECgfDbjSjVRp3UUH/jmankS57MaFIfB2plhrFlk0
 BAjMLhJ6GCLrDEAaMaes9wJXJJMQHfoZnwAqkfkvjabKbiq6yPZz2FIfjSKuV86Z
 F6XNuMxiM2qwt/HJ5IaBX0c0Bm9bsF3zQpVAs082KfLvTrmOf8SHk4b8OFOCJMvu
 asSl9J8DTo3LZwC1TNpbxvTj5k3OFhB8i16WT3lvdLv9QUxBwdUaG6WxUCZD/35C
 CJnjut7n09ZbG4dfVxAVl7KubX1llpNBopbTQEyoHaaVfOvFDL5R2Gf7/YG9G0+x
 aI4+rMmRt0KCTii7xjN63j88+YpGlTgrAZETzwxVolZGMOe74jGtCNQqlIBwPZI=
 =I1ki
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging

vhost, pc: fixes for 2.5

Minor vhost fixes.  HW version tweak for PC.
Documentation and test updates.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Thu 26 Nov 2015 16:40:25 GMT using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream:
  vhost-user-test: fix migration overlap test
  Fix memory leak on error
  Revert "vhost: send SET_VRING_ENABLE at start/stop"
  tests/vhost-user-bridge: read command line arguments
  tests/vhost-user-bridge: propose GUEST_ANNOUNCE feature
  vhost-user: clarify start and enable
  vhost-user: set link down when the char device is closed
  pc: Don't set hw_version on pc-*-2.5
  osdep: Change default value of qemu_hw_version() to "2.5+"

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-11-26 16:50:59 +00:00
commit 72f75c76d8
12 changed files with 156 additions and 42 deletions

View file

@ -45,6 +45,8 @@
#include <sys/mman.h>
#include <sys/eventfd.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <netdb.h>
#include <linux/vhost.h>
@ -747,6 +749,7 @@ vubr_get_features_exec(VubrDev *dev, VhostUserMsg *vmsg)
vmsg->payload.u64 =
((1ULL << VIRTIO_NET_F_MRG_RXBUF) |
(1ULL << VHOST_F_LOG_ALL) |
(1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE) |
(1ULL << VHOST_USER_F_PROTOCOL_FEATURES));
vmsg->size = sizeof(vmsg->payload.u64);
@ -1209,33 +1212,62 @@ vubr_new(const char *path)
return dev;
}
static void
vubr_set_host(struct sockaddr_in *saddr, const char *host)
{
if (isdigit(host[0])) {
if (!inet_aton(host, &saddr->sin_addr)) {
fprintf(stderr, "inet_aton() failed.\n");
exit(1);
}
} else {
struct hostent *he = gethostbyname(host);
if (!he) {
fprintf(stderr, "gethostbyname() failed.\n");
exit(1);
}
saddr->sin_addr = *(struct in_addr *)he->h_addr;
}
}
static void
vubr_backend_udp_setup(VubrDev *dev,
const char *local_host,
uint16_t local_port,
const char *dest_host,
uint16_t dest_port)
const char *local_port,
const char *remote_host,
const char *remote_port)
{
int sock;
struct sockaddr_in si_local = {
.sin_family = AF_INET,
.sin_port = htons(local_port),
};
const char *r;
if (inet_aton(local_host, &si_local.sin_addr) == 0) {
fprintf(stderr, "inet_aton() failed.\n");
int lport, rport;
lport = strtol(local_port, (char **)&r, 0);
if (r == local_port) {
fprintf(stderr, "lport parsing failed.\n");
exit(1);
}
rport = strtol(remote_port, (char **)&r, 0);
if (r == remote_port) {
fprintf(stderr, "rport parsing failed.\n");
exit(1);
}
struct sockaddr_in si_local = {
.sin_family = AF_INET,
.sin_port = htons(lport),
};
vubr_set_host(&si_local, local_host);
/* setup destination for sends */
dev->backend_udp_dest = (struct sockaddr_in) {
.sin_family = AF_INET,
.sin_port = htons(dest_port),
.sin_port = htons(rport),
};
if (inet_aton(dest_host, &dev->backend_udp_dest.sin_addr) == 0) {
fprintf(stderr, "inet_aton() failed.\n");
exit(1);
}
vubr_set_host(&dev->backend_udp_dest, remote_host);
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1) {
@ -1249,7 +1281,7 @@ vubr_backend_udp_setup(VubrDev *dev,
dev->backend_udp_sock = sock;
dispatcher_add(&dev->dispatcher, sock, dev, vubr_backend_recv_cb);
DPRINT("Waiting for data from udp backend on %s:%d...\n",
local_host, local_port);
local_host, lport);
}
static void
@ -1262,19 +1294,81 @@ vubr_run(VubrDev *dev)
}
}
static int
vubr_parse_host_port(const char **host, const char **port, const char *buf)
{
char *p = strchr(buf, ':');
if (!p) {
return -1;
}
*p = '\0';
*host = strdup(buf);
*port = strdup(p + 1);
return 0;
}
#define DEFAULT_UD_SOCKET "/tmp/vubr.sock"
#define DEFAULT_LHOST "127.0.0.1"
#define DEFAULT_LPORT "4444"
#define DEFAULT_RHOST "127.0.0.1"
#define DEFAULT_RPORT "5555"
static const char *ud_socket_path = DEFAULT_UD_SOCKET;
static const char *lhost = DEFAULT_LHOST;
static const char *lport = DEFAULT_LPORT;
static const char *rhost = DEFAULT_RHOST;
static const char *rport = DEFAULT_RPORT;
int
main(int argc, char *argv[])
{
VubrDev *dev;
int opt;
dev = vubr_new("/tmp/vubr.sock");
while ((opt = getopt(argc, argv, "l:r:u:")) != -1) {
switch (opt) {
case 'l':
if (vubr_parse_host_port(&lhost, &lport, optarg) < 0) {
goto out;
}
break;
case 'r':
if (vubr_parse_host_port(&rhost, &rport, optarg) < 0) {
goto out;
}
break;
case 'u':
ud_socket_path = strdup(optarg);
break;
default:
goto out;
}
}
DPRINT("ud socket: %s\n", ud_socket_path);
DPRINT("local: %s:%s\n", lhost, lport);
DPRINT("remote: %s:%s\n", rhost, rport);
dev = vubr_new(ud_socket_path);
if (!dev) {
return 1;
}
vubr_backend_udp_setup(dev,
"127.0.0.1", 4444,
"127.0.0.1", 5555);
vubr_backend_udp_setup(dev, lhost, lport, rhost, rport);
vubr_run(dev);
return 0;
out:
fprintf(stderr, "Usage: %s ", argv[0]);
fprintf(stderr, "[-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n");
fprintf(stderr, "\t-u path to unix doman socket. default: %s\n",
DEFAULT_UD_SOCKET);
fprintf(stderr, "\t-l local host and port. default: %s:%s\n",
DEFAULT_LHOST, DEFAULT_LPORT);
fprintf(stderr, "\t-r remote host and port. default: %s:%s\n",
DEFAULT_RHOST, DEFAULT_RPORT);
return 1;
}

View file

@ -131,6 +131,7 @@ typedef struct TestServer {
GMutex data_mutex;
GCond data_cond;
int log_fd;
uint64_t rings;
} TestServer;
#if !GLIB_CHECK_VERSION(2, 32, 0)
@ -279,6 +280,9 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
msg.payload.state.num = 0;
p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
assert(msg.payload.state.index < 2);
s->rings &= ~(0x1ULL << msg.payload.state.index);
break;
case VHOST_USER_SET_MEM_TABLE:
@ -316,10 +320,9 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
g_cond_signal(&s->data_cond);
break;
case VHOST_USER_SET_VRING_ENABLE:
if (!msg.payload.state.num) {
s->fds_num = 0;
}
case VHOST_USER_SET_VRING_BASE:
assert(msg.payload.state.index < 2);
s->rings |= 0x1ULL << msg.payload.state.index;
break;
default:
@ -486,7 +489,7 @@ static gboolean
test_migrate_source_check(GSource *source)
{
TestMigrateSource *t = (TestMigrateSource *)source;
gboolean overlap = t->src->fds_num > 0 && t->dest->fds_num > 0;
gboolean overlap = t->src->rings && t->dest->rings;
g_assert(!overlap);