[libvirt] [PATCH 06/10] vcpubandwidth: introduce two new libvirt APIs

Wen Congyang wency at cn.fujitsu.com
Thu Jun 30 03:13:18 UTC 2011


We want to control bandwidth for each vcpu, so we can not use the
API virDomainSetSchedulerParameters(). Introduce two new APIs to
change and query bandwidth for each vcpu.

---
 include/libvirt/libvirt.h.in |   38 ++++++++++++++
 python/generator.py          |    2 +
 src/conf/domain_conf.h       |    8 ---
 src/driver.h                 |   14 +++++
 src/libvirt.c                |  117 ++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms      |    6 ++
 6 files changed, 177 insertions(+), 8 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 14d6a88..03c04b3 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -547,6 +547,44 @@ int     virDomainSetSchedulerParametersFlags (virDomainPtr domain,
                                               unsigned int flags);
 
 /**
+ * virDomainVcpuBWDef:
+ *
+ * Vcpu's bandwidth.
+ */
+typedef struct _virDomainVcpuBWDef virDomainVcpuBWDef;
+struct _virDomainVcpuBWDef {
+    int vcpuid; /* vcpu id */
+    unsigned long long period; /* bandwidth period in usecs */
+    long long quota; /* cpu bandwidth (in usecs) that this vcpu will be allowed
+                      * to consume over period
+                      */
+};
+
+/**
+ * virDomainVcpuBWDefPtr:
+ *
+ * a pointer to a virDomainVcpuBWDef structure.
+ */
+typedef virDomainVcpuBWDef *virDomainVcpuBWDefPtr;
+
+/* Management of vcpu bandwidth */
+
+/*
+ * Fetch vcpu bandwidth, caller allocates 'vcpubw' field of size 'nvcpu'
+ */
+int     virDomainGetVcpuBW (virDomainPtr domain,
+                            virDomainVcpuBWDefPtr vcpubw,
+                            int *nvcpu,
+                            unsigned int flags);
+/*
+ * Change vcpu bandwidth.
+ */
+int     virDomainSetVcpuBW (virDomainPtr domain,
+                            virDomainVcpuBWDefPtr vcpubw,
+                            int nvcpu,
+                            unsigned int flags);
+
+/**
  * virDomainBlockStats:
  *
  * Block device stats for virDomainBlockStats.
diff --git a/python/generator.py b/python/generator.py
index c27ff73..3b08626 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -418,6 +418,8 @@ skip_function = (
     "virNWFilterGetConnect",
     "virStoragePoolGetConnect",
     "virStorageVolGetConnect",
+    "virDomainGetVcpuBW",
+    "virDomainSetVcpuBW",
 )
 
 # Generate C code, but skip python impl
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a2929b5..26f2c76 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1108,14 +1108,6 @@ struct _virDomainVcpuPinDef {
     char *cpumask;
 };
 
-typedef struct _virDomainVcpuBWDef virDomainVcpuBWDef;
-typedef virDomainVcpuBWDef *virDomainVcpuBWDefPtr;
-struct _virDomainVcpuBWDef {
-    int vcpuid;
-    unsigned long long period;
-    long long quota;
-};
-
 int virDomainVcpuPinIsDuplicate(virDomainVcpuPinDefPtr *def,
                                 int nvcpupin,
                                 int vcpu);
diff --git a/src/driver.h b/src/driver.h
index 871a4ae..aa3bde2 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -317,6 +317,18 @@ typedef int
                                          unsigned int flags);
 
 typedef int
+        (*virDrvDomainGetVcpuBW)	(virDomainPtr domain,
+                                         virDomainVcpuBWDefPtr vcpubw,
+                                         int *nvcpu,
+                                         unsigned int flags);
+
+typedef int
+        (*virDrvDomainSetVcpuBW)	(virDomainPtr domain,
+                                         virDomainVcpuBWDefPtr vcpubw,
+                                         int nvcpu,
+                                         unsigned int flags);
+
+typedef int
     (*virDrvDomainBlockStats)
                     (virDomainPtr domain,
                      const char *path,
@@ -739,6 +751,8 @@ struct _virDriver {
     virDrvDomainGetSchedulerParametersFlags domainGetSchedulerParametersFlags;
     virDrvDomainSetSchedulerParameters domainSetSchedulerParameters;
     virDrvDomainSetSchedulerParametersFlags domainSetSchedulerParametersFlags;
+    virDrvDomainGetVcpuBW	domainGetVcpuBW;
+    virDrvDomainSetVcpuBW	domainSetVcpuBW;
     virDrvDomainMigratePrepare	domainMigratePrepare;
     virDrvDomainMigratePerform	domainMigratePerform;
     virDrvDomainMigrateFinish	domainMigrateFinish;
diff --git a/src/libvirt.c b/src/libvirt.c
index 9857e3b..baaa4ad 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5852,6 +5852,123 @@ error:
     return -1;
 }
 
+/**
+ * virDomainGetVcpuBW:
+ * @domain: pointer to domain object
+ * @vcpubw: pointer to vcpu bandwidth objects
+ * @nvcpu:  pointer to the number of vcpu bandwidth objects
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Get the vcpu bandwidth, the @vcpubw array will be filled with the
+ * values.
+ *
+ * The value of @flags can be exactly VIR_DOMAIN_AFFECT_CURRENT,
+ * VIR_DOMAIN_AFFECT_LIVE, or VIR_DOMAIN_AFFECT_CONFIG.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetVcpuBW(virDomainPtr domain, virDomainVcpuBWDefPtr vcpubw,
+                   int *nvcpu, unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(domain, "vcpubw=%p, nvcpu=%d, flags=%u",
+                     vcpubw, *nvcpu, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+
+    if (vcpubw == NULL || *nvcpu < 0) {
+        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    if (domain->conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+    conn = domain->conn;
+
+    if (conn->driver->domainGetVcpuBW) {
+        int ret;
+        ret = conn->driver->domainGetVcpuBW(domain, vcpubw, nvcpu, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(domain->conn);
+    return -1;
+}
+
+
+/**
+ * virDomainSetVcpuBW:
+ * @domain: pointer to domain object
+ * @params: pointer to vcpu bandwidth objects
+ * @nparams: number of vcpu bandwidth objects
+ *          (this value can be the same or less than domain's vcpu num)
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Change a subset or all vcpu bandwidth.  The value of @flags
+ * should be either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of
+ * values from VIR_DOMAIN_AFFECT_LIVE and VIR_DOMAIN_AFFECT_CONFIG,
+ * although hypervisors vary in which flags are supported.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetVcpuBW(virDomainPtr domain, virDomainVcpuBWDefPtr vcpubw,
+                   int nvcpu, unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(domain, "vcpubw=%p, nvcpu=%d, flags=%u",
+                     vcpubw, nvcpu, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+
+    if (vcpubw == NULL || nvcpu < 0) {
+        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    if (domain->conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+    conn = domain->conn;
+
+    if (conn->driver->domainSetVcpuBW) {
+        int ret;
+        ret = conn->driver->domainSetVcpuBW(domain, vcpubw, nvcpu, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(domain->conn);
+    return -1;
+}
+
 
 /**
  * virDomainBlockStats:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 5f2541a..d4f80a6 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -466,4 +466,10 @@ LIBVIRT_0.9.3 {
         virNodeGetMemoryStats;
 } LIBVIRT_0.9.2;
 
+LIBVIRT_0.9.4 {
+    global:
+        virDomainGetVcpuBW;
+        virDomainSetVcpuBW;
+} LIBVIRT_0.9.3;
+
 # .... define new API here using predicted next version number ....
-- 
1.7.1




More information about the libvir-list mailing list