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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list