[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