[libvirt] [PATCH 1/2] qemu: Allow saving QEMU libvirt state to a pipe

Peter Krempa pkrempa at redhat.com
Thu Dec 8 12:08:11 UTC 2016


On Sat, Dec 03, 2016 at 17:45:47 +0800, Chen Hanxiao wrote:
> From: Chen Hanxiao <chenhanxiao at gmail.com>
> 
> Base upon patches from Roy Keene <rkeene at knightpoint.com>
> 
> Currently qemuDomainSaveMemory can save vm's config
> and memory to fd.
> It writes a magic QEMU_SAVE_PARTIAL firstly,
> then re-open it to change QEMU_SAVE_PARTIAL as QEMU_SAVE_MAGIC
> after a success write.
> 
> For pipes this is not possible, attempting to re-open the pipe
> will not connect you to the same consumer.
> Seeking is also not possible on a pipe.
> 
> This patch introduce VIR_DOMAIN_SAVE_PIPE.
> If set, write QEMU_SAVE_MAGIC directly.
> Try to write a regular file with VIR_DOMAIN_SAVE_PIPE
> is not supportted.
> 
> This is useful to me for saving a VM state directly to
> Ceph RBD images without having an intermediate file.
> 
> Cc: Roy Keene <rkeene at knightpoint.com>
> Signed-off-by: Chen Hanxiao <chenhanxiao at gmail.com>
> ---
>  include/libvirt/libvirt-domain.h |  1 +
>  src/qemu/qemu_driver.c           | 71 ++++++++++++++++++++++++++++++----------
>  2 files changed, 54 insertions(+), 18 deletions(-)
> 
> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
> index a8435ab..c3e4c15 100644
> --- a/include/libvirt/libvirt-domain.h
> +++ b/include/libvirt/libvirt-domain.h
> @@ -1169,6 +1169,7 @@ typedef enum {
>      VIR_DOMAIN_SAVE_BYPASS_CACHE = 1 << 0, /* Avoid file system cache pollution */
>      VIR_DOMAIN_SAVE_RUNNING      = 1 << 1, /* Favor running over paused */
>      VIR_DOMAIN_SAVE_PAUSED       = 1 << 2, /* Favor paused over running */
> +    VIR_DOMAIN_SAVE_PIPE         = 1 << 3, /* Output is a pipe */

It doesn't have necessarily to be a pipe.

>  } virDomainSaveRestoreFlags;
>  
>  int                     virDomainSave           (virDomainPtr domain,
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 3517aa2..58422ac 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -3054,14 +3054,15 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver,
>      virQEMUSaveHeader header;
>      bool bypassSecurityDriver = false;
>      bool needUnlink = false;
> +    bool canReopen = true;
>      int ret = -1;
>      int fd = -1;
>      int directFlag = 0;
>      virFileWrapperFdPtr wrapperFd = NULL;
>      unsigned int wrapperFlags = VIR_FILE_WRAPPER_NON_BLOCKING;
> +    struct stat statbuf;
>  
>      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;
> @@ -3077,6 +3078,27 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver,
>              goto cleanup;
>          }
>      }
> +
> +    /*
> +     * Determine if this file is a PIPE, which could not be reopen.
> +     */
> +    if (virFileExists(path)) {
> +        fd = qemuOpenFile(driver, vm, path, O_RDONLY | O_NONBLOCK, NULL, NULL);
> +        if (fd < 0)
> +            goto cleanup;
> +        if (fstat(fd, &statbuf) < 0)
> +            goto cleanup;
> +        if (S_ISFIFO(statbuf.st_mode)) {

You should not try to check this. If the user wishes to write the
complete header right away, then we should obey it and not have to check
prior to do so.

> +            if (flags & VIR_DOMAIN_SAVE_PIPE) {
> +                canReopen = false;
> +            } else {
> +                virReportSystemError(EINVAL, _("%s is not PIPE"), path);
> +                goto cleanup;
> +            }
> +        }
> +        VIR_FORCE_CLOSE(fd);
> +    }
> +
>      fd = qemuOpenFile(driver, vm, path,
>                        O_WRONLY | O_TRUNC | O_CREAT | directFlag,
>                        &needUnlink, &bypassSecurityDriver);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20161208/dc2ec368/attachment-0001.sig>


More information about the libvir-list mailing list