[libvirt] [PATCH 0/6] new virsh command "blkiotune" support

Hi All, This series implements a new command "blkiotune" for virsh. A lot of code borrows from memtune. You are able to tune blkio cgroup tunables by this command as follows. Show tunables #virsh blkiotune My_guest weight : 900 Tune tunables(Set IO weight) #virsh blkiotune My_guest --weight 500 #virsh blkiotune My_guest weight : 500 Thanks, Gui

Add virDomainSetBlkioParameters virDomainGetBlkioParameters Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- include/libvirt/libvirt.h.in | 67 +++++++++++++++++++++++++++++++++++++++ python/generator.py | 2 + python/libvirt-override-api.xml | 12 +++++++ python/libvirt-override.c | 17 ++++++++++ 4 files changed, 98 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 5dfb752..00b6216 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -676,6 +676,73 @@ int virDomainGetInfo (virDomainPtr domain, */ char * virDomainGetSchedulerType(virDomainPtr domain, int *nparams); +/** + * virDomainBlkioParameterType: + * + * A blkio parameter field type + */ +typedef enum { + VIR_DOMAIN_BLKIO_PARAM_INT = 1, /* integer case */ + VIR_DOMAIN_BLKIO_PARAM_UINT = 2, /* unsigned integer case */ + VIR_DOMAIN_BLKIO_PARAM_LLONG = 3, /* long long case */ + VIR_DOMAIN_BLKIO_PARAM_ULLONG = 4, /* unsigned long long case */ + VIR_DOMAIN_BLKIO_PARAM_DOUBLE = 5, /* double case */ + VIR_DOMAIN_BLKIO_PARAM_BOOLEAN = 6 /* boolean(character) case */ +} virBlkioParameterType; + +/** + * VIR_DOMAIN_BLKIO_FIELD_LENGTH: + * + * Macro providing the field length of virBlkioParameter + */ + +#define VIR_DOMAIN_BLKIO_FIELD_LENGTH 80 + +/** + * VIR_DOMAIN_BLKIO_WEIGHT: + * + * Macro for the Blkio tunable weight: it represents the io weight + * the guest can use. + */ + +#define VIR_DOMAIN_BLKIO_WEIGHT "weight" + +/** + * virDomainBlkioParameter: + * + * a virDomainBlkioParameter is the set of blkio cgroup parameteer + */ + +typedef struct _virBlkioParameter virBlkioParameter; + +struct _virBlkioParameter { + char field[VIR_DOMAIN_BLKIO_FIELD_LENGTH]; /* parameter name */ + int type; /* parameter type */ + union { + int i; /* data for integer case */ + unsigned int ui; /* data for unsigned integer case */ + long long int l; /* data for long long integer case */ + unsigned long long int ul; /* data for unsigned long long integer case */ + double d; /* data for double case */ + char b; /* data for char case */ + } value; /* parameter value */ +}; + +/** + * virBlkioParameterPtr: + * + * a virBlkioParameterPtr is a pointer to a virBlkioParameter structure. + */ + +typedef virBlkioParameter *virBlkioParameterPtr; + +/* Set Blkio tunables for the domain*/ +int virDomainSetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, unsigned int flags); +int virDomainGetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, unsigned int flags); /** * virDomainMemoryParameterType: diff --git a/python/generator.py b/python/generator.py index 15751bd..8db4b9e 100755 --- a/python/generator.py +++ b/python/generator.py @@ -306,6 +306,8 @@ skip_impl = ( 'virDomainGetSchedulerType', 'virDomainGetSchedulerParameters', 'virDomainSetSchedulerParameters', + 'virDomainSetBlkioParameters', + 'virDomainGetBlkioParameters', 'virDomainSetMemoryParameters', 'virDomainGetMemoryParameters', 'virDomainGetVcpus', diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index f209608..54deeb5 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -162,6 +162,18 @@ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> <arg name='params' type='virSchedParameterPtr' info='pointer to scheduler parameter objects'/> </function> + <function name='virDomainSetBlkioParameters' file='python'> + <info>Change the blkio tunables</info> + <return type='int' info='-1 in case of error, 0 in case of success.'/> + <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> + <arg name='params' type='virBlkioParameterPtr' info='pointer to blkio tunable objects'/> + </function> + <function name='virDomainGetBlkioParameters' file='python'> + <info>Get the blkio parameters, the @params array will be filled with the values.</info> + <return type='int' info='-1 in case of error, 0 in case of success.'/> + <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> + <arg name='params' type='virBlkioParameterPtr' info='pointer to blkio tunable objects'/> + </function> <function name='virDomainSetMemoryParameters' file='python'> <info>Change the memory tunables</info> <return type='int' info='-1 in case of error, 0 in case of success.'/> diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 4a03d72..e09e2b5 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -371,6 +371,23 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, return VIR_PY_INT_SUCCESS; } + + + +/* FIXME: This is a place holder for the implementation. */ +static PyObject * +libvirt_virDomainSetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + return VIR_PY_INT_FAIL; +} + +/* FIXME: This is a place holder for the implementation. */ +static PyObject * +libvirt_virDomainGetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + return VIR_PY_INT_FAIL; +} + /* FIXME: This is a place holder for the implementation. */ static PyObject * libvirt_virDomainSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, -- 1.7.1

Implements virDomainSetBlkioParameters and virDomainGetBlkioParameters and initialization Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/driver.h | 14 ++++++ src/esx/esx_driver.c | 2 + src/libvirt.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 +++ src/lxc/lxc_driver.c | 2 + src/openvz/openvz_driver.c | 2 + src/phyp/phyp_driver.c | 2 + src/qemu/qemu_driver.c | 2 + src/remote/remote_driver.c | 2 + src/test/test_driver.c | 2 + src/uml/uml_driver.c | 2 + src/vmware/vmware_driver.c | 2 + src/xen/xen_driver.c | 2 + 13 files changed, 148 insertions(+), 0 deletions(-) diff --git a/src/driver.h b/src/driver.h index 7451004..608efe9 100644 --- a/src/driver.h +++ b/src/driver.h @@ -135,6 +135,18 @@ typedef int (*virDrvDomainSetMemory) (virDomainPtr domain, unsigned long memory); typedef int + (*virDrvDomainSetBlkioParameters) + (virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, + unsigned int flags); +typedef int + (*virDrvDomainGetBlkioParameters) + (virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags); +typedef int (*virDrvDomainSetMemoryParameters) (virDomainPtr domain, virMemoryParameterPtr params, @@ -615,6 +627,8 @@ struct _virDriver { virDrvDomainSetMemoryParameters domainSetMemoryParameters; virDrvDomainGetMemoryParameters domainGetMemoryParameters; virDrvDomainOpenConsole domainOpenConsole; + virDrvDomainSetBlkioParameters domainSetBlkioParameters; + virDrvDomainGetBlkioParameters domainGetBlkioParameters; }; typedef int diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 97f3dbe..38f07bd 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4654,6 +4654,8 @@ static virDriver esxDriver = { esxDomainSetMemoryParameters, /* domainSetMemoryParameters */ esxDomainGetMemoryParameters, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; diff --git a/src/libvirt.c b/src/libvirt.c index f65cc24..b79f3c2 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2847,6 +2847,114 @@ error: } /** + * virDomainSetBlkioParameters: + * @domain: pointer to domain object + * @params: pointer to blkio parameter objects + * @nparams: number of blkio parameter (this value should be same or + * less than the number of parameters supported) + * @flags: currently unused, for future extension + * + * Change the blkio tunables + * This function requires privileged access to the hypervisor. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainSetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%u", + params, nparams, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + if ((nparams <= 0) || (params == NULL)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainSetBlkioParameters) { + int ret; + ret = conn->driver->domainSetBlkioParameters (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** + * virDomainGetBlkioParameters: + * @domain: pointer to domain object + * @params: pointer to blkio parameter object + * (return value, allocated by the caller) + * @nparams: pointer to number of blkio parameters + * @flags: currently unused, for future extension + * + * Get the blkio parameters, the @params array will be filled with the values + * equal to the number of parameters suggested by @nparams + * + * This function requires privileged access to the hypervisor. This function + * expects the caller to allocate the @params. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainGetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%u", + params, (nparams) ? *nparams : -1, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if ((nparams == NULL) || (*nparams < 0)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainGetBlkioParameters) { + int ret; + ret = conn->driver->domainGetBlkioParameters (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + virLibConnError (VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** * virDomainSetMemoryParameters: * @domain: pointer to domain object * @params: pointer to memory parameter objects diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 1a45be1..d43bc94 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -424,4 +424,10 @@ LIBVIRT_0.8.8 { virConnectGetSysinfo; } LIBVIRT_0.8.6; +LIBVIRT_0.8.7 { + global: + virDomainSetBlkioParameters; + virDomainGetBlkioParameters; +} LIBVIRT_0.8.6; + # .... define new API here using predicted next version number .... diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 0f78579..1940a16 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2930,6 +2930,8 @@ static virDriver lxcDriver = { lxcDomainSetMemoryParameters, /* domainSetMemoryParameters */ lxcDomainGetMemoryParameters, /* domainGetMemoryParameters */ lxcDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStateDriver lxcStateDriver = { diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 00d378a..5dec2c6 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1669,6 +1669,8 @@ static virDriver openvzDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; int openvzRegister(void) { diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index d954f2a..a93efde 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -4051,6 +4051,8 @@ static virDriver phypDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStorageDriver phypStorageDriver = { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 82a2210..882f323 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10502,6 +10502,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 4ca0d3b..6d148f1 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -10946,6 +10946,8 @@ static virDriver remote_driver = { remoteDomainSetMemoryParameters, /* domainSetMemoryParameters */ remoteDomainGetMemoryParameters, /* domainGetMemoryParameters */ remoteDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virNetworkDriver network_driver = { diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 1937da0..081652d 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5443,6 +5443,8 @@ static virDriver testDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virNetworkDriver testNetworkDriver = { diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 2af8002..ef11070 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2245,6 +2245,8 @@ static virDriver umlDriver = { NULL, /* domainSetMemoryParamters */ NULL, /* domainGetMemoryParamters */ umlDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static int diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 22b29d1..37e3346 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -1005,6 +1005,8 @@ static virDriver vmwareDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; int diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index b14c8db..508ed40 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2101,6 +2101,8 @@ static virDriver xenUnifiedDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ xenUnifiedDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; /** -- 1.7.1

Implement domainSetBlkioParamters and domainGetBlkioParamters for QEmu Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/qemu/qemu_driver.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 162 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 882f323..73ecd07 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -93,6 +93,7 @@ #define QEMU_NB_MEM_PARAM 3 +#define QEMU_NB_BLKIO_PARAM 1 #define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000)) @@ -7009,6 +7010,165 @@ cleanup: return ret; } +static int qemuDomainSetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + int ret = -1; + + qemuDriverLock(driver); + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, + __FUNCTION__); + goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + ret = 0; + for (i = 0; i < nparams; i++) { + virBlkioParameterPtr param = ¶ms[i]; + + if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) { + int rc; + if (param->type != VIR_DOMAIN_BLKIO_PARAM_UINT) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("invalid type for blkio weight tunable, expected a 'unsigned int'")); + ret = -1; + continue; + } + + if (params[i].value.ui > 1000 || params[i].value.ui < 100) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("out of blkio weight range.")); + ret = -1; + continue; + } + + rc = virCgroupSetBlkioWeight(group, params[i].value.ui); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to set blkio weight tunable")); + ret = -1; + } + } else { + qemuReportError(VIR_ERR_INVALID_ARG, + _("Parameter `%s' not supported"), param->field); + ret = -1; + } + } + +cleanup: + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} + +static int qemuDomainGetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + unsigned int val; + int ret = -1; + int rc; + + qemuDriverLock(driver); + + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, + __FUNCTION__); + goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if ((*nparams) == 0) { + /* Current number of blkio parameters supported by cgroups */ + *nparams = QEMU_NB_BLKIO_PARAM; + ret = 0; + goto cleanup; + } + + if ((*nparams) != QEMU_NB_BLKIO_PARAM) { + qemuReportError(VIR_ERR_INVALID_ARG, + "%s", _("Invalid parameter count")); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + for (i = 0; i < *nparams; i++) { + virBlkioParameterPtr param = ¶ms[i]; + val = 0; + param->value.ui = 0; + param->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + switch(i) { + case 0: /* fill blkio weight here */ + rc = virCgroupGetBlkioWeight(group, &val); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to get blkio weight")); + goto cleanup; + } + if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Field blkio weight too long for destination")); + goto cleanup; + } + param->value.ui = val; + break; + + default: + break; + /* should not hit here */ + } + } + + ret = 0; + +cleanup: + if (group) + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} static int qemuDomainSetMemoryParameters(virDomainPtr dom, virMemoryParameterPtr params, @@ -10502,8 +10662,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ - NULL, /* domainSetBlkioParameters */ - NULL, /* domainGetBlkioParameters */ + qemuDomainSetBlkioParameters, /* domainSetBlkioParameters */ + qemuDomainGetBlkioParameters, /* domainGetBlkioParameters */ }; -- 1.7.1

于 2011年02月16日 12:04, Gui Jianfeng 写道:
Implement domainSetBlkioParamters and domainGetBlkioParamters for QEmu
Signed-off-by: Gui Jianfeng<guijianfeng@cn.fujitsu.com> --- src/qemu/qemu_driver.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 162 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 882f323..73ecd07 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -93,6 +93,7 @@
#define QEMU_NB_MEM_PARAM 3
+#define QEMU_NB_BLKIO_PARAM 1
#define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000))
@@ -7009,6 +7010,165 @@ cleanup: return ret; }
+static int qemuDomainSetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + int ret = -1; + + qemuDriverLock(driver); + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, + __FUNCTION__);
Eric made patch to replace "__FUNCTION__" with descriptive string in d9b0494779, so perhaps it shouldn't introduced again.
+ goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name,&group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + ret = 0; + for (i = 0; i< nparams; i++) { + virBlkioParameterPtr param =¶ms[i]; + + if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) { + int rc; + if (param->type != VIR_DOMAIN_BLKIO_PARAM_UINT) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("invalid type for blkio weight tunable, expected a 'unsigned int'")); + ret = -1; + continue; + } + + if (params[i].value.ui> 1000 || params[i].value.ui< 100) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("out of blkio weight range.")); + ret = -1; + continue; + } + + rc = virCgroupSetBlkioWeight(group, params[i].value.ui); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to set blkio weight tunable")); + ret = -1; + } + } else { + qemuReportError(VIR_ERR_INVALID_ARG, + _("Parameter `%s' not supported"), param->field); + ret = -1; + } + } + +cleanup: + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} + +static int qemuDomainGetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + unsigned int val; + int ret = -1; + int rc; + + qemuDriverLock(driver); + + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, + __FUNCTION__);
likewise
+ goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if ((*nparams) == 0) { + /* Current number of blkio parameters supported by cgroups */ + *nparams = QEMU_NB_BLKIO_PARAM; + ret = 0; + goto cleanup; + } + + if ((*nparams) != QEMU_NB_BLKIO_PARAM) { + qemuReportError(VIR_ERR_INVALID_ARG, + "%s", _("Invalid parameter count")); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name,&group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + for (i = 0; i< *nparams; i++) { + virBlkioParameterPtr param =¶ms[i]; + val = 0; + param->value.ui = 0; + param->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + switch(i) { + case 0: /* fill blkio weight here */ + rc = virCgroupGetBlkioWeight(group,&val); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to get blkio weight")); + goto cleanup; + } + if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Field blkio weight too long for destination")); + goto cleanup; + } + param->value.ui = val; + break; + + default: + break; + /* should not hit here */ + } + } + + ret = 0; + +cleanup: + if (group) + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +}
static int qemuDomainSetMemoryParameters(virDomainPtr dom, virMemoryParameterPtr params, @@ -10502,8 +10662,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ - NULL, /* domainSetBlkioParameters */ - NULL, /* domainGetBlkioParameters */ + qemuDomainSetBlkioParameters, /* domainSetBlkioParameters */ + qemuDomainGetBlkioParameters, /* domainGetBlkioParameters */ };

Implement domainSetBlkioParamters and domainGetBlkioParamters for QEmu v1-> v2 Changes: - Improve error message output suggested by Osier. Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/qemu/qemu_driver.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 160 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 882f323..abaefca 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -93,6 +93,7 @@ #define QEMU_NB_MEM_PARAM 3 +#define QEMU_NB_BLKIO_PARAM 1 #define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000)) @@ -7009,6 +7010,163 @@ cleanup: return ret; } +static int qemuDomainSetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + int ret = -1; + + qemuDriverLock(driver); + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, _("blkio cgroup isn't mounted")); + goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + ret = 0; + for (i = 0; i < nparams; i++) { + virBlkioParameterPtr param = ¶ms[i]; + + if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) { + int rc; + if (param->type != VIR_DOMAIN_BLKIO_PARAM_UINT) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("invalid type for blkio weight tunable, expected a 'unsigned int'")); + ret = -1; + continue; + } + + if (params[i].value.ui > 1000 || params[i].value.ui < 100) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("out of blkio weight range.")); + ret = -1; + continue; + } + + rc = virCgroupSetBlkioWeight(group, params[i].value.ui); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to set blkio weight tunable")); + ret = -1; + } + } else { + qemuReportError(VIR_ERR_INVALID_ARG, + _("Parameter `%s' not supported"), param->field); + ret = -1; + } + } + +cleanup: + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} + +static int qemuDomainGetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + unsigned int val; + int ret = -1; + int rc; + + qemuDriverLock(driver); + + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, _("blkio cgroup isn't mounted")); + goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if ((*nparams) == 0) { + /* Current number of blkio parameters supported by cgroups */ + *nparams = QEMU_NB_BLKIO_PARAM; + ret = 0; + goto cleanup; + } + + if ((*nparams) != QEMU_NB_BLKIO_PARAM) { + qemuReportError(VIR_ERR_INVALID_ARG, + "%s", _("Invalid parameter count")); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + for (i = 0; i < *nparams; i++) { + virBlkioParameterPtr param = ¶ms[i]; + val = 0; + param->value.ui = 0; + param->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + switch(i) { + case 0: /* fill blkio weight here */ + rc = virCgroupGetBlkioWeight(group, &val); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to get blkio weight")); + goto cleanup; + } + if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Field blkio weight too long for destination")); + goto cleanup; + } + param->value.ui = val; + break; + + default: + break; + /* should not hit here */ + } + } + + ret = 0; + +cleanup: + if (group) + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} static int qemuDomainSetMemoryParameters(virDomainPtr dom, virMemoryParameterPtr params, @@ -10502,8 +10660,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ - NULL, /* domainSetBlkioParameters */ - NULL, /* domainGetBlkioParameters */ + qemuDomainSetBlkioParameters, /* domainSetBlkioParameters */ + qemuDomainGetBlkioParameters, /* domainGetBlkioParameters */ }; -- 1.7.1

