From 28a3605906385cba43df77051dc26e865f237b09 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 29 Sep 2010 17:40:45 -0600 Subject: [PATCH 11/15] vcpu: complete vcpu support in qemu driver * src/qemu/qemu_driver.c (qemudDomainSetVcpusFlags) (qemudDomainGetVcpusFlags): Support all feasible flag combinations. --- src/qemu/qemu_driver.c | 100 ++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 85 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c66dc04..a9e057f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5941,13 +5941,27 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; + virDomainDefPtr def; const char * type; int max; int ret = -1; - if (flags != VIR_DOMAIN_VCPU_LIVE) { - qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), - flags); + virCheckFlags(VIR_DOMAIN_VCPU_LIVE | + VIR_DOMAIN_VCPU_CONFIG | + VIR_DOMAIN_VCPU_MAXIMUM, -1); + + /* At least one of LIVE or CONFIG must be set. MAXIMUM cannot be + * mixed with LIVE. */ + if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 || + (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) == + (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) { + qemuReportError(VIR_ERR_INVALID_ARG, + _("invalid flag combination: (0x%x)"), flags); + return -1; + } + if (!nvcpus || (unsigned short) nvcpus != nvcpus) { + qemuReportError(VIR_ERR_INVALID_ARG, + _("argument out of range: %d"), nvcpus); return -1; } @@ -5966,7 +5980,7 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, if (qemuDomainObjBeginJob(vm) < 0) goto cleanup; - if (!virDomainObjIsActive(vm)) { + if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_VCPU_LIVE)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); goto endjob; @@ -5985,6 +5999,11 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, goto endjob; } + if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) == + VIR_DOMAIN_VCPU_LIVE && vm->def->maxvcpus < max) { + max = vm->def->maxvcpus; + } + if (nvcpus > max) { qemuReportError(VIR_ERR_INVALID_ARG, _("requested vcpus is greater than max allowable" @@ -5992,7 +6011,49 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, goto endjob; } - ret = qemudDomainHotplugVcpus(vm, nvcpus); + switch (flags) { + case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG: + def = vm->def; + if (virDomainObjIsActive(vm)) { + if (vm->newDef) + def = vm->newDef; + else{ + qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("no persistent state")); + goto endjob; + } + } + def->maxvcpus = nvcpus; + if (nvcpus < vm->newDef->vcpus) + def->vcpus = nvcpus; + ret = 0; + break; + + case VIR_DOMAIN_VCPU_CONFIG: + def = vm->def; + if (virDomainObjIsActive(vm)) { + if (vm->newDef) + def = vm->newDef; + else { + qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("no persistent state")); + goto endjob; + } + } + def->vcpus = nvcpus; + ret = 0; + break; + + case VIR_DOMAIN_VCPU_LIVE: + ret = qemudDomainHotplugVcpus(vm, nvcpus); + break; + + case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG: + ret = qemudDomainHotplugVcpus(vm, nvcpus); + if (ret == 0 && vm->newDef) + vm->newDef->vcpus = nvcpus; + break; + } endjob: if (qemuDomainObjEndJob(vm) == 0) @@ -6171,12 +6232,17 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; - const char *type; + virDomainDefPtr def; int ret = -1; - if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) { - qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), - flags); + virCheckFlags(VIR_DOMAIN_VCPU_LIVE | + VIR_DOMAIN_VCPU_CONFIG | + VIR_DOMAIN_VCPU_MAXIMUM, -1); + + /* Exactly one of LIVE or CONFIG must be set. */ + if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) { + qemuReportError(VIR_ERR_INVALID_ARG, + _("invalid flag combination: (0x%x)"), flags); return -1; } @@ -6192,14 +6258,18 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) goto cleanup; } - if (!(type = virDomainVirtTypeToString(vm->def->virtType))) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("unknown virt type in domain definition '%d'"), - vm->def->virtType); - goto cleanup; + if (flags & VIR_DOMAIN_VCPU_LIVE) { + if (!virDomainObjIsActive(vm)) { + qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain not active")); + goto cleanup; + } + def = vm->def; + } else { + def = vm->newDef ? vm->newDef : vm->def; } - ret = qemudGetMaxVCPUs(NULL, type); + ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus; cleanup: if (vm) -- 1.7.2.3