[libvirt] [PATCH 4/8] Implement virDomainBlockPull for the qemu driver

Daniel P. Berrange berrange at redhat.com
Tue Jun 14 09:54:40 UTC 2011


On Thu, Jun 09, 2011 at 12:10:10PM -0500, Adam Litke wrote:
> The virDomainBlockPull* family of commands are enabled by the
> 'block_stream' and 'info block_stream' qemu monitor commands.
> 
> * src/qemu/qemu_driver.c src/qemu/qemu_monitor_text.[ch]: implement disk
>   streaming by using the stream and info stream text monitor commands
> * src/qemu/qemu_monitor_json.[ch]: implement commands using the qmp monitor
> 
> Signed-off-by: Adam Litke <agl at us.ibm.com>
> ---
>  src/qemu/qemu_driver.c       |  108 +++++++++++++++++++++++++++++
>  src/qemu/qemu_monitor.c      |   16 ++++
>  src/qemu/qemu_monitor.h      |   13 ++++
>  src/qemu/qemu_monitor_json.c |  131 +++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_monitor_json.h |    4 +
>  src/qemu/qemu_monitor_text.c |  156 ++++++++++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_monitor_text.h |    5 ++
>  7 files changed, 433 insertions(+), 0 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 80de79a..1cbb151 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -7971,6 +7971,110 @@ cleanup:
>      return ret;
>  }
>  
> +static const char *
> +qemuDiskPathToAlias(virDomainObjPtr vm, const char *path) {
> +    int i;
> +    char *ret = NULL;
> +
> +    for (i = 0 ; i < vm->def->ndisks ; i++) {
> +        virDomainDiskDefPtr disk = vm->def->disks[i];
> +
> +        if (disk->src != NULL && STREQ(disk->src, path)) {

You also rather want to check that disk->type is one of

    VIR_DOMAIN_DISK_TYPE_BLOCK
    VIR_DOMAIN_DISK_TYPE_FILE

before looking at disk->src

> +            if (virAsprintf(&ret, "drive-%s", disk->info.alias) < 0) {
> +                virReportOOMError();
> +                return NULL;
> +            }
> +            break;
> +        }
> +    }
> +
> +    if (!ret) {
> +        qemuReportError(VIR_ERR_INVALID_ARG,
> +                        "%s", _("No device found for specified path"));
> +    }
> +    return ret;
> +}
> +
> +static int
> +qemuDomainBlockPullImpl(virDomainPtr dom, const char *path,
> +                        virDomainBlockPullInfoPtr info,
> +                        int mode)
> +{
> +    struct qemud_driver *driver = dom->conn->privateData;
> +    virDomainObjPtr vm = NULL;
> +    qemuDomainObjPrivatePtr priv;
> +    char uuidstr[VIR_UUID_STRING_BUFLEN];
> +    const char *device = NULL;
> +    int ret = -1;
> +
> +    qemuDriverLock(driver);
> +    virUUIDFormat(dom->uuid, uuidstr);
> +    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
> +    if (!vm) {
> +        qemuReportError(VIR_ERR_NO_DOMAIN,
> +                        _("no domain with matching uuid '%s'"), uuidstr);
> +        goto cleanup;
> +    }
> +
> +    if (!virDomainObjIsActive(vm)) {
> +        qemuReportError(VIR_ERR_OPERATION_INVALID,
> +                        "%s", _("domain is not running"));
> +        goto cleanup;
> +    }
> +
> +    device = qemuDiskPathToAlias(vm, path);
> +    if (!device) {
> +        goto cleanup;
> +    }
> +
> +    if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
> +        goto cleanup;
> +    qemuDomainObjEnterMonitorWithDriver(driver, vm);
> +    priv = vm->privateData;
> +    ret = qemuMonitorBlockPull(priv->mon, device, info, mode);
> +    qemuDomainObjExitMonitorWithDriver(driver, vm);
> +    if (qemuDomainObjEndJob(vm) == 0) {
> +        vm = NULL;
> +        goto cleanup;
> +    }
> +
> +cleanup:
> +    VIR_FREE(device);
> +    if (vm)
> +        virDomainObjUnlock(vm);
> +    qemuDriverUnlock(driver);
> +    return ret;
> +}
> +
> +static int
> +qemuDomainBlockPull(virDomainPtr dom, const char *path,
> +                    virDomainBlockPullInfoPtr info, unsigned int flags)
> +{
> +    virCheckFlags(0, -1);
> +    return qemuDomainBlockPullImpl(dom, path, info, BLOCK_PULL_MODE_ONE);
> +}
> +
> +static int
> +qemuDomainBlockPullAll(virDomainPtr dom, const char *path, unsigned int flags)
> +{
> +    virCheckFlags(0, -1);
> +    return qemuDomainBlockPullImpl(dom, path, NULL, BLOCK_PULL_MODE_ALL);
> +}
> +
> +static int
> +qemuDomainBlockPullAbort(virDomainPtr dom, const char *path, unsigned int flags)
> +{
> +    virCheckFlags(0, -1);
> +    return qemuDomainBlockPullImpl(dom, path, NULL, BLOCK_PULL_MODE_ABORT);
> +}
> +
> +static int
> +qemuDomainGetBlockPullInfo(virDomainPtr dom, const char *path,
> +                           virDomainBlockPullInfoPtr info, unsigned int flags)
> +{
> +    virCheckFlags(0, -1);
> +    return qemuDomainBlockPullImpl(dom, path, info, BLOCK_PULL_MODE_INFO);
> +}
>  
>  static virDriver qemuDriver = {
>      .no = VIR_DRV_QEMU,
> @@ -8090,6 +8194,10 @@ static virDriver qemuDriver = {
>      .domainMigratePerform3 = qemuDomainMigratePerform3, /* 0.9.2 */
>      .domainMigrateFinish3 = qemuDomainMigrateFinish3, /* 0.9.2 */
>      .domainMigrateConfirm3 = qemuDomainMigrateConfirm3, /* 0.9.2 */
> +    .domainBlockPull = qemuDomainBlockPull, /* 0.9.2 */
> +    .domainBlockPullAll = qemuDomainBlockPullAll, /* 0.9.2 */
> +    .domainBlockPullAbort = qemuDomainBlockPullAbort, /* 0.9.2 */
> +    .domainGetBlockPullInfo = qemuDomainGetBlockPullInfo, /* 0.9.2 */
>  };

These want to be 0.9.3

ACK to the rest of the patch

Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list