Adding memtune command to virsh tool Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 127 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 50d5e33..864900d 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2973,6 +2973,132 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd) } /* + * "blkiotune" command + */ +static const vshCmdInfo info_blkiotune[] = { + {"help", N_("Get or set blkio parameters")}, + {"desc", N_("Get or set the current blkio parameters for a guest" \ + " domain.\n" \ + " To get the blkio parameters use following command: \n\n" \ + " virsh # blkiotune <domain>")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_blkiotune[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"weight", VSH_OT_INT, VSH_OFLAG_NONE, + N_("IO Weight in range [100, 1000]")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) +{ + virDomainPtr dom; + int weight; + int nparams = 0; + unsigned int i = 0; + virBlkioParameterPtr params = NULL, temp = NULL; + int ret = FALSE; + int found; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return FALSE; + + weight = vshCommandOptInt(cmd, "weight", &found); + if (found) { + nparams++; + if (weight < 0) { + virDomainFree(dom); + vshError(ctl, _("Invalid value of %d for I/O weight"), weight); + return FALSE; + } + } + + if (nparams == 0) { + /* get the number of blkio parameters */ + if (virDomainGetBlkioParameters(dom, NULL, &nparams, 0) != 0) { + vshError(ctl, "%s", + _("Unable to get number of blkio parameters")); + goto cleanup; + } + + if (nparams == 0) { + /* nothing to output */ + ret = TRUE; + goto cleanup; + } + + /* now go get all the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + if (virDomainGetBlkioParameters(dom, params, &nparams, 0) != 0) { + vshError(ctl, "%s", _("Unable to get blkio parameters")); + goto cleanup; + } + + for (i = 0; i < nparams; i++) { + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.i); + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + vshPrint(ctl, "%-15s: %u\n", params[i].field, + params[i].value.ui); + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + vshPrint(ctl, "%-15s: %lld\n", params[i].field, + params[i].value.l); + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + vshPrint(ctl, "%-15s: %llu\n", params[i].field, + params[i].value.ul); + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + vshPrint(ctl, "%-15s: %f\n", params[i].field, + params[i].value.d); + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.b); + break; + default: + vshPrint(ctl, "unimplemented blkio parameter type\n"); + } + } + + ret = TRUE; + } else { + /* set the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + + for (i = 0; i < nparams; i++) { + temp = ¶ms[i]; + temp->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + if (weight) { + temp->value.ui = (unsigned int)weight; + strncpy(temp->field, VIR_DOMAIN_BLKIO_WEIGHT, + sizeof(temp->field)); + weight = 0; + } + } + if (virDomainSetBlkioParameters(dom, params, nparams, 0) != 0) + vshError(ctl, "%s", _("Unable to change blkio parameters")); + else + ret = TRUE; + } + + cleanup: + VIR_FREE(params); + virDomainFree(dom); + return ret; +} + +/* * "memtune" command */ static const vshCmdInfo info_memtune[] = { @@ -10287,6 +10413,7 @@ static const vshCmdDef domManagementCmds[] = { {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, info_managedsaveremove}, {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune}, {"memtune", cmdMemtune, opts_memtune, info_memtune}, {"migrate", cmdMigrate, opts_migrate, info_migrate}, {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime}, -- 1.7.1

于 2011年02月16日 12:05, Gui Jianfeng 写道:
Adding memtune command to virsh tool
s/memtune/blkiotune/ Also applies to patch subject.
Signed-off-by: Gui Jianfeng<guijianfeng@cn.fujitsu.com> --- tools/virsh.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 127 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c index 50d5e33..864900d 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2973,6 +2973,132 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd) }
/* + * "blkiotune" command + */ +static const vshCmdInfo info_blkiotune[] = { + {"help", N_("Get or set blkio parameters")}, + {"desc", N_("Get or set the current blkio parameters for a guest" \ + " domain.\n" \ + " To get the blkio parameters use following command: \n\n" \ + " virsh # blkiotune<domain>")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_blkiotune[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"weight", VSH_OT_INT, VSH_OFLAG_NONE, + N_("IO Weight in range [100, 1000]")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) +{ + virDomainPtr dom; + int weight; + int nparams = 0; + unsigned int i = 0; + virBlkioParameterPtr params = NULL, temp = NULL; + int ret = FALSE; + int found; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return FALSE; + + weight = vshCommandOptInt(cmd, "weight",&found); + if (found) { + nparams++; + if (weight< 0) { + virDomainFree(dom); + vshError(ctl, _("Invalid value of %d for I/O weight"), weight); + return FALSE; + } + } + + if (nparams == 0) { + /* get the number of blkio parameters */ + if (virDomainGetBlkioParameters(dom, NULL,&nparams, 0) != 0) { + vshError(ctl, "%s", + _("Unable to get number of blkio parameters")); + goto cleanup; + } + + if (nparams == 0) { + /* nothing to output */ + ret = TRUE; + goto cleanup; + } + + /* now go get all the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + if (virDomainGetBlkioParameters(dom, params,&nparams, 0) != 0) { + vshError(ctl, "%s", _("Unable to get blkio parameters")); + goto cleanup; + } + + for (i = 0; i< nparams; i++) { + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.i); + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + vshPrint(ctl, "%-15s: %u\n", params[i].field, + params[i].value.ui); + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + vshPrint(ctl, "%-15s: %lld\n", params[i].field, + params[i].value.l); + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + vshPrint(ctl, "%-15s: %llu\n", params[i].field, + params[i].value.ul); + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + vshPrint(ctl, "%-15s: %f\n", params[i].field, + params[i].value.d); + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.b); + break; + default: + vshPrint(ctl, "unimplemented blkio parameter type\n"); + } + } + + ret = TRUE; + } else { + /* set the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + + for (i = 0; i< nparams; i++) { + temp =¶ms[i]; + temp->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + if (weight) { + temp->value.ui = (unsigned int)weight; + strncpy(temp->field, VIR_DOMAIN_BLKIO_WEIGHT, + sizeof(temp->field)); + weight = 0; + } + } + if (virDomainSetBlkioParameters(dom, params, nparams, 0) != 0) + vshError(ctl, "%s", _("Unable to change blkio parameters")); + else + ret = TRUE; + } + + cleanup: + VIR_FREE(params); + virDomainFree(dom); + return ret; +} + +/* * "memtune" command */ static const vshCmdInfo info_memtune[] = { @@ -10287,6 +10413,7 @@ static const vshCmdDef domManagementCmds[] = { {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, info_managedsaveremove}, {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune}, {"memtune", cmdMemtune, opts_memtune, info_memtune}, {"migrate", cmdMigrate, opts_migrate, info_migrate}, {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime},

Adding blkiotune command to virsh tool v1 -> v2 Changes: - Fix some typo. Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 127 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 50d5e33..864900d 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2973,6 +2973,132 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd) } /* + * "blkiotune" command + */ +static const vshCmdInfo info_blkiotune[] = { + {"help", N_("Get or set blkio parameters")}, + {"desc", N_("Get or set the current blkio parameters for a guest" \ + " domain.\n" \ + " To get the blkio parameters use following command: \n\n" \ + " virsh # blkiotune <domain>")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_blkiotune[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"weight", VSH_OT_INT, VSH_OFLAG_NONE, + N_("IO Weight in range [100, 1000]")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) +{ + virDomainPtr dom; + int weight; + int nparams = 0; + unsigned int i = 0; + virBlkioParameterPtr params = NULL, temp = NULL; + int ret = FALSE; + int found; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return FALSE; + + weight = vshCommandOptInt(cmd, "weight", &found); + if (found) { + nparams++; + if (weight < 0) { + virDomainFree(dom); + vshError(ctl, _("Invalid value of %d for I/O weight"), weight); + return FALSE; + } + } + + if (nparams == 0) { + /* get the number of blkio parameters */ + if (virDomainGetBlkioParameters(dom, NULL, &nparams, 0) != 0) { + vshError(ctl, "%s", + _("Unable to get number of blkio parameters")); + goto cleanup; + } + + if (nparams == 0) { + /* nothing to output */ + ret = TRUE; + goto cleanup; + } + + /* now go get all the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + if (virDomainGetBlkioParameters(dom, params, &nparams, 0) != 0) { + vshError(ctl, "%s", _("Unable to get blkio parameters")); + goto cleanup; + } + + for (i = 0; i < nparams; i++) { + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.i); + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + vshPrint(ctl, "%-15s: %u\n", params[i].field, + params[i].value.ui); + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + vshPrint(ctl, "%-15s: %lld\n", params[i].field, + params[i].value.l); + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + vshPrint(ctl, "%-15s: %llu\n", params[i].field, + params[i].value.ul); + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + vshPrint(ctl, "%-15s: %f\n", params[i].field, + params[i].value.d); + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.b); + break; + default: + vshPrint(ctl, "unimplemented blkio parameter type\n"); + } + } + + ret = TRUE; + } else { + /* set the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + + for (i = 0; i < nparams; i++) { + temp = ¶ms[i]; + temp->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + if (weight) { + temp->value.ui = (unsigned int)weight; + strncpy(temp->field, VIR_DOMAIN_BLKIO_WEIGHT, + sizeof(temp->field)); + weight = 0; + } + } + if (virDomainSetBlkioParameters(dom, params, nparams, 0) != 0) + vshError(ctl, "%s", _("Unable to change blkio parameters")); + else + ret = TRUE; + } + + cleanup: + VIR_FREE(params); + virDomainFree(dom); + return ret; +} + +/* * "memtune" command */ static const vshCmdInfo info_memtune[] = { @@ -10287,6 +10413,7 @@ static const vshCmdDef domManagementCmds[] = { {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, info_managedsaveremove}, {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune}, {"memtune", cmdMemtune, opts_memtune, info_memtune}, {"migrate", cmdMigrate, opts_migrate, info_migrate}, {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime}, -- 1.7.1

Remote protocol implementation of virDomainSetBlkioParameters and virDomainGetBlkioParameters. Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- daemon/remote.c | 210 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 2 + daemon/remote_dispatch_prototypes.h | 16 +++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 10 ++ src/remote/remote_driver.c | 173 ++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 89 +++++++++++++++ src/remote/remote_protocol.h | 55 +++++++++ src/remote/remote_protocol.x | 44 +++++++- 9 files changed, 597 insertions(+), 3 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index d53b466..b8e79f9 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2384,6 +2384,216 @@ remoteDispatchDomainSetMemory (struct qemud_server *server ATTRIBUTE_UNUSED, } static int +remoteDispatchDomainSetBlkioParameters(struct qemud_server *server + ATTRIBUTE_UNUSED, + struct qemud_client *client + ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header * + hdr ATTRIBUTE_UNUSED, + remote_error * rerr, + remote_domain_set_blkio_parameters_args + * args, void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom; + int i, r, nparams; + virBlkioParameterPtr params; + unsigned int flags; + + nparams = args->params.params_len; + flags = args->flags; + + if (nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) { + remoteDispatchFormatError(rerr, "%s", _("nparams too large")); + return -1; + } + if (VIR_ALLOC_N(params, nparams) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + + /* Deserialise parameters. */ + for (i = 0; i < nparams; ++i) { + if (virStrcpyStatic + (params[i].field, args->params.params_val[i].field) == NULL) { + remoteDispatchFormatError(rerr, + _ + ("Field %s too big for destination"), + args->params.params_val[i].field); + return -1; + } + params[i].type = args->params.params_val[i].value.type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + params[i].value.i = + args->params.params_val[i].value. + remote_blkio_param_value_u.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + params[i].value.ui = + args->params.params_val[i].value. + remote_blkio_param_value_u.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + params[i].value.l = + args->params.params_val[i].value. + remote_blkio_param_value_u.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + params[i].value.ul = + args->params.params_val[i].value. + remote_blkio_param_value_u.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + params[i].value.d = + args->params.params_val[i].value. + remote_blkio_param_value_u.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + params[i].value.b = + args->params.params_val[i].value. + remote_blkio_param_value_u.b; + break; + } + } + + dom = get_nonnull_domain(conn, args->dom); + if (dom == NULL) { + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + + r = virDomainSetBlkioParameters(dom, params, nparams, flags); + virDomainFree(dom); + VIR_FREE(params); + if (r == -1) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + return 0; +} + +static int +remoteDispatchDomainGetBlkioParameters(struct qemud_server *server + ATTRIBUTE_UNUSED, + struct qemud_client *client + ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header * + hdr ATTRIBUTE_UNUSED, + remote_error * rerr, + remote_domain_get_blkio_parameters_args + * args, + remote_domain_get_blkio_parameters_ret + * ret) +{ + virDomainPtr dom; + virBlkioParameterPtr params; + int i, r, nparams; + unsigned int flags; + + nparams = args->nparams; + flags = args->flags; + + if (nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) { + remoteDispatchFormatError(rerr, "%s", _("nparams too large")); + return -1; + } + if (VIR_ALLOC_N(params, nparams) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + + dom = get_nonnull_domain(conn, args->dom); + if (dom == NULL) { + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + + r = virDomainGetBlkioParameters(dom, params, &nparams, flags); + if (r == -1) { + virDomainFree(dom); + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + /* In this case, we need to send back the number of parameters + * supported + */ + if (args->nparams == 0) { + ret->nparams = nparams; + goto success; + } + + /* Serialise the blkio parameters. */ + ret->params.params_len = nparams; + if (VIR_ALLOC_N(ret->params.params_val, nparams) < 0) + goto oom; + + for (i = 0; i < nparams; ++i) { + // remoteDispatchClientRequest will free this: + ret->params.params_val[i].field = strdup(params[i].field); + if (ret->params.params_val[i].field == NULL) + goto oom; + + ret->params.params_val[i].value.type = params[i].type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.i = + params[i].value.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.ui = + params[i].value.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.l = + params[i].value.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.ul = + params[i].value.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.d = + params[i].value.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.b = + params[i].value.b; + break; + default: + remoteDispatchFormatError(rerr, "%s", _("unknown type")); + goto cleanup; + } + } + + success: + virDomainFree(dom); + VIR_FREE(params); + + return 0; + + oom: + remoteDispatchOOMError(rerr); + cleanup: + virDomainFree(dom); + for (i = 0; i < nparams; i++) + VIR_FREE(ret->params.params_val[i].field); + VIR_FREE(params); + return -1; +} + +static int remoteDispatchDomainSetMemoryParameters(struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h index 57962d1..e8b2a7e 100644 --- a/daemon/remote_dispatch_args.h +++ b/daemon/remote_dispatch_args.h @@ -172,3 +172,5 @@ remote_domain_open_console_args val_remote_domain_open_console_args; remote_domain_is_updated_args val_remote_domain_is_updated_args; remote_get_sysinfo_args val_remote_get_sysinfo_args; + remote_domain_set_blkio_parameters_args val_remote_domain_set_blkio_parameters_args; + remote_domain_get_blkio_parameters_args val_remote_domain_get_blkio_parameters_args; diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h index e59701a..692391b 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -218,6 +218,14 @@ static int remoteDispatchDomainGetAutostart( remote_error *err, remote_domain_get_autostart_args *args, remote_domain_get_autostart_ret *ret); +static int remoteDispatchDomainGetBlkioParameters( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_get_blkio_parameters_args *args, + remote_domain_get_blkio_parameters_ret *ret); static int remoteDispatchDomainGetBlockInfo( struct qemud_server *server, struct qemud_client *client, @@ -538,6 +546,14 @@ static int remoteDispatchDomainSetAutostart( remote_error *err, remote_domain_set_autostart_args *args, void *ret); +static int remoteDispatchDomainSetBlkioParameters( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_set_blkio_parameters_args *args, + void *ret); static int remoteDispatchDomainSetMaxMemory( struct qemud_server *server, struct qemud_client *client, diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h index 78e5469..114e832 100644 --- a/daemon/remote_dispatch_ret.h +++ b/daemon/remote_dispatch_ret.h @@ -139,3 +139,4 @@ remote_domain_get_vcpus_flags_ret val_remote_domain_get_vcpus_flags_ret; remote_domain_is_updated_ret val_remote_domain_is_updated_ret; remote_get_sysinfo_ret val_remote_get_sysinfo_ret; + remote_domain_get_blkio_parameters_ret val_remote_domain_get_blkio_parameters_ret; diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h index 5d27390..627e8a8 100644 --- a/daemon/remote_dispatch_table.h +++ b/daemon/remote_dispatch_table.h @@ -1022,3 +1022,13 @@ .args_filter = (xdrproc_t) xdr_remote_get_sysinfo_args, .ret_filter = (xdrproc_t) xdr_remote_get_sysinfo_ret, }, +{ /* DomainSetBlkioParameters => 204 */ + .fn = (dispatch_fn) remoteDispatchDomainSetBlkioParameters, + .args_filter = (xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + .ret_filter = (xdrproc_t) xdr_void, +}, +{ /* DomainGetBlkioParameters => 205 */ + .fn = (dispatch_fn) remoteDispatchDomainGetBlkioParameters, + .args_filter = (xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, + .ret_filter = (xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, +}, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 6d148f1..ff39da0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -2445,6 +2445,175 @@ done: } static int +remoteDomainSetBlkioParameters (virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, + unsigned int flags) +{ + int rv = -1; + remote_domain_set_blkio_parameters_args args; + int i, do_error; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + + /* Serialise the blkio parameters. */ + args.params.params_len = nparams; + args.flags = flags; + if (VIR_ALLOC_N(args.params.params_val, nparams) < 0) { + virReportOOMError(); + goto done; + } + + do_error = 0; + for (i = 0; i < nparams; ++i) { + // call() will free this: + args.params.params_val[i].field = strdup (params[i].field); + if (args.params.params_val[i].field == NULL) { + virReportOOMError(); + do_error = 1; + } + args.params.params_val[i].value.type = params[i].type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + args.params.params_val[i].value.remote_blkio_param_value_u.i = + params[i].value.i; break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + args.params.params_val[i].value.remote_blkio_param_value_u.ui = + params[i].value.ui; break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + args.params.params_val[i].value.remote_blkio_param_value_u.l = + params[i].value.l; break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + args.params.params_val[i].value.remote_blkio_param_value_u.ul = + params[i].value.ul; break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + args.params.params_val[i].value.remote_blkio_param_value_u.d = + params[i].value.d; break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + args.params.params_val[i].value.remote_blkio_param_value_u.b = + params[i].value.b; break; + default: + remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type")); + do_error = 1; + } + } + + if (do_error) { + xdr_free ((xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + (char *) &args); + goto done; + } + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS, + (xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + (char *) &args, (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int +remoteDomainGetBlkioParameters (virDomainPtr domain, + virBlkioParameterPtr params, int *nparams, + unsigned int flags) +{ + int rv = -1; + remote_domain_get_blkio_parameters_args args; + remote_domain_get_blkio_parameters_ret ret; + int i = -1; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + args.nparams = *nparams; + args.flags = flags; + + memset (&ret, 0, sizeof ret); + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS, + (xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, (char *) &args, + (xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, (char *) &ret) == -1) + goto done; + + /* Check the length of the returned list carefully. */ + if (ret.params.params_len > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX || + ret.params.params_len > *nparams) { + remoteError(VIR_ERR_RPC, "%s", + _("remoteDomainGetBlkioParameters: " + "returned number of parameters exceeds limit")); + goto cleanup; + } + /* Handle the case when the caller does not know the number of parameters + * and is asking for the number of parameters supported + */ + if (*nparams == 0) { + *nparams = ret.nparams; + rv = 0; + goto cleanup; + } + + *nparams = ret.params.params_len; + + /* Deserialise the result. */ + for (i = 0; i < *nparams; ++i) { + if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) { + remoteError(VIR_ERR_INTERNAL_ERROR, + _("Parameter %s too big for destination"), + ret.params.params_val[i].field); + goto cleanup; + } + params[i].type = ret.params.params_val[i].value.type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + params[i].value.i = + ret.params.params_val[i].value.remote_blkio_param_value_u.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + params[i].value.ui = + ret.params.params_val[i].value.remote_blkio_param_value_u.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + params[i].value.l = + ret.params.params_val[i].value.remote_blkio_param_value_u.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + params[i].value.ul = + ret.params.params_val[i].value.remote_blkio_param_value_u.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + params[i].value.d = + ret.params.params_val[i].value.remote_blkio_param_value_u.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + params[i].value.b = + ret.params.params_val[i].value.remote_blkio_param_value_u.b; + break; + default: + remoteError(VIR_ERR_RPC, "%s", + _("remoteDomainGetBlkioParameters: " + "unknown parameter type")); + goto cleanup; + } + } + + rv = 0; + +cleanup: + xdr_free ((xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, + (char *) &ret); +done: + remoteDriverUnlock(priv); + return rv; +} + +static int remoteDomainSetMemoryParameters (virDomainPtr domain, virMemoryParameterPtr params, int nparams, @@ -10946,8 +11115,8 @@ static virDriver remote_driver = { remoteDomainSetMemoryParameters, /* domainSetMemoryParameters */ remoteDomainGetMemoryParameters, /* domainGetMemoryParameters */ remoteDomainOpenConsole, /* domainOpenConsole */ - NULL, /* domainSetBlkioParameters */ - NULL, /* domainGetBlkioParameters */ + remoteDomainSetBlkioParameters, /* domainSetBlkioParameters */ + remoteDomainGetBlkioParameters, /* domainGetBlkioParameters */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c index bae92ca..2a3daa6 100644 --- a/src/remote/remote_protocol.c +++ b/src/remote/remote_protocol.c @@ -308,6 +308,53 @@ xdr_remote_sched_param (XDR *xdrs, remote_sched_param *objp) } bool_t +xdr_remote_blkio_param_value (XDR *xdrs, remote_blkio_param_value *objp) +{ + + if (!xdr_int (xdrs, &objp->type)) + return FALSE; + switch (objp->type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + if (!xdr_u_int (xdrs, &objp->remote_blkio_param_value_u.ui)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + if (!xdr_int64_t (xdrs, &objp->remote_blkio_param_value_u.l)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + if (!xdr_uint64_t (xdrs, &objp->remote_blkio_param_value_u.ul)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + if (!xdr_double (xdrs, &objp->remote_blkio_param_value_u.d)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + if (!xdr_int (xdrs, &objp->remote_blkio_param_value_u.b)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +bool_t +xdr_remote_blkio_param (XDR *xdrs, remote_blkio_param *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->field)) + return FALSE; + if (!xdr_remote_blkio_param_value (xdrs, &objp->value)) + return FALSE; + return TRUE; +} + +bool_t xdr_remote_memory_param_value (XDR *xdrs, remote_memory_param_value *objp) { @@ -646,6 +693,48 @@ xdr_remote_domain_set_scheduler_parameters_args (XDR *xdrs, remote_domain_set_sc } bool_t +xdr_remote_domain_set_blkio_parameters_args (XDR *xdrs, remote_domain_set_blkio_parameters_args *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->params.params_val; + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->params.params_len, REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX, + sizeof (remote_blkio_param), (xdrproc_t) xdr_remote_blkio_param)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_blkio_parameters_args (XDR *xdrs, remote_domain_get_blkio_parameters_args *objp) +{ + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_int (xdrs, &objp->nparams)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_blkio_parameters_ret (XDR *xdrs, remote_domain_get_blkio_parameters_ret *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->params.params_val; + + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->params.params_len, REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX, + sizeof (remote_blkio_param), (xdrproc_t) xdr_remote_blkio_param)) + return FALSE; + if (!xdr_int (xdrs, &objp->nparams)) + return FALSE; + return TRUE; +} + + +bool_t xdr_remote_domain_set_memory_parameters_args (XDR *xdrs, remote_domain_set_memory_parameters_args *objp) { char **objp_cpp0 = (char **) (void *) &objp->params.params_val; diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h index 46d526a..52a9d71 100644 --- a/src/remote/remote_protocol.h +++ b/src/remote/remote_protocol.h @@ -53,6 +53,7 @@ typedef remote_nonnull_string *remote_string; #define REMOTE_NODE_DEVICE_CAPS_LIST_MAX 16384 #define REMOTE_NWFILTER_NAME_LIST_MAX 1024 #define REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX 16 +#define REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX 16 #define REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX 16 #define REMOTE_NODE_MAX_CELLS 1024 #define REMOTE_AUTH_SASL_DATA_MAX 65536 @@ -187,6 +188,25 @@ struct remote_sched_param { }; typedef struct remote_sched_param remote_sched_param; +struct remote_blkio_param_value { + int type; + union { + int i; + u_int ui; + int64_t l; + uint64_t ul; + double d; + int b; + } remote_blkio_param_value_u; +}; +typedef struct remote_blkio_param_value remote_blkio_param_value; + +struct remote_blkio_param { + remote_nonnull_string field; + remote_blkio_param_value value; +}; +typedef struct remote_blkio_param remote_blkio_param; + struct remote_memory_param_value { int type; union { @@ -337,6 +357,32 @@ struct remote_domain_set_scheduler_parameters_args { }; typedef struct remote_domain_set_scheduler_parameters_args remote_domain_set_scheduler_parameters_args; +struct remote_domain_set_blkio_parameters_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_blkio_param *params_val; + } params; + u_int flags; +}; +typedef struct remote_domain_set_blkio_parameters_args remote_domain_set_blkio_parameters_args; + +struct remote_domain_get_blkio_parameters_args { + remote_nonnull_domain dom; + int nparams; + u_int flags; +}; +typedef struct remote_domain_get_blkio_parameters_args remote_domain_get_blkio_parameters_args; + +struct remote_domain_get_blkio_parameters_ret { + struct { + u_int params_len; + remote_blkio_param *params_val; + } params; + int nparams; +}; +typedef struct remote_domain_get_blkio_parameters_ret remote_domain_get_blkio_parameters_ret; + struct remote_domain_set_memory_parameters_args { remote_nonnull_domain dom; struct { @@ -2331,6 +2377,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, REMOTE_PROC_DOMAIN_IS_UPDATED = 202, REMOTE_PROC_GET_SYSINFO = 203, + REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 204, + REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 205, }; typedef enum remote_procedure remote_procedure; @@ -2386,6 +2434,8 @@ extern bool_t xdr_remote_auth_type (XDR *, remote_auth_type*); extern bool_t xdr_remote_vcpu_info (XDR *, remote_vcpu_info*); extern bool_t xdr_remote_sched_param_value (XDR *, remote_sched_param_value*); extern bool_t xdr_remote_sched_param (XDR *, remote_sched_param*); +extern bool_t xdr_remote_blkio_param_value (XDR *, remote_blkio_param_value*); +extern bool_t xdr_remote_blkio_param (XDR *, remote_blkio_param*); extern bool_t xdr_remote_memory_param_value (XDR *, remote_memory_param_value*); extern bool_t xdr_remote_memory_param (XDR *, remote_memory_param*); extern bool_t xdr_remote_open_args (XDR *, remote_open_args*); @@ -2410,6 +2460,9 @@ extern bool_t xdr_remote_domain_get_scheduler_type_ret (XDR *, remote_domain_ge extern bool_t xdr_remote_domain_get_scheduler_parameters_args (XDR *, remote_domain_get_scheduler_parameters_args*); extern bool_t xdr_remote_domain_get_scheduler_parameters_ret (XDR *, remote_domain_get_scheduler_parameters_ret*); extern bool_t xdr_remote_domain_set_scheduler_parameters_args (XDR *, remote_domain_set_scheduler_parameters_args*); +extern bool_t xdr_remote_domain_set_blkio_parameters_args (XDR *, remote_domain_set_blkio_parameters_args*); +extern bool_t xdr_remote_domain_get_blkio_parameters_args (XDR *, remote_domain_get_blkio_parameters_args*); +extern bool_t xdr_remote_domain_get_blkio_parameters_ret (XDR *, remote_domain_get_blkio_parameters_ret*); extern bool_t xdr_remote_domain_set_memory_parameters_args (XDR *, remote_domain_set_memory_parameters_args*); extern bool_t xdr_remote_domain_get_memory_parameters_args (XDR *, remote_domain_get_memory_parameters_args*); extern bool_t xdr_remote_domain_get_memory_parameters_ret (XDR *, remote_domain_get_memory_parameters_ret*); @@ -2734,6 +2787,8 @@ extern bool_t xdr_remote_auth_type (); extern bool_t xdr_remote_vcpu_info (); extern bool_t xdr_remote_sched_param_value (); extern bool_t xdr_remote_sched_param (); +extern bool_t xdr_remote_blkio_param_value (); +extern bool_t xdr_remote_blkio_param (); extern bool_t xdr_remote_memory_param_value (); extern bool_t xdr_remote_memory_param (); extern bool_t xdr_remote_open_args (); diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index e77aca1..334c672 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -128,6 +128,9 @@ const REMOTE_NWFILTER_NAME_LIST_MAX = 1024; /* Upper limit on list of scheduler parameters. */ const REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX = 16; +/* Upper limit on list of blkio parameters. */ +const REMOTE_DOMAIN_blkio_PARAMETERS_MAX = 16; + /* Upper limit on list of memory parameters. */ const REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX = 16; @@ -316,6 +319,26 @@ struct remote_sched_param { remote_sched_param_value value; }; +union remote_blkio_param_value switch (int type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + int i; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + unsigned int ui; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + hyper l; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + unsigned hyper ul; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + double d; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + int b; +}; + +struct remote_blkio_param { + remote_nonnull_string field; + remote_blkio_param_value value; +}; + union remote_memory_param_value switch (int type) { case VIR_DOMAIN_MEMORY_PARAM_INT: int i; @@ -453,6 +476,23 @@ struct remote_domain_set_scheduler_parameters_args { remote_sched_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>; }; +struct remote_domain_set_blkio_parameters_args { + remote_nonnull_domain dom; + remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>; + unsigned int flags; +}; + +struct remote_domain_get_blkio_parameters_args { + remote_nonnull_domain dom; + int nparams; + unsigned int flags; +}; + +struct remote_domain_get_blkio_parameters_ret { + remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>; + int nparams; +}; + struct remote_domain_set_memory_parameters_args { remote_nonnull_domain dom; remote_memory_param params<REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX>; @@ -2103,7 +2143,9 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, REMOTE_PROC_DOMAIN_IS_UPDATED = 202, - REMOTE_PROC_GET_SYSINFO = 203 + REMOTE_PROC_GET_SYSINFO = 203, + REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 204, + REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 205 /* * Notice how the entries are grouped in sets of 10 ? -- 1.7.1

Documents for blkiotune Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..56bf22f 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,11 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element. +=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio cgroup parameters. LXC and QEMU/KVM supports +I<--weight>. + =item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes> optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit> B<kilobytes> -I<--min-guarantee> B<kilobytes> -- 1.7.1

于 2011年02月16日 12:07, Gui Jianfeng 写道:
Documents for blkiotune
Signed-off-by: Gui Jianfeng<guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..56bf22f 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,11 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML<memory> element.
+=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio cgroup parameters. LXC and QEMU/KVM supports +I<--weight>. +
From your patches, no implementations for LXC driver yet. So perhaps shouldn't mention LXC here.
=item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes> optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit> B<kilobytes> -I<--min-guarantee> B<kilobytes>

Osier Yang wrote:
于 2011年02月16日 12:07, Gui Jianfeng 写道:
Documents for blkiotune
Signed-off-by: Gui Jianfeng<guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..56bf22f 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,11 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML<memory> element.
+=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio cgroup parameters. LXC and QEMU/KVM supports +I<--weight>. +
From your patches, no implementations for LXC driver yet. So perhaps shouldn't mention LXC here.
Thanks for reviewing Yang,will update All. Thanks, Gui
=item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes> optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit> B<kilobytes> -I<--min-guarantee> B<kilobytes>

Documents for blkiotune. Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..014d953 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,10 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element. +=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio cgroup parameters. QEMU/KVM supports I<--weight>. + =item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes> optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit> B<kilobytes> -I<--min-guarantee> B<kilobytes> -- 1.7.1

On 02/17/2011 07:05 PM, Gui Jianfeng wrote:
Documents for blkiotune.
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..014d953 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,10 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element.
+=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio cgroup parameters. QEMU/KVM supports I<--weight>. +
Is it worth listing the range 100-1000? (Am I right on that range?) -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Eric Blake wrote:
On 02/17/2011 07:05 PM, Gui Jianfeng wrote:
Documents for blkiotune.
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..014d953 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,10 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element.
+=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio cgroup parameters. QEMU/KVM supports I<--weight>. +
Is it worth listing the range 100-1000? (Am I right on that range?)
Yes, range is [100, 1000] now. listing the range here makes more sense i think. Thanks, Gui

Eric Blake wrote:
On 02/17/2011 07:05 PM, Gui Jianfeng wrote:
Documents for blkiotune.
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..014d953 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,10 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element.
+=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio cgroup parameters. QEMU/KVM supports I<--weight>. +
Is it worth listing the range 100-1000? (Am I right on that range?)
Update it. From: Gui Jianfeng <guijianfeng@cn.fujitsu.com> Documents for blkiotune Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..83a86af 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,11 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element. +=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio cgroup parameters. QEMU/KVM supports I<--weight>. +I<--weight> is in range [100, 1000]. + =item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes> optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit> B<kilobytes> -I<--min-guarantee> B<kilobytes> -- 1.7.1

On Wed, Feb 16, 2011 at 11:53:06AM +0800, Gui Jianfeng wrote:
Hi All,
This series implements a new command "blkiotune" for virsh. A lot of code borrows from memtune. You are able to tune blkio cgroup tunables by this command as follows.
Show tunables #virsh blkiotune My_guest weight : 900
Tune tunables(Set IO weight) #virsh blkiotune My_guest --weight 500 #virsh blkiotune My_guest weight : 500
Okay, I reviewed the patch set, it looks okay to me, one could discuss the need to go for something as generic a parameters for memeory when there is only one parameter (right now) but since this is likely to expand in the future, that's fine. I suggest you rebase your patch set to the current git head, fix for example src/libvirt_public.syms since we are past 0.8.8, and drop any mention of cgroup in the comments or documentation since that API is generic and doesn't need to be tied to that specific implentation used for QEmu, for example if there is something equivalent to tune Block I/Os in VMWare it's very unlikely to be based on cgroups :-) thanks ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Daniel Veillard wrote:
On Wed, Feb 16, 2011 at 11:53:06AM +0800, Gui Jianfeng wrote:
Hi All,
This series implements a new command "blkiotune" for virsh. A lot of code borrows from memtune. You are able to tune blkio cgroup tunables by this command as follows.
Show tunables #virsh blkiotune My_guest weight : 900
Tune tunables(Set IO weight) #virsh blkiotune My_guest --weight 500 #virsh blkiotune My_guest weight : 500
Okay, I reviewed the patch set, it looks okay to me, one could discuss the need to go for something as generic a parameters for memeory when there is only one parameter (right now) but since this is likely to expand in the future, that's fine. I suggest you rebase your patch set to the current git head, fix for example src/libvirt_public.syms since we are past 0.8.8, and drop any mention of cgroup in the comments or documentation since that API is generic and doesn't need to be tied to that specific implentation used for QEmu, for example if there is something equivalent to tune Block I/Os in VMWare it's very unlikely to be based on cgroups :-)
Okay, Daniel, Will update and rebase to current git head. Thanks Gui
thanks !
Daniel

Add virDomainSetBlkioParameters virDomainGetBlkioParameters Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- .gnulib | 2 +- include/libvirt/libvirt.h.in | 67 +++++++++++++++++++++++++++++++++++++++ python/generator.py | 2 + python/libvirt-override-api.xml | 12 +++++++ python/libvirt-override.c | 17 ++++++++++ 5 files changed, 99 insertions(+), 1 deletions(-) diff --git a/.gnulib b/.gnulib index 17adb5d..ecb020f 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 17adb5d75404cf6cdde0eb3b2edc6110d9fa8001 +Subproject commit ecb020f2b046790d76d05d377ca1e864e2bc9fdc diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 5dfb752..819c700 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -676,6 +676,73 @@ int virDomainGetInfo (virDomainPtr domain, */ char * virDomainGetSchedulerType(virDomainPtr domain, int *nparams); +/** + * virDomainBlkioParameterType: + * + * A blkio parameter field type + */ +typedef enum { + VIR_DOMAIN_BLKIO_PARAM_INT = 1, /* integer case */ + VIR_DOMAIN_BLKIO_PARAM_UINT = 2, /* unsigned integer case */ + VIR_DOMAIN_BLKIO_PARAM_LLONG = 3, /* long long case */ + VIR_DOMAIN_BLKIO_PARAM_ULLONG = 4, /* unsigned long long case */ + VIR_DOMAIN_BLKIO_PARAM_DOUBLE = 5, /* double case */ + VIR_DOMAIN_BLKIO_PARAM_BOOLEAN = 6 /* boolean(character) case */ +} virBlkioParameterType; + +/** + * VIR_DOMAIN_BLKIO_FIELD_LENGTH: + * + * Macro providing the field length of virBlkioParameter + */ + +#define VIR_DOMAIN_BLKIO_FIELD_LENGTH 80 + +/** + * VIR_DOMAIN_BLKIO_WEIGHT: + * + * Macro for the Blkio tunable weight: it represents the io weight + * the guest can use. + */ + +#define VIR_DOMAIN_BLKIO_WEIGHT "weight" + +/** + * virDomainBlkioParameter: + * + * a virDomainBlkioParameter is the set of blkio parameteer + */ + +typedef struct _virBlkioParameter virBlkioParameter; + +struct _virBlkioParameter { + char field[VIR_DOMAIN_BLKIO_FIELD_LENGTH]; /* parameter name */ + int type; /* parameter type */ + union { + int i; /* data for integer case */ + unsigned int ui; /* data for unsigned integer case */ + long long int l; /* data for long long integer case */ + unsigned long long int ul; /* data for unsigned long long integer case */ + double d; /* data for double case */ + char b; /* data for char case */ + } value; /* parameter value */ +}; + +/** + * virBlkioParameterPtr: + * + * a virBlkioParameterPtr is a pointer to a virBlkioParameter structure. + */ + +typedef virBlkioParameter *virBlkioParameterPtr; + +/* Set Blkio tunables for the domain*/ +int virDomainSetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, unsigned int flags); +int virDomainGetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, unsigned int flags); /** * virDomainMemoryParameterType: diff --git a/python/generator.py b/python/generator.py index ee9dfe4..6f4bb40 100755 --- a/python/generator.py +++ b/python/generator.py @@ -306,6 +306,8 @@ skip_impl = ( 'virDomainGetSchedulerType', 'virDomainGetSchedulerParameters', 'virDomainSetSchedulerParameters', + 'virDomainSetBlkioParameters', + 'virDomainGetBlkioParameters', 'virDomainSetMemoryParameters', 'virDomainGetMemoryParameters', 'virDomainGetVcpus', diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index f209608..54deeb5 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -162,6 +162,18 @@ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> <arg name='params' type='virSchedParameterPtr' info='pointer to scheduler parameter objects'/> </function> + <function name='virDomainSetBlkioParameters' file='python'> + <info>Change the blkio tunables</info> + <return type='int' info='-1 in case of error, 0 in case of success.'/> + <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> + <arg name='params' type='virBlkioParameterPtr' info='pointer to blkio tunable objects'/> + </function> + <function name='virDomainGetBlkioParameters' file='python'> + <info>Get the blkio parameters, the @params array will be filled with the values.</info> + <return type='int' info='-1 in case of error, 0 in case of success.'/> + <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> + <arg name='params' type='virBlkioParameterPtr' info='pointer to blkio tunable objects'/> + </function> <function name='virDomainSetMemoryParameters' file='python'> <info>Change the memory tunables</info> <return type='int' info='-1 in case of error, 0 in case of success.'/> diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 4a03d72..e09e2b5 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -371,6 +371,23 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, return VIR_PY_INT_SUCCESS; } + + + +/* FIXME: This is a place holder for the implementation. */ +static PyObject * +libvirt_virDomainSetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + return VIR_PY_INT_FAIL; +} + +/* FIXME: This is a place holder for the implementation. */ +static PyObject * +libvirt_virDomainGetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + return VIR_PY_INT_FAIL; +} + /* FIXME: This is a place holder for the implementation. */ static PyObject * libvirt_virDomainSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, -- 1.7.1

On 02/21/2011 02:21 AM, Gui Jianfeng wrote:
Add virDomainSetBlkioParameters virDomainGetBlkioParameters
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- .gnulib | 2 +-
That was unintended - it rewinds .gnulib backwards in time, which reintroduces some upstream gnulib bugs. To fix it, run another rebase, and mark this commit for edit. Then: git checkout HEAD^ .gnulib git submodule update
include/libvirt/libvirt.h.in | 67 +++++++++++++++++++++++++++++++++++++++ python/generator.py | 2 + python/libvirt-override-api.xml | 12 +++++++ python/libvirt-override.c | 17 ++++++++++ 5 files changed, 99 insertions(+), 1 deletions(-)
+ * virDomainBlkioParameter: + * + * a virDomainBlkioParameter is the set of blkio parameteer
s/parameteer/parameters/ -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Implements virDomainSetBlkioParameters and virDomainGetBlkioParameters and initialization Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/driver.h | 14 ++++++ src/esx/esx_driver.c | 2 + src/libvirt.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 +++ src/lxc/lxc_driver.c | 2 + src/openvz/openvz_driver.c | 2 + src/phyp/phyp_driver.c | 2 + src/qemu/qemu_driver.c | 2 + src/remote/remote_driver.c | 2 + src/test/test_driver.c | 2 + src/uml/uml_driver.c | 2 + src/vmware/vmware_driver.c | 2 + src/xen/xen_driver.c | 2 + 13 files changed, 148 insertions(+), 0 deletions(-) diff --git a/src/driver.h b/src/driver.h index 7451004..608efe9 100644 --- a/src/driver.h +++ b/src/driver.h @@ -135,6 +135,18 @@ typedef int (*virDrvDomainSetMemory) (virDomainPtr domain, unsigned long memory); typedef int + (*virDrvDomainSetBlkioParameters) + (virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, + unsigned int flags); +typedef int + (*virDrvDomainGetBlkioParameters) + (virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags); +typedef int (*virDrvDomainSetMemoryParameters) (virDomainPtr domain, virMemoryParameterPtr params, @@ -615,6 +627,8 @@ struct _virDriver { virDrvDomainSetMemoryParameters domainSetMemoryParameters; virDrvDomainGetMemoryParameters domainGetMemoryParameters; virDrvDomainOpenConsole domainOpenConsole; + virDrvDomainSetBlkioParameters domainSetBlkioParameters; + virDrvDomainGetBlkioParameters domainGetBlkioParameters; }; typedef int diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 116ad0f..675c266 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4655,6 +4655,8 @@ static virDriver esxDriver = { esxDomainSetMemoryParameters, /* domainSetMemoryParameters */ esxDomainGetMemoryParameters, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; diff --git a/src/libvirt.c b/src/libvirt.c index f65cc24..b79f3c2 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2847,6 +2847,114 @@ error: } /** + * virDomainSetBlkioParameters: + * @domain: pointer to domain object + * @params: pointer to blkio parameter objects + * @nparams: number of blkio parameter (this value should be same or + * less than the number of parameters supported) + * @flags: currently unused, for future extension + * + * Change the blkio tunables + * This function requires privileged access to the hypervisor. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainSetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%u", + params, nparams, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + if ((nparams <= 0) || (params == NULL)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainSetBlkioParameters) { + int ret; + ret = conn->driver->domainSetBlkioParameters (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** + * virDomainGetBlkioParameters: + * @domain: pointer to domain object + * @params: pointer to blkio parameter object + * (return value, allocated by the caller) + * @nparams: pointer to number of blkio parameters + * @flags: currently unused, for future extension + * + * Get the blkio parameters, the @params array will be filled with the values + * equal to the number of parameters suggested by @nparams + * + * This function requires privileged access to the hypervisor. This function + * expects the caller to allocate the @params. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainGetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%u", + params, (nparams) ? *nparams : -1, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if ((nparams == NULL) || (*nparams < 0)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainGetBlkioParameters) { + int ret; + ret = conn->driver->domainGetBlkioParameters (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + virLibConnError (VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** * virDomainSetMemoryParameters: * @domain: pointer to domain object * @params: pointer to memory parameter objects diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 1a45be1..9dea737 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -424,4 +424,10 @@ LIBVIRT_0.8.8 { virConnectGetSysinfo; } LIBVIRT_0.8.6; +LIBVIRT_0.8.9 { + global: + virDomainSetBlkioParameters; + virDomainGetBlkioParameters; +} LIBVIRT_0.8.8; + # .... define new API here using predicted next version number .... diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 0f78579..1940a16 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2930,6 +2930,8 @@ static virDriver lxcDriver = { lxcDomainSetMemoryParameters, /* domainSetMemoryParameters */ lxcDomainGetMemoryParameters, /* domainGetMemoryParameters */ lxcDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStateDriver lxcStateDriver = { diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 00d378a..5dec2c6 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1669,6 +1669,8 @@ static virDriver openvzDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; int openvzRegister(void) { diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index d954f2a..a93efde 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -4051,6 +4051,8 @@ static virDriver phypDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStorageDriver phypStorageDriver = { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0f25a2a..6b63ca1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6864,6 +6864,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 4ca0d3b..6d148f1 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -10946,6 +10946,8 @@ static virDriver remote_driver = { remoteDomainSetMemoryParameters, /* domainSetMemoryParameters */ remoteDomainGetMemoryParameters, /* domainGetMemoryParameters */ remoteDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virNetworkDriver network_driver = { diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 1937da0..081652d 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5443,6 +5443,8 @@ static virDriver testDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virNetworkDriver testNetworkDriver = { diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 2af8002..ef11070 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2245,6 +2245,8 @@ static virDriver umlDriver = { NULL, /* domainSetMemoryParamters */ NULL, /* domainGetMemoryParamters */ umlDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static int diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 22b29d1..37e3346 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -1005,6 +1005,8 @@ static virDriver vmwareDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; int diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index b14c8db..508ed40 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2101,6 +2101,8 @@ static virDriver xenUnifiedDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ xenUnifiedDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; /** -- 1.7.1

Implement domainSetBlkioParamters and domainGetBlkioParamters for QEmu Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/qemu/qemu_driver.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 160 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6b63ca1..7e5e00d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -110,6 +110,7 @@ # define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ #endif +#define QEMU_NB_BLKIO_PARAM 1 #define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000)) @@ -4435,6 +4436,163 @@ cleanup: return ret; } +static int qemuDomainSetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + int ret = -1; + + qemuDriverLock(driver); + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, _("blkio cgroup isn't mounted")); + goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + ret = 0; + for (i = 0; i < nparams; i++) { + virBlkioParameterPtr param = ¶ms[i]; + + if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) { + int rc; + if (param->type != VIR_DOMAIN_BLKIO_PARAM_UINT) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("invalid type for blkio weight tunable, expected a 'unsigned int'")); + ret = -1; + continue; + } + + if (params[i].value.ui > 1000 || params[i].value.ui < 100) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("out of blkio weight range.")); + ret = -1; + continue; + } + + rc = virCgroupSetBlkioWeight(group, params[i].value.ui); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to set blkio weight tunable")); + ret = -1; + } + } else { + qemuReportError(VIR_ERR_INVALID_ARG, + _("Parameter `%s' not supported"), param->field); + ret = -1; + } + } + +cleanup: + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} + +static int qemuDomainGetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + unsigned int val; + int ret = -1; + int rc; + + qemuDriverLock(driver); + + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, _("blkio cgroup isn't mounted")); + goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if ((*nparams) == 0) { + /* Current number of blkio parameters supported by cgroups */ + *nparams = QEMU_NB_BLKIO_PARAM; + ret = 0; + goto cleanup; + } + + if ((*nparams) != QEMU_NB_BLKIO_PARAM) { + qemuReportError(VIR_ERR_INVALID_ARG, + "%s", _("Invalid parameter count")); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + for (i = 0; i < *nparams; i++) { + virBlkioParameterPtr param = ¶ms[i]; + val = 0; + param->value.ui = 0; + param->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + switch(i) { + case 0: /* fill blkio weight here */ + rc = virCgroupGetBlkioWeight(group, &val); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to get blkio weight")); + goto cleanup; + } + if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Field blkio weight too long for destination")); + goto cleanup; + } + param->value.ui = val; + break; + + default: + break; + /* should not hit here */ + } + } + + ret = 0; + +cleanup: + if (group) + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} static int qemuDomainSetMemoryParameters(virDomainPtr dom, virMemoryParameterPtr params, @@ -6864,8 +7022,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ - NULL, /* domainSetBlkioParameters */ - NULL, /* domainGetBlkioParameters */ + qemuDomainSetBlkioParameters, /* domainSetBlkioParameters */ + qemuDomainGetBlkioParameters, /* domainGetBlkioParameters */ }; -- 1.7.1

On 02/21/2011 02:24 AM, Gui Jianfeng wrote:
Implement domainSetBlkioParamters and domainGetBlkioParamters for QEmu
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/qemu/qemu_driver.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 160 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6b63ca1..7e5e00d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -110,6 +110,7 @@ # define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ #endif
+#define QEMU_NB_BLKIO_PARAM 1
#define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000))
@@ -4435,6 +4436,163 @@ cleanup: return ret; }
+static int qemuDomainSetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int nparams, + unsigned int flags ATTRIBUTE_UNUSED)
New API should _not_ mark flags ATTRIBUTE_UNUSED. Rather, you should add...
+{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + int ret = -1; +
virCheckFlags(0, -1); That way, if we do add a flag in the future, then a new client that knows about the flag but talks to an older server that doesn't know about the flag will be properly rejected, rather than silently ignoring the unknown flag. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Adding blkiotune command to virsh tool Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 127 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index ce275f1..5d6e06e 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3010,6 +3010,132 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd) } /* + * "blkiotune" command + */ +static const vshCmdInfo info_blkiotune[] = { + {"help", N_("Get or set blkio parameters")}, + {"desc", N_("Get or set the current blkio parameters for a guest" \ + " domain.\n" \ + " To get the blkio parameters use following command: \n\n" \ + " virsh # blkiotune <domain>")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_blkiotune[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"weight", VSH_OT_INT, VSH_OFLAG_NONE, + N_("IO Weight in range [100, 1000]")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) +{ + virDomainPtr dom; + int weight; + int nparams = 0; + unsigned int i = 0; + virBlkioParameterPtr params = NULL, temp = NULL; + int ret = FALSE; + int found; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return FALSE; + + weight = vshCommandOptInt(cmd, "weight", &found); + if (found) { + nparams++; + if (weight < 0) { + virDomainFree(dom); + vshError(ctl, _("Invalid value of %d for I/O weight"), weight); + return FALSE; + } + } + + if (nparams == 0) { + /* get the number of blkio parameters */ + if (virDomainGetBlkioParameters(dom, NULL, &nparams, 0) != 0) { + vshError(ctl, "%s", + _("Unable to get number of blkio parameters")); + goto cleanup; + } + + if (nparams == 0) { + /* nothing to output */ + ret = TRUE; + goto cleanup; + } + + /* now go get all the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + if (virDomainGetBlkioParameters(dom, params, &nparams, 0) != 0) { + vshError(ctl, "%s", _("Unable to get blkio parameters")); + goto cleanup; + } + + for (i = 0; i < nparams; i++) { + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.i); + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + vshPrint(ctl, "%-15s: %u\n", params[i].field, + params[i].value.ui); + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + vshPrint(ctl, "%-15s: %lld\n", params[i].field, + params[i].value.l); + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + vshPrint(ctl, "%-15s: %llu\n", params[i].field, + params[i].value.ul); + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + vshPrint(ctl, "%-15s: %f\n", params[i].field, + params[i].value.d); + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.b); + break; + default: + vshPrint(ctl, "unimplemented blkio parameter type\n"); + } + } + + ret = TRUE; + } else { + /* set the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + + for (i = 0; i < nparams; i++) { + temp = ¶ms[i]; + temp->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + if (weight) { + temp->value.ui = (unsigned int)weight; + strncpy(temp->field, VIR_DOMAIN_BLKIO_WEIGHT, + sizeof(temp->field)); + weight = 0; + } + } + if (virDomainSetBlkioParameters(dom, params, nparams, 0) != 0) + vshError(ctl, "%s", _("Unable to change blkio parameters")); + else + ret = TRUE; + } + + cleanup: + VIR_FREE(params); + virDomainFree(dom); + return ret; +} + +/* * "memtune" command */ static const vshCmdInfo info_memtune[] = { @@ -10324,6 +10450,7 @@ static const vshCmdDef domManagementCmds[] = { {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, info_managedsaveremove}, {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune}, {"memtune", cmdMemtune, opts_memtune, info_memtune}, {"migrate", cmdMigrate, opts_migrate, info_migrate}, {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime}, -- 1.7.1

Remote protocol implementation of virDomainSetBlkioParameters and virDomainGetBlkioParameters. Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- daemon/remote.c | 210 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 2 + daemon/remote_dispatch_prototypes.h | 16 +++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 10 ++ src/remote/remote_driver.c | 173 ++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 89 +++++++++++++++ src/remote/remote_protocol.h | 55 +++++++++ src/remote/remote_protocol.x | 44 +++++++- 9 files changed, 597 insertions(+), 3 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index d53b466..b8e79f9 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2384,6 +2384,216 @@ remoteDispatchDomainSetMemory (struct qemud_server *server ATTRIBUTE_UNUSED, } static int +remoteDispatchDomainSetBlkioParameters(struct qemud_server *server + ATTRIBUTE_UNUSED, + struct qemud_client *client + ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header * + hdr ATTRIBUTE_UNUSED, + remote_error * rerr, + remote_domain_set_blkio_parameters_args + * args, void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom; + int i, r, nparams; + virBlkioParameterPtr params; + unsigned int flags; + + nparams = args->params.params_len; + flags = args->flags; + + if (nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) { + remoteDispatchFormatError(rerr, "%s", _("nparams too large")); + return -1; + } + if (VIR_ALLOC_N(params, nparams) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + + /* Deserialise parameters. */ + for (i = 0; i < nparams; ++i) { + if (virStrcpyStatic + (params[i].field, args->params.params_val[i].field) == NULL) { + remoteDispatchFormatError(rerr, + _ + ("Field %s too big for destination"), + args->params.params_val[i].field); + return -1; + } + params[i].type = args->params.params_val[i].value.type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + params[i].value.i = + args->params.params_val[i].value. + remote_blkio_param_value_u.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + params[i].value.ui = + args->params.params_val[i].value. + remote_blkio_param_value_u.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + params[i].value.l = + args->params.params_val[i].value. + remote_blkio_param_value_u.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + params[i].value.ul = + args->params.params_val[i].value. + remote_blkio_param_value_u.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + params[i].value.d = + args->params.params_val[i].value. + remote_blkio_param_value_u.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + params[i].value.b = + args->params.params_val[i].value. + remote_blkio_param_value_u.b; + break; + } + } + + dom = get_nonnull_domain(conn, args->dom); + if (dom == NULL) { + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + + r = virDomainSetBlkioParameters(dom, params, nparams, flags); + virDomainFree(dom); + VIR_FREE(params); + if (r == -1) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + return 0; +} + +static int +remoteDispatchDomainGetBlkioParameters(struct qemud_server *server + ATTRIBUTE_UNUSED, + struct qemud_client *client + ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header * + hdr ATTRIBUTE_UNUSED, + remote_error * rerr, + remote_domain_get_blkio_parameters_args + * args, + remote_domain_get_blkio_parameters_ret + * ret) +{ + virDomainPtr dom; + virBlkioParameterPtr params; + int i, r, nparams; + unsigned int flags; + + nparams = args->nparams; + flags = args->flags; + + if (nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) { + remoteDispatchFormatError(rerr, "%s", _("nparams too large")); + return -1; + } + if (VIR_ALLOC_N(params, nparams) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + + dom = get_nonnull_domain(conn, args->dom); + if (dom == NULL) { + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + + r = virDomainGetBlkioParameters(dom, params, &nparams, flags); + if (r == -1) { + virDomainFree(dom); + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + /* In this case, we need to send back the number of parameters + * supported + */ + if (args->nparams == 0) { + ret->nparams = nparams; + goto success; + } + + /* Serialise the blkio parameters. */ + ret->params.params_len = nparams; + if (VIR_ALLOC_N(ret->params.params_val, nparams) < 0) + goto oom; + + for (i = 0; i < nparams; ++i) { + // remoteDispatchClientRequest will free this: + ret->params.params_val[i].field = strdup(params[i].field); + if (ret->params.params_val[i].field == NULL) + goto oom; + + ret->params.params_val[i].value.type = params[i].type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.i = + params[i].value.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.ui = + params[i].value.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.l = + params[i].value.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.ul = + params[i].value.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.d = + params[i].value.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.b = + params[i].value.b; + break; + default: + remoteDispatchFormatError(rerr, "%s", _("unknown type")); + goto cleanup; + } + } + + success: + virDomainFree(dom); + VIR_FREE(params); + + return 0; + + oom: + remoteDispatchOOMError(rerr); + cleanup: + virDomainFree(dom); + for (i = 0; i < nparams; i++) + VIR_FREE(ret->params.params_val[i].field); + VIR_FREE(params); + return -1; +} + +static int remoteDispatchDomainSetMemoryParameters(struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h index 57962d1..e8b2a7e 100644 --- a/daemon/remote_dispatch_args.h +++ b/daemon/remote_dispatch_args.h @@ -172,3 +172,5 @@ remote_domain_open_console_args val_remote_domain_open_console_args; remote_domain_is_updated_args val_remote_domain_is_updated_args; remote_get_sysinfo_args val_remote_get_sysinfo_args; + remote_domain_set_blkio_parameters_args val_remote_domain_set_blkio_parameters_args; + remote_domain_get_blkio_parameters_args val_remote_domain_get_blkio_parameters_args; diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h index e59701a..692391b 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -218,6 +218,14 @@ static int remoteDispatchDomainGetAutostart( remote_error *err, remote_domain_get_autostart_args *args, remote_domain_get_autostart_ret *ret); +static int remoteDispatchDomainGetBlkioParameters( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_get_blkio_parameters_args *args, + remote_domain_get_blkio_parameters_ret *ret); static int remoteDispatchDomainGetBlockInfo( struct qemud_server *server, struct qemud_client *client, @@ -538,6 +546,14 @@ static int remoteDispatchDomainSetAutostart( remote_error *err, remote_domain_set_autostart_args *args, void *ret); +static int remoteDispatchDomainSetBlkioParameters( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_set_blkio_parameters_args *args, + void *ret); static int remoteDispatchDomainSetMaxMemory( struct qemud_server *server, struct qemud_client *client, diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h index 78e5469..114e832 100644 --- a/daemon/remote_dispatch_ret.h +++ b/daemon/remote_dispatch_ret.h @@ -139,3 +139,4 @@ remote_domain_get_vcpus_flags_ret val_remote_domain_get_vcpus_flags_ret; remote_domain_is_updated_ret val_remote_domain_is_updated_ret; remote_get_sysinfo_ret val_remote_get_sysinfo_ret; + remote_domain_get_blkio_parameters_ret val_remote_domain_get_blkio_parameters_ret; diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h index 5d27390..627e8a8 100644 --- a/daemon/remote_dispatch_table.h +++ b/daemon/remote_dispatch_table.h @@ -1022,3 +1022,13 @@ .args_filter = (xdrproc_t) xdr_remote_get_sysinfo_args, .ret_filter = (xdrproc_t) xdr_remote_get_sysinfo_ret, }, +{ /* DomainSetBlkioParameters => 204 */ + .fn = (dispatch_fn) remoteDispatchDomainSetBlkioParameters, + .args_filter = (xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + .ret_filter = (xdrproc_t) xdr_void, +}, +{ /* DomainGetBlkioParameters => 205 */ + .fn = (dispatch_fn) remoteDispatchDomainGetBlkioParameters, + .args_filter = (xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, + .ret_filter = (xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, +}, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 6d148f1..ff39da0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -2445,6 +2445,175 @@ done: } static int +remoteDomainSetBlkioParameters (virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, + unsigned int flags) +{ + int rv = -1; + remote_domain_set_blkio_parameters_args args; + int i, do_error; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + + /* Serialise the blkio parameters. */ + args.params.params_len = nparams; + args.flags = flags; + if (VIR_ALLOC_N(args.params.params_val, nparams) < 0) { + virReportOOMError(); + goto done; + } + + do_error = 0; + for (i = 0; i < nparams; ++i) { + // call() will free this: + args.params.params_val[i].field = strdup (params[i].field); + if (args.params.params_val[i].field == NULL) { + virReportOOMError(); + do_error = 1; + } + args.params.params_val[i].value.type = params[i].type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + args.params.params_val[i].value.remote_blkio_param_value_u.i = + params[i].value.i; break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + args.params.params_val[i].value.remote_blkio_param_value_u.ui = + params[i].value.ui; break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + args.params.params_val[i].value.remote_blkio_param_value_u.l = + params[i].value.l; break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + args.params.params_val[i].value.remote_blkio_param_value_u.ul = + params[i].value.ul; break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + args.params.params_val[i].value.remote_blkio_param_value_u.d = + params[i].value.d; break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + args.params.params_val[i].value.remote_blkio_param_value_u.b = + params[i].value.b; break; + default: + remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type")); + do_error = 1; + } + } + + if (do_error) { + xdr_free ((xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + (char *) &args); + goto done; + } + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS, + (xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + (char *) &args, (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int +remoteDomainGetBlkioParameters (virDomainPtr domain, + virBlkioParameterPtr params, int *nparams, + unsigned int flags) +{ + int rv = -1; + remote_domain_get_blkio_parameters_args args; + remote_domain_get_blkio_parameters_ret ret; + int i = -1; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + args.nparams = *nparams; + args.flags = flags; + + memset (&ret, 0, sizeof ret); + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS, + (xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, (char *) &args, + (xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, (char *) &ret) == -1) + goto done; + + /* Check the length of the returned list carefully. */ + if (ret.params.params_len > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX || + ret.params.params_len > *nparams) { + remoteError(VIR_ERR_RPC, "%s", + _("remoteDomainGetBlkioParameters: " + "returned number of parameters exceeds limit")); + goto cleanup; + } + /* Handle the case when the caller does not know the number of parameters + * and is asking for the number of parameters supported + */ + if (*nparams == 0) { + *nparams = ret.nparams; + rv = 0; + goto cleanup; + } + + *nparams = ret.params.params_len; + + /* Deserialise the result. */ + for (i = 0; i < *nparams; ++i) { + if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) { + remoteError(VIR_ERR_INTERNAL_ERROR, + _("Parameter %s too big for destination"), + ret.params.params_val[i].field); + goto cleanup; + } + params[i].type = ret.params.params_val[i].value.type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + params[i].value.i = + ret.params.params_val[i].value.remote_blkio_param_value_u.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + params[i].value.ui = + ret.params.params_val[i].value.remote_blkio_param_value_u.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + params[i].value.l = + ret.params.params_val[i].value.remote_blkio_param_value_u.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + params[i].value.ul = + ret.params.params_val[i].value.remote_blkio_param_value_u.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + params[i].value.d = + ret.params.params_val[i].value.remote_blkio_param_value_u.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + params[i].value.b = + ret.params.params_val[i].value.remote_blkio_param_value_u.b; + break; + default: + remoteError(VIR_ERR_RPC, "%s", + _("remoteDomainGetBlkioParameters: " + "unknown parameter type")); + goto cleanup; + } + } + + rv = 0; + +cleanup: + xdr_free ((xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, + (char *) &ret); +done: + remoteDriverUnlock(priv); + return rv; +} + +static int remoteDomainSetMemoryParameters (virDomainPtr domain, virMemoryParameterPtr params, int nparams, @@ -10946,8 +11115,8 @@ static virDriver remote_driver = { remoteDomainSetMemoryParameters, /* domainSetMemoryParameters */ remoteDomainGetMemoryParameters, /* domainGetMemoryParameters */ remoteDomainOpenConsole, /* domainOpenConsole */ - NULL, /* domainSetBlkioParameters */ - NULL, /* domainGetBlkioParameters */ + remoteDomainSetBlkioParameters, /* domainSetBlkioParameters */ + remoteDomainGetBlkioParameters, /* domainGetBlkioParameters */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c index bae92ca..2a3daa6 100644 --- a/src/remote/remote_protocol.c +++ b/src/remote/remote_protocol.c @@ -308,6 +308,53 @@ xdr_remote_sched_param (XDR *xdrs, remote_sched_param *objp) } bool_t +xdr_remote_blkio_param_value (XDR *xdrs, remote_blkio_param_value *objp) +{ + + if (!xdr_int (xdrs, &objp->type)) + return FALSE; + switch (objp->type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + if (!xdr_u_int (xdrs, &objp->remote_blkio_param_value_u.ui)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + if (!xdr_int64_t (xdrs, &objp->remote_blkio_param_value_u.l)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + if (!xdr_uint64_t (xdrs, &objp->remote_blkio_param_value_u.ul)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + if (!xdr_double (xdrs, &objp->remote_blkio_param_value_u.d)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + if (!xdr_int (xdrs, &objp->remote_blkio_param_value_u.b)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +bool_t +xdr_remote_blkio_param (XDR *xdrs, remote_blkio_param *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->field)) + return FALSE; + if (!xdr_remote_blkio_param_value (xdrs, &objp->value)) + return FALSE; + return TRUE; +} + +bool_t xdr_remote_memory_param_value (XDR *xdrs, remote_memory_param_value *objp) { @@ -646,6 +693,48 @@ xdr_remote_domain_set_scheduler_parameters_args (XDR *xdrs, remote_domain_set_sc } bool_t +xdr_remote_domain_set_blkio_parameters_args (XDR *xdrs, remote_domain_set_blkio_parameters_args *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->params.params_val; + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->params.params_len, REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX, + sizeof (remote_blkio_param), (xdrproc_t) xdr_remote_blkio_param)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_blkio_parameters_args (XDR *xdrs, remote_domain_get_blkio_parameters_args *objp) +{ + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_int (xdrs, &objp->nparams)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_blkio_parameters_ret (XDR *xdrs, remote_domain_get_blkio_parameters_ret *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->params.params_val; + + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->params.params_len, REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX, + sizeof (remote_blkio_param), (xdrproc_t) xdr_remote_blkio_param)) + return FALSE; + if (!xdr_int (xdrs, &objp->nparams)) + return FALSE; + return TRUE; +} + + +bool_t xdr_remote_domain_set_memory_parameters_args (XDR *xdrs, remote_domain_set_memory_parameters_args *objp) { char **objp_cpp0 = (char **) (void *) &objp->params.params_val; diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h index 46d526a..52a9d71 100644 --- a/src/remote/remote_protocol.h +++ b/src/remote/remote_protocol.h @@ -53,6 +53,7 @@ typedef remote_nonnull_string *remote_string; #define REMOTE_NODE_DEVICE_CAPS_LIST_MAX 16384 #define REMOTE_NWFILTER_NAME_LIST_MAX 1024 #define REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX 16 +#define REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX 16 #define REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX 16 #define REMOTE_NODE_MAX_CELLS 1024 #define REMOTE_AUTH_SASL_DATA_MAX 65536 @@ -187,6 +188,25 @@ struct remote_sched_param { }; typedef struct remote_sched_param remote_sched_param; +struct remote_blkio_param_value { + int type; + union { + int i; + u_int ui; + int64_t l; + uint64_t ul; + double d; + int b; + } remote_blkio_param_value_u; +}; +typedef struct remote_blkio_param_value remote_blkio_param_value; + +struct remote_blkio_param { + remote_nonnull_string field; + remote_blkio_param_value value; +}; +typedef struct remote_blkio_param remote_blkio_param; + struct remote_memory_param_value { int type; union { @@ -337,6 +357,32 @@ struct remote_domain_set_scheduler_parameters_args { }; typedef struct remote_domain_set_scheduler_parameters_args remote_domain_set_scheduler_parameters_args; +struct remote_domain_set_blkio_parameters_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_blkio_param *params_val; + } params; + u_int flags; +}; +typedef struct remote_domain_set_blkio_parameters_args remote_domain_set_blkio_parameters_args; + +struct remote_domain_get_blkio_parameters_args { + remote_nonnull_domain dom; + int nparams; + u_int flags; +}; +typedef struct remote_domain_get_blkio_parameters_args remote_domain_get_blkio_parameters_args; + +struct remote_domain_get_blkio_parameters_ret { + struct { + u_int params_len; + remote_blkio_param *params_val; + } params; + int nparams; +}; +typedef struct remote_domain_get_blkio_parameters_ret remote_domain_get_blkio_parameters_ret; + struct remote_domain_set_memory_parameters_args { remote_nonnull_domain dom; struct { @@ -2331,6 +2377,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, REMOTE_PROC_DOMAIN_IS_UPDATED = 202, REMOTE_PROC_GET_SYSINFO = 203, + REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 204, + REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 205, }; typedef enum remote_procedure remote_procedure; @@ -2386,6 +2434,8 @@ extern bool_t xdr_remote_auth_type (XDR *, remote_auth_type*); extern bool_t xdr_remote_vcpu_info (XDR *, remote_vcpu_info*); extern bool_t xdr_remote_sched_param_value (XDR *, remote_sched_param_value*); extern bool_t xdr_remote_sched_param (XDR *, remote_sched_param*); +extern bool_t xdr_remote_blkio_param_value (XDR *, remote_blkio_param_value*); +extern bool_t xdr_remote_blkio_param (XDR *, remote_blkio_param*); extern bool_t xdr_remote_memory_param_value (XDR *, remote_memory_param_value*); extern bool_t xdr_remote_memory_param (XDR *, remote_memory_param*); extern bool_t xdr_remote_open_args (XDR *, remote_open_args*); @@ -2410,6 +2460,9 @@ extern bool_t xdr_remote_domain_get_scheduler_type_ret (XDR *, remote_domain_ge extern bool_t xdr_remote_domain_get_scheduler_parameters_args (XDR *, remote_domain_get_scheduler_parameters_args*); extern bool_t xdr_remote_domain_get_scheduler_parameters_ret (XDR *, remote_domain_get_scheduler_parameters_ret*); extern bool_t xdr_remote_domain_set_scheduler_parameters_args (XDR *, remote_domain_set_scheduler_parameters_args*); +extern bool_t xdr_remote_domain_set_blkio_parameters_args (XDR *, remote_domain_set_blkio_parameters_args*); +extern bool_t xdr_remote_domain_get_blkio_parameters_args (XDR *, remote_domain_get_blkio_parameters_args*); +extern bool_t xdr_remote_domain_get_blkio_parameters_ret (XDR *, remote_domain_get_blkio_parameters_ret*); extern bool_t xdr_remote_domain_set_memory_parameters_args (XDR *, remote_domain_set_memory_parameters_args*); extern bool_t xdr_remote_domain_get_memory_parameters_args (XDR *, remote_domain_get_memory_parameters_args*); extern bool_t xdr_remote_domain_get_memory_parameters_ret (XDR *, remote_domain_get_memory_parameters_ret*); @@ -2734,6 +2787,8 @@ extern bool_t xdr_remote_auth_type (); extern bool_t xdr_remote_vcpu_info (); extern bool_t xdr_remote_sched_param_value (); extern bool_t xdr_remote_sched_param (); +extern bool_t xdr_remote_blkio_param_value (); +extern bool_t xdr_remote_blkio_param (); extern bool_t xdr_remote_memory_param_value (); extern bool_t xdr_remote_memory_param (); extern bool_t xdr_remote_open_args (); diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index e77aca1..334c672 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -128,6 +128,9 @@ const REMOTE_NWFILTER_NAME_LIST_MAX = 1024; /* Upper limit on list of scheduler parameters. */ const REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX = 16; +/* Upper limit on list of blkio parameters. */ +const REMOTE_DOMAIN_blkio_PARAMETERS_MAX = 16; + /* Upper limit on list of memory parameters. */ const REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX = 16; @@ -316,6 +319,26 @@ struct remote_sched_param { remote_sched_param_value value; }; +union remote_blkio_param_value switch (int type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + int i; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + unsigned int ui; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + hyper l; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + unsigned hyper ul; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + double d; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + int b; +}; + +struct remote_blkio_param { + remote_nonnull_string field; + remote_blkio_param_value value; +}; + union remote_memory_param_value switch (int type) { case VIR_DOMAIN_MEMORY_PARAM_INT: int i; @@ -453,6 +476,23 @@ struct remote_domain_set_scheduler_parameters_args { remote_sched_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>; }; +struct remote_domain_set_blkio_parameters_args { + remote_nonnull_domain dom; + remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>; + unsigned int flags; +}; + +struct remote_domain_get_blkio_parameters_args { + remote_nonnull_domain dom; + int nparams; + unsigned int flags; +}; + +struct remote_domain_get_blkio_parameters_ret { + remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>; + int nparams; +}; + struct remote_domain_set_memory_parameters_args { remote_nonnull_domain dom; remote_memory_param params<REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX>; @@ -2103,7 +2143,9 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, REMOTE_PROC_DOMAIN_IS_UPDATED = 202, - REMOTE_PROC_GET_SYSINFO = 203 + REMOTE_PROC_GET_SYSINFO = 203, + REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 204, + REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 205 /* * Notice how the entries are grouped in sets of 10 ? -- 1.7.1

On 02/21/2011 02:28 AM, Gui Jianfeng wrote:
Remote protocol implementation of virDomainSetBlkioParameters and virDomainGetBlkioParameters.
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- daemon/remote.c | 210 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 2 + daemon/remote_dispatch_prototypes.h | 16 +++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 10 ++ src/remote/remote_driver.c | 173 ++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 89 +++++++++++++++ src/remote/remote_protocol.h | 55 +++++++++ src/remote/remote_protocol.x | 44 +++++++- 9 files changed, 597 insertions(+), 3 deletions(-)
If you will install the dwarves package for pdwtags, then 'make check' will alert you to the fact that you also need to patch src/remote_protocol-structs to make it clear that the API is pure addition. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Thanks Eric, Will update. Gui Eric Blake wrote:
On 02/21/2011 02:28 AM, Gui Jianfeng wrote:
Remote protocol implementation of virDomainSetBlkioParameters and virDomainGetBlkioParameters.
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- daemon/remote.c | 210 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 2 + daemon/remote_dispatch_prototypes.h | 16 +++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 10 ++ src/remote/remote_driver.c | 173 ++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 89 +++++++++++++++ src/remote/remote_protocol.h | 55 +++++++++ src/remote/remote_protocol.x | 44 +++++++- 9 files changed, 597 insertions(+), 3 deletions(-)
If you will install the dwarves package for pdwtags, then 'make check' will alert you to the fact that you also need to patch src/remote_protocol-structs to make it clear that the API is pure addition.

Add virDomainSetBlkioParameters virDomainGetBlkioParameters Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- include/libvirt/libvirt.h.in | 67 +++++++++++++++++++++++++++++++++++++++ python/generator.py | 2 + python/libvirt-override-api.xml | 12 +++++++ python/libvirt-override.c | 17 ++++++++++ 4 files changed, 98 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 5dfb752..819c700 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -676,6 +676,73 @@ int virDomainGetInfo (virDomainPtr domain, */ char * virDomainGetSchedulerType(virDomainPtr domain, int *nparams); +/** + * virDomainBlkioParameterType: + * + * A blkio parameter field type + */ +typedef enum { + VIR_DOMAIN_BLKIO_PARAM_INT = 1, /* integer case */ + VIR_DOMAIN_BLKIO_PARAM_UINT = 2, /* unsigned integer case */ + VIR_DOMAIN_BLKIO_PARAM_LLONG = 3, /* long long case */ + VIR_DOMAIN_BLKIO_PARAM_ULLONG = 4, /* unsigned long long case */ + VIR_DOMAIN_BLKIO_PARAM_DOUBLE = 5, /* double case */ + VIR_DOMAIN_BLKIO_PARAM_BOOLEAN = 6 /* boolean(character) case */ +} virBlkioParameterType; + +/** + * VIR_DOMAIN_BLKIO_FIELD_LENGTH: + * + * Macro providing the field length of virBlkioParameter + */ + +#define VIR_DOMAIN_BLKIO_FIELD_LENGTH 80 + +/** + * VIR_DOMAIN_BLKIO_WEIGHT: + * + * Macro for the Blkio tunable weight: it represents the io weight + * the guest can use. + */ + +#define VIR_DOMAIN_BLKIO_WEIGHT "weight" + +/** + * virDomainBlkioParameter: + * + * a virDomainBlkioParameter is the set of blkio parameteer + */ + +typedef struct _virBlkioParameter virBlkioParameter; + +struct _virBlkioParameter { + char field[VIR_DOMAIN_BLKIO_FIELD_LENGTH]; /* parameter name */ + int type; /* parameter type */ + union { + int i; /* data for integer case */ + unsigned int ui; /* data for unsigned integer case */ + long long int l; /* data for long long integer case */ + unsigned long long int ul; /* data for unsigned long long integer case */ + double d; /* data for double case */ + char b; /* data for char case */ + } value; /* parameter value */ +}; + +/** + * virBlkioParameterPtr: + * + * a virBlkioParameterPtr is a pointer to a virBlkioParameter structure. + */ + +typedef virBlkioParameter *virBlkioParameterPtr; + +/* Set Blkio tunables for the domain*/ +int virDomainSetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, unsigned int flags); +int virDomainGetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, unsigned int flags); /** * virDomainMemoryParameterType: diff --git a/python/generator.py b/python/generator.py index ee9dfe4..6f4bb40 100755 --- a/python/generator.py +++ b/python/generator.py @@ -306,6 +306,8 @@ skip_impl = ( 'virDomainGetSchedulerType', 'virDomainGetSchedulerParameters', 'virDomainSetSchedulerParameters', + 'virDomainSetBlkioParameters', + 'virDomainGetBlkioParameters', 'virDomainSetMemoryParameters', 'virDomainGetMemoryParameters', 'virDomainGetVcpus', diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index f209608..54deeb5 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -162,6 +162,18 @@ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> <arg name='params' type='virSchedParameterPtr' info='pointer to scheduler parameter objects'/> </function> + <function name='virDomainSetBlkioParameters' file='python'> + <info>Change the blkio tunables</info> + <return type='int' info='-1 in case of error, 0 in case of success.'/> + <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> + <arg name='params' type='virBlkioParameterPtr' info='pointer to blkio tunable objects'/> + </function> + <function name='virDomainGetBlkioParameters' file='python'> + <info>Get the blkio parameters, the @params array will be filled with the values.</info> + <return type='int' info='-1 in case of error, 0 in case of success.'/> + <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> + <arg name='params' type='virBlkioParameterPtr' info='pointer to blkio tunable objects'/> + </function> <function name='virDomainSetMemoryParameters' file='python'> <info>Change the memory tunables</info> <return type='int' info='-1 in case of error, 0 in case of success.'/> diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 4a03d72..e09e2b5 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -371,6 +371,23 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, return VIR_PY_INT_SUCCESS; } + + + +/* FIXME: This is a place holder for the implementation. */ +static PyObject * +libvirt_virDomainSetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + return VIR_PY_INT_FAIL; +} + +/* FIXME: This is a place holder for the implementation. */ +static PyObject * +libvirt_virDomainGetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + return VIR_PY_INT_FAIL; +} + /* FIXME: This is a place holder for the implementation. */ static PyObject * libvirt_virDomainSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, -- 1.7.1

On 02/21/2011 10:30 PM, Gui Jianfeng wrote:
Add virDomainSetBlkioParameters virDomainGetBlkioParameters
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com>
+/** + * virDomainBlkioParameter: + * + * a virDomainBlkioParameter is the set of blkio parameteer
s/parameteer/parameters/
+++ b/python/libvirt-override.c @@ -371,6 +371,23 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, return VIR_PY_INT_SUCCESS; }
+ + + +/* FIXME: This is a place holder for the implementation. */ +static PyObject * +libvirt_virDomainSetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + return VIR_PY_INT_FAIL; +} + +/* FIXME: This is a place holder for the implementation. */ +static PyObject * +libvirt_virDomainGetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + return VIR_PY_INT_FAIL; +} +
This fails to compile with --enable-compile-warnings=error: CC libvirtmod_la-libvirt-override.lo cc1: warnings being treated as errors libvirt-override.c:379:1: error: 'libvirt_virDomainSetBlkioParameters' defined but not used [-Wunused-function] libvirt-override.c:386:1: error: 'libvirt_virDomainGetBlkioParameters' defined but not used [-Wunused-function] You missed: diff --git i/python/libvirt-override.c w/python/libvirt-override.c index e09e2b5..4a9b432 100644 --- i/python/libvirt-override.c +++ w/python/libvirt-override.c @@ -4,7 +4,7 @@ * entry points where an automatically generated stub is * unpractical * - * Copyright (C) 2005, 2007-2010 Red Hat, Inc. + * Copyright (C) 2005, 2007-2011 Red Hat, Inc. * * Daniel Veillard <veillard@redhat.com> */ @@ -3549,6 +3549,8 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virDomainGetSchedulerType", libvirt_virDomainGetSchedulerType, METH_VARARGS, NULL}, {(char *) "virDomainGetSchedulerParameters", libvirt_virDomainGetSchedulerParameters, METH_VARARGS, NULL}, {(char *) "virDomainSetSchedulerParameters", libvirt_virDomainSetSchedulerParameters, METH_VARARGS, NULL}, + {(char *) "virDomainSetBlkioParameters", libvirt_virDomainSetBlkioParameters, METH_VARARGS, NULL}, + {(char *) "virDomainGetBlkioParameters", libvirt_virDomainGetBlkioParameters, METH_VARARGS, NULL}, {(char *) "virDomainSetMemoryParameters", libvirt_virDomainSetMemoryParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetMemoryParameters", libvirt_virDomainGetMemoryParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetVcpus", libvirt_virDomainGetVcpus, METH_VARARGS, NULL}, ACK with those changes. I'll push this once I get through reviewing the rest of the series. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Implements virDomainSetBlkioParameters and virDomainGetBlkioParameters and initialization Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/driver.h | 14 ++++++ src/esx/esx_driver.c | 2 + src/libvirt.c | 108 +++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 ++ src/lxc/lxc_driver.c | 2 + src/opennebula/one_driver.c | 2 + src/openvz/openvz_driver.c | 2 + src/phyp/phyp_driver.c | 2 + src/qemu/qemu_driver.c | 2 + src/remote/remote_driver.c | 2 + src/test/test_driver.c | 2 + src/uml/uml_driver.c | 2 + src/vbox/vbox_tmpl.c | 2 + src/vmware/vmware_driver.c | 2 + src/xen/xen_driver.c | 2 + src/xenapi/xenapi_driver.c | 2 + 16 files changed, 154 insertions(+), 0 deletions(-) diff --git a/src/driver.h b/src/driver.h index 7451004..608efe9 100644 --- a/src/driver.h +++ b/src/driver.h @@ -135,6 +135,18 @@ typedef int (*virDrvDomainSetMemory) (virDomainPtr domain, unsigned long memory); typedef int + (*virDrvDomainSetBlkioParameters) + (virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, + unsigned int flags); +typedef int + (*virDrvDomainGetBlkioParameters) + (virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags); +typedef int (*virDrvDomainSetMemoryParameters) (virDomainPtr domain, virMemoryParameterPtr params, @@ -615,6 +627,8 @@ struct _virDriver { virDrvDomainSetMemoryParameters domainSetMemoryParameters; virDrvDomainGetMemoryParameters domainGetMemoryParameters; virDrvDomainOpenConsole domainOpenConsole; + virDrvDomainSetBlkioParameters domainSetBlkioParameters; + virDrvDomainGetBlkioParameters domainGetBlkioParameters; }; typedef int diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 116ad0f..675c266 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4655,6 +4655,8 @@ static virDriver esxDriver = { esxDomainSetMemoryParameters, /* domainSetMemoryParameters */ esxDomainGetMemoryParameters, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; diff --git a/src/libvirt.c b/src/libvirt.c index e4b451e..044255f 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2847,6 +2847,114 @@ error: } /** + * virDomainSetBlkioParameters: + * @domain: pointer to domain object + * @params: pointer to blkio parameter objects + * @nparams: number of blkio parameter (this value should be same or + * less than the number of parameters supported) + * @flags: currently unused, for future extension + * + * Change the blkio tunables + * This function requires privileged access to the hypervisor. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainSetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%u", + params, nparams, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + if ((nparams <= 0) || (params == NULL)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainSetBlkioParameters) { + int ret; + ret = conn->driver->domainSetBlkioParameters (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** + * virDomainGetBlkioParameters: + * @domain: pointer to domain object + * @params: pointer to blkio parameter object + * (return value, allocated by the caller) + * @nparams: pointer to number of blkio parameters + * @flags: currently unused, for future extension + * + * Get the blkio parameters, the @params array will be filled with the values + * equal to the number of parameters suggested by @nparams + * + * This function requires privileged access to the hypervisor. This function + * expects the caller to allocate the @params. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainGetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%u", + params, (nparams) ? *nparams : -1, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if ((nparams == NULL) || (*nparams < 0)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainGetBlkioParameters) { + int ret; + ret = conn->driver->domainGetBlkioParameters (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + virLibConnError (VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** * virDomainSetMemoryParameters: * @domain: pointer to domain object * @params: pointer to memory parameter objects diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 1a45be1..9dea737 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -424,4 +424,10 @@ LIBVIRT_0.8.8 { virConnectGetSysinfo; } LIBVIRT_0.8.6; +LIBVIRT_0.8.9 { + global: + virDomainSetBlkioParameters; + virDomainGetBlkioParameters; +} LIBVIRT_0.8.8; + # .... define new API here using predicted next version number .... diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index a17b0b6..a4fecc2 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2930,6 +2930,8 @@ static virDriver lxcDriver = { lxcDomainSetMemoryParameters, /* domainSetMemoryParameters */ lxcDomainGetMemoryParameters, /* domainGetMemoryParameters */ lxcDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStateDriver lxcStateDriver = { diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c index 75d7b9a..4069798 100644 --- a/src/opennebula/one_driver.c +++ b/src/opennebula/one_driver.c @@ -829,6 +829,8 @@ static virDriver oneDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStateDriver oneStateDriver = { diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 00d378a..5dec2c6 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1669,6 +1669,8 @@ static virDriver openvzDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; int openvzRegister(void) { diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index d954f2a..a93efde 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -4051,6 +4051,8 @@ static virDriver phypDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStorageDriver phypStorageDriver = { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0f25a2a..6b63ca1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6864,6 +6864,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 0be9c56..abee1c5 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -10946,6 +10946,8 @@ static virDriver remote_driver = { remoteDomainSetMemoryParameters, /* domainSetMemoryParameters */ remoteDomainGetMemoryParameters, /* domainGetMemoryParameters */ remoteDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virNetworkDriver network_driver = { diff --git a/src/test/test_driver.c b/src/test/test_driver.c index b168570..02748f8 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5443,6 +5443,8 @@ static virDriver testDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virNetworkDriver testNetworkDriver = { diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 2af8002..ef11070 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2245,6 +2245,8 @@ static virDriver umlDriver = { NULL, /* domainSetMemoryParamters */ NULL, /* domainGetMemoryParamters */ umlDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static int diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 1c4e46f..d4672f5 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -8644,6 +8644,8 @@ virDriver NAME(Driver) = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; virNetworkDriver NAME(NetworkDriver) = { diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 22b29d1..37e3346 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -1005,6 +1005,8 @@ static virDriver vmwareDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; int diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 979f9e0..ab48f73 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2112,6 +2112,8 @@ static virDriver xenUnifiedDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ xenUnifiedDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; /** diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 7851e93..8cf4d1c 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -1881,6 +1881,8 @@ static virDriver xenapiDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; /** -- 1.7.1

On 02/21/2011 10:31 PM, Gui Jianfeng wrote:
Implements virDomainSetBlkioParameters and virDomainGetBlkioParameters and initialization
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/driver.h | 14 ++++++ src/esx/esx_driver.c | 2 + src/libvirt.c | 108 +++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 ++
Merge conflicts; how fun.
+++ b/src/driver.h @@ -135,6 +135,18 @@ typedef int (*virDrvDomainSetMemory) (virDomainPtr domain, unsigned long memory); typedef int + (*virDrvDomainSetBlkioParameters)
...
+ unsigned int flags); +typedef int (*virDrvDomainSetMemoryParameters) (virDomainPtr domain, virMemoryParameterPtr params,
Maybe it's just me, but I'd rather see SetMemory, SetMemoryFlags, SetMemoryParameters all in a group, then SetBlkio after that. I rearranged your patch to order things differently.
@@ -615,6 +627,8 @@ struct _virDriver { virDrvDomainSetMemoryParameters domainSetMemoryParameters; virDrvDomainGetMemoryParameters domainGetMemoryParameters; virDrvDomainOpenConsole domainOpenConsole; + virDrvDomainSetBlkioParameters domainSetBlkioParameters; + virDrvDomainGetBlkioParameters domainGetBlkioParameters;
Likewise, here it's nicer to stick the related callbacks next to one another (SetMemoryFlags, SetMemoryParameters, SetBlkioParameters). That means I basically rewrote this patch. Oh well; at least it's a trivial reordering. Most of this code benefits from copy-and-paste from MemoryParameters. I wonder why :)
+++ b/src/libvirt_public.syms @@ -424,4 +424,10 @@ LIBVIRT_0.8.8 { virConnectGetSysinfo; } LIBVIRT_0.8.6;
+LIBVIRT_0.8.9 { + global: + virDomainSetBlkioParameters; + virDomainGetBlkioParameters; +} LIBVIRT_0.8.8;
I fixed this merge conflict, too. ACK as adjusted; again, I'll push once I finish applying your series (now that I've adjusted things, I'm sure to have merge conflicts with several remaining patches to trivially work out). -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Implement domainSetBlkioParamters and domainGetBlkioParamters for QEmu Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/qemu/qemu_driver.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 162 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6b63ca1..f489496 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -110,6 +110,7 @@ # define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ #endif +#define QEMU_NB_BLKIO_PARAM 1 #define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000)) @@ -4435,6 +4436,165 @@ cleanup: return ret; } +static int qemuDomainSetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int nparams, + unsigned int flags) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + int ret = -1; + + virCheckFlags(0, -1); + qemuDriverLock(driver); + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, _("blkio cgroup isn't mounted")); + goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + ret = 0; + for (i = 0; i < nparams; i++) { + virBlkioParameterPtr param = ¶ms[i]; + + if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) { + int rc; + if (param->type != VIR_DOMAIN_BLKIO_PARAM_UINT) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("invalid type for blkio weight tunable, expected a 'unsigned int'")); + ret = -1; + continue; + } + + if (params[i].value.ui > 1000 || params[i].value.ui < 100) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("out of blkio weight range.")); + ret = -1; + continue; + } + + rc = virCgroupSetBlkioWeight(group, params[i].value.ui); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to set blkio weight tunable")); + ret = -1; + } + } else { + qemuReportError(VIR_ERR_INVALID_ARG, + _("Parameter `%s' not supported"), param->field); + ret = -1; + } + } + +cleanup: + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} + +static int qemuDomainGetBlkioParameters(virDomainPtr dom, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags) +{ + struct qemud_driver *driver = dom->conn->privateData; + int i; + virCgroupPtr group = NULL; + virDomainObjPtr vm = NULL; + unsigned int val; + int ret = -1; + int rc; + + virCheckFlags(0, -1); + qemuDriverLock(driver); + + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { + qemuReportError(VIR_ERR_NO_SUPPORT, _("blkio cgroup isn't mounted")); + goto cleanup; + } + + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if ((*nparams) == 0) { + /* Current number of blkio parameters supported by cgroups */ + *nparams = QEMU_NB_BLKIO_PARAM; + ret = 0; + goto cleanup; + } + + if ((*nparams) != QEMU_NB_BLKIO_PARAM) { + qemuReportError(VIR_ERR_INVALID_ARG, + "%s", _("Invalid parameter count")); + goto cleanup; + } + + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), vm->def->name); + goto cleanup; + } + + for (i = 0; i < *nparams; i++) { + virBlkioParameterPtr param = ¶ms[i]; + val = 0; + param->value.ui = 0; + param->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + switch(i) { + case 0: /* fill blkio weight here */ + rc = virCgroupGetBlkioWeight(group, &val); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to get blkio weight")); + goto cleanup; + } + if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Field blkio weight too long for destination")); + goto cleanup; + } + param->value.ui = val; + break; + + default: + break; + /* should not hit here */ + } + } + + ret = 0; + +cleanup: + if (group) + virCgroupFree(&group); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} static int qemuDomainSetMemoryParameters(virDomainPtr dom, virMemoryParameterPtr params, @@ -6864,8 +7024,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ - NULL, /* domainSetBlkioParameters */ - NULL, /* domainGetBlkioParameters */ + qemuDomainSetBlkioParameters, /* domainSetBlkioParameters */ + qemuDomainGetBlkioParameters, /* domainGetBlkioParameters */ }; -- 1.7.1

On 02/21/2011 10:32 PM, Gui Jianfeng wrote:
Implement domainSetBlkioParamters and domainGetBlkioParamters for QEmu
s/Paramters/Parameters/g
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> ---
ACK. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Adding blkiotune command to virsh tool Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 127 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index ce275f1..5d6e06e 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3010,6 +3010,132 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd) } /* + * "blkiotune" command + */ +static const vshCmdInfo info_blkiotune[] = { + {"help", N_("Get or set blkio parameters")}, + {"desc", N_("Get or set the current blkio parameters for a guest" \ + " domain.\n" \ + " To get the blkio parameters use following command: \n\n" \ + " virsh # blkiotune <domain>")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_blkiotune[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"weight", VSH_OT_INT, VSH_OFLAG_NONE, + N_("IO Weight in range [100, 1000]")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) +{ + virDomainPtr dom; + int weight; + int nparams = 0; + unsigned int i = 0; + virBlkioParameterPtr params = NULL, temp = NULL; + int ret = FALSE; + int found; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return FALSE; + + weight = vshCommandOptInt(cmd, "weight", &found); + if (found) { + nparams++; + if (weight < 0) { + virDomainFree(dom); + vshError(ctl, _("Invalid value of %d for I/O weight"), weight); + return FALSE; + } + } + + if (nparams == 0) { + /* get the number of blkio parameters */ + if (virDomainGetBlkioParameters(dom, NULL, &nparams, 0) != 0) { + vshError(ctl, "%s", + _("Unable to get number of blkio parameters")); + goto cleanup; + } + + if (nparams == 0) { + /* nothing to output */ + ret = TRUE; + goto cleanup; + } + + /* now go get all the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + if (virDomainGetBlkioParameters(dom, params, &nparams, 0) != 0) { + vshError(ctl, "%s", _("Unable to get blkio parameters")); + goto cleanup; + } + + for (i = 0; i < nparams; i++) { + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.i); + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + vshPrint(ctl, "%-15s: %u\n", params[i].field, + params[i].value.ui); + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + vshPrint(ctl, "%-15s: %lld\n", params[i].field, + params[i].value.l); + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + vshPrint(ctl, "%-15s: %llu\n", params[i].field, + params[i].value.ul); + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + vshPrint(ctl, "%-15s: %f\n", params[i].field, + params[i].value.d); + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.b); + break; + default: + vshPrint(ctl, "unimplemented blkio parameter type\n"); + } + } + + ret = TRUE; + } else { + /* set the blkio parameters */ + params = vshCalloc(ctl, nparams, sizeof(*params)); + + for (i = 0; i < nparams; i++) { + temp = ¶ms[i]; + temp->type = VIR_DOMAIN_BLKIO_PARAM_UINT; + + if (weight) { + temp->value.ui = (unsigned int)weight; + strncpy(temp->field, VIR_DOMAIN_BLKIO_WEIGHT, + sizeof(temp->field)); + weight = 0; + } + } + if (virDomainSetBlkioParameters(dom, params, nparams, 0) != 0) + vshError(ctl, "%s", _("Unable to change blkio parameters")); + else + ret = TRUE; + } + + cleanup: + VIR_FREE(params); + virDomainFree(dom); + return ret; +} + +/* * "memtune" command */ static const vshCmdInfo info_memtune[] = { @@ -10324,6 +10450,7 @@ static const vshCmdDef domManagementCmds[] = { {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, info_managedsaveremove}, {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune}, {"memtune", cmdMemtune, opts_memtune, info_memtune}, {"migrate", cmdMigrate, opts_migrate, info_migrate}, {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime}, -- 1.7.1

On 02/21/2011 10:33 PM, Gui Jianfeng wrote:
Adding blkiotune command to virsh tool
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 127 insertions(+), 0 deletions(-)
+static int +cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) +{ + virDomainPtr dom; + int weight; + int nparams = 0; + unsigned int i = 0; + virBlkioParameterPtr params = NULL, temp = NULL; + int ret = FALSE; + int found; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return FALSE; + + weight = vshCommandOptInt(cmd, "weight", &found);
Oh my - more merge resolution (and the compiler didn't catch that we'd reworked vshCommandOptInt in d03f199).
+ if (found) { + nparams++; + if (weight < 0) { + virDomainFree(dom); + vshError(ctl, _("Invalid value of %d for I/O weight"), weight); + return FALSE;
Mem leak of dom.
+ if (weight) { + temp->value.ui = (unsigned int)weight;
Unnecessary cast.
@@ -10324,6 +10450,7 @@ static const vshCmdDef domManagementCmds[] = { {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, info_managedsaveremove}, {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune},
Sorted order. I like documentation closer to the changes, so I squashed 6/6 into this one. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On 03/10/2011 05:21 PM, Eric Blake wrote:
+ weight = vshCommandOptInt(cmd, "weight", &found);
Oh my - more merge resolution (and the compiler didn't catch that we'd reworked vshCommandOptInt in d03f199).
...
I like documentation closer to the changes, so I squashed 6/6 into this one.
Oh, I meant to add that I squashed in this to fix the above problems: diff --git i/tools/virsh.c w/tools/virsh.c index c0b3d38..a5e9c4f 100644 --- i/tools/virsh.c +++ w/tools/virsh.c @@ -3058,12 +3058,11 @@ static int cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) { virDomainPtr dom; - int weight; + int weight = 0; int nparams = 0; unsigned int i = 0; virBlkioParameterPtr params = NULL, temp = NULL; int ret = FALSE; - int found; if (!vshConnectionUsability(ctl, ctl->conn)) return FALSE; @@ -3071,13 +3070,18 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) return FALSE; - weight = vshCommandOptInt(cmd, "weight", &found); - if (found) { + if (vshCommandOptInt(cmd, "weight", &weight) < 0) { + vshError(ctl, "%s", + _("Unable to parse integer parameter")); + goto cleanup; + } + + if (weight) { nparams++; if (weight < 0) { virDomainFree(dom); vshError(ctl, _("Invalid value of %d for I/O weight"), weight); - return FALSE; + goto cleanup; } } @@ -3143,7 +3147,7 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) temp->type = VIR_DOMAIN_BLKIO_PARAM_UINT; if (weight) { - temp->value.ui = (unsigned int)weight; + temp->value.ui = weight; strncpy(temp->field, VIR_DOMAIN_BLKIO_WEIGHT, sizeof(temp->field)); weight = 0; @@ -10415,6 +10419,7 @@ static const vshCmdDef domManagementCmds[] = { {"attach-disk", cmdAttachDisk, opts_attach_disk, info_attach_disk}, {"attach-interface", cmdAttachInterface, opts_attach_interface, info_attach_interface}, {"autostart", cmdAutostart, opts_autostart, info_autostart}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune}, #ifndef WIN32 {"console", cmdConsole, opts_console, info_console}, #endif @@ -10439,7 +10444,6 @@ static const vshCmdDef domManagementCmds[] = { {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, info_managedsaveremove}, {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus}, - {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune}, {"memtune", cmdMemtune, opts_memtune, info_memtune}, {"migrate", cmdMigrate, opts_migrate, info_migrate}, {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime}, -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Remote protocol implementation of virDomainSetBlkioParameters and virDomainGetBlkioParameters. Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- daemon/remote.c | 210 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 2 + daemon/remote_dispatch_prototypes.h | 16 +++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 10 ++ src/remote/remote_driver.c | 173 ++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 89 +++++++++++++++ src/remote/remote_protocol.h | 55 +++++++++ src/remote/remote_protocol.x | 44 +++++++- src/remote_protocol-structs | 35 ++++++ 10 files changed, 632 insertions(+), 3 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index c5509ad..feb26f6 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2384,6 +2384,216 @@ remoteDispatchDomainSetMemory (struct qemud_server *server ATTRIBUTE_UNUSED, } static int +remoteDispatchDomainSetBlkioParameters(struct qemud_server *server + ATTRIBUTE_UNUSED, + struct qemud_client *client + ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header * + hdr ATTRIBUTE_UNUSED, + remote_error * rerr, + remote_domain_set_blkio_parameters_args + * args, void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom; + int i, r, nparams; + virBlkioParameterPtr params; + unsigned int flags; + + nparams = args->params.params_len; + flags = args->flags; + + if (nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) { + remoteDispatchFormatError(rerr, "%s", _("nparams too large")); + return -1; + } + if (VIR_ALLOC_N(params, nparams) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + + /* Deserialise parameters. */ + for (i = 0; i < nparams; ++i) { + if (virStrcpyStatic + (params[i].field, args->params.params_val[i].field) == NULL) { + remoteDispatchFormatError(rerr, + _ + ("Field %s too big for destination"), + args->params.params_val[i].field); + return -1; + } + params[i].type = args->params.params_val[i].value.type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + params[i].value.i = + args->params.params_val[i].value. + remote_blkio_param_value_u.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + params[i].value.ui = + args->params.params_val[i].value. + remote_blkio_param_value_u.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + params[i].value.l = + args->params.params_val[i].value. + remote_blkio_param_value_u.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + params[i].value.ul = + args->params.params_val[i].value. + remote_blkio_param_value_u.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + params[i].value.d = + args->params.params_val[i].value. + remote_blkio_param_value_u.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + params[i].value.b = + args->params.params_val[i].value. + remote_blkio_param_value_u.b; + break; + } + } + + dom = get_nonnull_domain(conn, args->dom); + if (dom == NULL) { + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + + r = virDomainSetBlkioParameters(dom, params, nparams, flags); + virDomainFree(dom); + VIR_FREE(params); + if (r == -1) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + return 0; +} + +static int +remoteDispatchDomainGetBlkioParameters(struct qemud_server *server + ATTRIBUTE_UNUSED, + struct qemud_client *client + ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header * + hdr ATTRIBUTE_UNUSED, + remote_error * rerr, + remote_domain_get_blkio_parameters_args + * args, + remote_domain_get_blkio_parameters_ret + * ret) +{ + virDomainPtr dom; + virBlkioParameterPtr params; + int i, r, nparams; + unsigned int flags; + + nparams = args->nparams; + flags = args->flags; + + if (nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) { + remoteDispatchFormatError(rerr, "%s", _("nparams too large")); + return -1; + } + if (VIR_ALLOC_N(params, nparams) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + + dom = get_nonnull_domain(conn, args->dom); + if (dom == NULL) { + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + + r = virDomainGetBlkioParameters(dom, params, &nparams, flags); + if (r == -1) { + virDomainFree(dom); + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + /* In this case, we need to send back the number of parameters + * supported + */ + if (args->nparams == 0) { + ret->nparams = nparams; + goto success; + } + + /* Serialise the blkio parameters. */ + ret->params.params_len = nparams; + if (VIR_ALLOC_N(ret->params.params_val, nparams) < 0) + goto oom; + + for (i = 0; i < nparams; ++i) { + // remoteDispatchClientRequest will free this: + ret->params.params_val[i].field = strdup(params[i].field); + if (ret->params.params_val[i].field == NULL) + goto oom; + + ret->params.params_val[i].value.type = params[i].type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.i = + params[i].value.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.ui = + params[i].value.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.l = + params[i].value.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.ul = + params[i].value.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.d = + params[i].value.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + ret->params.params_val[i]. + value.remote_blkio_param_value_u.b = + params[i].value.b; + break; + default: + remoteDispatchFormatError(rerr, "%s", _("unknown type")); + goto cleanup; + } + } + + success: + virDomainFree(dom); + VIR_FREE(params); + + return 0; + + oom: + remoteDispatchOOMError(rerr); + cleanup: + virDomainFree(dom); + for (i = 0; i < nparams; i++) + VIR_FREE(ret->params.params_val[i].field); + VIR_FREE(params); + return -1; +} + +static int remoteDispatchDomainSetMemoryParameters(struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h index 57962d1..e8b2a7e 100644 --- a/daemon/remote_dispatch_args.h +++ b/daemon/remote_dispatch_args.h @@ -172,3 +172,5 @@ remote_domain_open_console_args val_remote_domain_open_console_args; remote_domain_is_updated_args val_remote_domain_is_updated_args; remote_get_sysinfo_args val_remote_get_sysinfo_args; + remote_domain_set_blkio_parameters_args val_remote_domain_set_blkio_parameters_args; + remote_domain_get_blkio_parameters_args val_remote_domain_get_blkio_parameters_args; diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h index e59701a..692391b 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -218,6 +218,14 @@ static int remoteDispatchDomainGetAutostart( remote_error *err, remote_domain_get_autostart_args *args, remote_domain_get_autostart_ret *ret); +static int remoteDispatchDomainGetBlkioParameters( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_get_blkio_parameters_args *args, + remote_domain_get_blkio_parameters_ret *ret); static int remoteDispatchDomainGetBlockInfo( struct qemud_server *server, struct qemud_client *client, @@ -538,6 +546,14 @@ static int remoteDispatchDomainSetAutostart( remote_error *err, remote_domain_set_autostart_args *args, void *ret); +static int remoteDispatchDomainSetBlkioParameters( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_set_blkio_parameters_args *args, + void *ret); static int remoteDispatchDomainSetMaxMemory( struct qemud_server *server, struct qemud_client *client, diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h index 78e5469..114e832 100644 --- a/daemon/remote_dispatch_ret.h +++ b/daemon/remote_dispatch_ret.h @@ -139,3 +139,4 @@ remote_domain_get_vcpus_flags_ret val_remote_domain_get_vcpus_flags_ret; remote_domain_is_updated_ret val_remote_domain_is_updated_ret; remote_get_sysinfo_ret val_remote_get_sysinfo_ret; + remote_domain_get_blkio_parameters_ret val_remote_domain_get_blkio_parameters_ret; diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h index 5d27390..627e8a8 100644 --- a/daemon/remote_dispatch_table.h +++ b/daemon/remote_dispatch_table.h @@ -1022,3 +1022,13 @@ .args_filter = (xdrproc_t) xdr_remote_get_sysinfo_args, .ret_filter = (xdrproc_t) xdr_remote_get_sysinfo_ret, }, +{ /* DomainSetBlkioParameters => 204 */ + .fn = (dispatch_fn) remoteDispatchDomainSetBlkioParameters, + .args_filter = (xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + .ret_filter = (xdrproc_t) xdr_void, +}, +{ /* DomainGetBlkioParameters => 205 */ + .fn = (dispatch_fn) remoteDispatchDomainGetBlkioParameters, + .args_filter = (xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, + .ret_filter = (xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, +}, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index abee1c5..d450ece 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -2445,6 +2445,175 @@ done: } static int +remoteDomainSetBlkioParameters (virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, + unsigned int flags) +{ + int rv = -1; + remote_domain_set_blkio_parameters_args args; + int i, do_error; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + + /* Serialise the blkio parameters. */ + args.params.params_len = nparams; + args.flags = flags; + if (VIR_ALLOC_N(args.params.params_val, nparams) < 0) { + virReportOOMError(); + goto done; + } + + do_error = 0; + for (i = 0; i < nparams; ++i) { + // call() will free this: + args.params.params_val[i].field = strdup (params[i].field); + if (args.params.params_val[i].field == NULL) { + virReportOOMError(); + do_error = 1; + } + args.params.params_val[i].value.type = params[i].type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + args.params.params_val[i].value.remote_blkio_param_value_u.i = + params[i].value.i; break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + args.params.params_val[i].value.remote_blkio_param_value_u.ui = + params[i].value.ui; break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + args.params.params_val[i].value.remote_blkio_param_value_u.l = + params[i].value.l; break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + args.params.params_val[i].value.remote_blkio_param_value_u.ul = + params[i].value.ul; break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + args.params.params_val[i].value.remote_blkio_param_value_u.d = + params[i].value.d; break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + args.params.params_val[i].value.remote_blkio_param_value_u.b = + params[i].value.b; break; + default: + remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type")); + do_error = 1; + } + } + + if (do_error) { + xdr_free ((xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + (char *) &args); + goto done; + } + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS, + (xdrproc_t) xdr_remote_domain_set_blkio_parameters_args, + (char *) &args, (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int +remoteDomainGetBlkioParameters (virDomainPtr domain, + virBlkioParameterPtr params, int *nparams, + unsigned int flags) +{ + int rv = -1; + remote_domain_get_blkio_parameters_args args; + remote_domain_get_blkio_parameters_ret ret; + int i = -1; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + args.nparams = *nparams; + args.flags = flags; + + memset (&ret, 0, sizeof ret); + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS, + (xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, (char *) &args, + (xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, (char *) &ret) == -1) + goto done; + + /* Check the length of the returned list carefully. */ + if (ret.params.params_len > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX || + ret.params.params_len > *nparams) { + remoteError(VIR_ERR_RPC, "%s", + _("remoteDomainGetBlkioParameters: " + "returned number of parameters exceeds limit")); + goto cleanup; + } + /* Handle the case when the caller does not know the number of parameters + * and is asking for the number of parameters supported + */ + if (*nparams == 0) { + *nparams = ret.nparams; + rv = 0; + goto cleanup; + } + + *nparams = ret.params.params_len; + + /* Deserialise the result. */ + for (i = 0; i < *nparams; ++i) { + if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) { + remoteError(VIR_ERR_INTERNAL_ERROR, + _("Parameter %s too big for destination"), + ret.params.params_val[i].field); + goto cleanup; + } + params[i].type = ret.params.params_val[i].value.type; + switch (params[i].type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + params[i].value.i = + ret.params.params_val[i].value.remote_blkio_param_value_u.i; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + params[i].value.ui = + ret.params.params_val[i].value.remote_blkio_param_value_u.ui; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + params[i].value.l = + ret.params.params_val[i].value.remote_blkio_param_value_u.l; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + params[i].value.ul = + ret.params.params_val[i].value.remote_blkio_param_value_u.ul; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + params[i].value.d = + ret.params.params_val[i].value.remote_blkio_param_value_u.d; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + params[i].value.b = + ret.params.params_val[i].value.remote_blkio_param_value_u.b; + break; + default: + remoteError(VIR_ERR_RPC, "%s", + _("remoteDomainGetBlkioParameters: " + "unknown parameter type")); + goto cleanup; + } + } + + rv = 0; + +cleanup: + xdr_free ((xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, + (char *) &ret); +done: + remoteDriverUnlock(priv); + return rv; +} + +static int remoteDomainSetMemoryParameters (virDomainPtr domain, virMemoryParameterPtr params, int nparams, @@ -10946,8 +11115,8 @@ static virDriver remote_driver = { remoteDomainSetMemoryParameters, /* domainSetMemoryParameters */ remoteDomainGetMemoryParameters, /* domainGetMemoryParameters */ remoteDomainOpenConsole, /* domainOpenConsole */ - NULL, /* domainSetBlkioParameters */ - NULL, /* domainGetBlkioParameters */ + remoteDomainSetBlkioParameters, /* domainSetBlkioParameters */ + remoteDomainGetBlkioParameters, /* domainGetBlkioParameters */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c index bae92ca..2a3daa6 100644 --- a/src/remote/remote_protocol.c +++ b/src/remote/remote_protocol.c @@ -308,6 +308,53 @@ xdr_remote_sched_param (XDR *xdrs, remote_sched_param *objp) } bool_t +xdr_remote_blkio_param_value (XDR *xdrs, remote_blkio_param_value *objp) +{ + + if (!xdr_int (xdrs, &objp->type)) + return FALSE; + switch (objp->type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + if (!xdr_u_int (xdrs, &objp->remote_blkio_param_value_u.ui)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + if (!xdr_int64_t (xdrs, &objp->remote_blkio_param_value_u.l)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + if (!xdr_uint64_t (xdrs, &objp->remote_blkio_param_value_u.ul)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + if (!xdr_double (xdrs, &objp->remote_blkio_param_value_u.d)) + return FALSE; + break; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + if (!xdr_int (xdrs, &objp->remote_blkio_param_value_u.b)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +bool_t +xdr_remote_blkio_param (XDR *xdrs, remote_blkio_param *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->field)) + return FALSE; + if (!xdr_remote_blkio_param_value (xdrs, &objp->value)) + return FALSE; + return TRUE; +} + +bool_t xdr_remote_memory_param_value (XDR *xdrs, remote_memory_param_value *objp) { @@ -646,6 +693,48 @@ xdr_remote_domain_set_scheduler_parameters_args (XDR *xdrs, remote_domain_set_sc } bool_t +xdr_remote_domain_set_blkio_parameters_args (XDR *xdrs, remote_domain_set_blkio_parameters_args *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->params.params_val; + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->params.params_len, REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX, + sizeof (remote_blkio_param), (xdrproc_t) xdr_remote_blkio_param)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_blkio_parameters_args (XDR *xdrs, remote_domain_get_blkio_parameters_args *objp) +{ + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_int (xdrs, &objp->nparams)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_blkio_parameters_ret (XDR *xdrs, remote_domain_get_blkio_parameters_ret *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->params.params_val; + + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->params.params_len, REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX, + sizeof (remote_blkio_param), (xdrproc_t) xdr_remote_blkio_param)) + return FALSE; + if (!xdr_int (xdrs, &objp->nparams)) + return FALSE; + return TRUE; +} + + +bool_t xdr_remote_domain_set_memory_parameters_args (XDR *xdrs, remote_domain_set_memory_parameters_args *objp) { char **objp_cpp0 = (char **) (void *) &objp->params.params_val; diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h index 46d526a..52a9d71 100644 --- a/src/remote/remote_protocol.h +++ b/src/remote/remote_protocol.h @@ -53,6 +53,7 @@ typedef remote_nonnull_string *remote_string; #define REMOTE_NODE_DEVICE_CAPS_LIST_MAX 16384 #define REMOTE_NWFILTER_NAME_LIST_MAX 1024 #define REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX 16 +#define REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX 16 #define REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX 16 #define REMOTE_NODE_MAX_CELLS 1024 #define REMOTE_AUTH_SASL_DATA_MAX 65536 @@ -187,6 +188,25 @@ struct remote_sched_param { }; typedef struct remote_sched_param remote_sched_param; +struct remote_blkio_param_value { + int type; + union { + int i; + u_int ui; + int64_t l; + uint64_t ul; + double d; + int b; + } remote_blkio_param_value_u; +}; +typedef struct remote_blkio_param_value remote_blkio_param_value; + +struct remote_blkio_param { + remote_nonnull_string field; + remote_blkio_param_value value; +}; +typedef struct remote_blkio_param remote_blkio_param; + struct remote_memory_param_value { int type; union { @@ -337,6 +357,32 @@ struct remote_domain_set_scheduler_parameters_args { }; typedef struct remote_domain_set_scheduler_parameters_args remote_domain_set_scheduler_parameters_args; +struct remote_domain_set_blkio_parameters_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_blkio_param *params_val; + } params; + u_int flags; +}; +typedef struct remote_domain_set_blkio_parameters_args remote_domain_set_blkio_parameters_args; + +struct remote_domain_get_blkio_parameters_args { + remote_nonnull_domain dom; + int nparams; + u_int flags; +}; +typedef struct remote_domain_get_blkio_parameters_args remote_domain_get_blkio_parameters_args; + +struct remote_domain_get_blkio_parameters_ret { + struct { + u_int params_len; + remote_blkio_param *params_val; + } params; + int nparams; +}; +typedef struct remote_domain_get_blkio_parameters_ret remote_domain_get_blkio_parameters_ret; + struct remote_domain_set_memory_parameters_args { remote_nonnull_domain dom; struct { @@ -2331,6 +2377,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, REMOTE_PROC_DOMAIN_IS_UPDATED = 202, REMOTE_PROC_GET_SYSINFO = 203, + REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 204, + REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 205, }; typedef enum remote_procedure remote_procedure; @@ -2386,6 +2434,8 @@ extern bool_t xdr_remote_auth_type (XDR *, remote_auth_type*); extern bool_t xdr_remote_vcpu_info (XDR *, remote_vcpu_info*); extern bool_t xdr_remote_sched_param_value (XDR *, remote_sched_param_value*); extern bool_t xdr_remote_sched_param (XDR *, remote_sched_param*); +extern bool_t xdr_remote_blkio_param_value (XDR *, remote_blkio_param_value*); +extern bool_t xdr_remote_blkio_param (XDR *, remote_blkio_param*); extern bool_t xdr_remote_memory_param_value (XDR *, remote_memory_param_value*); extern bool_t xdr_remote_memory_param (XDR *, remote_memory_param*); extern bool_t xdr_remote_open_args (XDR *, remote_open_args*); @@ -2410,6 +2460,9 @@ extern bool_t xdr_remote_domain_get_scheduler_type_ret (XDR *, remote_domain_ge extern bool_t xdr_remote_domain_get_scheduler_parameters_args (XDR *, remote_domain_get_scheduler_parameters_args*); extern bool_t xdr_remote_domain_get_scheduler_parameters_ret (XDR *, remote_domain_get_scheduler_parameters_ret*); extern bool_t xdr_remote_domain_set_scheduler_parameters_args (XDR *, remote_domain_set_scheduler_parameters_args*); +extern bool_t xdr_remote_domain_set_blkio_parameters_args (XDR *, remote_domain_set_blkio_parameters_args*); +extern bool_t xdr_remote_domain_get_blkio_parameters_args (XDR *, remote_domain_get_blkio_parameters_args*); +extern bool_t xdr_remote_domain_get_blkio_parameters_ret (XDR *, remote_domain_get_blkio_parameters_ret*); extern bool_t xdr_remote_domain_set_memory_parameters_args (XDR *, remote_domain_set_memory_parameters_args*); extern bool_t xdr_remote_domain_get_memory_parameters_args (XDR *, remote_domain_get_memory_parameters_args*); extern bool_t xdr_remote_domain_get_memory_parameters_ret (XDR *, remote_domain_get_memory_parameters_ret*); @@ -2734,6 +2787,8 @@ extern bool_t xdr_remote_auth_type (); extern bool_t xdr_remote_vcpu_info (); extern bool_t xdr_remote_sched_param_value (); extern bool_t xdr_remote_sched_param (); +extern bool_t xdr_remote_blkio_param_value (); +extern bool_t xdr_remote_blkio_param (); extern bool_t xdr_remote_memory_param_value (); extern bool_t xdr_remote_memory_param (); extern bool_t xdr_remote_open_args (); diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index e77aca1..334c672 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -128,6 +128,9 @@ const REMOTE_NWFILTER_NAME_LIST_MAX = 1024; /* Upper limit on list of scheduler parameters. */ const REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX = 16; +/* Upper limit on list of blkio parameters. */ +const REMOTE_DOMAIN_blkio_PARAMETERS_MAX = 16; + /* Upper limit on list of memory parameters. */ const REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX = 16; @@ -316,6 +319,26 @@ struct remote_sched_param { remote_sched_param_value value; }; +union remote_blkio_param_value switch (int type) { + case VIR_DOMAIN_BLKIO_PARAM_INT: + int i; + case VIR_DOMAIN_BLKIO_PARAM_UINT: + unsigned int ui; + case VIR_DOMAIN_BLKIO_PARAM_LLONG: + hyper l; + case VIR_DOMAIN_BLKIO_PARAM_ULLONG: + unsigned hyper ul; + case VIR_DOMAIN_BLKIO_PARAM_DOUBLE: + double d; + case VIR_DOMAIN_BLKIO_PARAM_BOOLEAN: + int b; +}; + +struct remote_blkio_param { + remote_nonnull_string field; + remote_blkio_param_value value; +}; + union remote_memory_param_value switch (int type) { case VIR_DOMAIN_MEMORY_PARAM_INT: int i; @@ -453,6 +476,23 @@ struct remote_domain_set_scheduler_parameters_args { remote_sched_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>; }; +struct remote_domain_set_blkio_parameters_args { + remote_nonnull_domain dom; + remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>; + unsigned int flags; +}; + +struct remote_domain_get_blkio_parameters_args { + remote_nonnull_domain dom; + int nparams; + unsigned int flags; +}; + +struct remote_domain_get_blkio_parameters_ret { + remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>; + int nparams; +}; + struct remote_domain_set_memory_parameters_args { remote_nonnull_domain dom; remote_memory_param params<REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX>; @@ -2103,7 +2143,9 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, REMOTE_PROC_DOMAIN_IS_UPDATED = 202, - REMOTE_PROC_GET_SYSINFO = 203 + REMOTE_PROC_GET_SYSINFO = 203, + REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 204, + REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 205 /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 6a7f03d..51d7368 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -70,6 +70,21 @@ struct remote_sched_param { remote_nonnull_string field; remote_sched_param_value value; }; +struct remote_blkio_param_value { + int type; + union { + int i; + u_int ui; + int64_t l; + uint64_t ul; + double d; + int b; + } remote_blkio_param_value_u; +}; +struct remote_blkio_param { + remote_nonnull_string field; + remote_blkio_param_value value; +}; struct remote_memory_param_value { int type; union { @@ -172,6 +187,26 @@ struct remote_domain_set_scheduler_parameters_args { remote_sched_param * params_val; } params; }; +struct remote_domain_set_blkio_parameters_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_blkio_param *params_val; + } params; + u_int flags; +}; +struct remote_domain_get_blkio_parameters_args { + remote_nonnull_domain dom; + int nparams; + u_int flags; +}; +struct remote_domain_get_blkio_parameters_ret { + struct { + u_int params_len; + remote_blkio_param *params_val; + } params; + int nparams; +}; struct remote_domain_set_memory_parameters_args { remote_nonnull_domain dom; struct { -- 1.7.1

On 02/21/2011 10:34 PM, Gui Jianfeng wrote:
Remote protocol implementation of virDomainSetBlkioParameters and virDomainGetBlkioParameters.
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- daemon/remote.c | 210 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 2 + daemon/remote_dispatch_prototypes.h | 16 +++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 10 ++ src/remote/remote_driver.c | 173 ++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 89 +++++++++++++++ src/remote/remote_protocol.h | 55 +++++++++ src/remote/remote_protocol.x | 44 +++++++- src/remote_protocol-structs | 35 ++++++ 10 files changed, 632 insertions(+), 3 deletions(-)
ACK, although I had quite the rough time applying this after the conflicts with virDomainSetMemoryFlags. I ended up shuffling things to match shuffles earlier in the series.
+++ b/src/remote/remote_protocol.x @@ -128,6 +128,9 @@ const REMOTE_NWFILTER_NAME_LIST_MAX = 1024; /* Upper limit on list of scheduler parameters. */ const REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX = 16;
+/* Upper limit on list of blkio parameters. */ +const REMOTE_DOMAIN_blkio_PARAMETERS_MAX = 16; +
Wrong case. How'd you test this?
@@ -2103,7 +2143,9 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, REMOTE_PROC_DOMAIN_IS_UPDATED = 202, - REMOTE_PROC_GET_SYSINFO = 203 + REMOTE_PROC_GET_SYSINFO = 203, + REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 204, + REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 205
SET_MEMORY_FLAGS beat you to 204; you get 205 and 206. Hmm, I guess that completes my review, so I'm pushing it. Thanks again for the work! However, I do have a parting comment that this was a _lot_ of code duplication; if we ever add another cgroup tunable, it would be worth the time to first factor out the common elements into something that memtune, blkio, and that new cgroup tunable could share. For example, we don't need three copies of the union for i/ui/l/ul/d/b - that should be something easy to share between tunables. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Eric Blake wrote:
On 02/21/2011 10:34 PM, Gui Jianfeng wrote:
Remote protocol implementation of virDomainSetBlkioParameters and virDomainGetBlkioParameters.
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- daemon/remote.c | 210 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 2 + daemon/remote_dispatch_prototypes.h | 16 +++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 10 ++ src/remote/remote_driver.c | 173 ++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 89 +++++++++++++++ src/remote/remote_protocol.h | 55 +++++++++ src/remote/remote_protocol.x | 44 +++++++- src/remote_protocol-structs | 35 ++++++ 10 files changed, 632 insertions(+), 3 deletions(-)
ACK, although I had quite the rough time applying this after the conflicts with virDomainSetMemoryFlags. I ended up shuffling things to match shuffles earlier in the series.
+++ b/src/remote/remote_protocol.x @@ -128,6 +128,9 @@ const REMOTE_NWFILTER_NAME_LIST_MAX = 1024; /* Upper limit on list of scheduler parameters. */ const REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX = 16;
+/* Upper limit on list of blkio parameters. */ +const REMOTE_DOMAIN_blkio_PARAMETERS_MAX = 16; +
Wrong case. How'd you test this?
@@ -2103,7 +2143,9 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_OPEN_CONSOLE = 201, REMOTE_PROC_DOMAIN_IS_UPDATED = 202, - REMOTE_PROC_GET_SYSINFO = 203 + REMOTE_PROC_GET_SYSINFO = 203, + REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS = 204, + REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 205
SET_MEMORY_FLAGS beat you to 204; you get 205 and 206.
Hmm, I guess that completes my review, so I'm pushing it. Thanks again for the work!
However, I do have a parting comment that this was a _lot_ of code duplication; if we ever add another cgroup tunable, it would be worth the time to first factor out the common elements into something that memtune, blkio, and that new cgroup tunable could share. For example, we don't need three copies of the union for i/ui/l/ul/d/b - that should be something easy to share between tunables.
Agreed. We should extract some common code in the future. Thanks for rebasing and pushing this seires Eric. Thanks, Gui

Documents for blkiotune Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..72dc1a2 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,11 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element. +=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio parameters. QEMU/KVM supports I<--weight>. +I<--weight> is in range [100, 1000]. + =item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes> optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit> B<kilobytes> -I<--min-guarantee> B<kilobytes> -- 1.7.1

On 02/21/2011 10:34 PM, Gui Jianfeng wrote:
Documents for blkiotune
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..72dc1a2 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,11 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element.
+=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio parameters. QEMU/KVM supports I<--weight>. +I<--weight> is in range [100, 1000]. + =item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes> optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit> B<kilobytes> -I<--min-guarantee> B<kilobytes>
ACK, but I shuffled it to keep <memtune> next to <setmaxmem>, and squashed it into patch 4/6 (that way, git history for the next guy will remind people to touch docs at the same time as adding features). -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Documents for blkiotune Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- tools/virsh.pod | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/tools/virsh.pod b/tools/virsh.pod index a2ca384..72dc1a2 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -610,6 +610,11 @@ of 4MB, while 266240 (260MB) is valid without rounding. Note, to change the maximum memory allocation for a QEMU/KVM guest domain, use the virsh B<edit> command instead to update its XML <memory> element. +=item B<blkiotune> I<domain-id> optional I<--weight> B<weight> + +Display or set the blkio parameters. QEMU/KVM supports I<--weight>. +I<--weight> is in range [100, 1000]. + =item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes> optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit> B<kilobytes> -I<--min-guarantee> B<kilobytes> -- 1.7.1

Implements virDomainSetBlkioParameters and virDomainGetBlkioParameters and initialization Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/driver.h | 14 ++++++ src/esx/esx_driver.c | 2 + src/libvirt.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 +++ src/lxc/lxc_driver.c | 2 + src/openvz/openvz_driver.c | 2 + src/phyp/phyp_driver.c | 2 + src/qemu/qemu_driver.c | 2 + src/remote/remote_driver.c | 2 + src/test/test_driver.c | 2 + src/uml/uml_driver.c | 2 + src/vmware/vmware_driver.c | 2 + src/xen/xen_driver.c | 2 + 13 files changed, 148 insertions(+), 0 deletions(-) diff --git a/src/driver.h b/src/driver.h index 7451004..608efe9 100644 --- a/src/driver.h +++ b/src/driver.h @@ -135,6 +135,18 @@ typedef int (*virDrvDomainSetMemory) (virDomainPtr domain, unsigned long memory); typedef int + (*virDrvDomainSetBlkioParameters) + (virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, + unsigned int flags); +typedef int + (*virDrvDomainGetBlkioParameters) + (virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, + unsigned int flags); +typedef int (*virDrvDomainSetMemoryParameters) (virDomainPtr domain, virMemoryParameterPtr params, @@ -615,6 +627,8 @@ struct _virDriver { virDrvDomainSetMemoryParameters domainSetMemoryParameters; virDrvDomainGetMemoryParameters domainGetMemoryParameters; virDrvDomainOpenConsole domainOpenConsole; + virDrvDomainSetBlkioParameters domainSetBlkioParameters; + virDrvDomainGetBlkioParameters domainGetBlkioParameters; }; typedef int diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 116ad0f..675c266 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4655,6 +4655,8 @@ static virDriver esxDriver = { esxDomainSetMemoryParameters, /* domainSetMemoryParameters */ esxDomainGetMemoryParameters, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; diff --git a/src/libvirt.c b/src/libvirt.c index f65cc24..b79f3c2 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2847,6 +2847,114 @@ error: } /** + * virDomainSetBlkioParameters: + * @domain: pointer to domain object + * @params: pointer to blkio parameter objects + * @nparams: number of blkio parameter (this value should be same or + * less than the number of parameters supported) + * @flags: currently unused, for future extension + * + * Change the blkio tunables + * This function requires privileged access to the hypervisor. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainSetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int nparams, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%u", + params, nparams, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + if ((nparams <= 0) || (params == NULL)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainSetBlkioParameters) { + int ret; + ret = conn->driver->domainSetBlkioParameters (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** + * virDomainGetBlkioParameters: + * @domain: pointer to domain object + * @params: pointer to blkio parameter object + * (return value, allocated by the caller) + * @nparams: pointer to number of blkio parameters + * @flags: currently unused, for future extension + * + * Get the blkio parameters, the @params array will be filled with the values + * equal to the number of parameters suggested by @nparams + * + * This function requires privileged access to the hypervisor. This function + * expects the caller to allocate the @params. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainGetBlkioParameters(virDomainPtr domain, + virBlkioParameterPtr params, + int *nparams, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%u", + params, (nparams) ? *nparams : -1, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if ((nparams == NULL) || (*nparams < 0)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainGetBlkioParameters) { + int ret; + ret = conn->driver->domainGetBlkioParameters (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + virLibConnError (VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** * virDomainSetMemoryParameters: * @domain: pointer to domain object * @params: pointer to memory parameter objects diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 1a45be1..9dea737 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -424,4 +424,10 @@ LIBVIRT_0.8.8 { virConnectGetSysinfo; } LIBVIRT_0.8.6; +LIBVIRT_0.8.9 { + global: + virDomainSetBlkioParameters; + virDomainGetBlkioParameters; +} LIBVIRT_0.8.8; + # .... define new API here using predicted next version number .... diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 0f78579..1940a16 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2930,6 +2930,8 @@ static virDriver lxcDriver = { lxcDomainSetMemoryParameters, /* domainSetMemoryParameters */ lxcDomainGetMemoryParameters, /* domainGetMemoryParameters */ lxcDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStateDriver lxcStateDriver = { diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 00d378a..5dec2c6 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1669,6 +1669,8 @@ static virDriver openvzDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; int openvzRegister(void) { diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index d954f2a..a93efde 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -4051,6 +4051,8 @@ static virDriver phypDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virStorageDriver phypStorageDriver = { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0f25a2a..6b63ca1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6864,6 +6864,8 @@ static virDriver qemuDriver = { qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ qemuDomainGetMemoryParameters, /* domainGetMemoryParameters */ qemuDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 4ca0d3b..6d148f1 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -10946,6 +10946,8 @@ static virDriver remote_driver = { remoteDomainSetMemoryParameters, /* domainSetMemoryParameters */ remoteDomainGetMemoryParameters, /* domainGetMemoryParameters */ remoteDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virNetworkDriver network_driver = { diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 1937da0..081652d 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5443,6 +5443,8 @@ static virDriver testDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static virNetworkDriver testNetworkDriver = { diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 2af8002..ef11070 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2245,6 +2245,8 @@ static virDriver umlDriver = { NULL, /* domainSetMemoryParamters */ NULL, /* domainGetMemoryParamters */ umlDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; static int diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 22b29d1..37e3346 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -1005,6 +1005,8 @@ static virDriver vmwareDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ NULL, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; int diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index b14c8db..508ed40 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2101,6 +2101,8 @@ static virDriver xenUnifiedDriver = { NULL, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ xenUnifiedDomainOpenConsole, /* domainOpenConsole */ + NULL, /* domainSetBlkioParameters */ + NULL, /* domainGetBlkioParameters */ }; /** -- 1.7.1

On 02/21/2011 02:47 AM, Gui Jianfeng wrote:
Implements virDomainSetBlkioParameters and virDomainGetBlkioParameters and initialization
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/driver.h | 14 ++++++ src/esx/esx_driver.c | 2 + src/libvirt.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 +++ src/lxc/lxc_driver.c | 2 + src/openvz/openvz_driver.c | 2 + src/phyp/phyp_driver.c | 2 + src/qemu/qemu_driver.c | 2 + src/remote/remote_driver.c | 2 + src/test/test_driver.c | 2 + src/uml/uml_driver.c | 2 + src/vmware/vmware_driver.c | 2 + src/xen/xen_driver.c | 2 + 13 files changed, 148 insertions(+), 0 deletions(-)
@@ -615,6 +627,8 @@ struct _virDriver { virDrvDomainSetMemoryParameters domainSetMemoryParameters; virDrvDomainGetMemoryParameters domainGetMemoryParameters; virDrvDomainOpenConsole domainOpenConsole; + virDrvDomainSetBlkioParameters domainSetBlkioParameters; + virDrvDomainGetBlkioParameters domainGetBlkioParameters; };
This is an internal struct; I think it makes more sense to group related callbacks than to place new callbacks at the end. That is, I would have inserted these two new callbacks between domainGetMemoryParameters and domainOpenConsole, rather than after domainOpenConsole. However, that has knock-on effects to the rest of this patch and to a lesser extent the rest of the series, so I'll leave it up to you whether to adjust the positioning in a respin. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On 02/21/2011 02:47 AM, Gui Jianfeng wrote:
Implements virDomainSetBlkioParameters and virDomainGetBlkioParameters and initialization
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/driver.h | 14 ++++++ src/esx/esx_driver.c | 2 + src/libvirt.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 +++ src/lxc/lxc_driver.c | 2 + src/openvz/openvz_driver.c | 2 + src/phyp/phyp_driver.c | 2 + src/qemu/qemu_driver.c | 2 + src/remote/remote_driver.c | 2 + src/test/test_driver.c | 2 + src/uml/uml_driver.c | 2 + src/vmware/vmware_driver.c | 2 + src/xen/xen_driver.c | 2 + 13 files changed, 148 insertions(+), 0 deletions(-)
Also, this missed: src/opennebula/one_driver.c src/vbox/vbox_tmpl.c src/xenapi/xenapi_driver.c (see commit dec13a5a for an example of all the drivers that need to be touched). Depending on whether libxenlight support goes in first, that would be another driver to watch out for. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On Wed, 16 Feb 2011 11:53:06 +0800, Gui Jianfeng <guijianfeng@cn.fujitsu.com> wrote:
Hi All,
This series implements a new command "blkiotune" for virsh. A lot of code borrows from memtune. You are able to tune blkio cgroup tunables by this command as follows.
Show tunables #virsh blkiotune My_guest weight : 900
Tune tunables(Set IO weight) #virsh blkiotune My_guest --weight 500 #virsh blkiotune My_guest weight : 500
Reviewed the v3 of the patch series, looks good to me. Reviewed-by: "Nikunj A. Dadhania" <nikunj@linux.vnet.ibm.com> Regards, Nikunj

Nikunj A. Dadhania wrote:
On Wed, 16 Feb 2011 11:53:06 +0800, Gui Jianfeng <guijianfeng@cn.fujitsu.com> wrote:
Hi All,
This series implements a new command "blkiotune" for virsh. A lot of code borrows from memtune. You are able to tune blkio cgroup tunables by this command as follows.
Show tunables #virsh blkiotune My_guest weight : 900
Tune tunables(Set IO weight) #virsh blkiotune My_guest --weight 500 #virsh blkiotune My_guest weight : 500
Reviewed the v3 of the patch series, looks good to me.
Reviewed-by: "Nikunj A. Dadhania" <nikunj@linux.vnet.ibm.com>
Eric, If everyting seems ok, Would you push this series? Thanks, Gui
Regards, Nikunj
participants (5)
-
Daniel Veillard
-
Eric Blake
-
Gui Jianfeng
-
Nikunj A. Dadhania
-
Osier Yang