Part of qemuSaveImageStartVM() function will be used when reverting
external snapshots. To avoid duplicating code and logic extract the
shared bits into separate function.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/qemu/qemu_saveimage.c | 96 +++++++++++++++++++++++++++------------
src/qemu/qemu_saveimage.h | 11 +++++
2 files changed, 78 insertions(+), 29 deletions(-)
diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c
index 41310d6a9a..27b95b03ae 100644
--- a/src/qemu/qemu_saveimage.c
+++ b/src/qemu/qemu_saveimage.c
@@ -565,42 +565,50 @@ qemuSaveImageOpen(virQEMUDriver *driver,
return ret;
}
+/**
+ * qemuSaveImageStartProcess:
+ * @conn: connection object
+ * @driver: qemu driver object
+ * @vm: domain object
+ * @fd: FD pointer of memory state file
+ * @path: path to memory state file
+ * @data: data from memory state file
+ * @asyncJob: type of asynchronous job
+ * @start_flags: flags to start QEMU process with
+ * @started: boolean to store if QEMU process was started
+ *
+ * Start VM with existing memory state. Make sure that the stored memory state
+ * is correctly decompressed so it can be loaded by QEMU process.
+ *
+ * Returns 0 on success, -1 on error.
+ */
int
-qemuSaveImageStartVM(virConnectPtr conn,
- virQEMUDriver *driver,
- virDomainObj *vm,
- int *fd,
- virQEMUSaveData *data,
- const char *path,
- bool start_paused,
- bool reset_nvram,
- virDomainAsyncJob asyncJob)
+qemuSaveImageStartProcess(virConnectPtr conn,
+ virQEMUDriver *driver,
+ virDomainObj *vm,
+ int *fd,
+ const char *path,
+ virQEMUSaveData *data,
+ virDomainAsyncJob asyncJob,
+ unsigned int start_flags,
+ bool *started)
{
qemuDomainObjPrivate *priv = vm->privateData;
- int ret = -1;
- bool started = false;
- virObjectEvent *event;
+ g_autoptr(qemuDomainSaveCookie) cookie = NULL;
+ virQEMUSaveHeader *header = &data->header;
VIR_AUTOCLOSE intermediatefd = -1;
g_autoptr(virCommand) cmd = NULL;
g_autofree char *errbuf = NULL;
- g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
- virQEMUSaveHeader *header = &data->header;
- g_autoptr(qemuDomainSaveCookie) cookie = NULL;
int rc = 0;
- unsigned int start_flags = VIR_QEMU_PROCESS_START_PAUSED |
- VIR_QEMU_PROCESS_START_GEN_VMID;
-
- if (reset_nvram)
- start_flags |= VIR_QEMU_PROCESS_START_RESET_NVRAM;
if (virSaveCookieParseString(data->cookie, (virObject **)&cookie,
virDomainXMLOptionGetSaveCookie(driver->xmlopt)) <
0)
- goto cleanup;
+ return -1;
if ((header->version == 2) &&
(header->compressed != QEMU_SAVE_FORMAT_RAW)) {
if (!(cmd = qemuSaveImageGetCompressionCommand(header->compressed)))
- goto cleanup;
+ return -1;
intermediatefd = *fd;
*fd = -1;
@@ -613,7 +621,7 @@ qemuSaveImageStartVM(virConnectPtr conn,
if (virCommandRunAsync(cmd, NULL) < 0) {
*fd = intermediatefd;
intermediatefd = -1;
- goto cleanup;
+ return -1;
}
}
@@ -622,7 +630,7 @@ qemuSaveImageStartVM(virConnectPtr conn,
*/
if (cookie &&
qemuDomainFixupCPUs(vm, &cookie->cpu) < 0)
- goto cleanup;
+ return -1;
if (cookie && !cookie->slirpHelper)
priv->disableSlirp = true;
@@ -631,12 +639,12 @@ qemuSaveImageStartVM(virConnectPtr conn,
asyncJob, "stdio", *fd, path, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
start_flags) == 0)
- started = true;
+ *started = true;
if (intermediatefd != -1) {
virErrorPtr orig_err = NULL;
- if (!started) {
+ if (!*started) {
/* if there was an error setting up qemu, the intermediate
* process will wait forever to write to stdout, so we
* must manually kill it and ignore any error related to
@@ -656,15 +664,45 @@ qemuSaveImageStartVM(virConnectPtr conn,
rc = -1;
}
- virDomainAuditStart(vm, "restored", started);
- if (!started || rc < 0)
- goto cleanup;
+ virDomainAuditStart(vm, "restored", *started);
+ if (!*started || rc < 0)
+ return -1;
/* qemuProcessStart doesn't unset the qemu error reporting infrastructure
* in case of migration (which is used in this case) so we need to reset it
* so that the handle to virtlogd is not held open unnecessarily */
qemuMonitorSetDomainLog(qemuDomainGetMonitor(vm), NULL, NULL, NULL);
+ return 0;
+}
+
+int
+qemuSaveImageStartVM(virConnectPtr conn,
+ virQEMUDriver *driver,
+ virDomainObj *vm,
+ int *fd,
+ virQEMUSaveData *data,
+ const char *path,
+ bool start_paused,
+ bool reset_nvram,
+ virDomainAsyncJob asyncJob)
+{
+ int ret = -1;
+ bool started = false;
+ virObjectEvent *event;
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+ virQEMUSaveHeader *header = &data->header;
+ unsigned int start_flags = VIR_QEMU_PROCESS_START_PAUSED |
+ VIR_QEMU_PROCESS_START_GEN_VMID;
+
+ if (reset_nvram)
+ start_flags |= VIR_QEMU_PROCESS_START_RESET_NVRAM;
+
+ if (qemuSaveImageStartProcess(conn, driver, vm, fd, path, data,
+ asyncJob, start_flags, &started) < 0) {
+ goto cleanup;
+ }
+
event = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_RESTORED);
diff --git a/src/qemu/qemu_saveimage.h b/src/qemu/qemu_saveimage.h
index 30cf4b1ee0..24249ddf4c 100644
--- a/src/qemu/qemu_saveimage.h
+++ b/src/qemu/qemu_saveimage.h
@@ -57,6 +57,17 @@ qemuSaveImageUpdateDef(virQEMUDriver *driver,
virDomainDef *def,
const char *newxml);
+int
+qemuSaveImageStartProcess(virConnectPtr conn,
+ virQEMUDriver *driver,
+ virDomainObj *vm,
+ int *fd,
+ const char *path,
+ virQEMUSaveData *data,
+ virDomainAsyncJob asyncJob,
+ unsigned int start_flags,
+ bool *started);
+
int
qemuSaveImageStartVM(virConnectPtr conn,
virQEMUDriver *driver,
--
2.41.0