All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/5] Migration patches
@ 2019-06-05 11:53 Juan Quintela
  2019-06-05 11:53 ` [Qemu-devel] [PULL 1/5] migration/ram.c: MultiFDSendParams.sem_sync is not really used Juan Quintela
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Juan Quintela @ 2019-06-05 11:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Juan Quintela,
	Dr. David Alan Gilbert, Markus Armbruster, Paolo Bonzini

The following changes since commit 47fbad45d47af8af784bb12a5719489edcd89b4c:

  Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2019-06-04 17:22:42 +0100)

are available in the Git repository at:

  https://github.com/juanquintela/qemu.git tags/migration-pull-request

for you to fetch changes up to 03158519384f15890d587937bd1b3ea699898e55:

  migratioin/ram: leave RAMBlock->bmap blank on allocating (2019-06-05 12:44:03 +0200)

----------------------------------------------------------------
Migration Pull request

- Fd fixes and test (yuri)
- several fixes (wei)

----------------------------------------------------------------

Wei Yang (3):
  migration/ram.c: MultiFDSendParams.sem_sync is not really used
  migration/ram.c: multifd_send_state->count is not really used
  migratioin/ram: leave RAMBlock->bmap blank on allocating

Yury Kotov (2):
  migration: Fix fd protocol for incoming defer
  migration-test: Add a test for fd protocol

 migration/fd.c         |   8 ++--
 migration/fd.h         |   2 +-
 migration/ram.c        |  27 ++++++-----
 tests/libqtest.c       |  80 ++++++++++++++++++++++++++++++--
 tests/libqtest.h       |  51 ++++++++++++++++++++-
 tests/migration-test.c | 101 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 246 insertions(+), 23 deletions(-)

-- 
2.21.0



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PULL 1/5] migration/ram.c: MultiFDSendParams.sem_sync is not really used
  2019-06-05 11:53 [Qemu-devel] [PULL 0/5] Migration patches Juan Quintela
@ 2019-06-05 11:53 ` Juan Quintela
  2019-06-05 11:53 ` [Qemu-devel] [PULL 2/5] migration/ram.c: multifd_send_state->count " Juan Quintela
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Juan Quintela @ 2019-06-05 11:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Juan Quintela,
	Dr. David Alan Gilbert, Markus Armbruster, Wei Yang,
	Paolo Bonzini

From: Wei Yang <richardw.yang@linux.intel.com>

Besides init and destroy, MultiFDSendParams.sem_sync is not really used.

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 migration/ram.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 4c60869226..4c15f6fda1 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -661,8 +661,6 @@ typedef struct {
     uint64_t num_packets;
     /* pages sent through this channel */
     uint64_t num_pages;
-    /* syncs main thread and channels */
-    QemuSemaphore sem_sync;
 }  MultiFDSendParams;
 
 typedef struct {
@@ -1027,7 +1025,6 @@ void multifd_save_cleanup(void)
         p->c = NULL;
         qemu_mutex_destroy(&p->mutex);
         qemu_sem_destroy(&p->sem);
-        qemu_sem_destroy(&p->sem_sync);
         g_free(p->name);
         p->name = NULL;
         multifd_pages_clear(p->pages);
@@ -1201,7 +1198,6 @@ int multifd_save_setup(void)
 
         qemu_mutex_init(&p->mutex);
         qemu_sem_init(&p->sem, 0);
-        qemu_sem_init(&p->sem_sync, 0);
         p->quit = false;
         p->pending_job = 0;
         p->id = i;
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PULL 2/5] migration/ram.c: multifd_send_state->count is not really used
  2019-06-05 11:53 [Qemu-devel] [PULL 0/5] Migration patches Juan Quintela
  2019-06-05 11:53 ` [Qemu-devel] [PULL 1/5] migration/ram.c: MultiFDSendParams.sem_sync is not really used Juan Quintela
@ 2019-06-05 11:53 ` Juan Quintela
  2019-06-05 11:53 ` [Qemu-devel] [PULL 3/5] migration: Fix fd protocol for incoming defer Juan Quintela
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Juan Quintela @ 2019-06-05 11:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Juan Quintela,
	Dr. David Alan Gilbert, Markus Armbruster, Wei Yang,
	Paolo Bonzini

