[libvirt] [PATCH 0/4] support for changing cpu.shares for inactive domains from virsh cmd

Currently cpu.shares can only be configured by editing domains' xmls. this series enables us to change cpu.shares from virsh cmd schedinfo even when domain is inactive. Hu Tao (4): introduce virDomainSetSchedulerParametersFlags qemu: introduce qemuSetSchedulerParametersFlags remote: introduce remoteSetSchedulerParametersFlags virsh: add --persistent to cmd schedinfo daemon/remote.c | 71 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 1 + daemon/remote_dispatch_prototypes.h | 8 ++++ daemon/remote_dispatch_table.h | 5 ++ include/libvirt/libvirt.h.in | 13 ++++++ python/generator.py | 1 + src/driver.h | 8 ++++ src/esx/esx_driver.c | 1 + src/libvirt.c | 62 ++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++ 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 | 66 +++++++++++++++++++++++++------- src/remote/remote_driver.c | 69 ++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.c | 15 +++++++ src/remote/remote_protocol.h | 12 ++++++ src/remote/remote_protocol.x | 10 ++++- 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 + tools/virsh.c | 14 ++++++- 26 files changed, 354 insertions(+), 17 deletions(-) -- 1.7.3.1 -- Thanks, Hu Tao

This new function allows aditional flags to be passed into from the virsh command line. --- include/libvirt/libvirt.h.in | 13 +++++++++ python/generator.py | 1 + src/driver.h | 8 +++++ src/esx/esx_driver.c | 1 + src/libvirt.c | 62 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ 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 | 1 + 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 + 18 files changed, 102 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 5783303..2c38118 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -243,6 +243,11 @@ typedef enum { VIR_DOMAIN_SCHED_FIELD_BOOLEAN = 6 /* boolean(character) case */ } virSchedParameterType; +typedef enum { + VIR_DOMAIN_SCHEDPARAM_LIVE = (1 << 0), /* Affect active domain */ + VIR_DOMAIN_SCHEDPARAM_CONFIG = (1 << 1), /* Affect next boot */ +} virDomainSchedParameterFlags; + /** * VIR_DOMAIN_SCHED_FIELD_LENGTH: * @@ -294,6 +299,14 @@ int virDomainSetSchedulerParameters (virDomainPtr domain, virSchedParameterPtr params, int nparams); +/* + * Change scheduler parameters + */ +int virDomainSetSchedulerParametersFlags (virDomainPtr domain, + virSchedParameterPtr params, + int nparams, + unsigned int flags); + /** * virDomainBlockStats: * 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/src/driver.h b/src/driver.h index a8b79e6..3347a53 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 7933f11..181d6aa 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4653,6 +4653,7 @@ static virDriver esxDriver = { esxDomainGetSchedulerType, /* domainGetSchedulerType */ esxDomainGetSchedulerParameters, /* domainGetSchedulerParameters */ esxDomainSetSchedulerParameters, /* domainSetSchedulerParameters */ + NULL, /* domainSetSchedulerParametersFlags */ esxDomainMigratePrepare, /* domainMigratePrepare */ esxDomainMigratePerform, /* domainMigratePerform */ esxDomainMigrateFinish, /* domainMigrateFinish */ diff --git a/src/libvirt.c b/src/libvirt.c index e74e977..92e804e 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -4409,6 +4409,68 @@ error: /** + * virDomainSetSchedulerParametersFlags: + * @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: virDomainSchedParameterFlags + * + * Change the scheduler parameters + * + * 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, flags=%u", + params, nparams, flags); + + virResetLastError(); + + if (!(flags & (VIR_DOMAIN_SCHEDPARAM_LIVE | VIR_DOMAIN_SCHEDPARAM_CONFIG))) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + 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: * @dom: pointer to the domain object * @path: path to the block device 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 .... diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index dec4f43..270bef9 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -2700,6 +2700,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 b94941d..e8afcd3 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2859,6 +2859,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 0bd007a..1c11e73 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 30d4adf..d2f30d2 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -3782,6 +3782,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 dd89786..15c5744 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7148,6 +7148,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 e30780c..0f8040b 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -11252,6 +11252,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 0978214..abe4283 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 8241d34..6ec0f1a 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -8596,6 +8596,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 bbfb1a4..fc667fe 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 dd94fbc..41b48ae 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2162,6 +2162,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 3fbdcc6..a57c98f 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.3.1 -- Thanks, Hu Tao

Support for virDomainSetSchedulerParametersFlags of qemu driver. --- src/qemu/qemu_driver.c | 67 ++++++++++++++++++++++++++++++++++++----------- 1 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 15c5744..c769637 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4768,7 +4768,7 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom, goto cleanup; } - if (!virDomainObjIsActive(vm)) { + if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_SCHEDPARAM_LIVE)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); goto cleanup; @@ -4862,16 +4862,21 @@ 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; + virCheckFlags(VIR_DOMAIN_SCHEDPARAM_LIVE | + VIR_DOMAIN_SCHEDPARAM_CONFIG, -1); + qemuDriverLock(driver); if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { qemuReportError(VIR_ERR_OPERATION_INVALID, @@ -4887,13 +4892,14 @@ static int qemuSetSchedulerParameters(virDomainPtr dom, goto cleanup; } - if (!virDomainObjIsActive(vm)) { + if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_SCHEDPARAM_LIVE)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); goto cleanup; } - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + if ((flags & VIR_DOMAIN_SCHEDPARAM_LIVE) && + 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; @@ -4910,20 +4916,39 @@ static int qemuSetSchedulerParameters(virDomainPtr dom, goto cleanup; } - rc = virCgroupSetCpuShares(group, params[i].value.ul); - if (rc != 0) { - virReportSystemError(-rc, "%s", - _("unable to set cpu shares tunable")); - goto cleanup; + if (flags & VIR_DOMAIN_SCHEDPARAM_LIVE) { + rc = virCgroupSetCpuShares(group, params[i].value.ul); + if (rc != 0) { + virReportSystemError(-rc, "%s", + _("unable to set cpu shares tunable")); + goto cleanup; + } + + vm->def->cputune.shares = params[i].value.ul; } - vm->def->cputune.shares = params[i].value.ul; + if (flags & VIR_DOMAIN_SCHEDPARAM_CONFIG) { + persistentDef = virDomainObjGetPersistentDef(driver->caps, vm); + if (!persistentDef) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("can't get persistentDef")); + goto cleanup; + } + persistentDef->cputune.shares = params[i].value.ul; + rc = virDomainSaveConfig(driver->configDir, persistentDef); + if (rc) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("can't save config")); + goto cleanup; + } + } } else { qemuReportError(VIR_ERR_INVALID_ARG, _("Invalid parameter `%s'"), param->field); goto cleanup; } } + ret = 0; cleanup: @@ -4934,6 +4959,16 @@ cleanup: return ret; } +static int qemuSetSchedulerParameters(virDomainPtr dom, + virSchedParameterPtr params, + int nparams) +{ + return qemuSetSchedulerParametersFlags(dom, + params, + nparams, + VIR_DOMAIN_SCHEDPARAM_LIVE); +} + static int qemuGetSchedulerParameters(virDomainPtr dom, virSchedParameterPtr params, int *nparams) @@ -4967,9 +5002,8 @@ static int qemuGetSchedulerParameters(virDomainPtr dom, } if (!virDomainObjIsActive(vm)) { - qemuReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("domain is not running")); - goto cleanup; + val = vm->def->cputune.shares; + goto out; } if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { @@ -4984,6 +5018,7 @@ static int qemuGetSchedulerParameters(virDomainPtr dom, _("unable to get cpu shares tunable")); goto cleanup; } +out: params[0].value.ul = val; params[0].type = VIR_DOMAIN_SCHED_FIELD_ULLONG; if (virStrcpyStatic(params[0].field, "cpu_shares") == NULL) { @@ -7148,7 +7183,7 @@ static virDriver qemuDriver = { qemuGetSchedulerType, /* domainGetSchedulerType */ qemuGetSchedulerParameters, /* domainGetSchedulerParameters */ qemuSetSchedulerParameters, /* domainSetSchedulerParameters */ - NULL, /* domainSetSchedulerParametersFlags */ + qemuSetSchedulerParametersFlags, /* domainSetSchedulerParametersFlags */ NULL, /* domainMigratePrepare (v1) */ qemudDomainMigratePerform, /* domainMigratePerform */ NULL, /* domainMigrateFinish */ -- 1.7.3.1 -- Thanks, Hu Tao

