Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
src/qemu/qemu_migration.c | 19 +++++++++++----
src/qemu/qemu_migration.h | 3 ++-
src/qemu/qemu_process.c | 49 ++++++++++++++++++++++++++++-----------
src/qemu/qemu_process.h | 13 +++++++----
src/qemu/qemu_saveimage.c | 26 ++++++++++++++-------
5 files changed, 76 insertions(+), 34 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 3110ef2621..b1d27e07e1 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2281,13 +2281,23 @@ qemuMigrationDstGetURI(const char *migrateFrom,
int
qemuMigrationDstRun(virDomainObj *vm,
const char *uri,
- virDomainAsyncJob asyncJob)
+ virDomainAsyncJob asyncJob,
+ unsigned int flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
int rv;
VIR_DEBUG("Setting up incoming migration with URI %s", uri);
+ if (flags & VIR_QEMU_PROCESS_START_MAPPED_RAM) {
+ g_autoptr(qemuMigrationParams) migParams = NULL;
+
+ if (!(migParams = qemuMigrationParamsForMappedSave()))
+ return -1;
+
+ qemuMigrationParamsApply(vm, asyncJob, migParams, 0);
+ }
+
if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
return -1;
@@ -2945,7 +2955,6 @@ qemuMigrationDstPrepare(virDomainObj *vm,
unsigned short port,
int fd)
{
- qemuDomainObjPrivate *priv = vm->privateData;
g_autofree char *migrateFrom = NULL;
if (tunnel) {
@@ -2999,8 +3008,8 @@ qemuMigrationDstPrepare(virDomainObj *vm,
migrateFrom = g_strdup_printf(incFormat, protocol, listenAddress, port);
}
- return qemuProcessIncomingDefNew(priv->qemuCaps, listenAddress,
- migrateFrom, fd, NULL);
+ return qemuProcessIncomingDefNew(vm, listenAddress,
+ migrateFrom, fd, NULL, 0);
}
@@ -3238,7 +3247,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
}
if (qemuMigrationDstRun(vm, incoming->uri,
- VIR_ASYNC_JOB_MIGRATION_IN) < 0)
+ VIR_ASYNC_JOB_MIGRATION_IN, 0) < 0)
goto error;
if (qemuProcessFinishStartup(driver, vm, VIR_ASYNC_JOB_MIGRATION_IN,
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index f845a0198b..864f3280e5 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -286,7 +286,8 @@ qemuMigrationDstGetURI(const char *migrateFrom,
int
qemuMigrationDstRun(virDomainObj *vm,
const char *uri,
- virDomainAsyncJob asyncJob);
+ virDomainAsyncJob asyncJob,
+ unsigned int flags);
void
qemuMigrationSrcPostcopyFailed(virDomainObj *vm);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7ef7040a85..f700390a8c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4684,28 +4684,43 @@ qemuProcessIncomingDefFree(qemuProcessIncomingDef *inc)
* qemuProcessIncomingDefFree will NOT close it.
*/
qemuProcessIncomingDef *
-qemuProcessIncomingDefNew(virQEMUCaps *qemuCaps,
+qemuProcessIncomingDefNew(virDomainObj *vm,
const char *listenAddress,
const char *migrateFrom,
int fd,
- const char *path)
+ const char *path,
+ unsigned int flags)
{
+ qemuDomainObjPrivate *priv = vm->privateData;
qemuProcessIncomingDef *inc = NULL;
- if (qemuMigrationDstCheckProtocol(qemuCaps, migrateFrom) < 0)
+ if (qemuMigrationDstCheckProtocol(priv->qemuCaps, migrateFrom) < 0)
return NULL;
inc = g_new0(qemuProcessIncomingDef, 1);
inc->address = g_strdup(listenAddress);
-
- inc->uri = qemuMigrationDstGetURI(migrateFrom, fd);
- if (!inc->uri)
- goto error;
-
inc->fd = fd;
inc->path = path;
+ if (flags & VIR_QEMU_PROCESS_START_MAPPED_RAM) {
+ unsigned int fdsetId;
+ off_t offset;
+
+ if ((offset = lseek(fd, 0, SEEK_CUR)) == -1)
+ offset = 0;
+
+ inc->fdPassMigrate = qemuFDPassNew("migrate", priv);
+ qemuFDPassAddFD(inc->fdPassMigrate, &fd, "-fd");
+ qemuFDPassGetId(inc->fdPassMigrate, &fdsetId);
+ inc->uri = g_strdup_printf("file:/dev/fdset/%u,offset=%#lx",
fdsetId, offset);
+ } else {
+ inc->uri = qemuMigrationDstGetURI(migrateFrom, fd);
+ }
+
+ if (!inc->uri)
+ goto error;
+
return inc;
error:
@@ -7667,7 +7682,8 @@ qemuProcessLaunch(virConnectPtr conn,
VIR_QEMU_PROCESS_START_AUTODESTROY |
VIR_QEMU_PROCESS_START_NEW |
VIR_QEMU_PROCESS_START_GEN_VMID |
- VIR_QEMU_PROCESS_START_RESET_NVRAM, -1);
+ VIR_QEMU_PROCESS_START_RESET_NVRAM |
+ VIR_QEMU_PROCESS_START_MAPPED_RAM, -1);
cfg = virQEMUDriverGetConfig(driver);
@@ -7717,8 +7733,12 @@ qemuProcessLaunch(virConnectPtr conn,
&nnicindexes, &nicindexes)))
goto cleanup;
- if (incoming && incoming->fd != -1)
+ if (incoming && incoming->fd != -1) {
virCommandPassFD(cmd, incoming->fd, 0);
+ if (incoming->fdPassMigrate != NULL) {
+ qemuFDPassTransferCommand(incoming->fdPassMigrate, cmd);
+ }
+ }
/* now that we know it is about to start call the hook if present */
if (qemuProcessStartHook(driver, vm,
@@ -8153,7 +8173,8 @@ qemuProcessStart(virConnectPtr conn,
VIR_QEMU_PROCESS_START_PAUSED |
VIR_QEMU_PROCESS_START_AUTODESTROY |
VIR_QEMU_PROCESS_START_GEN_VMID |
- VIR_QEMU_PROCESS_START_RESET_NVRAM, cleanup);
+ VIR_QEMU_PROCESS_START_RESET_NVRAM |
+ VIR_QEMU_PROCESS_START_MAPPED_RAM, cleanup);
if (!migrateFrom && !snapshot)
flags |= VIR_QEMU_PROCESS_START_NEW;
@@ -8163,8 +8184,8 @@ qemuProcessStart(virConnectPtr conn,
goto cleanup;
if (migrateFrom) {
- incoming = qemuProcessIncomingDefNew(priv->qemuCaps, NULL, migrateFrom,
- migrateFd, migratePath);
+ incoming = qemuProcessIncomingDefNew(vm, NULL, migrateFrom,
+ migrateFd, migratePath, flags);
if (!incoming)
goto stop;
}
@@ -8191,7 +8212,7 @@ qemuProcessStart(virConnectPtr conn,
relabel = true;
if (incoming) {
- if (qemuMigrationDstRun(vm, incoming->uri, asyncJob) < 0)
+ if (qemuMigrationDstRun(vm, incoming->uri, asyncJob, flags) < 0)
goto stop;
} else {
/* Refresh state of devices from QEMU. During migration this happens
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index c1ea949215..a5212ee56e 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -54,14 +54,16 @@ struct _qemuProcessIncomingDef {
char *address; /* address where QEMU is supposed to listen */
char *uri; /* used when calling migrate-incoming QMP command */
int fd; /* for fd:N URI */
+ qemuFDPass *fdPassMigrate; /* for file:/dev/fdset/n,offset=x URI */
const char *path; /* path associated with fd */
};
-qemuProcessIncomingDef *qemuProcessIncomingDefNew(virQEMUCaps *qemuCaps,
- const char *listenAddress,
- const char *migrateFrom,
- int fd,
- const char *path);
+qemuProcessIncomingDef *qemuProcessIncomingDefNew(virDomainObj *vm,
+ const char *listenAddress,
+ const char *migrateFrom,
+ int fd,
+ const char *path,
+ unsigned int flags);
void qemuProcessIncomingDefFree(qemuProcessIncomingDef *inc);
int qemuProcessBeginJob(virDomainObj *vm,
@@ -77,6 +79,7 @@ typedef enum {
VIR_QEMU_PROCESS_START_NEW = 1 << 4, /* internal, new VM is starting
*/
VIR_QEMU_PROCESS_START_GEN_VMID = 1 << 5, /* Generate a new VMID */
VIR_QEMU_PROCESS_START_RESET_NVRAM = 1 << 6, /* Re-initialize NVRAM from
template */
+ VIR_QEMU_PROCESS_START_MAPPED_RAM = 1 << 7, /* Re-initialize NVRAM from
template */
} qemuProcessStartFlags;
int qemuProcessStart(virConnectPtr conn,
diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c
index 8f28770086..1545c00472 100644
--- a/src/qemu/qemu_saveimage.c
+++ b/src/qemu/qemu_saveimage.c
@@ -628,6 +628,7 @@ qemuSaveImageOpen(virQEMUDriver *driver,
int oflags = open_write ? O_RDWR : O_RDONLY;
size_t xml_len;
size_t cookie_len;
+ bool use_mapped_ram = false;
if (bypass_cache) {
int directFlag = virFileDirectFdFlag();
@@ -642,11 +643,6 @@ qemuSaveImageOpen(virQEMUDriver *driver,
if ((fd = qemuDomainOpenFile(cfg, NULL, path, oflags, NULL)) < 0)
return -1;
- if (bypass_cache &&
- !(*wrapperFd = virFileWrapperFdNew(&fd, path,
- VIR_FILE_WRAPPER_BYPASS_CACHE)))
- return -1;
-
data = g_new0(virQEMUSaveData, 1);
header = &data->header;
@@ -708,10 +704,14 @@ qemuSaveImageOpen(virQEMUDriver *driver,
return -1;
}
- if (header->features && header->features !=
QEMU_SAVE_FEATURE_MAPPED_RAM) {
- virReportError(VIR_ERR_OPERATION_FAILED, "%s",
- _("image contains unsupported features)"));
- return -1;
+ if (header->features) {
+ if (header->features == QEMU_SAVE_FEATURE_MAPPED_RAM) {
+ use_mapped_ram = true;
+ } else {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("image contains unsupported features)"));
+ return -1;
+ }
}
if (header->cookieOffset)
@@ -739,6 +739,11 @@ qemuSaveImageOpen(virQEMUDriver *driver,
}
}
+ if (bypass_cache && !use_mapped_ram &&
+ !(*wrapperFd = virFileWrapperFdNew(&fd, path,
+ VIR_FILE_WRAPPER_BYPASS_CACHE)))
+ return -1;
+
/* Create a domain from this XML */
if (!(def = virDomainDefParseString(data->xml, driver->xmlopt, qemuCaps,
VIR_DOMAIN_DEF_PARSE_INACTIVE |
@@ -777,6 +782,9 @@ qemuSaveImageStartVM(virConnectPtr conn,
if (reset_nvram)
start_flags |= VIR_QEMU_PROCESS_START_RESET_NVRAM;
+ if (header->features & QEMU_SAVE_FEATURE_MAPPED_RAM)
+ start_flags |= VIR_QEMU_PROCESS_START_MAPPED_RAM;
+
if (qemuProcessStartWithMemoryState(conn, driver, vm, fd, path, NULL, data,
asyncJob, start_flags, "restored",
&started) < 0) {
--
2.44.0