[libvirt] [PATCH 3/4] Fix QEMU save/restore with block devices
Laine Stump
laine at laine.org
Sat Apr 24 04:50:41 UTC 2010
On 04/22/2010 07:43 AM, Daniel P. Berrange wrote:
> The save process was relying on use of the shell>> append
> operator to ensure the save data was placed after the libvirt
> header + XML. This doesn't work for block devices though.
> Replace this code with use of 'dd' and its 'seek' parameter.
> This means that we need to pad the header + XML out to a
> multiple of dd block size (in this case we choose 512).
>
> The qemuMonitorMigateToCommand() monitor API is used for both
> save/coredump, and migration via UNIX socket. We can't simply
> switch this to use 'dd' since this causes problems with the
> migration usage. Thus, create a dedicated qemuMonitorMigateToFile
> which can accept an filename + offset, and remove the filename
> from the current qemuMonitorMigateToCommand() API
>
> * src/qemu/qemu_driver.c: Switch to qemuMonitorMigateToFile
> for save and core dump
> * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
> src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h,
> src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Create
> a new qemuMonitorMigateToFile, separate from the existing
> qemuMonitorMigateToCommand to allow handling file offsets
> ---
> src/qemu/qemu_driver.c | 190 +++++++++++++++++++++++++-----------------
> src/qemu/qemu_monitor.c | 35 +++++++--
> src/qemu/qemu_monitor.h | 11 ++-
> src/qemu/qemu_monitor_json.c | 37 ++++++++-
> src/qemu/qemu_monitor_json.h | 9 ++-
> src/qemu/qemu_monitor_text.c | 37 ++++++++-
> src/qemu/qemu_monitor_text.h | 9 ++-
> 7 files changed, 232 insertions(+), 96 deletions(-)
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 41a516c..09b6493 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -4789,6 +4789,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
> qemuDomainObjPrivatePtr priv;
> struct stat sb;
> int is_reg = 0;
> + unsigned long long offset;
>
> memset(&header, 0, sizeof(header));
> memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
> @@ -4862,104 +4863,137 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
> hdata.path = path;
> hdata.xml = xml;
> hdata.header =&header;
> + offset = sizeof(header) + header.xml_len;
> +
> + /* Due to way we append QEMU state on our header with dd,
> + * we need to ensure there's a 512 byte boundary. Unfortunately
> + * we don't have an explicit offset in the header, so we fake
> + * it by padding the XML string with NULLs */
> + if (offset % QEMU_MONITOR_MIGRATE_TO_FILE_BS) {
> + unsigned long long pad =
> + QEMU_MONITOR_MIGRATE_TO_FILE_BS -
> + (offset % QEMU_MONITOR_MIGRATE_TO_FILE_BS);
> +
> + if (VIR_REALLOC_N(xml, header.xml_len + pad)< 0) {
> + virReportOOMError();
> + goto endjob;
> + }
> + memset(xml + header.xml_len, 0, pad);
> + offset += pad;
> + header.xml_len += pad;
> + }
>
Is it really necessary to add this padding even when we *aren't* using
dd? (ie, when is_reg == 1).
More information about the libvir-list
mailing list