support for virDomainSetSchedulerParametersFlags of remote driver. --- 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 | 70 ++++++++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 15 +++++++ src/remote/remote_protocol.h | 12 ++++++ src/remote/remote_protocol.x | 10 ++++- 8 files changed, 190 insertions(+), 2 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 214f7a4..e93e87a 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1032,6 +1032,77 @@ cleanup: } 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 = NULL; + virSchedParameterPtr params = NULL; + int i, nparams; + int rv = -1; + + if (!conn) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + nparams = args->params.params_len; + + if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large")); + goto cleanup; + } + if (VIR_ALLOC_N(params, nparams) < 0) { + virReportOOMError(); + goto cleanup; + } + + /* Deserialise parameters. */ + for (i = 0; i < nparams; ++i) { + if (virStrcpyStatic(params[i].field, args->params.params_val[i].field) == NULL) { + virNetError(VIR_ERR_INTERNAL_ERROR, _("Field %s too big for destination"), + args->params.params_val[i].field); + goto cleanup; + } + 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; + } + } + + if (!(dom = get_nonnull_domain(conn, args->dom))) + goto cleanup; + + if (virDomainSetSchedulerParametersFlags(dom, params, nparams, args->flags) < 0) + goto cleanup; + + rv = 0; + +cleanup: + if (rv < 0) + remoteDispatchError(rerr); + if (dom) + virDomainFree(dom); + VIR_FREE(params); + return rv; +} + +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 cf2f38c..4de06aa 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -602,6 +602,14 @@ static int remoteDispatchDomainSetSchedulerParameters( remote_error *rerr, 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 *rerr, + 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 0f8040b..0719bf0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -4058,6 +4058,74 @@ 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; + 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_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; + } + } + + 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) { @@ -11252,7 +11320,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..cb940b4 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..0b7088e 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*); diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 675eccd..4851786 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,9 @@ 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.3.1 -- Thanks, Hu Tao

