[libvirt] [PATCH 1/8] Add new API virDomain{Set, Get}BlockIoTune

This patch add new pulic API virDomainSetBlockIoTune and virDomainGetBlockIoTune. Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com> --- include/libvirt/libvirt.h.in | 69 ++++++++++++++++++++ src/driver.h | 18 +++++ src/libvirt.c | 142 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 2 + 4 files changed, 231 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 2ab89f5..f4988c4 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1671,6 +1671,75 @@ int virDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth, unsigned int flags); +/* Block I/O throttling support */ + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC: + * + * Macro for the BlockIoTune tunable weight: it represents the total + * bytes per second permitted through a block device, as a ullong. + */ + +#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC "total_bytes_sec" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC: + * + * Macro for the BlockIoTune tunable weight: it repersents the read + * bytes per second permitted through a block device, as a ullong. + */ + +#define VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC "read_bytes_sec" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC: + * + * Macro for the BlockIoTune tunable weight: it repersents the write + * bytes per second permitted through a block device, as a ullong. + */ + +#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC "write_bytes_sec" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC: + * + * Macro for the BlockIoTune tunable weight: it repersents the total + * I/O operations per second permitted through a block device, as a ullong. + */ + +#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC "total_iops_sec" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC: + * + * Macro for the BlockIoTune tunable weight: it repersents the read + * I/O operations per second permitted through a block device, as a ullong. + */ + +#define VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC "read_iops_sec" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC: + * Macro for the BlockIoTune tunable weight: it repersents the write + * I/O operations per second permitted through a block device, as a ullong. + */ + +#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC "write_iops_sec" + +int +virDomainSetBlockIoTune(virDomainPtr dom, + const char *disk, + virTypedParameterPtr params, + int nparams, + unsigned int flags); +int +virDomainGetBlockIoTune(virDomainPtr dom, + const char *disk, + virTypedParameterPtr params, + int *nparams, + unsigned int flags); + + /* * NUMA support */ diff --git a/src/driver.h b/src/driver.h index 4c14aaa..6ce3efc 100644 --- a/src/driver.h +++ b/src/driver.h @@ -740,6 +740,24 @@ typedef int (*virDrvDomainBlockPull)(virDomainPtr dom, const char *path, unsigned long bandwidth, unsigned int flags); +/* + * Block I/O throttling support + */ + +typedef int + (*virDrvDomainSetBlockIoTune)(virDomainPtr dom, + const char *disk, + virTypedParameterPtr params, + int nparams, + unsigned int flags); + +typedef int + (*virDrvDomainGetBlockIoTune)(virDomainPtr dom, + const char *disk, + virTypedParameterPtr params, + int *nparams, + unsigned int flags); + /** * _virDriver: diff --git a/src/libvirt.c b/src/libvirt.c index 1518ed2..32ad5db 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -17149,3 +17149,145 @@ error: virDispatchError(dom->conn); return -1; } + +/** + * virDomainSetBlockIoTune: + * @dom: pointer to domain object + * @disk: Fully-qualified disk name + * @params: Pointer to blkio parameter objects + * @nparams: Number of blkio parameters (this value can be the same or + * less than the number of parameters supported) + * @flags: An OR'ed set of virDomainModificationImpact + * + * Change all or a subset of the per-device block IO tunables. + * + * The @disk parameter is the name of the block device. Get this + * by calling virDomainGetXMLDesc and finding the <target dev='...'> + * attribute within //domain/devices/disk. (For example, "xvda"). + * + * Returns -1 in case of error, 0 in case of success. + */ +int virDomainSetBlockIoTune(virDomainPtr dom, + const char *disk, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(dom, "disk=%p, params=%p, nparams=%d, flags=%x", + disk, params, nparams, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN (dom)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (dom->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if (!disk || (nparams <= 0) || (params == NULL)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (virTypedParameterValidateSet(dom, params, nparams) < 0) + return -1; + + conn = dom->conn; + + if (conn->driver->domainSetBlockIoTune) { + int ret; + ret = conn->driver->domainSetBlockIoTune(dom, disk, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(dom->conn); + return -1; +} + +/** + * virDomainGetBlockIoTune: + * @dom: pointer to domain object + * @disk: Fully-qualified disk name + * @params: Pointer to blkio parameter object + * (return value, allocated by the caller) + * @nparams: Pointer to number of blkio parameters + * @flags: An OR'ed set of virDomainModificationImpact + * + * Get all block IO tunable parameters for a given device. On input, + * @nparams gives the size of the @params array; on output, @nparams + * gives how many slots were filled with parameter information, which + * might be less but will not exceed the input value. + * + * As a special case, calling with @params as NULL and @nparams as 0 on + * input will cause @nparams on output to contain the number of parameters + * supported by the hypervisor. The caller should then allocate @params + * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API + * agiain. + * + * See virDomainGetMemoryParameters() for an equivalent usage example. + * + * The @disk parameter is the name of the block device. Get this + * by calling virDomainGetXMLDesc and finding the <target dev='...'> + * attribute within //domain/devices/disk. (For example, "xvda"). + * + * Returns -1 in case of error, 0 in case of success. + */ +int virDomainGetBlockIoTune(virDomainPtr dom, + const char *disk, + virTypedParameterPtr params, + int *nparams, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(dom, "disk=%p, params=%p, nparams=%d, flags=%x", + disk, params, (nparams) ? *nparams : -1, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN (dom)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (!disk || (nparams == NULL) || (*nparams < 0) || + (params == NULL && *nparams != 0)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn, + VIR_DRV_FEATURE_TYPED_PARAM_STRING)) + flags |= VIR_TYPED_PARAM_STRING_OKAY; + + conn = dom->conn; + + if (conn->driver->domainGetBlockIoTune) { + int ret; + ret = conn->driver->domainGetBlockIoTune(dom, disk, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(dom->conn); + return -1; + +} + diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index bcefb10..4808891 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -496,6 +496,8 @@ LIBVIRT_0.9.7 { virDomainSnapshotGetParent; virDomainSnapshotListChildrenNames; virDomainSnapshotNumChildren; + virDomainSetBlockIoTune; + virDomainGetBlockIoTune; } LIBVIRT_0.9.5; # .... define new API here using predicted next version number .... -- 1.7.1