From: Wei Yang <richardw.yang@linux.intel.com>

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 migration/ram.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 4c15f6fda1..03a9cce9f9 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -892,8 +892,6 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
 
 struct {
     MultiFDSendParams *params;
-    /* number of created threads */
-    int count;
     /* array of pages to sent */
     MultiFDPages_t *pages;
     /* syncs main thread and channels */
@@ -1171,8 +1169,6 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
         p->running = true;
         qemu_thread_create(&p->thread, p->name, multifd_send_thread, p,
                            QEMU_THREAD_JOINABLE);
-
-        atomic_inc(&multifd_send_state->count);
     }
 }
 
@@ -1188,7 +1184,6 @@ int multifd_save_setup(void)
     thread_count = migrate_multifd_channels();
     multifd_send_state = g_malloc0(sizeof(*multifd_send_state));
     multifd_send_state->params = g_new0(MultiFDSendParams, thread_count);
-    atomic_set(&multifd_send_state->count, 0);
     multifd_send_state->pages = multifd_pages_init(page_count);
     qemu_sem_init(&multifd_send_state->sem_sync, 0);
     qemu_sem_init(&multifd_send_state->channels_ready, 0);
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PULL 3/5] migration: Fix fd protocol for incoming defer
  2019-06-05 11:53 [Qemu-devel] [PULL 0/5] Migration patches Juan Quintela
  2019-06-05 11:53 ` [Qemu-devel] [PULL 1/5] migration/ram.c: MultiFDSendParams.sem_sync is not really used Juan Quintela
  2019-06-05 11:53 ` [Qemu-devel] [PULL 2/5] migration/ram.c: multifd_send_state->count " Juan Quintela
@ 2019-06-05 11:53 ` Juan Quintela
  2019-06-05 11:53 ` [Qemu-devel] [PULL 4/5] migration-test: Add a test for fd protocol Juan Quintela
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Juan Quintela @ 2019-06-05 11:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Juan Quintela,
	Dr. David Alan Gilbert, Peter Xu, Markus Armbruster, Yury Kotov,
	Paolo Bonzini

From: Yury Kotov <yury-kotov@yandex-team.ru>

Currently, incoming migration through fd supports only command-line case:
E.g.
    fork();
    fd = open();
    exec("qemu ... -incoming fd:%d", fd);

It's possible to use add-fd commands to pass fd for migration, but it's
invalid case. add-fd works with fdset but not with particular fds.

To work with getfd in incoming defer it's enough to use monitor_fd_param
instead of strtol. monitor_fd_param supports both cases:
* fd:123
* fd:fd_name (added by getfd).

And also the use of monitor_fd_param improves error messages.

Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 migration/fd.c | 8 +++++---
 migration/fd.h | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/migration/fd.c b/migration/fd.c
index a7c13df4ad..0a29ecdebf 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -52,12 +52,14 @@ static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
     return G_SOURCE_REMOVE;
 }
 
-void fd_start_incoming_migration(const char *infd, Error **errp)
+void fd_start_incoming_migration(const char *fdname, Error **errp)
 {
     QIOChannel *ioc;
-    int fd;
+    int fd = monitor_fd_param(cur_mon, fdname, errp);
+    if (fd == -1) {
+        return;
+    }
 
-    fd = strtol(infd, NULL, 0);
     trace_migration_fd_incoming(fd);
 
     ioc = qio_channel_new_fd(fd, errp);
diff --git a/migration/fd.h b/migration/fd.h
index a14a63ce2e..b901bc014e 100644
--- a/migration/fd.h
+++ b/migration/fd.h
@@ -16,7 +16,7 @@
 
 #ifndef QEMU_MIGRATION_FD_H
 #define QEMU_MIGRATION_FD_H
-void fd_start_incoming_migration(const char *path, Error **errp);
+void fd_start_incoming_migration(const char *fdname, Error **errp);
 
 void fd_start_outgoing_migration(MigrationState *s, const char *fdname,
                                  Error **errp);
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PULL 4/5] migration-test: Add a test for fd protocol
  2019-06-05 11:53 [Qemu-devel] [PULL 0/5] Migration patches Juan Quintela
                   ` (2 preceding siblings ...)
  2019-06-05 11:53 ` [Qemu-devel] [PULL 3/5] migration: Fix fd protocol for incoming defer Juan Quintela
