| From d37bad5cb5da2804d51cd6c45903f538d9ec85c5 Mon Sep 17 00:00:00 2001 |
| Message-Id: <d37bad5cb5da2804d51cd6c45903f538d9ec85c5@dist-git> |
| From: Jiri Denemark <jdenemar@redhat.com> |
| Date: Tue, 6 Jun 2017 22:29:24 +0200 |
| Subject: [PATCH] qemu: Introduce virQEMUSaveData{New,Free} |
| |
| This is a preparation for creating a new virQEMUSaveData structure which |
| will encapsulate all save image header data. |
| |
| Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
| Reviewed-by: Pavel Hrdina <phrdina@redhat.com> |
| (cherry picked from commit a2d2aae148980f00dd83093d61b1aa06c54fbe96) |
| |
| https://bugzilla.redhat.com/show_bug.cgi?id=1441662 |
| |
| Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
| |
| src/qemu/qemu_driver.c | 128 ++++++++++++++++++++++++++++++++----------------- |
| 1 file changed, 83 insertions(+), 45 deletions(-) |
| |
| diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c |
| index 5db92b04a1..4a05793339 100644 |
| |
| |
| @@ -2826,6 +2826,36 @@ bswap_header(virQEMUSaveHeaderPtr hdr) |
| } |
| |
| |
| +static void |
| +virQEMUSaveDataFree(virQEMUSaveHeaderPtr header) |
| +{ |
| + if (!header) |
| + return; |
| + |
| + VIR_FREE(header); |
| +} |
| + |
| + |
| +static virQEMUSaveHeaderPtr |
| +virQEMUSaveDataNew(char *domXML, |
| + bool running, |
| + int compressed) |
| +{ |
| + virQEMUSaveHeaderPtr header = NULL; |
| + |
| + if (VIR_ALLOC(header) < 0) |
| + return NULL; |
| + |
| + memcpy(header->magic, QEMU_SAVE_PARTIAL, sizeof(header->magic)); |
| + header->version = QEMU_SAVE_VERSION; |
| + header->was_running = running ? 1 : 0; |
| + header->compressed = compressed; |
| + header->data_len = strlen(domXML) + 1; |
| + |
| + return header; |
| +} |
| + |
| + |
| /* return -errno on failure, or 0 on success */ |
| static int |
| qemuDomainSaveHeader(int fd, const char *path, const char *xml, |
| @@ -3048,13 +3078,11 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver, |
| virDomainObjPtr vm, |
| const char *path, |
| const char *domXML, |
| - int compressed, |
| + virQEMUSaveHeaderPtr header, |
| const char *compressedpath, |
| - bool was_running, |
| unsigned int flags, |
| qemuDomainAsyncJob asyncJob) |
| { |
| - virQEMUSaveHeader header; |
| bool bypassSecurityDriver = false; |
| bool needUnlink = false; |
| int ret = -1; |
| @@ -3063,13 +3091,6 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver, |
| virFileWrapperFdPtr wrapperFd = NULL; |
| unsigned int wrapperFlags = VIR_FILE_WRAPPER_NON_BLOCKING; |
| |
| - memset(&header, 0, sizeof(header)); |
| - memcpy(header.magic, QEMU_SAVE_PARTIAL, sizeof(header.magic)); |
| - header.version = QEMU_SAVE_VERSION; |
| - header.was_running = was_running ? 1 : 0; |
| - header.compressed = compressed; |
| - header.data_len = strlen(domXML) + 1; |
| - |
| /* Obtain the file handle. */ |
| if ((flags & VIR_DOMAIN_SAVE_BYPASS_CACHE)) { |
| wrapperFlags |= VIR_FILE_WRAPPER_BYPASS_CACHE; |
| @@ -3093,7 +3114,7 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver, |
| goto cleanup; |
| |
| /* Write header to file, followed by XML */ |
| - if (qemuDomainSaveHeader(fd, path, domXML, &header) < 0) |
| + if (qemuDomainSaveHeader(fd, path, domXML, header) < 0) |
| goto cleanup; |
| |
| /* Perform the migration */ |
| @@ -3117,7 +3138,7 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver, |
| if ((fd = qemuOpenFile(driver, vm, path, O_WRONLY, NULL, NULL)) < 0) |
| goto cleanup; |
| |
| - memcpy(header.magic, QEMU_SAVE_MAGIC, sizeof(header.magic)); |
| + memcpy(header->magic, QEMU_SAVE_MAGIC, sizeof(header->magic)); |
| |
| if (safewrite(fd, &header, sizeof(header)) != sizeof(header)) { |
| virReportSystemError(errno, _("unable to write %s"), path); |
| @@ -3158,6 +3179,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom, |
| virObjectEventPtr event = NULL; |
| qemuDomainObjPrivatePtr priv = vm->privateData; |
| virCapsPtr caps; |
| + virQEMUSaveHeaderPtr header = NULL; |
| |
| if (!(caps = virQEMUDriverGetCapabilities(driver, false))) |
| goto cleanup; |
| @@ -3223,9 +3245,11 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom, |
| goto endjob; |
| } |
| |
| - ret = qemuDomainSaveMemory(driver, vm, path, xml, compressed, |
| - compressedpath, was_running, flags, |
| - QEMU_ASYNC_JOB_SAVE); |
| + if (!(header = virQEMUSaveDataNew(xml, was_running, compressed))) |
| + goto endjob; |
| + |
| + ret = qemuDomainSaveMemory(driver, vm, path, xml, header, compressedpath, |
| + flags, QEMU_ASYNC_JOB_SAVE); |
| if (ret < 0) |
| goto endjob; |
| |
| @@ -3258,6 +3282,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom, |
| |
| cleanup: |
| VIR_FREE(xml); |
| + virQEMUSaveDataFree(header); |
| qemuDomainEventQueue(driver, event); |
| virObjectUnref(caps); |
| return ret; |
| @@ -6189,7 +6214,7 @@ static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) |
| qemuDomainSaveImageOpen(virQEMUDriverPtr driver, |
| const char *path, |
| virDomainDefPtr *ret_def, |
| - virQEMUSaveHeaderPtr ret_header, |
| + virQEMUSaveHeaderPtr *ret_header, |
| char **xmlout, |
| bool bypass_cache, |
| virFileWrapperFdPtr *wrapperFd, |
| @@ -6197,8 +6222,8 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, |
| bool unlink_corrupt) |
| { |
| int fd = -1; |
| - virQEMUSaveHeader header; |
| char *xml = NULL; |
| + virQEMUSaveHeaderPtr header = NULL; |
| virDomainDefPtr def = NULL; |
| int oflags = open_write ? O_RDWR : O_RDONLY; |
| virCapsPtr caps = NULL; |
| @@ -6223,7 +6248,10 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, |
| VIR_FILE_WRAPPER_BYPASS_CACHE))) |
| goto error; |
| |
| - if (saferead(fd, &header, sizeof(header)) != sizeof(header)) { |
| + if (VIR_ALLOC(header) < 0) |
| + goto error; |
| + |
| + if (saferead(fd, header, sizeof(*header)) != sizeof(*header)) { |
| if (unlink_corrupt) { |
| if (VIR_CLOSE(fd) < 0 || unlink(path) < 0) { |
| virReportSystemError(errno, |
| @@ -6239,11 +6267,11 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, |
| goto error; |
| } |
| |
| - if (memcmp(header.magic, QEMU_SAVE_MAGIC, sizeof(header.magic)) != 0) { |
| + if (memcmp(header->magic, QEMU_SAVE_MAGIC, sizeof(header->magic)) != 0) { |
| const char *msg = _("image magic is incorrect"); |
| |
| - if (memcmp(header.magic, QEMU_SAVE_PARTIAL, |
| - sizeof(header.magic)) == 0) { |
| + if (memcmp(header->magic, QEMU_SAVE_PARTIAL, |
| + sizeof(header->magic)) == 0) { |
| msg = _("save image is incomplete"); |
| if (unlink_corrupt) { |
| if (VIR_CLOSE(fd) < 0 || unlink(path) < 0) { |
| @@ -6260,28 +6288,28 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, |
| goto error; |
| } |
| |
| - if (header.version > QEMU_SAVE_VERSION) { |
| + if (header->version > QEMU_SAVE_VERSION) { |
| /* convert endianess and try again */ |
| - bswap_header(&header); |
| + bswap_header(header); |
| } |
| |
| - if (header.version > QEMU_SAVE_VERSION) { |
| + if (header->version > QEMU_SAVE_VERSION) { |
| virReportError(VIR_ERR_OPERATION_FAILED, |
| _("image version is not supported (%d > %d)"), |
| - header.version, QEMU_SAVE_VERSION); |
| + header->version, QEMU_SAVE_VERSION); |
| goto error; |
| } |
| |
| - if (header.data_len <= 0) { |
| + if (header->data_len <= 0) { |
| virReportError(VIR_ERR_OPERATION_FAILED, |
| - _("invalid XML length: %d"), header.data_len); |
| + _("invalid XML length: %d"), header->data_len); |
| goto error; |
| } |
| |
| - if (VIR_ALLOC_N(xml, header.data_len) < 0) |
| + if (VIR_ALLOC_N(xml, header->data_len) < 0) |
| goto error; |
| |
| - if (saferead(fd, xml, header.data_len) != header.data_len) { |
| + if (saferead(fd, xml, header->data_len) != header->data_len) { |
| virReportError(VIR_ERR_OPERATION_FAILED, |
| "%s", _("failed to read XML")); |
| goto error; |
| @@ -6308,6 +6336,7 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, |
| error: |
| virDomainDefFree(def); |
| VIR_FREE(xml); |
| + virQEMUSaveDataFree(header); |
| VIR_FORCE_CLOSE(fd); |
| virObjectUnref(caps); |
| |
| @@ -6319,7 +6348,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, |
| virQEMUDriverPtr driver, |
| virDomainObjPtr vm, |
| int *fd, |
| - const virQEMUSaveHeader *header, |
| + virQEMUSaveHeaderPtr header, |
| const char *path, |
| bool start_paused, |
| qemuDomainAsyncJob asyncJob) |
| @@ -6445,7 +6474,7 @@ qemuDomainRestoreFlags(virConnectPtr conn, |
| const char *newxml = dxml; |
| int fd = -1; |
| int ret = -1; |
| - virQEMUSaveHeader header; |
| + virQEMUSaveHeaderPtr header = NULL; |
| virFileWrapperFdPtr wrapperFd = NULL; |
| bool hook_taint = false; |
| |
| @@ -6502,9 +6531,9 @@ qemuDomainRestoreFlags(virConnectPtr conn, |
| def = NULL; |
| |
| if (flags & VIR_DOMAIN_SAVE_RUNNING) |
| - header.was_running = 1; |
| + header->was_running = 1; |
| else if (flags & VIR_DOMAIN_SAVE_PAUSED) |
| - header.was_running = 0; |
| + header->was_running = 0; |
| |
| if (hook_taint) { |
| priv = vm->privateData; |
| @@ -6514,7 +6543,7 @@ qemuDomainRestoreFlags(virConnectPtr conn, |
| if (qemuProcessBeginJob(driver, vm, VIR_DOMAIN_JOB_OPERATION_RESTORE) < 0) |
| goto cleanup; |
| |
| - ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path, |
| + ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, header, path, |
| false, QEMU_ASYNC_JOB_START); |
| if (virFileWrapperFdClose(wrapperFd) < 0) |
| VIR_WARN("Failed to close %s", path); |
| @@ -6525,6 +6554,7 @@ qemuDomainRestoreFlags(virConnectPtr conn, |
| virDomainDefFree(def); |
| VIR_FORCE_CLOSE(fd); |
| VIR_FREE(xml); |
| + virQEMUSaveDataFree(header); |
| VIR_FREE(xmlout); |
| virFileWrapperFdFree(wrapperFd); |
| if (vm && ret < 0) |
| @@ -6549,7 +6579,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path, |
| char *ret = NULL; |
| virDomainDefPtr def = NULL; |
| int fd = -1; |
| - virQEMUSaveHeader header; |
| + virQEMUSaveHeaderPtr header = NULL; |
| |
| /* We only take subset of virDomainDefFormat flags. */ |
| virCheckFlags(VIR_DOMAIN_XML_SECURE, NULL); |
| @@ -6566,6 +6596,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path, |
| ret = qemuDomainDefFormatXML(driver, def, flags); |
| |
| cleanup: |
| + virQEMUSaveDataFree(header); |
| virDomainDefFree(def); |
| VIR_FORCE_CLOSE(fd); |
| return ret; |
| @@ -6580,9 +6611,9 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, |
| virDomainDefPtr def = NULL; |
| virDomainDefPtr newdef = NULL; |
| int fd = -1; |
| - virQEMUSaveHeader header; |
| char *xml = NULL; |
| size_t len; |
| + virQEMUSaveHeaderPtr header = NULL; |
| int state = -1; |
| |
| virCheckFlags(VIR_DOMAIN_SAVE_RUNNING | |
| @@ -6603,14 +6634,14 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, |
| goto cleanup; |
| |
| if (STREQ(xml, dxml) && |
| - (state < 0 || state == header.was_running)) { |
| + (state < 0 || state == header->was_running)) { |
| /* no change to the XML */ |
| ret = 0; |
| goto cleanup; |
| } |
| |
| if (state >= 0) |
| - header.was_running = state; |
| + header->was_running = state; |
| |
| if (!(newdef = qemuDomainSaveImageUpdateDef(driver, def, dxml))) |
| goto cleanup; |
| @@ -6625,12 +6656,12 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, |
| goto cleanup; |
| len = strlen(xml) + 1; |
| |
| - if (len > header.data_len) { |
| + if (len > header->data_len) { |
| virReportError(VIR_ERR_OPERATION_FAILED, "%s", |
| _("new xml too large to fit in file")); |
| goto cleanup; |
| } |
| - if (VIR_EXPAND_N(xml, len, header.data_len - len) < 0) |
| + if (VIR_EXPAND_N(xml, len, header->data_len - len) < 0) |
| goto cleanup; |
| |
| if (lseek(fd, 0, SEEK_SET) != 0) { |
| @@ -6651,6 +6682,7 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, |
| virDomainDefFree(newdef); |
| VIR_FORCE_CLOSE(fd); |
| VIR_FREE(xml); |
| + virQEMUSaveDataFree(header); |
| return ret; |
| } |
| |
| @@ -6671,7 +6703,7 @@ qemuDomainObjRestore(virConnectPtr conn, |
| int ret = -1; |
| char *xml = NULL; |
| char *xmlout = NULL; |
| - virQEMUSaveHeader header; |
| + virQEMUSaveHeaderPtr header = NULL; |
| virFileWrapperFdPtr wrapperFd = NULL; |
| |
| fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml, |
| @@ -6722,13 +6754,14 @@ qemuDomainObjRestore(virConnectPtr conn, |
| virDomainObjAssignDef(vm, def, true, NULL); |
| def = NULL; |
| |
| - ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path, |
| + ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, header, path, |
| start_paused, asyncJob); |
| if (virFileWrapperFdClose(wrapperFd) < 0) |
| VIR_WARN("Failed to close %s", path); |
| |
| cleanup: |
| VIR_FREE(xml); |
| + virQEMUSaveDataFree(header); |
| VIR_FREE(xmlout); |
| virDomainDefFree(def); |
| VIR_FORCE_CLOSE(fd); |
| @@ -14301,6 +14334,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn, |
| virQEMUDriverConfigPtr cfg = NULL; |
| int compressed; |
| char *compressedpath = NULL; |
| + virQEMUSaveHeaderPtr header = NULL; |
| |
| /* If quiesce was requested, then issue a freeze command, and a |
| * counterpart thaw command when it is actually sent to agent. |
| @@ -14372,9 +14406,12 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn, |
| if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true))) |
| goto cleanup; |
| |
| - if ((ret = qemuDomainSaveMemory(driver, vm, snap->def->file, xml, |
| - compressed, compressedpath, resume, |
| - 0, QEMU_ASYNC_JOB_SNAPSHOT)) < 0) |
| + if (!(header = virQEMUSaveDataNew(xml, resume, compressed))) |
| + goto cleanup; |
| + |
| + if ((ret = qemuDomainSaveMemory(driver, vm, snap->def->file, xml, header, |
| + compressedpath, 0, |
| + QEMU_ASYNC_JOB_SNAPSHOT)) < 0) |
| goto cleanup; |
| |
| /* the memory image was created, remove it on errors */ |
| @@ -14442,6 +14479,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn, |
| ret = -1; |
| } |
| |
| + virQEMUSaveDataFree(header); |
| VIR_FREE(xml); |
| VIR_FREE(compressedpath); |
| virObjectUnref(cfg); |
| -- |
| 2.13.1 |
| |