On Fri, Feb 10, 2017 at 06:10:20PM +0100, Peter Krempa wrote: > Add code that validates user's selection of cores and then uses the > existing code to plug in the vCPU. > --- > src/qemu/qemu_driver.c | 74 +++++++++++++++++++++++ > src/qemu/qemu_hotplug.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ > src/qemu/qemu_hotplug.h | 7 +++ > 3 files changed, 234 insertions(+) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 89bc833de..2b875b3e9 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -20190,6 +20190,79 @@ qemuDomainSetGuestVcpus(virDomainPtr dom, > } > > > +static int > +qemuDomainSetVcpu(virDomainPtr dom, > + const char *cpumap, > + int state, > + unsigned int flags) > +{ > + virQEMUDriverPtr driver = dom->conn->privateData; > + virDomainObjPtr vm = NULL; > + virDomainDefPtr def = NULL; > + virDomainDefPtr persistentDef = NULL; > + virBitmapPtr map = NULL; > + ssize_t lastvcpu; > + int ret = -1; > + > + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | > + VIR_DOMAIN_AFFECT_CONFIG, -1); > + > + if (state != 0 && state != 1) { > + virReportInvalidArg(state, "%s", _("unsupported state value")); > + return -1; > + } > + > + if (virBitmapParse(cpumap, &map, QEMU_GUEST_VCPU_MAX_ID) < 0) > + goto cleanup; > + > + if ((lastvcpu = virBitmapLastSetBit(map)) < 0) { > + virReportError(VIR_ERR_INVALID_ARG, "%s", > + _("no vcpus selected for modification")); > + goto cleanup; > + } > + > + if (!(vm = qemuDomObjFromDomain(dom))) > + goto cleanup; > + > + if (virDomainSetVcpuEnsureACL(dom->conn, vm->def, flags) < 0) > + goto cleanup; > + > + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) > + goto cleanup; > + > + if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0) > + goto endjob; > + > + if (persistentDef) { > + if (lastvcpu >= virDomainDefGetVcpusMax(persistentDef)) { > + virReportError(VIR_ERR_INVALID_ARG, > + _("vcpu %zd is not present in persistent config"), > + lastvcpu); > + goto endjob; > + } > + } > + > + if (def) { > + if (lastvcpu >= virDomainDefGetVcpusMax(def)) { > + virReportError(VIR_ERR_INVALID_ARG, > + _("vcpu %zd is not present in live config"), > + lastvcpu); > + goto endjob; > + } > + } > + > + ret = qemuDomainSetVcpuInternal(driver, vm, def, persistentDef, map, !!state); > + > + endjob: > + qemuDomainObjEndJob(driver, vm); > + > + cleanup: > + virBitmapFree(map); > + virDomainObjEndAPI(&vm); > + return ret; > +} > + > + > static virHypervisorDriver qemuHypervisorDriver = { > .name = QEMU_DRIVER_NAME, > .connectOpen = qemuConnectOpen, /* 0.2.0 */ > @@ -20403,6 +20476,7 @@ static virHypervisorDriver qemuHypervisorDriver = { > .domainMigrateStartPostCopy = qemuDomainMigrateStartPostCopy, /* 1.3.3 */ > .domainGetGuestVcpus = qemuDomainGetGuestVcpus, /* 2.0.0 */ > .domainSetGuestVcpus = qemuDomainSetGuestVcpus, /* 2.0.0 */ > + .domainSetVcpu = qemuDomainSetVcpu, /* 3.1.0 */ > }; > > > diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c > index 2f209f12b..363d1070b 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -5700,3 +5700,156 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver, > virObjectUnref(cfg); > return ret; > } > + > + > +static void > +qemuDomainSetVcpuInactive(virDomainDefPtr def, > + virBitmapPtr map, > + bool state) qemuDomainSetVcpuConfig is probably a better name because we use *Live vs *Config naming. > +{ > + virDomainVcpuDefPtr vcpu; > + ssize_t next = -1; > + > + def->individualvcpus = true; > + > + while ((next = virBitmapNextSetBit(map, next)) > 0) { > + if (!(vcpu = virDomainDefGetVcpu(def, next))) > + continue; > + > + vcpu->online = state; > + vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES; > + vcpu->order = 0; > + } > +} > + > + > +/** > + * qemuDomainFilterHotplugVcpuEntities: > + * > + * Returns a bitmap of hotpluggable vcpu entities that correspond to the logical > + * vcpus requested in @vcpus. > + */ > +static virBitmapPtr > +qemuDomainFilterHotplugVcpuEntities(virDomainDefPtr def, > + virBitmapPtr vcpus, > + bool state) > +{ > + qemuDomainVcpuPrivatePtr vcpupriv; > + virDomainVcpuDefPtr vcpu; > + virBitmapPtr map = NULL; > + virBitmapPtr ret = NULL; > + ssize_t next = -1; > + size_t i; > + > + if (!(map = virBitmapNewCopy(vcpus))) > + return NULL; > + > + /* make sure that all selected vcpus are in the correct state */ > + while ((next = virBitmapNextSetBit(map, next)) > 0) { > + if (!(vcpu = virDomainDefGetVcpu(def, next))) > + continue; > + > + if (vcpu->online == state) { > + virReportError(VIR_ERR_INVALID_ARG, > + _("vcpu '%zu' is already in requested state"), next); > + goto cleanup; > + } > + > + if (vcpu->online && !vcpu->hotpluggable) { > + virReportError(VIR_ERR_INVALID_ARG, > + _("vcpu '%zu' can't be hotunplugged"), next); > + goto cleanup; > + } > + } > + > + /* Make sure that all vCPUs belonging to a single hotpluggable entity were > + * selected and then de-select any sub-threads of it. */ > + next = -1; > + while ((next = virBitmapNextSetBit(map, next)) > 0) { > + if (!(vcpu = virDomainDefGetVcpu(def, next))) > + continue; > + > + vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu); Remove the extra space :) ACK with the issues fixed. Pavel
Attachment:
signature.asc
Description: Digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list