[libvirt] [RFC] Support changing scheduler setting persistently

This patch series introduce a new API virDomainSetSchedulerParametersFlags to change the scheduler setting persistently. The new API accepts two flags, VIR_DOMAIN_SCHED_PARAMS_LIVE and VIR_DOMAIN_SCHED_PARAMS_PERSISTENT, "LIVE" flag affects the running domain config, "PERSISTENT" affects both the running and persistent domain config, both flags require the domain is running. "LIVE" flags is used by default. It's not like "setvcpus", which accepts "--live", "--config", and "--current" flags, as scheduler setting relates with cgroup (QEMU/LXC), upper layer apps probably need to use virDomainGetSchedulerParameter and virDomainSetSchedulerParametersFlags together, such as virsh, virDomainGetSchedulerParameter looks up parameters, so support changing the scheduler setting on inactive domain probably is not good idea. Regards Osier

Flags may include VIR_DOMAIN_SCHED_PARAMS_LIVE and VIR_DOMAIN_SCHED_PARAMS_PERSISTENT, the first one means changing the domain scheduler setting only for running domain config, and the later one means changing both the running and persistent domain config. Both flags require domain is running, VIR_DOMAIN_SCHED_PARAMS_LIVE is used by default. --- include/libvirt/libvirt.h.in | 14 ++++++++++++++ src/libvirt_public.syms | 5 +++++ 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 04b7fbf..c87608c 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -280,6 +280,13 @@ struct _virSchedParameter { typedef virSchedParameter *virSchedParameterPtr; +/* Domain scheduler parameters setting flags. */ +typedef enum { + /* Both these two flags works on running domain. */ + VIR_DOMAIN_SCHED_PARAMS_LIVE = (1 << 0), /* Affects active domain config */ + VIR_DOMAIN_SCHED_PARAMS_PERSISTENT = (1 << 1), /* Affects both active and persistent domain config. */ +} virDomainSchedParametersFlags; + /* * Fetch scheduler parameters, caller allocates 'params' field of size 'nparams' */ @@ -293,6 +300,13 @@ int virDomainGetSchedulerParameters (virDomainPtr domain, int virDomainSetSchedulerParameters (virDomainPtr domain, virSchedParameterPtr params, int nparams); +/* + * Change scheduler parameters according to flags. + */ +int virDomainSetSchedulerParametersFlags (virDomainPtr domain, + virSchedParameterPtr params, + int nparams, + unsigned int flags); /** * virDomainBlockStats: diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index b4aed41..03d08f1 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -436,4 +436,9 @@ LIBVIRT_0.9.0 { virStorageVolUpload; } LIBVIRT_0.8.8; +LIBVIRT_0.9.1 { + global: + virDomainSetSchedulerParametersFlags; +} LIBVIRT_0.9.0; + # .... define new API here using predicted next version number .... -- 1.7.4

--- src/driver.h | 8 ++++++++ src/esx/esx_driver.c | 1 + src/libxl/libxl_driver.c | 1 + src/lxc/lxc_driver.c | 1 + src/openvz/openvz_driver.c | 1 + src/phyp/phyp_driver.c | 1 + src/qemu/qemu_driver.c | 1 + src/remote/remote_driver.c | 6 ++++-- src/test/test_driver.c | 1 + src/uml/uml_driver.c | 1 + src/vbox/vbox_tmpl.c | 1 + src/vmware/vmware_driver.c | 1 + src/xen/xen_driver.c | 1 + src/xenapi/xenapi_driver.c | 1 + 14 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/driver.h b/src/driver.h index e5f91ca..55ffab2 100644 --- a/src/driver.h +++ b/src/driver.h @@ -276,6 +276,13 @@ typedef int int nparams); typedef int + (*virDrvDomainSetSchedulerParametersFlags) + (virDomainPtr domain, + virSchedParameterPtr params, + int nparams, + unsigned int flags); + +typedef int (*virDrvDomainBlockStats) (virDomainPtr domain, const char *path, @@ -593,6 +600,7 @@ struct _virDriver { virDrvDomainGetSchedulerType domainGetSchedulerType; virDrvDomainGetSchedulerParameters domainGetSchedulerParameters; virDrvDomainSetSchedulerParameters domainSetSchedulerParameters; + virDrvDomainSetSchedulerParametersFlags domainSetSchedulerParametersFlags; virDrvDomainMigratePrepare domainMigratePrepare; virDrvDomainMigratePerform domainMigratePerform; virDrvDomainMigrateFinish domainMigrateFinish; diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index deda372..5c7bd80 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4629,6 +4629,7 @@ static virDriver esxDriver = { esxDomainGetSchedulerType, /* domainGetSchedulerType */ esxDomainGetSchedulerParameters, /* domainGetSchedulerParameters */ esxDomainSetSchedulerParameters, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ esxDomainMigratePrepare, /* domainMigratePrepare */ esxDomainMigratePerform, /* domainMigratePerform */ esxDomainMigrateFinish, /* domainMigrateFinish */ diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 3040914..ef3ea46 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -2617,6 +2617,7 @@ static virDriver libxlDriver = { libxlDomainGetSchedulerType,/* domainGetSchedulerType */ libxlDomainGetSchedulerParameters,/* domainGetSchedulerParameters */ libxlDomainSetSchedulerParameters,/* domainSetSchedulerParameters */ + NULL /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index e905302..72c0a0a 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2860,6 +2860,7 @@ static virDriver lxcDriver = { lxcGetSchedulerType, /* domainGetSchedulerType */ lxcGetSchedulerParameters, /* domainGetSchedulerParameters */ lxcSetSchedulerParameters, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 4af28e9..d3d3365 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1621,6 +1621,7 @@ static virDriver openvzDriver = { NULL, /* domainGetSchedulerType */ NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index ddbc103..dd90fca 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -4026,6 +4026,7 @@ static virDriver phypDriver = { NULL, /* domainGetSchedulerType */ NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 04a5f65..f06dcea 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6924,6 +6924,7 @@ static virDriver qemuDriver = { qemuGetSchedulerType, /* domainGetSchedulerType */ qemuGetSchedulerParameters, /* domainGetSchedulerParameters */ qemuSetSchedulerParameters, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare (v1) */ qemudDomainMigratePerform, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 9310ddf..7fe57d0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -1223,7 +1223,7 @@ initialize_gnutls(char *pkipath, int flags) goto out_of_memory; /* Use default location as long as one of CA certificate, - * client key, and client certificate can not be found in + * client key, and client certificate cannot be found in * $HOME/.pki/libvirt, we don't want to make user confused * with one file is here, the other is there. */ @@ -10672,8 +10672,9 @@ remoteIOEventLoop(virConnectPtr conn, */ VIR_DEBUG("Waking up sleep %d %p %p", tmp->proc_nr, tmp, priv->waitDispatch); virCondSignal(&tmp->cond); + } else { + prev = tmp; } - prev = tmp; tmp = tmp->next; } @@ -11254,6 +11255,7 @@ static virDriver remote_driver = { remoteDomainGetSchedulerType, /* domainGetSchedulerType */ remoteDomainGetSchedulerParameters, /* domainGetSchedulerParameters */ remoteDomainSetSchedulerParameters, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ remoteDomainMigratePrepare, /* domainMigratePrepare */ remoteDomainMigratePerform, /* domainMigratePerform */ remoteDomainMigrateFinish, /* domainMigrateFinish */ diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 17f5ad9..42ec89c 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5401,6 +5401,7 @@ static virDriver testDriver = { testDomainGetSchedulerType, /* domainGetSchedulerType */ testDomainGetSchedulerParams, /* domainGetSchedulerParameters */ testDomainSetSchedulerParams, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 33849a0..852e066 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2207,6 +2207,7 @@ static virDriver umlDriver = { NULL, /* domainGetSchedulerType */ NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 0fbfba5..0d9d17e 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -8591,6 +8591,7 @@ virDriver NAME(Driver) = { NULL, /* domainGetSchedulerType */ NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index b5e416b..1db1b0d 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -961,6 +961,7 @@ static virDriver vmwareDriver = { NULL, /* domainGetSchedulerType */ NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 9f47722..48a777f 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2095,6 +2095,7 @@ static virDriver xenUnifiedDriver = { xenUnifiedDomainGetSchedulerType, /* domainGetSchedulerType */ xenUnifiedDomainGetSchedulerParameters, /* domainGetSchedulerParameters */ xenUnifiedDomainSetSchedulerParameters, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ xenUnifiedDomainMigratePrepare, /* domainMigratePrepare */ xenUnifiedDomainMigratePerform, /* domainMigratePerform */ xenUnifiedDomainMigrateFinish, /* domainMigrateFinish */ diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 60b23c7..db21c1a 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -1843,6 +1843,7 @@ static virDriver xenapiDriver = { xenapiDomainGetSchedulerType, /* domainGetSchedulerType */ NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ -- 1.7.4

--- src/libvirt.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 60 insertions(+), 0 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 0da9885..fae83fe 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -4401,6 +4401,66 @@ error: return -1; } +/** + * virDomainSetSchedulerParameters: + * @domain: pointer to domain object + * @params: pointer to scheduler parameter objects + * @nparams: number of scheduler parameter + * (this value should be same or less than the returned value + * nparams of virDomainGetSchedulerType) + * @flags: an OR'ed set of virDomainMemoryModFlags + * + * Change the scheduler parameters according to the specified flags + * + * @flags may include VIR_DOMAIN_SCHED_PARAMS_LIVE or + * VIR_DOMAIN_SCHED_PARAMS_CONFIG, both flags may be set, and both flags + * requires the domain is running. + * If VIR_DOMAIN_SCHED_PARAMS_LIVE is set, the change affects a running + * domain and will fail if the domain is not active. + * If VIR_DOMAIN_SCHED_PARAMS_CONFIG is set, the change affects both the + * running and persistent domain config, and will fail for transient + * domains or the domain is not active. + + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainSetSchedulerParametersFlags(virDomainPtr domain, + virSchedParameterPtr params, + int nparams, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d", params, nparams); + + 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; + } + conn = domain->conn; + + if (conn->driver->domainSetSchedulerParametersFlags) { + int ret; + ret = conn->driver->domainSetSchedulerParametersFlags (domain, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + /** * virDomainBlockStats: -- 1.7.4

--- python/generator.py | 1 + python/libvirt-override-api.xml | 7 +++ python/libvirt-override.c | 95 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 0 deletions(-) diff --git a/python/generator.py b/python/generator.py index 4fa4f65..a44a4d0 100755 --- a/python/generator.py +++ b/python/generator.py @@ -311,6 +311,7 @@ skip_impl = ( 'virDomainGetSchedulerType', 'virDomainGetSchedulerParameters', 'virDomainSetSchedulerParameters', + 'virDomainSetSchedulerParametersFlags', 'virDomainSetBlkioParameters', 'virDomainGetBlkioParameters', 'virDomainSetMemoryParameters', diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index 54deeb5..490217b 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -162,6 +162,13 @@ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> <arg name='params' type='virSchedParameterPtr' info='pointer to scheduler parameter objects'/> </function> + <function name='virDomainSetSchedulerParametersFlags' file='python'> + <info>Change the scheduler parameters according to flags</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='virSchedParameterPtr' info='pointer to scheduler parameter objects'/> + <arg name='flags' type='unsigned int' info='scheduler parameters setting flags'/> + </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.'/> diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 4a9b432..35e823c 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -371,7 +371,101 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, return VIR_PY_INT_SUCCESS; } +static PyObject * +libvirt_virDomainSetSchedulerParametersFlags(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) { + virDomainPtr domain; + PyObject *pyobj_domain, *info; + char *c_retval; + int i_retval; + int nparams, i; + virSchedParameterPtr params; + unsigned int flags; + + if (!PyArg_ParseTuple(args, (char *)"OO:virDomainSetScedulerParameters", + &pyobj_domain, &info, &flags)) + return(NULL); + domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); + + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virDomainGetSchedulerType(domain, &nparams); + LIBVIRT_END_ALLOW_THREADS; + + if (c_retval == NULL) + return VIR_PY_INT_FAIL; + free(c_retval); + + if ((params = malloc(sizeof(*params)*nparams)) == NULL) + return VIR_PY_INT_FAIL; + + LIBVIRT_BEGIN_ALLOW_THREADS; + i_retval = virDomainGetSchedulerParameters(domain, params, &nparams); + LIBVIRT_END_ALLOW_THREADS; + + if (i_retval < 0) { + free(params); + return VIR_PY_INT_FAIL; + } + + /* convert to a Python tuple of long objects */ + for (i = 0 ; i < nparams ; i++) { + PyObject *key, *val; + key = libvirt_constcharPtrWrap(params[i].field); + val = PyDict_GetItem(info, key); + Py_DECREF(key); + + if (val == NULL) + continue; + + switch (params[i].type) { + case VIR_DOMAIN_SCHED_FIELD_INT: + params[i].value.i = (int)PyInt_AS_LONG(val); + break; + + case VIR_DOMAIN_SCHED_FIELD_UINT: + params[i].value.ui = (unsigned int)PyInt_AS_LONG(val); + break; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + params[i].value.l = (long long)PyLong_AsLongLong(val); + break; + + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + params[i].value.ul = (unsigned long long)PyLong_AsLongLong(val); + break; + + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + params[i].value.d = (double)PyFloat_AsDouble(val); + break; + + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + { + /* Hack - Python's definition of Py_True breaks strict + * aliasing rules, so can't directly compare :-( + */ + PyObject *hacktrue = PyBool_FromLong(1); + params[i].value.b = hacktrue == val ? 1 : 0; + Py_DECREF(hacktrue); + } + break; + + default: + free(params); + return VIR_PY_INT_FAIL; + } + } + + LIBVIRT_BEGIN_ALLOW_THREADS; + i_retval = virDomainSetSchedulerParametersFlags(domain, params, nparams, flags); + LIBVIRT_END_ALLOW_THREADS; + if (i_retval < 0) { + free(params); + return VIR_PY_INT_FAIL; + } + + free(params); + return VIR_PY_INT_SUCCESS; +} /* FIXME: This is a place holder for the implementation. */ @@ -3549,6 +3643,7 @@ 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 *) "virDomainSetSchedulerParametersFlags", libvirt_virDomainSetSchedulerParametersFlags, METH_VARARGS, NULL}, {(char *) "virDomainSetBlkioParameters", libvirt_virDomainSetBlkioParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetBlkioParameters", libvirt_virDomainGetBlkioParameters, METH_VARARGS, NULL}, {(char *) "virDomainSetMemoryParameters", libvirt_virDomainSetMemoryParameters, METH_VARARGS, NULL}, -- 1.7.4

--- daemon/remote.c | 71 ++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 1 + daemon/remote_dispatch_prototypes.h | 8 ++++ daemon/remote_dispatch_table.h | 5 ++ src/remote/remote_driver.c | 77 +++++++++++++++++++++++++++++++++-- src/remote/remote_protocol.c | 15 +++++++ src/remote/remote_protocol.h | 13 ++++++ src/remote/remote_protocol.x | 9 ++++- 8 files changed, 194 insertions(+), 5 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index dd85ef1..3ad116b 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -921,6 +921,77 @@ remoteDispatchDomainSetSchedulerParameters (struct qemud_server *server ATTRIBUT } static int +remoteDispatchDomainSetSchedulerParametersFlags (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_scheduler_parameters_flags_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom; + int i, r, nparams; + virSchedParameterPtr params; + unsigned int flags; + + nparams = args->params.params_len; + + if (nparams > REMOTE_DOMAIN_SCHEDULER_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_SCHED_FIELD_INT: + params[i].value.i = args->params.params_val[i].value.remote_sched_param_value_u.i; break; + case VIR_DOMAIN_SCHED_FIELD_UINT: + params[i].value.ui = args->params.params_val[i].value.remote_sched_param_value_u.ui; break; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + params[i].value.l = args->params.params_val[i].value.remote_sched_param_value_u.l; break; + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + params[i].value.ul = args->params.params_val[i].value.remote_sched_param_value_u.ul; break; + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + params[i].value.d = args->params.params_val[i].value.remote_sched_param_value_u.d; break; + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + params[i].value.b = args->params.params_val[i].value.remote_sched_param_value_u.b; break; + } + } + + dom = get_nonnull_domain (conn, args->dom); + if (dom == NULL) { + VIR_FREE(params); + remoteDispatchConnError(rerr, conn); + return -1; + } + + flags = args->flags; + + r = virDomainSetSchedulerParametersFlags (dom, params, nparams, flags); + VIR_FREE(params); + if (r == -1) { + remoteDispatchConnError(rerr, conn); + virDomainFree(dom); + return -1; + } + virDomainFree(dom); + + return 0; +} + + +static int remoteDispatchDomainBlockStats (struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, virConnectPtr conn, diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h index f9537d7..5cb2572 100644 --- a/daemon/remote_dispatch_args.h +++ b/daemon/remote_dispatch_args.h @@ -178,3 +178,4 @@ remote_domain_migrate_set_max_speed_args val_remote_domain_migrate_set_max_speed_args; remote_storage_vol_upload_args val_remote_storage_vol_upload_args; remote_storage_vol_download_args val_remote_storage_vol_download_args; + remote_domain_set_scheduler_parameters_flags_args val_remote_domain_set_scheduler_parameters_flags_args; diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h index 18bf41d..8b249ad 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -602,6 +602,14 @@ static int remoteDispatchDomainSetSchedulerParameters( remote_error *err, remote_domain_set_scheduler_parameters_args *args, void *ret); +static int remoteDispatchDomainSetSchedulerParametersFlags( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_set_scheduler_parameters_flags_args *args, + void *ret); static int remoteDispatchDomainSetVcpus( struct qemud_server *server, struct qemud_client *client, diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h index b39f7c2..96485eb 100644 --- a/daemon/remote_dispatch_table.h +++ b/daemon/remote_dispatch_table.h @@ -1052,3 +1052,8 @@ .args_filter = (xdrproc_t) xdr_remote_storage_vol_download_args, .ret_filter = (xdrproc_t) xdr_void, }, +{ /* DomainSetSchedulerParametersFlags => 210 */ + .fn = (dispatch_fn) remoteDispatchDomainSetSchedulerParametersFlags, + .args_filter = (xdrproc_t) xdr_remote_domain_set_scheduler_parameters_flags_args, + .ret_filter = (xdrproc_t) xdr_void, +}, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 7fe57d0..c89cef5 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -1223,7 +1223,7 @@ initialize_gnutls(char *pkipath, int flags) goto out_of_memory; /* Use default location as long as one of CA certificate, - * client key, and client certificate cannot be found in + * client key, and client certificate can not be found in * $HOME/.pki/libvirt, we don't want to make user confused * with one file is here, the other is there. */ @@ -4058,6 +4058,76 @@ done: } static int +remoteDomainSetSchedulerParametersFlags (virDomainPtr domain, + virSchedParameterPtr params, + int nparams, + unsigned int flags) +{ + int rv = -1; + remote_domain_set_scheduler_parameters_flags_args args; + int i, do_error; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + + /* Serialise the scheduler parameters. */ + args.params.params_len = nparams; + 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_SCHED_FIELD_INT: + args.params.params_val[i].value.remote_sched_param_value_u.i = params[i].value.i; break; + case VIR_DOMAIN_SCHED_FIELD_UINT: + args.params.params_val[i].value.remote_sched_param_value_u.ui = params[i].value.ui; break; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + args.params.params_val[i].value.remote_sched_param_value_u.l = params[i].value.l; break; + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + args.params.params_val[i].value.remote_sched_param_value_u.ul = params[i].value.ul; break; + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + args.params.params_val[i].value.remote_sched_param_value_u.d = params[i].value.d; break; + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + args.params.params_val[i].value.remote_sched_param_value_u.b = params[i].value.b; break; + default: + remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type")); + do_error = 1; + } + } + + args.flags = flags; + + if (do_error) { + xdr_free ((xdrproc_t) xdr_remote_domain_set_scheduler_parameters_flags_args, (char *) &args); + goto done; + } + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS_FLAGS, + (xdrproc_t) xdr_remote_domain_set_scheduler_parameters_flags_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + + +static int remoteDomainBlockStats (virDomainPtr domain, const char *path, struct _virDomainBlockStats *stats) { @@ -10672,9 +10742,8 @@ remoteIOEventLoop(virConnectPtr conn, */ VIR_DEBUG("Waking up sleep %d %p %p", tmp->proc_nr, tmp, priv->waitDispatch); virCondSignal(&tmp->cond); - } else { - prev = tmp; } + prev = tmp; tmp = tmp->next; } @@ -11255,7 +11324,7 @@ static virDriver remote_driver = { remoteDomainGetSchedulerType, /* domainGetSchedulerType */ remoteDomainGetSchedulerParameters, /* domainGetSchedulerParameters */ remoteDomainSetSchedulerParameters, /* domainSetSchedulerParameters */ - NULL, /* domainSetSchedulerParametersFlags */ + remoteDomainSetSchedulerParametersFlags, /* domainSetSchedulerParametersFlags */ remoteDomainMigratePrepare, /* domainMigratePrepare */ remoteDomainMigratePerform, /* domainMigratePerform */ remoteDomainMigrateFinish, /* domainMigrateFinish */ diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c index 5604371..5036cac 100644 --- a/src/remote/remote_protocol.c +++ b/src/remote/remote_protocol.c @@ -693,6 +693,21 @@ xdr_remote_domain_set_scheduler_parameters_args (XDR *xdrs, remote_domain_set_sc } bool_t +xdr_remote_domain_set_scheduler_parameters_flags_args (XDR *xdrs, remote_domain_set_scheduler_parameters_flags_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_SCHEDULER_PARAMETERS_MAX, + sizeof (remote_sched_param), (xdrproc_t) xdr_remote_sched_param)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +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; diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h index d9bf151..ec576a0 100644 --- a/src/remote/remote_protocol.h +++ b/src/remote/remote_protocol.h @@ -357,6 +357,16 @@ 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_scheduler_parameters_flags_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_sched_param *params_val; + } params; + u_int flags; +}; +typedef struct remote_domain_set_scheduler_parameters_flags_args remote_domain_set_scheduler_parameters_flags_args; + struct remote_domain_set_blkio_parameters_args { remote_nonnull_domain dom; struct { @@ -2413,6 +2423,7 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, + REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS_FLAGS = 210, }; typedef enum remote_procedure remote_procedure; @@ -2494,6 +2505,7 @@ 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_scheduler_parameters_flags_args (XDR *, remote_domain_set_scheduler_parameters_flags_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*); @@ -2851,6 +2863,7 @@ extern bool_t xdr_remote_domain_get_scheduler_type_ret (); extern bool_t xdr_remote_domain_get_scheduler_parameters_args (); extern bool_t xdr_remote_domain_get_scheduler_parameters_ret (); extern bool_t xdr_remote_domain_set_scheduler_parameters_args (); +extern bool_t xdr_remote_domain_set_scheduler_parameters_flags_args (); extern bool_t xdr_remote_domain_set_blkio_parameters_args (); extern bool_t xdr_remote_domain_get_blkio_parameters_args (); extern bool_t xdr_remote_domain_get_blkio_parameters_ret (); diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 675eccd..a320fe0 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -476,6 +476,12 @@ struct remote_domain_set_scheduler_parameters_args { remote_sched_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>; }; +struct remote_domain_set_scheduler_parameters_flags_args { + remote_nonnull_domain dom; + remote_sched_param params<REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX>; + unsigned int flags; +}; + struct remote_domain_set_blkio_parameters_args { remote_nonnull_domain dom; remote_blkio_param params<REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX>; @@ -2176,7 +2182,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 206, REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, - REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209 + REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, + REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS_FLAGS = 210 /* * Notice how the entries are grouped in sets of 10 ? -- 1.7.4

--- src/qemu/qemu_driver.c | 64 +++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f06dcea..1c71962 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4651,37 +4651,59 @@ cleanup: return ret; } -static int qemuSetSchedulerParameters(virDomainPtr dom, - virSchedParameterPtr params, - int nparams) +static int qemuSetSchedulerParametersFlags(virDomainPtr dom, + virSchedParameterPtr params, + int nparams, + unsigned int flags) { struct qemud_driver *driver = dom->conn->privateData; int i; virCgroupPtr group = NULL; virDomainObjPtr vm = NULL; + virDomainDefPtr persistentDef = NULL; int ret = -1; - qemuDriverLock(driver); + virCheckFlags(VIR_DOMAIN_SCHED_PARAMS_LIVE | + VIR_DOMAIN_SCHED_PARAMS_PERSISTENT, -1); + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("cgroup CPU controller is not mounted")); goto cleanup; } + qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); + qemuDriverUnlock(driver); if (vm == NULL) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("No such domain %s"), dom->uuid); + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(dom->uuid, uuidstr); + qemuReportError(VIR_ERR_NO_DOMAIN, + _("No domain with uuid: %s"), uuidstr); goto cleanup; } + /* Could find the cgroup for domain implies the domain is running. */ if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), vm->def->name); + _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; } + if (qemuDomainObjBeginJob(vm) < 0) + goto cleanup; + + if (flags & VIR_DOMAIN_SCHED_PARAMS_PERSISTENT) { + if (!vm->persistent) { + qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot change persistent config of a transient domain")); + goto endjob; + } + if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm))) + goto endjob; + } + for (i = 0; i < nparams; i++) { virSchedParameterPtr param = ¶ms[i]; @@ -4690,25 +4712,35 @@ static int qemuSetSchedulerParameters(virDomainPtr dom, if (param->type != VIR_DOMAIN_SCHED_FIELD_ULLONG) { qemuReportError(VIR_ERR_INVALID_ARG, "%s", _("invalid type for cpu_shares tunable, expected a 'ullong'")); - goto cleanup; + goto endjob; } rc = virCgroupSetCpuShares(group, params[i].value.ul); if (rc != 0) { virReportSystemError(-rc, "%s", - _("unable to set cpu shares tunable")); - goto cleanup; + _("unable to set cpu shares tunable")); + goto endjob; } vm->def->cputune.shares = params[i].value.ul; + + if (flags & VIR_DOMAIN_SCHED_PARAMS_PERSISTENT) { + persistentDef->cputune.shares = params[i].value.ul; + ret = virDomainSaveConfig(driver->configDir, persistentDef); + goto endjob; + } } else { qemuReportError(VIR_ERR_INVALID_ARG, _("Invalid parameter `%s'"), param->field); - goto cleanup; + goto endjob; } } ret = 0; +endjob: + if (qemuDomainObjEndJob(vm) == 0) + vm = NULL; + cleanup: virCgroupFree(&group); if (vm) @@ -4717,6 +4749,14 @@ cleanup: return ret; } +static int qemuSetSchedulerParameters(virDomainPtr dom, + virSchedParameterPtr params, + int nparams) +{ + return qemuSetSchedulerParametersFlags(dom, params, nparams, + VIR_DOMAIN_SCHED_PARAMS_LIVE); +} + static int qemuGetSchedulerParameters(virDomainPtr dom, virSchedParameterPtr params, int *nparams) @@ -6924,7 +6964,7 @@ static virDriver qemuDriver = { qemuGetSchedulerType, /* domainGetSchedulerType */ qemuGetSchedulerParameters, /* domainGetSchedulerParameters */ qemuSetSchedulerParameters, /* domainSetSchedulerParameters */ - NULL, /* domainSetSchedulerParametersFlags */ + qemuSetSchedulerParametersFlags, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare (v1) */ qemudDomainMigratePerform, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ -- 1.7.4

--- src/lxc/lxc_driver.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 72c0a0a..5db1035 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2244,21 +2244,28 @@ static char *lxcGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED, return schedulerType; } -static int lxcSetSchedulerParameters(virDomainPtr domain, - virSchedParameterPtr params, - int nparams) +static int lxcSetSchedulerParametersFlags(virDomainPtr domain, + virSchedParameterPtr params, + int nparams, + unsigned int flags) { lxc_driver_t *driver = domain->conn->privateData; int i; virCgroupPtr group = NULL; virDomainObjPtr vm = NULL; + virDomainDefPtr persistentDef = NULL; int ret = -1; + bool isActive; + + virCheckFlags(VIR_DOMAIN_SCHED_PARAMS_LIVE | + VIR_DOMAIN_SCHED_PARAMS_PERSISTENT, -1); if (driver->cgroup == NULL) return -1; lxcDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, domain->uuid); + lxcDriverUnlock(driver); if (vm == NULL) { char uuidstr[VIR_UUID_STRING_BUFLEN]; @@ -2268,9 +2275,20 @@ static int lxcSetSchedulerParameters(virDomainPtr domain, goto cleanup; } + /* Could find cgroup for domain implies the domain is running. */ if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) goto cleanup; + if (flags & VIR_DOMAIN_SCHED_PARAMS_PERSISTENT) { + if (!vm->persistent) { + lxcError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot change persistent config of a transient domain")); + goto cleanup; + } + if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm))) + goto cleanup; + } + for (i = 0; i < nparams; i++) { virSchedParameterPtr param = ¶ms[i]; @@ -2294,17 +2312,30 @@ static int lxcSetSchedulerParameters(virDomainPtr domain, } vm->def->cputune.shares = params[i].value.ul; + + if (flags & VIR_DOMAIN_SCHED_PARAMS_PERSISTENT) { + persistentDef->cputune.shares = params[i].value.ul; + ret = virDomainSaveConfig(driver->configDir, persistentDef); + goto cleanup; + } } ret = 0; cleanup: - lxcDriverUnlock(driver); virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); return ret; } +static int lxcSetSchedulerParameters(virDomainPtr domain, + virSchedParameterPtr params, + int nparams) +{ + return lxcSetSchedulerParametersFlags(domain, params, nparams, + VIR_DOMAIN_SCHED_PARAMS_LIVE); +} + static int lxcGetSchedulerParameters(virDomainPtr domain, virSchedParameterPtr params, int *nparams) @@ -2860,7 +2891,7 @@ static virDriver lxcDriver = { lxcGetSchedulerType, /* domainGetSchedulerType */ lxcGetSchedulerParameters, /* domainGetSchedulerParameters */ lxcSetSchedulerParameters, /* domainSetSchedulerParameters */ - NULL, /* domainSetSchedulerParametersFlags */ + lxcSetSchedulerParametersFlags, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare */ NULL, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ -- 1.7.4

--- tools/virsh.c | 26 +++++++++++++++++++++++--- tools/virsh.pod | 8 +++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 2e35021..e6e80b5 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -1598,6 +1598,8 @@ static const vshCmdOptDef opts_schedinfo[] = { {"set", VSH_OT_STRING, VSH_OFLAG_NONE, N_("parameter=value")}, {"weight", VSH_OT_INT, VSH_OFLAG_NONE, N_("weight for XEN_CREDIT")}, {"cap", VSH_OT_INT, VSH_OFLAG_NONE, N_("cap for XEN_CREDIT")}, + {"live", VSH_OT_BOOL, 0, N_("affect running domain")}, + {"persistent", VSH_OT_BOOL, 0, N_("affect both running domain and next boot")}, {NULL, 0, 0, NULL} }; @@ -1705,6 +1707,18 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) int update = 0; int i, ret; int ret_val = FALSE; + int live = vshCommandOptBool(cmd, "live"); + int persistent = vshCommandOptBool(cmd, "persistent"); + int flags = 0; + + if (live) + flags |= VIR_DOMAIN_SCHED_PARAMS_LIVE; + if (persistent) + flags |= VIR_DOMAIN_SCHED_PARAMS_PERSISTENT; + + /* neither option is specified */ + if (!live && !persistent) + flags = -1; if (!vshConnectionUsability(ctl, ctl->conn)) return FALSE; @@ -1714,9 +1728,10 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) /* Print SchedulerType */ schedulertype = virDomainGetSchedulerType(dom, &nparams); - if (schedulertype!= NULL){ + + if (schedulertype != NULL){ vshPrint(ctl, "%-15s: %s\n", _("Scheduler"), - schedulertype); + schedulertype); VIR_FREE(schedulertype); } else { vshPrint(ctl, "%-15s: %s\n", _("Scheduler"), _("Unknown")); @@ -1743,7 +1758,12 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) /* Update parameters & refresh data */ if (update) { - ret = virDomainSetSchedulerParameters(dom, params, nparams); + if (flags == -1) + ret = virDomainSetSchedulerParameters(dom, params, nparams); + else { + ret = virDomainSetSchedulerParametersFlags(dom, params, nparams, flags); + } + if (ret == -1) goto cleanup; diff --git a/tools/virsh.pod b/tools/virsh.pod index 2a708f6..8c1005b 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -567,7 +567,8 @@ severed upon restore, as TCP timeouts may have expired. =item B<schedinfo> optional I<--set> B<parameter=value> I<domain-id> -=item B<schedinfo> optional I<--weight> B<number> optional I<--cap> B<number> I<domain-id> +=item B<schedinfo> optional I<--weight> B<number> optional I<--cap> B<number> +I<domain-id> I<--live> I<--persistent> Allows you to show (and set) the domain scheduler parameters. The parameters available for each hypervisor are: @@ -577,6 +578,11 @@ Xen (credit scheduler): weight, cap ESX (allocation scheduler): reservation, limit, shares +Both I<--live> and I<--persistent> may be set, and both of them requires the domain +is running, I<--live> affects the running domain and fails if the domain is not +active. I<--persistent> affects both the active and persistent domain config, and +fails if the domain is transient or not active. I<--live> is the default flag. + B<Note>: The cpu_shares parameter has a valid value range of 0-262144; Negative values are wrapped to positive, and larger values are capped at the maximum. Therefore, -1 is a useful shorthand for 262144. -- 1.7.4
participants (1)
-
Osier Yang