On 11/14/2011 09:33 PM, Lei Li wrote:
This patch add new pulic API virDomainSetBlockIoTune and virDomainGetBlockIoTune.
+/** + * virDomainSetBlockIoTune: + * @dom: pointer to domain object + * @disk: Fully-qualified disk name
Hmm. Fully-qualified name here,
+ * @params: Pointer to blkio parameter objects + * @nparams: Number of blkio parameters (this value can be the same or + * less than the number of parameters supported) + * @flags: An OR'ed set of virDomainModificationImpact + * + * Change all or a subset of the per-device block IO tunables. + * + * The @disk parameter is the name of the block device. Get this + * by calling virDomainGetXMLDesc and finding the <target dev='...'> + * attribute within //domain/devices/disk. (For example, "xvda").
but device shorthand here. We probably ought to accept both forms, just as we do with virDomainBlockStats, as of commit 89b6284f (oh, and that means that I ought to update virDomainBlockStats to document the same thing) - which means this can be a separate cleanup to make libvirt.c docs consistent as well as teaching the new API to use the domain_conf.c virDomainDiskIndexByName method to allow both forms. I can get to that after finishing my review of this series, if you don't beat me.
+ * Get all block IO tunable parameters for a given device. On input, + * @nparams gives the size of the @params array; on output, @nparams + * gives how many slots were filled with parameter information, which + * might be less but will not exceed the input value. + * + * As a special case, calling with @params as NULL and @nparams as 0 on + * input will cause @nparams on output to contain the number of parameters + * supported by the hypervisor. The caller should then allocate @params + * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API + * agiain.
Trailing space (running 'make syntax-check' will gripe). s/agiain/again/ Also, probably worth mentioning that the value of @nparams may be disk-specific, so the user is best off reprobing an appropriate nparams for each disk rather than assuming the parameters from 1 disk apply to all others.
+++ b/src/libvirt_public.syms @@ -496,6 +496,8 @@ LIBVIRT_0.9.7 { virDomainSnapshotGetParent; virDomainSnapshotListChildrenNames; virDomainSnapshotNumChildren; + virDomainSetBlockIoTune; + virDomainGetBlockIoTune; } LIBVIRT_0.9.5;
This needs to be in a new section LIBVIRT_0.9.8 based off of LIBVIRT_0.9.5 (we aren't changing 0.9.7 at this point). The problems I mentioned are minor enough that I don't mind fixing them prior to pushing, if the rest of the series looks sane; but if later review finds more problems later in the series, we may need a v5 series instead. I'll see about reviewing the rest of the series this week (I've also got quite a few nwfilter patches backed up in my todo queue). -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 11/15/2011 12:46 PM, Eric Blake wrote:
On 11/14/2011 09:33 PM, Lei Li wrote:
This patch add new pulic API virDomainSetBlockIoTune and virDomainGetBlockIoTune.
+/** + * virDomainSetBlockIoTune: + * @dom: pointer to domain object + * @disk: Fully-qualified disk name Hmm. Fully-qualified name here,
+ * @params: Pointer to blkio parameter objects + * @nparams: Number of blkio parameters (this value can be the same or + * less than the number of parameters supported) + * @flags: An OR'ed set of virDomainModificationImpact + * + * Change all or a subset of the per-device block IO tunables. + * + * The @disk parameter is the name of the block device. Get this + * by calling virDomainGetXMLDesc and finding the<target dev='...'> + * attribute within //domain/devices/disk. (For example, "xvda"). but device shorthand here.
We probably ought to accept both forms, just as we do with virDomainBlockStats, as of commit 89b6284f (oh, and that means that I ought to update virDomainBlockStats to document the same thing) - which means this can be a separate cleanup to make libvirt.c docs consistent as well as teaching the new API to use the domain_conf.c virDomainDiskIndexByName method to allow both forms. I can get to that after finishing my review of this series, if you don't beat me.
Yes, both fully-qualified and shorthand name can all work.
+ * Get all block IO tunable parameters for a given device. On input, + * @nparams gives the size of the @params array; on output, @nparams + * gives how many slots were filled with parameter information, which + * might be less but will not exceed the input value. + * + * As a special case, calling with @params as NULL and @nparams as 0 on + * input will cause @nparams on output to contain the number of parameters + * supported by the hypervisor. The caller should then allocate @params + * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API + * agiain. Trailing space (running 'make syntax-check' will gripe).
Thanks..:)
s/agiain/again/
Also, probably worth mentioning that the value of @nparams may be disk-specific, so the user is best off reprobing an appropriate nparams for each disk rather than assuming the parameters from 1 disk apply to all others.
The QEMU Block I/O Throttling support these whole 6 parameters, so I think display all the fields might make sense.
+++ b/src/libvirt_public.syms @@ -496,6 +496,8 @@ LIBVIRT_0.9.7 { virDomainSnapshotGetParent; virDomainSnapshotListChildrenNames; virDomainSnapshotNumChildren; + virDomainSetBlockIoTune; + virDomainGetBlockIoTune; } LIBVIRT_0.9.5; This needs to be in a new section LIBVIRT_0.9.8 based off of LIBVIRT_0.9.5 (we aren't changing 0.9.7 at this point).
The problems I mentioned are minor enough that I don't mind fixing them prior to pushing, if the rest of the series looks sane; but if later review finds more problems later in the series, we may need a v5 series instead. I'll see about reviewing the rest of the series this week (I've also got quite a few nwfilter patches backed up in my todo queue).
OK. :) Thank you.
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- Lei
participants (2)
-
Eric Blake
-
Lei Li