[libvirt] [PATCH 5/8] Determine whether to start balloon memory stats gathering.

Daniel P. Berrange berrange at redhat.com
Wed Jul 3 11:02:22 UTC 2013


On Tue, Jul 02, 2013 at 09:39:23AM -0400, John Ferlan wrote:
> At vm startup, reconnect, and attach - check for the presence of the balloon
> driver and save the path in the private area of the driver.  This path will
> remain constant throughout the life of the domain and can then be used rather
> than attempting to find the path each time balloon driver statistics are
> fetched or the collection period changes. The qom object model model requires
> setting object properties after device startup.  That is, it's not possible
> to pass the period along via the startup code as it won't be recognized.
> If a balloon driver path is found a check of the existing collection period
> will be made against the saved domain value in order to determine if an
> adjustment needs to be made to the period to start or stop collecting stats
> ---
>  src/qemu/qemu_domain.c  |   1 +
>  src/qemu/qemu_domain.h  |   2 +
>  src/qemu/qemu_process.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 165 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 8d79066..5aaf1e1 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -244,6 +244,7 @@ qemuDomainObjPrivateFree(void *data)
>      VIR_FREE(priv->vcpupids);
>      VIR_FREE(priv->lockState);
>      VIR_FREE(priv->origname);
> +    VIR_FREE(priv->balloonpath);
>  
>      virChrdevFree(priv->devs);
>  
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 068a4c3..005fd0f 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -161,6 +161,8 @@ struct _qemuDomainObjPrivate {
>      char *origname;
>      int nbdPort; /* Port used for migration with NBD */
>  
> +    char *balloonpath;
> +
>      virChrdevsPtr devs;

I think I'd prefer this to be kept as a private property
in the struct qemuMonitor.

> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index ac5ffcf..9a2add1 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -1564,6 +1564,150 @@ qemuProcessLookupPTYs(virDomainChrDefPtr *devices,
>      return 0;
>  }
>  
> +/* Search the qom objects for the balloon driver object by it's known name
> + * of "virtio-balloon-pci".  The entry for the driver will be found in the
> + * returned 'type' field using the syntax "child<virtio-balloon-pci>".
> + *
> + * Once found, check the entry to ensure it has the correct property listed.
> + * If it does not, then obtaining statistics from qemu will not be possible.
> + * This feature was added to qemu 1.5.
> + *
> + * This procedure will be call recursively until found or the qom-list is
> + * exhausted.
> + *
> + * Returns:
> + *
> + *   1  - Found
> + *   0  - Not found still looking
> + *  -1  - Error bail out
> + *
> + * NOTE: This assumes we have already called qemuDomainObjEnterMonitor()
> + */
> +static int
> +qemuProcessFindBalloonObjectPath(qemuMonitorPtr mon,
> +                                 virDomainObjPtr vm,
> +                                 const char *curpath,
> +                                 char **balloonpath)
> +{
> +    int i,j;
> +    int npaths = 0;
> +    int nprops = 0;
> +    int ret = 0;
> +    char *nextpath = NULL;
> +    qemuMonitorListPathPtr *paths = NULL;
> +    qemuMonitorListPathPtr *bprops = NULL;
> +
> +    /* Not supported */
> +    if (vm->def->memballoon &&
> +        vm->def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO) {
> +        VIR_DEBUG("Model must be virtio to get memballoon path");
> +        return -1;
> +    }
> +
> +    /* Already set and won't change */
> +    if (*balloonpath)
> +        return 1;
> +
> +    VIR_DEBUG("Searching for Balloon Object Path starting at %s", curpath);
> +
> +    npaths = qemuMonitorGetObjectListPaths(mon, curpath, &paths);
> +
> +    for (i = 0; i < npaths && ret == 0; i++) {
> +
> +        if (STREQ_NULLABLE(paths[i]->type, "link<virtio-balloon-pci>")) {
> +            VIR_DEBUG("Path to <virtio-balloon-pci> is '%s/%s'",
> +                      curpath, paths[i]->name);
> +            if (virAsprintf(&nextpath, "%s/%s", curpath, paths[i]->name) < 0) {
> +                ret = -1;
> +                goto cleanup;
> +            }
> +
> +            /* Now look at the each of the property entries to determine
> +             * whether "guest-stats-polling-interval" exists.  If not,
> +             * then this version of qemu/kvm does not support the feature.
> +             */
> +            nprops = qemuMonitorGetObjectListPaths(mon, nextpath, &bprops);
> +            for (j = 0; j < nprops; j++) {
> +                if (STREQ(bprops[j]->name, "guest-stats-polling-interval")) {
> +                    *balloonpath = nextpath;
> +                    nextpath = NULL;
> +                    ret = 1;
> +                    goto cleanup;
> +                }
> +            }
> +
> +            /* If we get here, we found the path, but not the property */
> +            VIR_DEBUG("Property 'guest-stats-polling-interval' not found");
> +            ret = -1;
> +            goto cleanup;
> +        }
> +
> +        /* Type entries that begin with "child<" are a branch that can be
> +         * traversed looking for more entries
> +         */
> +        if (paths[i]->type && STRPREFIX(paths[i]->type, "child<")) {
> +            if (virAsprintf(&nextpath, "%s/%s", curpath, paths[i]->name) < 0) {
> +                virReportOOMError();
> +                ret = -1;
> +                goto cleanup;
> +            }
> +            ret = qemuProcessFindBalloonObjectPath(mon, vm, nextpath,
> +                                                   balloonpath);
> +        }
> +    }
> +
> +cleanup:
> +    for (i = 0; i < npaths; i++)
> +        qemuMonitorListPathFree(paths[i]);
> +    VIR_FREE(paths);
> +    for (j = 0; j < nprops; j++)
> +        qemuMonitorListPathFree(bprops[j]);
> +    VIR_FREE(bprops);
> +    VIR_FREE(nextpath);
> +    return ret;
> +}

I think this method should be kept in qemu_monitor.c and made static
to that file


We can then populate it on first use.

> +/*
> + * Using the provided balloonpath, determine if we need to set the
> + * collection interval property to enable statistics gathering.
> + *
> + * NOTE: This assumes we have already called qemuDomainObjEnterMonitor()
> + */
> +static void
> +qemuProcessUpdateBalloonStatsPeriod(qemuMonitorPtr mon,
> +                                    char *balloonpath,
> +                                    virDomainObjPtr vm)
> +{
> +    qemuMonitorObjectProperty prop;
> +
> +    /* Get the current value of the stats polling interval */
> +    memset(&prop, 0, sizeof(qemuMonitorObjectProperty));
> +    prop.type = QEMU_MONITOR_OBJECT_PROPERTY_INT;
> +    if (qemuMonitorGetObjectProperty(mon, balloonpath,
> +                                     "guest-stats-polling-interval",
> +                                     &prop) < 0) {
> +        VIR_DEBUG("Failed to get polling interval for balloon driver");
> +        return;
> +    }
> +
> +    VIR_DEBUG("memballoon period=%d 'guest-stats-polling-interval'=%d",
> +              vm->def->memballoon->period,  prop.val.i);
> +
> +    /* Same value - no need to set */
> +    if (vm->def->memballoon->period == prop.val.i)
> +        return;
> +
> +    /* Set to the value in memballoon (could enable or disable) */
> +    memset(&prop, 0, sizeof(qemuMonitorObjectProperty));
> +    prop.type = QEMU_MONITOR_OBJECT_PROPERTY_INT;
> +    prop.val.i = vm->def->memballoon->period;
> +    if (qemuMonitorSetObjectProperty(mon, balloonpath,
> +                                     "guest-stats-polling-interval",
> +                                     &prop) < 0)
> +        VIR_DEBUG("Failed to set polling interval for balloon driver");
> +
> +}

Since I recommended that we don't expose qemuMonitorGetObjectProperty
or qemuMonitorSetObjectProperty in qemu_monitor.h, what you'll need
todo here is move this code into qemu_monitor.c defining a method
something like

   int qemuMonitorSetBalloonStatsPeriod(qemuMonitorPtr mon,
                                        int period);

This method can populate the balloonpath field in qemuMOnitorPtr struct
on first use.

Regards,
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