diff mbox series

[v5,46/50] multi-process/mig: Restore the VMSD in remote process

Message ID 68144e5a0cdc4a16c1fe63f4a7482191f86b7c0f.1582576372.git.jag.raman@oracle.com (mailing list archive)
State New, archived
Headers show
Series Initial support for multi-process qemu | expand

Commit Message

Jag Raman Feb. 24, 2020, 8:55 p.m. UTC
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>

The remote process accepts the VMSD from Proxy object and
restores it

Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
---
 migration/savevm.c   | 36 ++++++++++++++++++++++++++++++++++++
 migration/savevm.h   |  1 +
 remote/remote-main.c | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)

Comments

Dr. David Alan Gilbert March 5, 2020, 4:05 p.m. UTC | #1
* Jagannathan Raman (jag.raman@oracle.com) wrote:
> From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
> 
> The remote process accepts the VMSD from Proxy object and
> restores it
> 
> Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
> Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
> Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
> ---
>  migration/savevm.c   | 36 ++++++++++++++++++++++++++++++++++++
>  migration/savevm.h   |  1 +
>  remote/remote-main.c | 33 +++++++++++++++++++++++++++++++++
>  3 files changed, 70 insertions(+)
> 
> diff --git a/migration/savevm.c b/migration/savevm.c
> index 09af14d..e95ea4a 100644
> --- a/migration/savevm.c
> +++ b/migration/savevm.c
> @@ -2969,3 +2969,39 @@ int qemu_remote_savevm(QEMUFile *f)
>  
>      return 0;
>  }
> +
> +int qemu_remote_loadvm(QEMUFile *f)
> +{
> +    uint8_t section_type;
> +    int ret = 0;
> +
> +    qemu_mutex_lock_iothread();
> +
> +    while (true) {
> +        section_type = qemu_get_byte(f);
> +
> +        if (qemu_file_get_error(f)) {
> +            ret = qemu_file_get_error(f);
> +            break;
> +        }
> +
> +        switch (section_type) {
> +        case QEMU_VM_SECTION_FULL:
> +            ret = qemu_loadvm_section_start_full(f, NULL);
> +            if (ret < 0) {
> +                break;
> +            }
> +            break;
> +        case QEMU_VM_EOF:
> +            goto out;
> +        default:
> +            ret = -EINVAL;

It's good to print an error there - when it goes wrong we'll want to
know it.

> +            goto out;
> +        }
> +    }
> +
> +out:
> +    qemu_mutex_unlock_iothread();
> +
> +    return ret;
> +}
> diff --git a/migration/savevm.h b/migration/savevm.h
> index 0491d3a..8741c66 100644
> --- a/migration/savevm.h
> +++ b/migration/savevm.h
> @@ -66,5 +66,6 @@ int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis);
>  int qemu_load_device_state(QEMUFile *f);
>  
>  int qemu_remote_savevm(QEMUFile *f);
> +int qemu_remote_loadvm(QEMUFile *f);
>  
>  #endif
> diff --git a/remote/remote-main.c b/remote/remote-main.c
> index 0260c7c..ab4ad0b 100644
> --- a/remote/remote-main.c
> +++ b/remote/remote-main.c
> @@ -68,6 +68,7 @@
>  #include "chardev/char.h"
>  #include "sysemu/reset.h"
>  #include "vl.h"
> +#include "migration/misc.h"
>  
>  static MPQemuLinkState *mpqemu_link;
>  
> @@ -363,6 +364,30 @@ static void process_start_mig_out(MPQemuMsg *msg)
>      qemu_fclose(f);
>  }
>  
> +static int process_start_mig_in(MPQemuMsg *msg)
> +{
> +    Error *err = NULL;
> +    QIOChannel *ioc;
> +    QEMUFile *f;
> +    int rc = -EINVAL;
> +
> +    ioc = qio_channel_new_fd(msg->fds[0], &err);
> +    if (err) {
> +        error_report_err(err);
> +        return rc;
> +    }
> +
> +    qio_channel_set_name(QIO_CHANNEL(ioc), "remote-migration-channel");
> +
> +    f = qemu_fopen_channel_input(ioc);
> +
> +    rc = qemu_remote_loadvm(f);
> +
> +    qemu_fclose(f);
> +
> +    return rc;
> +}
> +
>  static void process_msg(GIOCondition cond, MPQemuChannel *chan)
>  {
>      MPQemuMsg *msg = NULL;
> @@ -455,6 +480,12 @@ static void process_msg(GIOCondition cond, MPQemuChannel *chan)
>      case START_MIG_OUT:
>          process_start_mig_out(msg);
>          break;
> +    case START_MIG_IN:
> +        if (process_start_mig_in(msg)) {
> +            error_setg(&err, "Incoming migration failed.");
> +            goto finalize_loop;
> +        }
> +        break;

Do you have any sanity checks to make sure what happens if you were to
receive a MIG_IN while you were already running?

Dave

>      case RUNSTATE_SET:
>          remote_runstate_set(msg->data1.runstate.state);
>          notify_proxy(msg->fds[0], 0);
> @@ -532,6 +563,8 @@ int main(int argc, char *argv[])
>      }
>      mpqemu_init_channel(mpqemu_link, &mpqemu_link->mmio, fd);
>  
> +    migration_object_init();
> +
>      parse_cmdline(argc - 3, argv + 3, NULL);
>  
>      mpqemu_link_set_callback(mpqemu_link, process_msg);
> -- 
> 1.8.3.1
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
diff mbox series

