@@ -2930,3 +2930,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;
+}
@@ -65,5 +65,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
@@ -81,6 +81,7 @@
#include "chardev/char.h"
#include "sysemu/reset.h"
#include "vl.h"
+#include "migration/misc.h"
static MPQemuLinkState *mpqemu_link;
@@ -403,6 +404,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;
@@ -498,6 +523,13 @@ 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);
break;
@@ -569,6 +601,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);