I've been working with Anthony Liguori and Stefan Hajnoczi to enable data streaming to copy-on-read disk images in qemu. This work is working its way through peer review and I expect it to be upstream soon as part of the support for the new QED disk image format. I would like to enable these commands in libvirt in order to support at least two compelling use cases: 1) Rapid deployment of domains: Creating a new domain from a central repository of images can be time consuming since a local copy of the image must be made before the domain can be started. With copy-on-read and streaming, up-front copy time is eliminated and the domain can be started immediately. Streaming can run while the domain runs to fully populate the disk image. 2) Post-copy live block migration: A qemu-nbd server is started on the source host and serves the domain's block device to the destination host. A QED image is created on the destination host with backing to the nbd server. The domain is migrated as normal. When migration completes, a stream command is executed to fully populate the destination QED image. After streaming completes, the qemu-nbd server can be shut down and the domain (including local storage) is fully independent of the source host. Qemu will support two streaming modes: full device and single sector. Full device streaming is the easiest to use because one command will cause the whole device to be streamed as fast as possible. Single sector mode can be used if one wants to throttle streaming to reduce I/O pressure. In this mode, the user issues individual commands to stream single sectors. To enable this support in libvirt, I propose the following API... virDomainStreamDisk() initiates either a full device stream or a single sector stream (depending on virDomainStreamDiskFlags). For a full device stream, it returns either 0 or -1. For a single sector stream, it returns an offset that can be used to continue streaming with a subsequent call to virDomainStreamDisk(). virDomainStreamDiskInfo() returns the status of a currently-running full device stream (the device name, current streaming position, and total size). Comments on this design would be greatly appreciated. Thanks! diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 81db3a2..d80a8b5 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1046,6 +1046,39 @@ int virDomainUpdateDeviceFlags(virDomainPtr domain, const char *xml, unsigned int flags); /* + * Disk Streaming + */ +typedef enum { + VIR_STREAM_DISK_FULL = 1, /* Stream the entire disk */ + VIR_STREAM_DISK_ONE = 2, /* Stream a single disk unit */ +} virDomainStreamDiskFlags; + +#define VIR_STREAM_PATH_BUFLEN 100 +#define VIR_STREAM_DISK_MAX_STREAMS 10 + +typedef struct _virStreamDiskState virStreamDiskState; +struct _virStreamDiskState { + char path[VIR_STREAM_PATH_BUFLEN]; + /* + * The unit of measure for size and offset is unspecified. These fields + * are meant to indicate the progress of a continuous streaming operation. + */ + unsigned long long offset; /* Current offset of active streaming */ + unsigned long long size; /* Disk size */ +}; +typedef virStreamDiskState *virStreamDiskStatePtr; + +unsigned long long virDomainStreamDisk(virDomainPtr dom, + const char *path, + unsigned long long offset, + unsigned int flags); + +int virDomainStreamDiskInfo(virDomainPtr dom, + virStreamDiskStatePtr infos, + unsigned int nr_infos, + unsigned int flags); + +/* * NUMA support */ -- Thanks, Adam -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list