This enables user to modify cpu.shares even when domain is inactive. --- tools/virsh.c | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index e32680c..d03e501 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -1590,6 +1590,7 @@ 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")}, + {"persistent", VSH_OT_BOOL, 0, N_("persist VM on destination")}, {NULL, 0, 0, NULL} }; @@ -1697,6 +1698,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) int update = 0; int i, ret; bool ret_val = false; + unsigned int flags = 0; if (!vshConnectionUsability(ctl, ctl->conn)) return false; @@ -1704,6 +1706,16 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) return false; + if (vshCommandOptBool(cmd, "persistent")) + flags |= VIR_DOMAIN_SCHEDPARAM_CONFIG; + if (virDomainIsActive(dom)) + flags |= VIR_DOMAIN_SCHEDPARAM_LIVE; + + if (!(flags & (VIR_DOMAIN_SCHEDPARAM_CONFIG | VIR_DOMAIN_SCHEDPARAM_LIVE))) { + vshError(ctl, "%s", _("Domain is not running and you didn't specify --persistent parameter.")); + goto cleanup; + } + /* Print SchedulerType */ schedulertype = virDomainGetSchedulerType(dom, &nparams); if (schedulertype!= NULL){ @@ -1735,7 +1747,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) /* Update parameters & refresh data */ if (update) { - ret = virDomainSetSchedulerParameters(dom, params, nparams); + ret = virDomainSetSchedulerParametersFlags(dom, params, nparams, flags); if (ret == -1) goto cleanup; -- 1.7.3.1 -- Thanks, Hu Tao
participants (1)
-
Hu Tao