Patch

diff --git a/migration/savevm.c b/migration/savevm.c
index 09af14d..e95ea4a 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2969,3 +2969,39 @@  int qemu_remote_savevm(QEMUFile *f)
 
     return 0;
 }
+
+int qemu_remote_loadvm(QEMUFile *f)
+{
+    uint8_t section_type;
+    int ret = 0;
+
+    qemu_mutex_lock_iothread();
+
+    while (true) {
+        section_type = qemu_get_byte(f);
+
+        if (qemu_file_get_error(f)) {
+            ret = qemu_file_get_error(f);
+            break;
+        }
+
+        switch (section_type) {
+        case QEMU_VM_SECTION_FULL:
+            ret = qemu_loadvm_section_start_full(f, NULL);
+            if (ret < 0) {
+                break;
+            }
+            break;
+        case QEMU_VM_EOF:
+            goto out;
+        default:
+            ret = -EINVAL;
+            goto out;
+        }
+    }
+
+out:
+    qemu_mutex_unlock_iothread();
+
+    return ret;
+}
diff --git a/migration/savevm.h b/migration/savevm.h
index 0491d3a..8741c66 100644
--- a/migration/savevm.h
+++ b/migration/savevm.h
@@ -66,5 +66,6 @@  int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis);
 int qemu_load_device_state(QEMUFile *f);
 
 int qemu_remote_savevm(QEMUFile *f);
+int qemu_remote_loadvm(QEMUFile *f);
 
 #endif
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 0260c7c..ab4ad0b 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -68,6 +68,7 @@ 
 #include "chardev/char.h"
 #include "sysemu/reset.h"
 #include "vl.h"
+#include "migration/misc.h"
 
 static MPQemuLinkState *mpqemu_link;
 
@@ -363,6 +364,30 @@  static void process_start_mig_out(MPQemuMsg *msg)
     qemu_fclose(f);
 }
 
+static int process_start_mig_in(MPQemuMsg *msg)
+{
+    Error *err = NULL;
+    QIOChannel *ioc;
+    QEMUFile *f;
+    int rc = -EINVAL;
+
+    ioc = qio_channel_new_fd(msg->fds[0], &err);
+    if (err) {
+        error_report_err(err);
+        return rc;
+    }
+
+    qio_channel_set_name(QIO_CHANNEL(ioc), "remote-migration-channel");
+
+    f = qemu_fopen_channel_input(ioc);
+
+    rc = qemu_remote_loadvm(f);
+
+    qemu_fclose(f);
+
+    return rc;
+}
+
 static void process_msg(GIOCondition cond, MPQemuChannel *chan)
 {
     MPQemuMsg *msg = NULL;
@@ -455,6 +480,12 @@  static void process_msg(GIOCondition cond, MPQemuChannel *chan)
     case START_MIG_OUT:
         process_start_mig_out(msg);
         break;
+    case START_MIG_IN:
+        if (process_start_mig_in(msg)) {
+            error_setg(&err, "Incoming migration failed.");
+            goto finalize_loop;
+        }
+        break;
     case RUNSTATE_SET:
         remote_runstate_set(msg->data1.runstate.state);
         notify_proxy(msg->fds[0], 0);
@@ -532,6 +563,8 @@  int main(int argc, char *argv[])
     }
     mpqemu_init_channel(mpqemu_link, &mpqemu_link->mmio, fd);
 
+    migration_object_init();
+
     parse_cmdline(argc - 3, argv + 3, NULL);
 
     mpqemu_link_set_callback(mpqemu_link, process_msg);