OSDN Git Service

Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-3.0-20180703' into staging
[qmiga/qemu.git] / tests / vhost-user-test.c
1 /*
2  * QTest testcase for the vhost-user
3  *
4  * Copyright (c) 2014 Virtual Open Systems Sarl.
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7  * See the COPYING file in the top-level directory.
8  *
9  */
10
11 #include "qemu/osdep.h"
12
13 #include "libqtest.h"
14 #include "qapi/error.h"
15 #include "qapi/qmp/qdict.h"
16 #include "qemu/config-file.h"
17 #include "qemu/option.h"
18 #include "qemu/range.h"
19 #include "qemu/sockets.h"
20 #include "chardev/char-fe.h"
21 #include "qemu/memfd.h"
22 #include "sysemu/sysemu.h"
23 #include "libqos/libqos.h"
24 #include "libqos/pci-pc.h"
25 #include "libqos/virtio-pci.h"
26
27 #include "libqos/malloc-pc.h"
28 #include "hw/virtio/virtio-net.h"
29
30 #include <linux/vhost.h>
31 #include <linux/virtio_ids.h>
32 #include <linux/virtio_net.h>
33 #include <sys/vfs.h>
34
35
36 #define QEMU_CMD_MEM    " -m %d -object memory-backend-file,id=mem,size=%dM," \
37                         "mem-path=%s,share=on -numa node,memdev=mem"
38 #define QEMU_CMD_MEMFD  " -m %d -object memory-backend-memfd,id=mem,size=%dM," \
39                         " -numa node,memdev=mem"
40 #define QEMU_CMD_CHR    " -chardev socket,id=%s,path=%s%s"
41 #define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=%s,vhostforce"
42 #define QEMU_CMD_NET    " -device virtio-net-pci,netdev=net0"
43
44 #define HUGETLBFS_MAGIC       0x958458f6
45
46 /*********** FROM hw/virtio/vhost-user.c *************************************/
47
48 #define VHOST_MEMORY_MAX_NREGIONS    8
49 #define VHOST_MAX_VIRTQUEUES    0x100
50
51 #define VHOST_USER_F_PROTOCOL_FEATURES 30
52 #define VHOST_USER_PROTOCOL_F_MQ 0
53 #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
54
55 #define VHOST_LOG_PAGE 0x1000
56
57 typedef enum VhostUserRequest {
58     VHOST_USER_NONE = 0,
59     VHOST_USER_GET_FEATURES = 1,
60     VHOST_USER_SET_FEATURES = 2,
61     VHOST_USER_SET_OWNER = 3,
62     VHOST_USER_RESET_OWNER = 4,
63     VHOST_USER_SET_MEM_TABLE = 5,
64     VHOST_USER_SET_LOG_BASE = 6,
65     VHOST_USER_SET_LOG_FD = 7,
66     VHOST_USER_SET_VRING_NUM = 8,
67     VHOST_USER_SET_VRING_ADDR = 9,
68     VHOST_USER_SET_VRING_BASE = 10,
69     VHOST_USER_GET_VRING_BASE = 11,
70     VHOST_USER_SET_VRING_KICK = 12,
71     VHOST_USER_SET_VRING_CALL = 13,
72     VHOST_USER_SET_VRING_ERR = 14,
73     VHOST_USER_GET_PROTOCOL_FEATURES = 15,
74     VHOST_USER_SET_PROTOCOL_FEATURES = 16,
75     VHOST_USER_GET_QUEUE_NUM = 17,
76     VHOST_USER_SET_VRING_ENABLE = 18,
77     VHOST_USER_MAX
78 } VhostUserRequest;
79
80 typedef struct VhostUserMemoryRegion {
81     uint64_t guest_phys_addr;
82     uint64_t memory_size;
83     uint64_t userspace_addr;
84     uint64_t mmap_offset;
85 } VhostUserMemoryRegion;
86
87 typedef struct VhostUserMemory {
88     uint32_t nregions;
89     uint32_t padding;
90     VhostUserMemoryRegion regions[VHOST_MEMORY_MAX_NREGIONS];
91 } VhostUserMemory;
92
93 typedef struct VhostUserLog {
94     uint64_t mmap_size;
95     uint64_t mmap_offset;
96 } VhostUserLog;
97
98 typedef struct VhostUserMsg {
99     VhostUserRequest request;
100
101 #define VHOST_USER_VERSION_MASK     (0x3)
102 #define VHOST_USER_REPLY_MASK       (0x1<<2)
103     uint32_t flags;
104     uint32_t size; /* the following payload size */
105     union {
106 #define VHOST_USER_VRING_IDX_MASK   (0xff)
107 #define VHOST_USER_VRING_NOFD_MASK  (0x1<<8)
108         uint64_t u64;
109         struct vhost_vring_state state;
110         struct vhost_vring_addr addr;
111         VhostUserMemory memory;
112         VhostUserLog log;
113     } payload;
114 } QEMU_PACKED VhostUserMsg;
115
116 static VhostUserMsg m __attribute__ ((unused));
117 #define VHOST_USER_HDR_SIZE (sizeof(m.request) \
118                             + sizeof(m.flags) \
119                             + sizeof(m.size))
120
121 #define VHOST_USER_PAYLOAD_SIZE (sizeof(m) - VHOST_USER_HDR_SIZE)
122
123 /* The version of the protocol we support */
124 #define VHOST_USER_VERSION    (0x1)
125 /*****************************************************************************/
126
127 enum {
128     TEST_FLAGS_OK,
129     TEST_FLAGS_DISCONNECT,
130     TEST_FLAGS_BAD,
131     TEST_FLAGS_END,
132 };
133
134 typedef struct TestServer {
135     QPCIBus *bus;
136     QVirtioPCIDevice *dev;
137     QVirtQueue *vq[VHOST_MAX_VIRTQUEUES];
138     gchar *socket_path;
139     gchar *mig_path;
140     gchar *chr_name;
141     CharBackend chr;
142     int fds_num;
143     int fds[VHOST_MEMORY_MAX_NREGIONS];
144     VhostUserMemory memory;
145     GMutex data_mutex;
146     GCond data_cond;
147     int log_fd;
148     uint64_t rings;
149     bool test_fail;
150     int test_flags;
151     int queues;
152     QGuestAllocator *alloc;
153 } TestServer;
154
155 static TestServer *test_server_new(const gchar *name);
156 static void test_server_free(TestServer *server);
157 static void test_server_listen(TestServer *server);
158
159 static const char *tmpfs;
160 static const char *root;
161
162 enum test_memfd {
163     TEST_MEMFD_AUTO,
164     TEST_MEMFD_YES,
165     TEST_MEMFD_NO,
166 };
167
168 static char *get_qemu_cmd(TestServer *s,
169                           int mem, enum test_memfd memfd, const char *mem_path,
170                           const char *chr_opts, const char *extra)
171 {
172     if (memfd == TEST_MEMFD_AUTO && qemu_memfd_check()) {
173         memfd = TEST_MEMFD_YES;
174     }
175
176     if (memfd == TEST_MEMFD_YES) {
177         return g_strdup_printf(QEMU_CMD_MEMFD QEMU_CMD_CHR
178                                QEMU_CMD_NETDEV QEMU_CMD_NET "%s", mem, mem,
179                                s->chr_name, s->socket_path,
180                                chr_opts, s->chr_name, extra);
181     } else {
182         return g_strdup_printf(QEMU_CMD_MEM QEMU_CMD_CHR
183                                QEMU_CMD_NETDEV QEMU_CMD_NET "%s", mem, mem,
184                                mem_path, s->chr_name, s->socket_path,
185                                chr_opts, s->chr_name, extra);
186     }
187 }
188
189 static void init_virtio_dev(TestServer *s, uint32_t features_mask)
190 {
191     uint32_t features;
192     int i;
193
194     s->bus = qpci_init_pc(global_qtest, NULL);
195     g_assert_nonnull(s->bus);
196
197     s->dev = qvirtio_pci_device_find(s->bus, VIRTIO_ID_NET);
198     g_assert_nonnull(s->dev);
199
200     qvirtio_pci_device_enable(s->dev);
201     qvirtio_reset(&s->dev->vdev);
202     qvirtio_set_acknowledge(&s->dev->vdev);
203     qvirtio_set_driver(&s->dev->vdev);
204
205     s->alloc = pc_alloc_init(global_qtest);
206
207     for (i = 0; i < s->queues * 2; i++) {
208         s->vq[i] = qvirtqueue_setup(&s->dev->vdev, s->alloc, i);
209     }
210
211     features = qvirtio_get_features(&s->dev->vdev);
212     features = features & features_mask;
213     qvirtio_set_features(&s->dev->vdev, features);
214
215     qvirtio_set_driver_ok(&s->dev->vdev);
216 }
217
218 static void uninit_virtio_dev(TestServer *s)
219 {
220     int i;
221
222     for (i = 0; i < s->queues * 2; i++) {
223         qvirtqueue_cleanup(s->dev->vdev.bus, s->vq[i], s->alloc);
224     }
225     pc_alloc_uninit(s->alloc);
226
227     qvirtio_pci_device_free(s->dev);
228 }
229
230 static void wait_for_fds(TestServer *s)
231 {
232     gint64 end_time;
233
234     g_mutex_lock(&s->data_mutex);
235
236     end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
237     while (!s->fds_num) {
238         if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
239             /* timeout has passed */
240             g_assert(s->fds_num);
241             break;
242         }
243     }
244
245     /* check for sanity */
246     g_assert_cmpint(s->fds_num, >, 0);
247     g_assert_cmpint(s->fds_num, ==, s->memory.nregions);
248
249     g_mutex_unlock(&s->data_mutex);
250 }
251
252 static void read_guest_mem_server(TestServer *s)
253 {
254     uint32_t *guest_mem;
255     int i, j;
256     size_t size;
257
258     wait_for_fds(s);
259
260     g_mutex_lock(&s->data_mutex);
261
262     /* iterate all regions */
263     for (i = 0; i < s->fds_num; i++) {
264
265         /* We'll check only the region statring at 0x0*/
266         if (s->memory.regions[i].guest_phys_addr != 0x0) {
267             continue;
268         }
269
270         g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024);
271
272         size = s->memory.regions[i].memory_size +
273             s->memory.regions[i].mmap_offset;
274
275         guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
276                          MAP_SHARED, s->fds[i], 0);
277
278         g_assert(guest_mem != MAP_FAILED);
279         guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem));
280
281         for (j = 0; j < 256; j++) {
282             uint32_t a = readl(s->memory.regions[i].guest_phys_addr + j*4);
283             uint32_t b = guest_mem[j];
284
285             g_assert_cmpint(a, ==, b);
286         }
287
288         munmap(guest_mem, s->memory.regions[i].memory_size);
289     }
290
291     g_mutex_unlock(&s->data_mutex);
292 }
293
294 static void *thread_function(void *data)
295 {
296     GMainLoop *loop = data;
297     g_main_loop_run(loop);
298     return NULL;
299 }
300
301 static int chr_can_read(void *opaque)
302 {
303     return VHOST_USER_HDR_SIZE;
304 }
305
306 static void chr_read(void *opaque, const uint8_t *buf, int size)
307 {
308     TestServer *s = opaque;
309     CharBackend *chr = &s->chr;
310     VhostUserMsg msg;
311     uint8_t *p = (uint8_t *) &msg;
312     int fd;
313
314     if (s->test_fail) {
315         qemu_chr_fe_disconnect(chr);
316         /* now switch to non-failure */
317         s->test_fail = false;
318     }
319
320     if (size != VHOST_USER_HDR_SIZE) {
321         g_test_message("Wrong message size received %d\n", size);
322         return;
323     }
324
325     g_mutex_lock(&s->data_mutex);
326     memcpy(p, buf, VHOST_USER_HDR_SIZE);
327
328     if (msg.size) {
329         p += VHOST_USER_HDR_SIZE;
330         size = qemu_chr_fe_read_all(chr, p, msg.size);
331         if (size != msg.size) {
332             g_test_message("Wrong message size received %d != %d\n",
333                            size, msg.size);
334             return;
335         }
336     }
337
338     switch (msg.request) {
339     case VHOST_USER_GET_FEATURES:
340         /* send back features to qemu */
341         msg.flags |= VHOST_USER_REPLY_MASK;
342         msg.size = sizeof(m.payload.u64);
343         msg.payload.u64 = 0x1ULL << VHOST_F_LOG_ALL |
344             0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
345         if (s->queues > 1) {
346             msg.payload.u64 |= 0x1ULL << VIRTIO_NET_F_MQ;
347         }
348         if (s->test_flags >= TEST_FLAGS_BAD) {
349             msg.payload.u64 = 0;
350             s->test_flags = TEST_FLAGS_END;
351         }
352         p = (uint8_t *) &msg;
353         qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
354         break;
355
356     case VHOST_USER_SET_FEATURES:
357         g_assert_cmpint(msg.payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES),
358                         !=, 0ULL);
359         if (s->test_flags == TEST_FLAGS_DISCONNECT) {
360             qemu_chr_fe_disconnect(chr);
361             s->test_flags = TEST_FLAGS_BAD;
362         }
363         break;
364
365     case VHOST_USER_GET_PROTOCOL_FEATURES:
366         /* send back features to qemu */
367         msg.flags |= VHOST_USER_REPLY_MASK;
368         msg.size = sizeof(m.payload.u64);
369         msg.payload.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD;
370         if (s->queues > 1) {
371             msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ;
372         }
373         p = (uint8_t *) &msg;
374         qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
375         break;
376
377     case VHOST_USER_GET_VRING_BASE:
378         /* send back vring base to qemu */
379         msg.flags |= VHOST_USER_REPLY_MASK;
380         msg.size = sizeof(m.payload.state);
381         msg.payload.state.num = 0;
382         p = (uint8_t *) &msg;
383         qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
384
385         assert(msg.payload.state.index < s->queues * 2);
386         s->rings &= ~(0x1ULL << msg.payload.state.index);
387         break;
388
389     case VHOST_USER_SET_MEM_TABLE:
390         /* received the mem table */
391         memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory));
392         s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds,
393                                             G_N_ELEMENTS(s->fds));
394
395         /* signal the test that it can continue */
396         g_cond_signal(&s->data_cond);
397         break;
398
399     case VHOST_USER_SET_VRING_KICK:
400     case VHOST_USER_SET_VRING_CALL:
401         /* consume the fd */
402         qemu_chr_fe_get_msgfds(chr, &fd, 1);
403         /*
404          * This is a non-blocking eventfd.
405          * The receive function forces it to be blocking,
406          * so revert it back to non-blocking.
407          */
408         qemu_set_nonblock(fd);
409         break;
410
411     case VHOST_USER_SET_LOG_BASE:
412         if (s->log_fd != -1) {
413             close(s->log_fd);
414             s->log_fd = -1;
415         }
416         qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1);
417         msg.flags |= VHOST_USER_REPLY_MASK;
418         msg.size = 0;
419         p = (uint8_t *) &msg;
420         qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE);
421
422         g_cond_signal(&s->data_cond);
423         break;
424
425     case VHOST_USER_SET_VRING_BASE:
426         assert(msg.payload.state.index < s->queues * 2);
427         s->rings |= 0x1ULL << msg.payload.state.index;
428         break;
429
430     case VHOST_USER_GET_QUEUE_NUM:
431         msg.flags |= VHOST_USER_REPLY_MASK;
432         msg.size = sizeof(m.payload.u64);
433         msg.payload.u64 = s->queues;
434         p = (uint8_t *) &msg;
435         qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
436         break;
437
438     default:
439         break;
440     }
441
442     g_mutex_unlock(&s->data_mutex);
443 }
444
445 static const char *init_hugepagefs(const char *path)
446 {
447     struct statfs fs;
448     int ret;
449
450     if (access(path, R_OK | W_OK | X_OK)) {
451         g_test_message("access on path (%s): %s\n", path, strerror(errno));
452         return NULL;
453     }
454
455     do {
456         ret = statfs(path, &fs);
457     } while (ret != 0 && errno == EINTR);
458
459     if (ret != 0) {
460         g_test_message("statfs on path (%s): %s\n", path, strerror(errno));
461         return NULL;
462     }
463
464     if (fs.f_type != HUGETLBFS_MAGIC) {
465         g_test_message("Warning: path not on HugeTLBFS: %s\n", path);
466         return NULL;
467     }
468
469     return path;
470 }
471
472 static TestServer *test_server_new(const gchar *name)
473 {
474     TestServer *server = g_new0(TestServer, 1);
475
476     server->socket_path = g_strdup_printf("%s/%s.sock", tmpfs, name);
477     server->mig_path = g_strdup_printf("%s/%s.mig", tmpfs, name);
478     server->chr_name = g_strdup_printf("chr-%s", name);
479
480     g_mutex_init(&server->data_mutex);
481     g_cond_init(&server->data_cond);
482
483     server->log_fd = -1;
484     server->queues = 1;
485
486     return server;
487 }
488
489 static void chr_event(void *opaque, int event)
490 {
491     TestServer *s = opaque;
492
493     if (s->test_flags == TEST_FLAGS_END &&
494         event == CHR_EVENT_CLOSED) {
495         s->test_flags = TEST_FLAGS_OK;
496     }
497 }
498
499 static void test_server_create_chr(TestServer *server, const gchar *opt)
500 {
501     gchar *chr_path;
502     Chardev *chr;
503
504     chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt);
505     chr = qemu_chr_new(server->chr_name, chr_path);
506     g_free(chr_path);
507
508     g_assert_nonnull(chr);
509     qemu_chr_fe_init(&server->chr, chr, &error_abort);
510     qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read,
511                              chr_event, NULL, server, NULL, true);
512 }
513
514 static void test_server_listen(TestServer *server)
515 {
516     test_server_create_chr(server, ",server,nowait");
517 }
518
519 static gboolean _test_server_free(TestServer *server)
520 {
521     int i;
522
523     qemu_chr_fe_deinit(&server->chr, true);
524
525     for (i = 0; i < server->fds_num; i++) {
526         close(server->fds[i]);
527     }
528
529     if (server->log_fd != -1) {
530         close(server->log_fd);
531     }
532
533     unlink(server->socket_path);
534     g_free(server->socket_path);
535
536     unlink(server->mig_path);
537     g_free(server->mig_path);
538
539     g_free(server->chr_name);
540     qpci_free_pc(server->bus);
541
542     g_free(server);
543
544     return FALSE;
545 }
546
547 static void test_server_free(TestServer *server)
548 {
549     g_idle_add((GSourceFunc)_test_server_free, server);
550 }
551
552 static void wait_for_log_fd(TestServer *s)
553 {
554     gint64 end_time;
555
556     g_mutex_lock(&s->data_mutex);
557     end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
558     while (s->log_fd == -1) {
559         if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
560             /* timeout has passed */
561             g_assert(s->log_fd != -1);
562             break;
563         }
564     }
565
566     g_mutex_unlock(&s->data_mutex);
567 }
568
569 static void write_guest_mem(TestServer *s, uint32_t seed)
570 {
571     uint32_t *guest_mem;
572     int i, j;
573     size_t size;
574
575     wait_for_fds(s);
576
577     /* iterate all regions */
578     for (i = 0; i < s->fds_num; i++) {
579
580         /* We'll write only the region statring at 0x0 */
581         if (s->memory.regions[i].guest_phys_addr != 0x0) {
582             continue;
583         }
584
585         g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024);
586
587         size = s->memory.regions[i].memory_size +
588             s->memory.regions[i].mmap_offset;
589
590         guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
591                          MAP_SHARED, s->fds[i], 0);
592
593         g_assert(guest_mem != MAP_FAILED);
594         guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem));
595
596         for (j = 0; j < 256; j++) {
597             guest_mem[j] = seed + j;
598         }
599
600         munmap(guest_mem, s->memory.regions[i].memory_size);
601         break;
602     }
603 }
604
605 static guint64 get_log_size(TestServer *s)
606 {
607     guint64 log_size = 0;
608     int i;
609
610     for (i = 0; i < s->memory.nregions; ++i) {
611         VhostUserMemoryRegion *reg = &s->memory.regions[i];
612         guint64 last = range_get_last(reg->guest_phys_addr,
613                                        reg->memory_size);
614         log_size = MAX(log_size, last / (8 * VHOST_LOG_PAGE) + 1);
615     }
616
617     return log_size;
618 }
619
620 typedef struct TestMigrateSource {
621     GSource source;
622     TestServer *src;
623     TestServer *dest;
624 } TestMigrateSource;
625
626 static gboolean
627 test_migrate_source_check(GSource *source)
628 {
629     TestMigrateSource *t = (TestMigrateSource *)source;
630     gboolean overlap = t->src->rings && t->dest->rings;
631
632     g_assert(!overlap);
633
634     return FALSE;
635 }
636
637 GSourceFuncs test_migrate_source_funcs = {
638     .check = test_migrate_source_check,
639 };
640
641 static void test_read_guest_mem(const void *arg)
642 {
643     enum test_memfd memfd = GPOINTER_TO_INT(arg);
644     TestServer *server = NULL;
645     char *qemu_cmd = NULL;
646     QTestState *s = NULL;
647
648     server = test_server_new(memfd == TEST_MEMFD_YES ?
649                              "read-guest-memfd" : "read-guest-mem");
650     test_server_listen(server);
651
652     qemu_cmd = get_qemu_cmd(server, 512, memfd, root, "", "");
653
654     s = qtest_start(qemu_cmd);
655     g_free(qemu_cmd);
656
657     init_virtio_dev(server, 1u << VIRTIO_NET_F_MAC);
658
659     read_guest_mem_server(server);
660
661     uninit_virtio_dev(server);
662
663     qtest_quit(s);
664     test_server_free(server);
665 }
666
667 static void test_migrate(void)
668 {
669     TestServer *s = test_server_new("src");
670     TestServer *dest = test_server_new("dest");
671     char *uri = g_strdup_printf("%s%s", "unix:", dest->mig_path);
672     QTestState *global = global_qtest, *from, *to;
673     GSource *source;
674     gchar *cmd, *tmp;
675     QDict *rsp;
676     guint8 *log;
677     guint64 size;
678
679     test_server_listen(s);
680     test_server_listen(dest);
681
682     cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, "", "");
683     from = qtest_start(cmd);
684     g_free(cmd);
685
686     init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC);
687     wait_for_fds(s);
688     size = get_log_size(s);
689     g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
690
691     tmp = g_strdup_printf(" -incoming %s", uri);
692     cmd = get_qemu_cmd(dest, 2, TEST_MEMFD_AUTO, root, "", tmp);
693     g_free(tmp);
694     to = qtest_init(cmd);
695     g_free(cmd);
696
697     source = g_source_new(&test_migrate_source_funcs,
698                           sizeof(TestMigrateSource));
699     ((TestMigrateSource *)source)->src = s;
700     ((TestMigrateSource *)source)->dest = dest;
701     g_source_attach(source, NULL);
702
703     /* slow down migration to have time to fiddle with log */
704     /* TODO: qtest could learn to break on some places */
705     rsp = qmp("{ 'execute': 'migrate_set_speed',"
706               "'arguments': { 'value': 10 } }");
707     g_assert(qdict_haskey(rsp, "return"));
708     qobject_unref(rsp);
709
710     cmd = g_strdup_printf("{ 'execute': 'migrate',"
711                           "'arguments': { 'uri': '%s' } }",
712                           uri);
713     rsp = qmp(cmd);
714     g_free(cmd);
715     g_assert(qdict_haskey(rsp, "return"));
716     qobject_unref(rsp);
717
718     wait_for_log_fd(s);
719
720     log = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->log_fd, 0);
721     g_assert(log != MAP_FAILED);
722
723     /* modify first page */
724     write_guest_mem(s, 0x42);
725     log[0] = 1;
726     munmap(log, size);
727
728     /* speed things up */
729     rsp = qmp("{ 'execute': 'migrate_set_speed',"
730               "'arguments': { 'value': 0 } }");
731     g_assert(qdict_haskey(rsp, "return"));
732     qobject_unref(rsp);
733
734     qmp_eventwait("STOP");
735
736     global_qtest = to;
737     qmp_eventwait("RESUME");
738
739     read_guest_mem_server(dest);
740
741     uninit_virtio_dev(s);
742
743     g_source_destroy(source);
744     g_source_unref(source);
745
746     qtest_quit(to);
747     test_server_free(dest);
748     qtest_quit(from);
749     test_server_free(s);
750     g_free(uri);
751
752     global_qtest = global;
753 }
754
755 static void wait_for_rings_started(TestServer *s, size_t count)
756 {
757     gint64 end_time;
758
759     g_mutex_lock(&s->data_mutex);
760     end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
761     while (ctpop64(s->rings) != count) {
762         if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
763             /* timeout has passed */
764             g_assert_cmpint(ctpop64(s->rings), ==, count);
765             break;
766         }
767     }
768
769     g_mutex_unlock(&s->data_mutex);
770 }
771
772 #if defined(CONFIG_HAS_GLIB_SUBPROCESS_TESTS)
773 static inline void test_server_connect(TestServer *server)
774 {
775     test_server_create_chr(server, ",reconnect=1");
776 }
777
778 static gboolean
779 reconnect_cb(gpointer user_data)
780 {
781     TestServer *s = user_data;
782
783     qemu_chr_fe_disconnect(&s->chr);
784
785     return FALSE;
786 }
787
788 static gpointer
789 connect_thread(gpointer data)
790 {
791     TestServer *s = data;
792
793     /* wait for qemu to start before first try, to avoid extra warnings */
794     g_usleep(G_USEC_PER_SEC);
795     test_server_connect(s);
796
797     return NULL;
798 }
799
800 static void test_reconnect_subprocess(void)
801 {
802     TestServer *s = test_server_new("reconnect");
803     char *cmd;
804
805     g_thread_new("connect", connect_thread, s);
806     cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
807     qtest_start(cmd);
808     g_free(cmd);
809
810     init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC);
811     wait_for_fds(s);
812     wait_for_rings_started(s, 2);
813
814     /* reconnect */
815     s->fds_num = 0;
816     s->rings = 0;
817     g_idle_add(reconnect_cb, s);
818     wait_for_fds(s);
819     wait_for_rings_started(s, 2);
820
821     uninit_virtio_dev(s);
822
823     qtest_end();
824     test_server_free(s);
825     return;
826 }
827
828 static void test_reconnect(void)
829 {
830     gchar *path = g_strdup_printf("/%s/vhost-user/reconnect/subprocess",
831                                   qtest_get_arch());
832     g_test_trap_subprocess(path, 0, 0);
833     g_test_trap_assert_passed();
834     g_free(path);
835 }
836
837 static void test_connect_fail_subprocess(void)
838 {
839     TestServer *s = test_server_new("connect-fail");
840     char *cmd;
841
842     s->test_fail = true;
843     g_thread_new("connect", connect_thread, s);
844     cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
845     qtest_start(cmd);
846     g_free(cmd);
847
848     init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC);
849     wait_for_fds(s);
850     wait_for_rings_started(s, 2);
851
852     uninit_virtio_dev(s);
853
854     qtest_end();
855     test_server_free(s);
856 }
857
858 static void test_connect_fail(void)
859 {
860     gchar *path = g_strdup_printf("/%s/vhost-user/connect-fail/subprocess",
861                                   qtest_get_arch());
862     g_test_trap_subprocess(path, 0, 0);
863     g_test_trap_assert_passed();
864     g_free(path);
865 }
866
867 static void test_flags_mismatch_subprocess(void)
868 {
869     TestServer *s = test_server_new("flags-mismatch");
870     char *cmd;
871
872     s->test_flags = TEST_FLAGS_DISCONNECT;
873     g_thread_new("connect", connect_thread, s);
874     cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
875     qtest_start(cmd);
876     g_free(cmd);
877
878     init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC);
879     wait_for_fds(s);
880     wait_for_rings_started(s, 2);
881
882     uninit_virtio_dev(s);
883
884     qtest_end();
885     test_server_free(s);
886 }
887
888 static void test_flags_mismatch(void)
889 {
890     gchar *path = g_strdup_printf("/%s/vhost-user/flags-mismatch/subprocess",
891                                   qtest_get_arch());
892     g_test_trap_subprocess(path, 0, 0);
893     g_test_trap_assert_passed();
894     g_free(path);
895 }
896
897 #endif
898
899 static void test_multiqueue(void)
900 {
901     TestServer *s = test_server_new("mq");
902     char *cmd;
903     uint32_t features_mask = ~(QVIRTIO_F_BAD_FEATURE |
904                             (1u << VIRTIO_RING_F_INDIRECT_DESC) |
905                             (1u << VIRTIO_RING_F_EVENT_IDX));
906     s->queues = 2;
907     test_server_listen(s);
908
909     if (qemu_memfd_check()) {
910         cmd = g_strdup_printf(
911             QEMU_CMD_MEMFD QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
912             "-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
913             512, 512, s->chr_name,
914             s->socket_path, "", s->chr_name,
915             s->queues, s->queues * 2 + 2);
916     } else {
917         cmd = g_strdup_printf(
918             QEMU_CMD_MEM QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
919             "-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
920             512, 512, root, s->chr_name,
921             s->socket_path, "", s->chr_name,
922             s->queues, s->queues * 2 + 2);
923     }
924     qtest_start(cmd);
925     g_free(cmd);
926
927     init_virtio_dev(s, features_mask);
928
929     wait_for_rings_started(s, s->queues * 2);
930
931     uninit_virtio_dev(s);
932
933     qtest_end();
934
935     test_server_free(s);
936 }
937
938 int main(int argc, char **argv)
939 {
940     const char *hugefs;
941     int ret;
942     char template[] = "/tmp/vhost-test-XXXXXX";
943     GMainLoop *loop;
944     GThread *thread;
945
946     g_test_init(&argc, &argv, NULL);
947
948     module_call_init(MODULE_INIT_QOM);
949     qemu_add_opts(&qemu_chardev_opts);
950
951     tmpfs = mkdtemp(template);
952     if (!tmpfs) {
953         g_test_message("mkdtemp on path (%s): %s\n", template, strerror(errno));
954     }
955     g_assert(tmpfs);
956
957     hugefs = getenv("QTEST_HUGETLBFS_PATH");
958     if (hugefs) {
959         root = init_hugepagefs(hugefs);
960         g_assert(root);
961     } else {
962         root = tmpfs;
963     }
964
965     loop = g_main_loop_new(NULL, FALSE);
966     /* run the main loop thread so the chardev may operate */
967     thread = g_thread_new(NULL, thread_function, loop);
968
969     if (qemu_memfd_check()) {
970         qtest_add_data_func("/vhost-user/read-guest-mem/memfd",
971                             GINT_TO_POINTER(TEST_MEMFD_YES),
972                             test_read_guest_mem);
973     }
974     qtest_add_data_func("/vhost-user/read-guest-mem/memfile",
975                         GINT_TO_POINTER(TEST_MEMFD_NO), test_read_guest_mem);
976     qtest_add_func("/vhost-user/migrate", test_migrate);
977     qtest_add_func("/vhost-user/multiqueue", test_multiqueue);
978
979 #if defined(CONFIG_HAS_GLIB_SUBPROCESS_TESTS)
980     /* keeps failing on build-system since Aug 15 2017 */
981     if (getenv("QTEST_VHOST_USER_FIXME")) {
982         qtest_add_func("/vhost-user/reconnect/subprocess",
983                        test_reconnect_subprocess);
984         qtest_add_func("/vhost-user/reconnect", test_reconnect);
985         qtest_add_func("/vhost-user/connect-fail/subprocess",
986                        test_connect_fail_subprocess);
987         qtest_add_func("/vhost-user/connect-fail", test_connect_fail);
988         qtest_add_func("/vhost-user/flags-mismatch/subprocess",
989                        test_flags_mismatch_subprocess);
990         qtest_add_func("/vhost-user/flags-mismatch", test_flags_mismatch);
991     }
992 #endif
993
994     ret = g_test_run();
995
996     /* cleanup */
997
998     /* finish the helper thread and dispatch pending sources */
999     g_main_loop_quit(loop);
1000     g_thread_join(thread);
1001     while (g_main_context_pending(NULL)) {
1002         g_main_context_iteration (NULL, TRUE);
1003     }
1004     g_main_loop_unref(loop);
1005
1006     ret = rmdir(tmpfs);
1007     if (ret != 0) {
1008         g_test_message("unable to rmdir: path (%s): %s\n",
1009                        tmpfs, strerror(errno));
1010     }
1011     g_assert_cmpint(ret, ==, 0);
1012
1013     return ret;
1014 }