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