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