At 2016-12-08 20:08:11, "Peter Krempa" <pkrempa(a)redhat.com> wrote:
On Sat, Dec 03, 2016 at 17:45:47 +0800, Chen Hanxiao wrote:
> From: Chen Hanxiao <chenhanxiao(a)gmail.com>
>
> Base upon patches from Roy Keene <rkeene(a)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(a)knightpoint.com>
> Signed-off-by: Chen Hanxiao <chenhanxiao(a)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.
We need a flag to specify that
we need to write QEMU_SAVE_MAGIC directly.
Any suggestion for the name of this flag?
> } virDomainSaveRestoreFlags;
>
> int virDomainSave (virDomainPtr domain,
[snip]
> +
> + /*
> + * 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.
My concern is that
when we write to a pipe/fifo, if no one read it, we will hang.
We should prevent from doing this
only when we specify a flag.
Regards,
- Chen
> + 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);