@ 2019-06-05 11:53 ` Juan Quintela
  2019-06-05 11:53 ` [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating Juan Quintela
  2019-06-06 10:32 ` [Qemu-devel] [PULL 0/5] Migration patches Peter Maydell
  5 siblings, 0 replies; 10+ messages in thread
From: Juan Quintela @ 2019-06-05 11:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Juan Quintela,
	Dr. David Alan Gilbert, Peter Xu, Markus Armbruster, Yury Kotov,
	Paolo Bonzini

From: Yury Kotov <yury-kotov@yandex-team.ru>

Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 tests/libqtest.c       |  80 ++++++++++++++++++++++++++++++--
 tests/libqtest.h       |  51 ++++++++++++++++++++-
 tests/migration-test.c | 101 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 227 insertions(+), 5 deletions(-)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 546a875913..9b9b5f37fc 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -32,6 +32,7 @@
 
 #define MAX_IRQ 256
 #define SOCKET_TIMEOUT 50
+#define SOCKET_MAX_FDS 16
 
 QTestState *global_qtest;
 
@@ -391,6 +392,40 @@ static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...)
     va_end(ap);
 }
 
+/* Sends a message and file descriptors to the socket.
+ * It's needed for qmp-commands like getfd/add-fd */
+static void socket_send_fds(int socket_fd, int *fds, size_t fds_num,
+                            const char *buf, size_t buf_size)
+{
+    ssize_t ret;
+    struct msghdr msg = { 0 };
+    char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)] = { 0 };
+    size_t fdsize = sizeof(int) * fds_num;
+    struct cmsghdr *cmsg;
+    struct iovec iov = { .iov_base = (char *)buf, .iov_len = buf_size };
+
+    msg.msg_iov = &iov;
+    msg.msg_iovlen = 1;
+
+    if (fds && fds_num > 0) {
+        g_assert_cmpuint(fds_num, <, SOCKET_MAX_FDS);
+
+        msg.msg_control = control;
+        msg.msg_controllen = CMSG_SPACE(fdsize);
+
+        cmsg = CMSG_FIRSTHDR(&msg);
+        cmsg->cmsg_len = CMSG_LEN(fdsize);
+        cmsg->cmsg_level = SOL_SOCKET;
+        cmsg->cmsg_type = SCM_RIGHTS;
+        memcpy(CMSG_DATA(cmsg), fds, fdsize);
+    }
+
+    do {
+        ret = sendmsg(socket_fd, &msg, 0);
+    } while (ret < 0 && errno == EINTR);
+    g_assert_cmpint(ret, >, 0);
+}
+
 static GString *qtest_recv_line(QTestState *s)
 {
     GString *line;
@@ -545,7 +580,8 @@ QDict *qtest_qmp_receive(QTestState *s)
  * in the case that they choose to discard all replies up until
  * a particular EVENT is received.
  */
-void qmp_fd_vsend(int fd, const char *fmt, va_list ap)
+void qmp_fd_vsend_fds(int fd, int *fds, size_t fds_num,
+                      const char *fmt, va_list ap)
 {
     QObject *qobj;
 
@@ -569,25 +605,49 @@ void qmp_fd_vsend(int fd, const char *fmt, va_list ap)
             fprintf(stderr, "%s", str);
         }
         /* Send QMP request */
-        socket_send(fd, str, qstring_get_length(qstr));
+        if (fds && fds_num > 0) {
+            socket_send_fds(fd, fds, fds_num, str, qstring_get_length(qstr));
+        } else {
+            socket_send(fd, str, qstring_get_length(qstr));
+        }
 
         qobject_unref(qstr);
         qobject_unref(qobj);
     }
 }
 
+void qmp_fd_vsend(int fd, const char *fmt, va_list ap)
+{
+    qmp_fd_vsend_fds(fd, NULL, 0, fmt, ap);
+}
+
+void qtest_qmp_vsend_fds(QTestState *s, int *fds, size_t fds_num,
+                         const char *fmt, va_list ap)
+{
+    qmp_fd_vsend_fds(s->qmp_fd, fds, fds_num, fmt, ap);
+}
+
 void qtest_qmp_vsend(QTestState *s, const char *fmt, va_list ap)
 {
-    qmp_fd_vsend(s->qmp_fd, fmt, ap);
+    qmp_fd_vsend_fds(s->qmp_fd, NULL, 0, fmt, ap);
 }
 
 QDict *qmp_fdv(int fd, const char *fmt, va_list ap)
 {
-    qmp_fd_vsend(fd, fmt, ap);
+    qmp_fd_vsend_fds(fd, NULL, 0, fmt, ap);
 
     return qmp_fd_receive(fd);
 }
 
+QDict *qtest_vqmp_fds(QTestState *s, int *fds, size_t fds_num,
+                      const char *fmt, va_list ap)
+{
+    qtest_qmp_vsend_fds(s, fds, fds_num, fmt, ap);
+
+    /* Receive reply */
+    return qtest_qmp_receive(s);
+}
+
 QDict *qtest_vqmp(QTestState *s, const char *fmt, va_list ap)
 {
     qtest_qmp_vsend(s, fmt, ap);
@@ -616,6 +676,18 @@ void qmp_fd_send(int fd, const char *fmt, ...)
     va_end(ap);
 }
 
+QDict *qtest_qmp_fds(QTestState *s, int *fds, size_t fds_num,
+                     const char *fmt, ...)
+{
+    va_list ap;
+    QDict *response;
+
+    va_start(ap, fmt);
+    response = qtest_vqmp_fds(s, fds, fds_num, fmt, ap);
+    va_end(ap);
+    return response;
+}
+
 QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
 {
     va_list ap;
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 32d927755d..cadf1d4a03 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -84,6 +84,21 @@ QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd);
  */
 void qtest_quit(QTestState *s);
 
+/**
+ * qtest_qmp_fds:
+ * @s: #QTestState instance to operate on.
+ * @fds: array of file descriptors
+ * @fds_num: number of elements in @fds
+ * @fmt...: QMP message to send to qemu, formatted like
+ * qobject_from_jsonf_nofail().  See parse_escape() for what's
+ * supported after '%'.
+ *
+ * Sends a QMP message to QEMU with fds and returns the response.
+ */
+QDict *qtest_qmp_fds(QTestState *s, int *fds, size_t fds_num,
+                     const char *fmt, ...)
+    GCC_FMT_ATTR(4, 5);
+
 /**
  * qtest_qmp:
  * @s: #QTestState instance to operate on.
@@ -120,7 +135,23 @@ void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 
 /**
- * qtest_qmpv:
+ * qtest_vqmp_fds:
+ * @s: #QTestState instance to operate on.
+ * @fds: array of file descriptors
+ * @fds_num: number of elements in @fds
+ * @fmt: QMP message to send to QEMU, formatted like
+ * qobject_from_jsonf_nofail().  See parse_escape() for what's
+ * supported after '%'.
+ * @ap: QMP message arguments
+ *
+ * Sends a QMP message to QEMU with fds and returns the response.
+ */
+QDict *qtest_vqmp_fds(QTestState *s, int *fds, size_t fds_num,
+                      const char *fmt, va_list ap)
+    GCC_FMT_ATTR(4, 0);
+
+/**
+ * qtest_vqmp:
  * @s: #QTestState instance to operate on.
  * @fmt: QMP message to send to QEMU, formatted like
  * qobject_from_jsonf_nofail().  See parse_escape() for what's
@@ -132,6 +163,22 @@ void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...)
 QDict *qtest_vqmp(QTestState *s, const char *fmt, va_list ap)
     GCC_FMT_ATTR(2, 0);
 
+/**
+ * qtest_qmp_vsend_fds:
+ * @s: #QTestState instance to operate on.
+ * @fds: array of file descriptors
+ * @fds_num: number of elements in @fds
+ * @fmt: QMP message to send to QEMU, formatted like
+ * qobject_from_jsonf_nofail().  See parse_escape() for what's
+ * supported after '%'.
+ * @ap: QMP message arguments
+ *
+ * Sends a QMP message to QEMU and leaves the response in the stream.
+ */
+void qtest_qmp_vsend_fds(QTestState *s, int *fds, size_t fds_num,
+                         const char *fmt, va_list ap)
+    GCC_FMT_ATTR(4, 0);
+
 /**
  * qtest_qmp_vsend:
  * @s: #QTestState instance to operate on.
@@ -888,6 +935,8 @@ static inline int64_t clock_step(int64_t step)
 }
 
 QDict *qmp_fd_receive(int fd);
+void qmp_fd_vsend_fds(int fd, int *fds, size_t fds_num,
+                      const char *fmt, va_list ap) GCC_FMT_ATTR(4, 0);
 void qmp_fd_vsend(int fd, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
 void qmp_fd_send(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
 void qmp_fd_send_raw(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
diff --git a/tests/migration-test.c b/tests/migration-test.c
index bd3f5c3125..e0407576cb 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -174,6 +174,21 @@ static void stop_cb(void *opaque, const char *name, QDict *data)
     }
 }
 
+/*
+ * Events can get in the way of responses we are actually waiting for.
+ */
+GCC_FMT_ATTR(3, 4)
+static QDict *wait_command_fd(QTestState *who, int fd, const char *command, ...)
+{
+    va_list ap;
+
+    va_start(ap, command);
+    qtest_qmp_vsend_fds(who, &fd, 1, command, ap);
+    va_end(ap);
+
+    return qtest_qmp_receive_success(who, stop_cb, NULL);
+}
+
 /*
  * Events can get in the way of responses we are actually waiting for.
  */
@@ -480,6 +495,7 @@ static void migrate(QTestState *who, const char *uri, const char *fmt, ...)
     qdict_put_str(args, "uri", uri);
 
     rsp = qmp("{ 'execute': 'migrate', 'arguments': %p}", args);
+
     g_assert(qdict_haskey(rsp, "return"));
     qobject_unref(rsp);
 }
@@ -1027,6 +1043,90 @@ static void test_precopy_tcp(void)
     g_free(uri);
 }
 
+static void test_migrate_fd_proto(void)
+{
+    QTestState *from, *to;
+    int ret;
+    int pair[2];
+    QDict *rsp;
+    const char *error_desc;
+
+    if (test_migrate_start(&from, &to, "defer", false, false)) {
+        return;
+    }
+
+    /*
+     * We want to pick a speed slow enough that the test completes
+     * quickly, but that it doesn't complete precopy even on a slow
+     * machine, so also set the downtime.
+     */
+    /* 1 ms should make it not converge */
+    migrate_set_parameter(from, "downtime-limit", 1);
+    /* 1GB/s */
+    migrate_set_parameter(from, "max-bandwidth", 1000000000);
+
+    /* Wait for the first serial output from the source */
+    wait_for_serial("src_serial");
+
+    /* Create two connected sockets for migration */
+    ret = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
+    g_assert_cmpint(ret, ==, 0);
+
+    /* Send the 1st socket to the target */
+    rsp = wait_command_fd(to, pair[0],
+                          "{ 'execute': 'getfd',"
+                          "  'arguments': { 'fdname': 'fd-mig' }}");
+    qobject_unref(rsp);
+    close(pair[0]);
+
+    /* Start incoming migration from the 1st socket */
+    rsp = wait_command(to, "{ 'execute': 'migrate-incoming',"
+                           "  'arguments': { 'uri': 'fd:fd-mig' }}");
+    qobject_unref(rsp);
+
+    /* Send the 2nd socket to the target */
+    rsp = wait_command_fd(from, pair[1],
+                          "{ 'execute': 'getfd',"
+                          "  'arguments': { 'fdname': 'fd-mig' }}");
+    qobject_unref(rsp);
+    close(pair[1]);
+
+    /* Start migration to the 2nd socket*/
+    migrate(from, "fd:fd-mig", "{}");
+
+    wait_for_migration_pass(from);
+
+    /* 300ms should converge */
+    migrate_set_parameter(from, "downtime-limit", 300);
+
+    if (!got_stop) {
+        qtest_qmp_eventwait(from, "STOP");
+    }
+    qtest_qmp_eventwait(to, "RESUME");
+
+    /* Test closing fds */
+    /* We assume, that QEMU removes named fd from its list,
+     * so this should fail */
+    rsp = qtest_qmp(from, "{ 'execute': 'closefd',"
+                          "  'arguments': { 'fdname': 'fd-mig' }}");
+    g_assert_true(qdict_haskey(rsp, "error"));
+    error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
+    g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
+    qobject_unref(rsp);
+
+    rsp = qtest_qmp(to, "{ 'execute': 'closefd',"
+                        "  'arguments': { 'fdname': 'fd-mig' }}");
+    g_assert_true(qdict_haskey(rsp, "error"));
+    error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
+    g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
+    qobject_unref(rsp);
+
+    /* Complete migration */
+    wait_for_serial("dest_serial");
+    wait_for_migration_complete(from);
+    test_migrate_end(from, to, true);
+}
+
 int main(int argc, char **argv)
 {
     char template[] = "/tmp/migration-test-XXXXXX";
@@ -1081,6 +1181,7 @@ int main(int argc, char **argv)
     qtest_add_func("/migration/precopy/tcp", test_precopy_tcp);
     /* qtest_add_func("/migration/ignore_shared", test_ignore_shared); */
     qtest_add_func("/migration/xbzrle/unix", test_xbzrle_unix);
+    qtest_add_func("/migration/fd_proto", test_migrate_fd_proto);
 
     ret = g_test_run();
 
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating
  2019-06-05 11:53 [Qemu-devel] [PULL 0/5] Migration patches Juan Quintela
                   ` (3 preceding siblings ...)
  2019-06-05 11:53 ` [Qemu-devel] [PULL 4/5] migration-test: Add a test for fd protocol Juan Quintela
@ 2019-06-05 11:53 ` Juan Quintela
  2019-06-05 12:26   ` Philippe Mathieu-Daudé
  2019-06-05 13:37   ` Wei Yang
  2019-06-06 10:32 ` [Qemu-devel] [PULL 0/5] Migration patches Peter Maydell
  5 siblings, 2 replies; 10+ messages in thread
From: Juan Quintela @ 2019-06-05 11:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Juan Quintela,
	Dr. David Alan Gilbert, Markus Armbruster, Wei Yang,
	Paolo Bonzini

From: Wei Yang <richardw.yang@linux.intel.com>

During migration, we would sync bitmap from ram_list.dirty_memory to
RAMBlock.bmap in cpu_physical_memory_sync_dirty_bitmap().

Since we set RAMBlock.bmap and ram_list.dirty_memory both to all 1, this
means at the first round this sync is meaningless and is a duplicated
work.

Leaving RAMBlock->bmap blank on allocating would have a side effect on
migration_dirty_pages, since it is calculated from the result of
cpu_physical_memory_sync_dirty_bitmap(). To keep it right, we need to
set migration_dirty_pages to 0 in ram_state_init().

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 migration/ram.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 03a9cce9f9..082aea9d23 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3173,11 +3173,11 @@ static int ram_state_init(RAMState **rsp)
     QSIMPLEQ_INIT(&(*rsp)->src_page_requests);
 
     /*
-     * Count the total number of pages used by ram blocks not including any
-     * gaps due to alignment or unplugs.
+     * This must match with the initial values of dirty bitmap.
+     * Currently we initialize the dirty bitmap to all zeros so
+     * here the total dirty page count is zero.
      */
-    (*rsp)->migration_dirty_pages = ram_bytes_total() >> TARGET_PAGE_BITS;
-
+    (*rsp)->migration_dirty_pages = 0;
     ram_state_reset(*rsp);
 
     return 0;
@@ -3192,8 +3192,16 @@ static void ram_list_init_bitmaps(void)
     if (ram_bytes_total()) {
         RAMBLOCK_FOREACH_NOT_IGNORED(block) {
             pages = block->max_length >> TARGET_PAGE_BITS;
+            /*
+             * The initial dirty bitmap for migration must be set with all
+             * ones to make sure we'll migrate every guest RAM page to
+             * destination.
+             * Here we didn't set RAMBlock.bmap simply because it is already
+             * set in ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION] in
+             * ram_block_add, and that's where we'll sync the dirty bitmaps.
+             * Here setting RAMBlock.bmap would be fine too but not necessary.
+             */
             block->bmap = bitmap_new(pages);
-            bitmap_set(block->bmap, 0, pages);
             if (migrate_postcopy_ram()) {
                 block->unsentmap = bitmap_new(pages);
                 bitmap_set(block->unsentmap, 0, pages);
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating
  2019-06-05 11:53 ` [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating Juan Quintela
@ 2019-06-05 12:26   ` Philippe Mathieu-Daudé
  2019-06-05 13:36     ` Wei Yang
  2019-06-05 13:37   ` Wei Yang
  1 sibling, 1 reply; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-06-05 12:26 UTC (permalink / raw)
  To: Juan Quintela, qemu-devel
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Markus Armbruster,
	Dr. David Alan Gilbert, Wei Yang, Paolo Bonzini

migratioin -> migration


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating
  2019-06-05 12:26   ` Philippe Mathieu-Daudé
@ 2019-06-05 13:36     ` Wei Yang
  0 siblings, 0 replies; 10+ messages in thread
From: Wei Yang @ 2019-06-05 13:36 UTC (permalink / raw)
  To: Philippe Mathieu-Daud??
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Juan Quintela,
	qemu-devel, Markus Armbruster, Wei Yang, Paolo Bonzini,
	Dr. David Alan Gilbert

On Wed, Jun 05, 2019 at 02:26:52PM +0200, Philippe Mathieu-Daud?? wrote:
>migratioin -> migration

Ah, you are right.

-- 
Wei Yang
Help you, Help me


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating
  2019-06-05 11:53 ` [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating Juan Quintela
  2019-06-05 12:26   ` Philippe Mathieu-Daudé
@ 2019-06-05 13:37   ` Wei Yang
  1 sibling, 0 replies; 10+ messages in thread
From: Wei Yang @ 2019-06-05 13:37 UTC (permalink / raw)
  To: Juan Quintela
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Markus Armbruster,
	qemu-devel, Wei Yang, Paolo Bonzini, Dr. David Alan Gilbert

On Wed, Jun 05, 2019 at 01:53:18PM +0200, Juan Quintela wrote:
>From: Wei Yang <richardw.yang@linux.intel.com>
>
>During migration, we would sync bitmap from ram_list.dirty_memory to
>RAMBlock.bmap in cpu_physical_memory_sync_dirty_bitmap().
>
>Since we set RAMBlock.bmap and ram_list.dirty_memory both to all 1, this
>means at the first round this sync is meaningless and is a duplicated
>work.
>
>Leaving RAMBlock->bmap blank on allocating would have a side effect on
>migration_dirty_pages, since it is calculated from the result of
>cpu_physical_memory_sync_dirty_bitmap(). To keep it right, we need to
>set migration_dirty_pages to 0 in ram_state_init().
>
>Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
>Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>Reviewed-by: Juan Quintela <quintela@redhat.com>
>Signed-off-by: Juan Quintela <quintela@redhat.com>

I think Peter acked this and gave some suggestions.

>---
> migration/ram.c | 18 +++++++++++++-----
> 1 file changed, 13 insertions(+), 5 deletions(-)
>
>diff --git a/migration/ram.c b/migration/ram.c
>index 03a9cce9f9..082aea9d23 100644
>--- a/migration/ram.c
>+++ b/migration/ram.c
>@@ -3173,11 +3173,11 @@ static int ram_state_init(RAMState **rsp)
>     QSIMPLEQ_INIT(&(*rsp)->src_page_requests);
> 
>     /*
>-     * Count the total number of pages used by ram blocks not including any
>-     * gaps due to alignment or unplugs.
>+     * This must match with the initial values of dirty bitmap.
>+     * Currently we initialize the dirty bitmap to all zeros so
>+     * here the total dirty page count is zero.
>      */
>-    (*rsp)->migration_dirty_pages = ram_bytes_total() >> TARGET_PAGE_BITS;
>-
>+    (*rsp)->migration_dirty_pages = 0;
>     ram_state_reset(*rsp);
> 
>     return 0;
>@@ -3192,8 +3192,16 @@ static void ram_list_init_bitmaps(void)
>     if (ram_bytes_total()) {
>         RAMBLOCK_FOREACH_NOT_IGNORED(block) {
>             pages = block->max_length >> TARGET_PAGE_BITS;
>+            /*
>+             * The initial dirty bitmap for migration must be set with all
>+             * ones to make sure we'll migrate every guest RAM page to
>+             * destination.
>+             * Here we didn't set RAMBlock.bmap simply because it is already
>+             * set in ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION] in
>+             * ram_block_add, and that's where we'll sync the dirty bitmaps.
>+             * Here setting RAMBlock.bmap would be fine too but not necessary.
>+             */
>             block->bmap = bitmap_new(pages);
>-            bitmap_set(block->bmap, 0, pages);
>             if (migrate_postcopy_ram()) {
>                 block->unsentmap = bitmap_new(pages);
>                 bitmap_set(block->unsentmap, 0, pages);
>-- 
>2.21.0
>

-- 
Wei Yang
Help you, Help me


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PULL 0/5] Migration patches
  2019-06-05 11:53 [Qemu-devel] [PULL 0/5] Migration patches Juan Quintela
                   ` (4 preceding siblings ...)
  2019-06-05 11:53 ` [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating Juan Quintela
@ 2019-06-06 10:32 ` Peter Maydell
  5 siblings, 0 replies; 10+ messages in thread
From: Peter Maydell @ 2019-06-06 10:32 UTC (permalink / raw)
  To: Juan Quintela
  Cc: Laurent Vivier, Thomas Huth, zhanghailiang, Markus Armbruster,
	QEMU Developers, Paolo Bonzini, Dr. David Alan Gilbert

On Wed, 5 Jun 2019 at 12:55, Juan Quintela <quintela@redhat.com> wrote:
>
> The following changes since commit 47fbad45d47af8af784bb12a5719489edcd89b4c:
>
>   Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2019-06-04 17:22:42 +0100)
>
> are available in the Git repository at:
>
>   https://github.com/juanquintela/qemu.git tags/migration-pull-request
>
> for you to fetch changes up to 03158519384f15890d587937bd1b3ea699898e55:
>
>   migratioin/ram: leave RAMBlock->bmap blank on allocating (2019-06-05 12:44:03 +0200)
>
> ----------------------------------------------------------------
> Migration Pull request
>
> - Fd fixes and test (yuri)
> - several fixes (wei)
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.1
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-06-06 10:41 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-05 11:53 [Qemu-devel] [PULL 0/5] Migration patches Juan Quintela
2019-06-05 11:53 ` [Qemu-devel] [PULL 1/5] migration/ram.c: MultiFDSendParams.sem_sync is not really used Juan Quintela
2019-06-05 11:53 ` [Qemu-devel] [PULL 2/5] migration/ram.c: multifd_send_state->count " Juan Quintela
2019-06-05 11:53 ` [Qemu-devel] [PULL 3/5] migration: Fix fd protocol for incoming defer Juan Quintela
2019-06-05 11:53 ` [Qemu-devel] [PULL 4/5] migration-test: Add a test for fd protocol Juan Quintela
2019-06-05 11:53 ` [Qemu-devel] [PULL 5/5] migratioin/ram: leave RAMBlock->bmap blank on allocating Juan Quintela
2019-06-05 12:26   ` Philippe Mathieu-Daudé
2019-06-05 13:36     ` Wei Yang
2019-06-05 13:37   ` Wei Yang
2019-06-06 10:32 ` [Qemu-devel] [PULL 0/5] Migration patches Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.