[libvirt] [PATCH 2/8] Add public API for getting migration speed

Daniel P. Berrange berrange at redhat.com
Thu Sep 1 12:36:31 UTC 2011


On Fri, Aug 26, 2011 at 12:10:21PM -0600, Jim Fehlig wrote:
> Includes impl of python binding since the generator was not
> able to cope.
> 
> Note: Requires gendispatch.pl patch from Matthias Bolte
> 
> https://www.redhat.com/archives/libvir-list/2011-August/msg01367.html
> ---
>  docs/apibuild.py                |    3 +-
>  include/libvirt/libvirt.h.in    |    4 +++
>  python/generator.py             |    1 +
>  python/libvirt-override-api.xml |    6 ++++
>  python/libvirt-override.c       |   24 ++++++++++++++++++
>  src/driver.h                    |    6 ++++
>  src/libvirt.c                   |   51 +++++++++++++++++++++++++++++++++++++++
>  src/libvirt_public.syms         |    5 ++++
>  src/remote/remote_driver.c      |    1 +
>  src/remote/remote_protocol.x    |   13 +++++++++-
>  src/remote_protocol-structs     |    9 +++++++
>  src/rpc/gendispatch.pl          |    1 +
>  12 files changed, 122 insertions(+), 2 deletions(-)
> 
> diff --git a/docs/apibuild.py b/docs/apibuild.py
> index 53b3421..3563d94 100755
> --- a/docs/apibuild.py
> +++ b/docs/apibuild.py
> @@ -1643,7 +1643,8 @@ class CParser:
>          "virDomainSetMemory"             : (False, ("memory")),
>          "virDomainSetMemoryFlags"        : (False, ("memory")),
>          "virDomainBlockJobSetSpeed"      : (False, ("bandwidth")),
> -        "virDomainBlockPull"             : (False, ("bandwidth")) }
> +        "virDomainBlockPull"             : (False, ("bandwidth")),
> +        "virDomainMigrateGetMaxSpeed"    : (False, ("bandwidth")) }
>  
>      def checkLongLegacyFunction(self, name, return_type, signature):
>          if "long" in return_type and "long long" not in return_type:
> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> index 53a2f7d..bd6c607 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -711,6 +711,10 @@ int virDomainMigrateSetMaxSpeed(virDomainPtr domain,
>                                  unsigned long bandwidth,
>                                  unsigned int flags);
>  
> +int virDomainMigrateGetMaxSpeed(virDomainPtr domain,
> +                                unsigned long *bandwidth,
> +                                unsigned int flags);
> +
>  /**
>   * VIR_NODEINFO_MAXCPUS:
>   * @nodeinfo: virNodeInfo instance
> diff --git a/python/generator.py b/python/generator.py
> index 97434ed..cc253cf 100755
> --- a/python/generator.py
> +++ b/python/generator.py
> @@ -372,6 +372,7 @@ skip_impl = (
>      'virNodeGetCPUStats',
>      'virNodeGetMemoryStats',
>      'virDomainGetBlockJobInfo',
> +    'virDomainMigrateGetMaxSpeed',
>  )
>  
>  
> diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
> index 2fa5eed..1cf115c 100644
> --- a/python/libvirt-override-api.xml
> +++ b/python/libvirt-override-api.xml
> @@ -356,5 +356,11 @@
>        <arg name='flags' type='unsigned int' info='fine-tuning flags, currently unused, pass 0.'/>
>        <return type='virDomainBlockJobInfo' info='A dictionary containing job information.' />
>      </function>
> +    <function name='virDomainMigrateGetMaxSpeed' file='python'>
> +      <info>Get currently configured maximum migration speed for a domain</info>
> +      <arg name='domain' type='virDomainPtr' info='a domain object'/>
> +      <arg name='flags' type='unsigned int' info='flags, currently unused, pass 0.'/>
> +      <return type='unsigned long' info='current max migration speed, or None in case of error'/>
> +    </function>
>    </symbols>
>  </api>
> diff --git a/python/libvirt-override.c b/python/libvirt-override.c
> index b5650e2..b020342 100644
> --- a/python/libvirt-override.c
> +++ b/python/libvirt-override.c
> @@ -4543,6 +4543,29 @@ libvirt_virDomainSendKey(PyObject *self ATTRIBUTE_UNUSED,
>      return py_retval;
>  }
>  
> +static PyObject *
> +libvirt_virDomainMigrateGetMaxSpeed(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
> +    PyObject *py_retval;
> +    int c_retval;
> +    unsigned long bandwidth;
> +    virDomainPtr domain;
> +    PyObject *pyobj_domain;
> +
> +    if (!PyArg_ParseTuple(args, (char *)"O:virDomainMigrateGetMaxSpeed", &pyobj_domain))
> +        return(NULL);
> +
> +    domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
> +
> +    LIBVIRT_BEGIN_ALLOW_THREADS;
> +    c_retval = virDomainMigrateGetMaxSpeed(domain, &bandwidth, 0);
> +    LIBVIRT_END_ALLOW_THREADS;
> +
> +    if (c_retval < 0)
> +        return VIR_PY_INT_FAIL;
> +    py_retval = libvirt_ulongWrap(bandwidth);
> +    return(py_retval);
> +}
> +
>  /************************************************************************
>   *									*
>   *			The registration stuff				*
> @@ -4632,6 +4655,7 @@ static PyMethodDef libvirtMethods[] = {
>      {(char *) "virDomainRevertToSnapshot", libvirt_virDomainRevertToSnapshot, METH_VARARGS, NULL},
>      {(char *) "virDomainGetBlockJobInfo", libvirt_virDomainGetBlockJobInfo, METH_VARARGS, NULL},
>      {(char *) "virDomainSendKey", libvirt_virDomainSendKey, METH_VARARGS, NULL},
> +    {(char *) "virDomainMigrateGetMaxSpeed", libvirt_virDomainMigrateGetMaxSpeed, METH_VARARGS, NULL},
>      {NULL, NULL, 0, NULL}
>  };
>  
> diff --git a/src/driver.h b/src/driver.h
> index 80d6628..21b2bd3 100644
> --- a/src/driver.h
> +++ b/src/driver.h
> @@ -532,6 +532,11 @@ typedef int
>                                        unsigned int flags);
>  
>  typedef int
> +    (*virDrvDomainMigrateGetMaxSpeed)(virDomainPtr domain,
> +                                      unsigned long *bandwidth,
> +                                      unsigned int flags);
> +
> +typedef int
>      (*virDrvDomainEventRegisterAny)(virConnectPtr conn,
>                                      virDomainPtr dom,
>                                      int eventID,
> @@ -828,6 +833,7 @@ struct _virDriver {
>      virDrvDomainGetJobInfo     domainGetJobInfo;
>      virDrvDomainAbortJob     domainAbortJob;
>      virDrvDomainMigrateSetMaxDowntime  domainMigrateSetMaxDowntime;
> +    virDrvDomainMigrateGetMaxSpeed  domainMigrateGetMaxSpeed;
>      virDrvDomainMigrateSetMaxSpeed  domainMigrateSetMaxSpeed;
>      virDrvDomainEventRegisterAny domainEventRegisterAny;
>      virDrvDomainEventDeregisterAny domainEventDeregisterAny;
> diff --git a/src/libvirt.c b/src/libvirt.c
> index b8fe1b1..683b8e1 100644
> --- a/src/libvirt.c
> +++ b/src/libvirt.c
> @@ -15195,6 +15195,57 @@ error:
>  }
>  
>  /**
> + * virDomainMigrateGetMaxSpeed:
> + * @domain: a domain object
> + * @bandwidth: return value of current migration bandwidth limit in Mbps
> + * @flags: fine-tuning flags, currently unused, use 0
> + *
> + * Get the current maximum bandwidth (in Mbps) that will be used if the
> + * domain is migrated.  Not all hypervisors will support a bandwidth limit.
> + *
> + * Returns 0 in case of success, -1 otherwise.
> + */
> +int
> +virDomainMigrateGetMaxSpeed(virDomainPtr domain,
> +                            unsigned long *bandwidth,
> +                            unsigned int flags)
> +{
> +    virConnectPtr conn;
> +
> +    VIR_DOMAIN_DEBUG(domain, "bandwidth = %p, flags=%x", bandwidth, flags);
> +
> +    virResetLastError();
> +
> +    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
> +        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
> +        virDispatchError(NULL);
> +        return -1;
> +    }
> +
> +    if (!bandwidth) {
> +        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
> +        goto error;
> +    }
> +
> +    conn = domain->conn;
> +    if (conn->flags & VIR_CONNECT_RO) {
> +        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
> +        goto error;
> +    }
> +
> +    if (conn->driver->domainMigrateGetMaxSpeed) {
> +        if (conn->driver->domainMigrateGetMaxSpeed(domain, bandwidth, flags) < 0)
> +            goto error;
> +        return 0;
> +    }
> +
> +    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
> +error:
> +    virDispatchError(conn);
> +    return -1;
> +}
> +
> +/**
>   * virConnectDomainEventRegisterAny:
>   * @conn: pointer to the connection
>   * @dom: pointer to the domain
> diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
> index c2b6666..169c3ee 100644
> --- a/src/libvirt_public.syms
> +++ b/src/libvirt_public.syms
> @@ -480,4 +480,9 @@ LIBVIRT_0.9.4 {
>          virDomainBlockPull;
>  } LIBVIRT_0.9.3;
>  
> +LIBVIRT_0.9.5 {
> +    global:
> +        virDomainMigrateGetMaxSpeed;
> +} LIBVIRT_0.9.4;
> +
>  # .... define new API here using predicted next version number ....
> diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
> index 603d589..81930a9 100644
> --- a/src/remote/remote_driver.c
> +++ b/src/remote/remote_driver.c
> @@ -4335,6 +4335,7 @@ static virDriver remote_driver = {
>      .domainAbortJob = remoteDomainAbortJob, /* 0.7.7 */
>      .domainMigrateSetMaxDowntime = remoteDomainMigrateSetMaxDowntime, /* 0.8.0 */
>      .domainMigrateSetMaxSpeed = remoteDomainMigrateSetMaxSpeed, /* 0.9.0 */
> +    .domainMigrateGetMaxSpeed = remoteDomainMigrateGetMaxSpeed, /* 0.9.5 */
>      .domainEventRegisterAny = remoteDomainEventRegisterAny, /* 0.8.0 */
>      .domainEventDeregisterAny = remoteDomainEventDeregisterAny, /* 0.8.0 */
>      .domainManagedSave = remoteDomainManagedSave, /* 0.8.0 */
> diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
> index 8f68808..676570e 100644
> --- a/src/remote/remote_protocol.x
> +++ b/src/remote/remote_protocol.x
> @@ -1913,6 +1913,16 @@ struct remote_domain_migrate_set_max_speed_args {
>      unsigned int flags;
>  };
>  
> +struct remote_domain_migrate_get_max_speed_args {
> +    remote_nonnull_domain dom;
> +    unsigned int flags;
> +};
> +
> +struct remote_domain_migrate_get_max_speed_ret {
> +     unsigned hyper bandwidth; /* insert at 1 */
> +};
> +
> +
>  struct remote_domain_events_register_any_args {
>      int eventID;
>  };
> @@ -2475,7 +2485,8 @@ enum remote_procedure {
>      REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED = 239, /* autogen autogen */
>      REMOTE_PROC_DOMAIN_BLOCK_PULL = 240, /* autogen autogen */
>  
> -    REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241 /* skipgen skipgen */
> +    REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241, /* skipgen skipgen */
> +    REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_SPEED = 242 /* autogen autogen */
>  
>      /*
>       * Notice how the entries are grouped in sets of 10 ?
> diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
> index 91b3ca5..0498bd1 100644
> --- a/src/remote_protocol-structs
> +++ b/src/remote_protocol-structs
> @@ -1429,6 +1429,14 @@ struct remote_domain_migrate_set_max_speed_args {
>          uint64_t                   bandwidth;
>          u_int                      flags;
>  };
> +struct remote_domain_migrate_get_max_speed_args {
> +        remote_nonnull_domain      dom;
> +        u_int                      flags;
> +};
> +struct remote_domain_migrate_get_max_speed_ret {
> +        uint64_t                   bandwidth;
> +};
> +
>  struct remote_domain_events_register_any_args {
>          int                        eventID;
>  };
> @@ -1936,4 +1944,5 @@ enum remote_procedure {
>          REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED = 239,
>          REMOTE_PROC_DOMAIN_BLOCK_PULL = 240,
>          REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241,
> +        REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_SPEED = 242,
>  };
> diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
> index 0d344e8..c203324 100755
> --- a/src/rpc/gendispatch.pl
> +++ b/src/rpc/gendispatch.pl
> @@ -222,6 +222,7 @@ my $long_legacy = {
>      NodeGetInfo                 => { ret => { memory => 1 } },
>      DomainBlockPull             => { arg => { bandwidth => 1 } },
>      DomainBlockJobSetSpeed      => { arg => { bandwidth => 1 } },
> +    DomainMigrateGetMaxSpeed    => { ret => { bandwidth => 1 } },
>  };
>  
>  sub hyper_to_long

ACK


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