ping? On 04/17/2013 04:15 PM, Michal Novotny wrote: > Implement check whether (maximum) vCPUs doesn't exceed machine > type's cpu-max settings. > > On older versions of QEMU the check is disabled. > > Signed-off-by: Michal Novotny <minovotn@xxxxxxxxxx> > --- > src/qemu/qemu_capabilities.c | 38 +++++++++++++++++++++++++++++++++++++- > src/qemu/qemu_capabilities.h | 3 ++- > src/qemu/qemu_monitor.h | 1 + > src/qemu/qemu_monitor_json.c | 7 +++++++ > src/qemu/qemu_process.c | 27 +++++++++++++++++++++++++++ > 5 files changed, 74 insertions(+), 2 deletions(-) > > diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c > index d10c8aa..bbfe85f 100644 > --- a/src/qemu/qemu_capabilities.c > +++ b/src/qemu/qemu_capabilities.c > @@ -243,6 +243,7 @@ struct _virQEMUCaps { > size_t nmachineTypes; > char **machineTypes; > char **machineAliases; > + int *machineMaxCpus; > }; > > struct _virQEMUCapsCache { > @@ -322,6 +323,7 @@ virQEMUCapsSetDefaultMachine(virQEMUCapsPtr qemuCaps, > { > char *name = qemuCaps->machineTypes[defIdx]; > char *alias = qemuCaps->machineAliases[defIdx]; > + int cpu_max = qemuCaps->machineMaxCpus[defIdx]; > > memmove(qemuCaps->machineTypes + 1, > qemuCaps->machineTypes, > @@ -329,8 +331,12 @@ virQEMUCapsSetDefaultMachine(virQEMUCapsPtr qemuCaps, > memmove(qemuCaps->machineAliases + 1, > qemuCaps->machineAliases, > sizeof(qemuCaps->machineAliases[0]) * defIdx); > + memmove(qemuCaps->machineMaxCpus + 1, > + qemuCaps->machineMaxCpus, > + sizeof(qemuCaps->machineMaxCpus[0]) * defIdx); > qemuCaps->machineTypes[0] = name; > qemuCaps->machineAliases[0] = alias; > + qemuCaps->machineMaxCpus[0] = cpu_max; > } > > /* Format is: > @@ -377,7 +383,8 @@ virQEMUCapsParseMachineTypesStr(const char *output, > } > > if (VIR_REALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes + 1) < 0 || > - VIR_REALLOC_N(qemuCaps->machineAliases, qemuCaps->nmachineTypes + 1) < 0) { > + VIR_REALLOC_N(qemuCaps->machineAliases, qemuCaps->nmachineTypes + 1) < 0 || > + VIR_REALLOC_N(qemuCaps->machineMaxCpus, qemuCaps->nmachineTypes + 1) < 0) { > VIR_FREE(name); > VIR_FREE(canonical); > goto no_memory; > @@ -390,6 +397,8 @@ virQEMUCapsParseMachineTypesStr(const char *output, > qemuCaps->machineTypes[qemuCaps->nmachineTypes-1] = name; > qemuCaps->machineAliases[qemuCaps->nmachineTypes-1] = NULL; > } > + /* Value 0 means "unknown" as it's not exposed by QEMU binary */ > + qemuCaps->machineMaxCpus[qemuCaps->nmachineTypes-1] = 0; > } while ((p = next)); > > > @@ -1718,6 +1727,8 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps) > goto no_memory; > if (VIR_ALLOC_N(ret->machineAliases, qemuCaps->nmachineTypes) < 0) > goto no_memory; > + if (VIR_ALLOC_N(ret->machineMaxCpus, qemuCaps->nmachineTypes) < 0) > + goto no_memory; > ret->nmachineTypes = qemuCaps->nmachineTypes; > for (i = 0 ; i < qemuCaps->nmachineTypes ; i++) { > if (!(ret->machineTypes[i] = strdup(qemuCaps->machineTypes[i]))) > @@ -1725,6 +1736,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps) > if (qemuCaps->machineAliases[i] && > !(ret->machineAliases[i] = strdup(qemuCaps->machineAliases[i]))) > goto no_memory; > + ret->machineMaxCpus[i] = qemuCaps->machineMaxCpus[i]; > } > > return ret; > @@ -1923,6 +1935,25 @@ const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps, > } > > > +int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps, > + const char *name) > +{ > + size_t i; > + > + if (!name) > + return 0; > + > + for (i = 0 ; i < qemuCaps->nmachineTypes ; i++) { > + if (!qemuCaps->machineMaxCpus[i]) > + continue; > + if (STREQ(qemuCaps->machineTypes[i], name)) > + return qemuCaps->machineMaxCpus[i]; > + } > + > + return 0; > +} > + > + > static int > virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps, > qemuMonitorPtr mon) > @@ -2073,6 +2104,10 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps, > virReportOOMError(); > goto cleanup; > } > + if (VIR_ALLOC_N(qemuCaps->machineMaxCpus, nmachines) < 0) { > + virReportOOMError(); > + goto cleanup; > + } > > for (i = 0 ; i < nmachines ; i++) { > if (machines[i]->alias) { > @@ -2087,6 +2122,7 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps, > } > if (machines[i]->isDefault) > defIdx = i; > + qemuCaps->machineMaxCpus[i] = machines[i]->cpu_max; > } > qemuCaps->nmachineTypes = nmachines; > > diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h > index 4e76799..bd97e8d 100644 > --- a/src/qemu/qemu_capabilities.h > +++ b/src/qemu/qemu_capabilities.h > @@ -223,7 +223,8 @@ size_t virQEMUCapsGetMachineTypes(virQEMUCapsPtr qemuCaps, > char ***names); > const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps, > const char *name); > - > +int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps, > + const char *name); > int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps, > size_t *nmachines, > virCapsGuestMachinePtr **machines); > diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h > index f39f009..c097953 100644 > --- a/src/qemu/qemu_monitor.h > +++ b/src/qemu/qemu_monitor.h > @@ -650,6 +650,7 @@ struct _qemuMonitorMachineInfo { > char *name; > bool isDefault; > char *alias; > + int cpu_max; > }; > > int qemuMonitorGetMachines(qemuMonitorPtr mon, > diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c > index 6fdd650..adbd865 100644 > --- a/src/qemu/qemu_monitor_json.c > +++ b/src/qemu/qemu_monitor_json.c > @@ -4024,6 +4024,13 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon, > goto cleanup; > } > } > + > + if (virJSONValueObjectHasKey(child, "cpu-max") && > + virJSONValueObjectGetNumberInt(child, "cpu-max", &info->cpu_max) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("query-machines reply has malformed 'cpu-max' data")); > + goto cleanup; > + } > } > > ret = n; > diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c > index ce9f501..9eae8f6 100644 > --- a/src/qemu/qemu_process.c > +++ b/src/qemu/qemu_process.c > @@ -3266,6 +3266,30 @@ qemuSetUnprivSGIO(virDomainDiskDefPtr disk) > return ret; > } > > +static bool > +qemuValidateCpuMax(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) > +{ > + int cpu_max; > + > + cpu_max = virQEMUCapsGetMachineMaxCpus(qemuCaps, def->os.machine); > + if (!cpu_max) > + return true; > + > + if (def->vcpus > cpu_max) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + "%s", _("CPUs greater than specified machine type limit")); > + return false; > + } > + > + if (def->maxvcpus > cpu_max) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + "%s", _("Maximum CPUs greater than specified machine type limit")); > + return false; > + } > + > + return true; > +} > + > int qemuProcessStart(virConnectPtr conn, > virQEMUDriverPtr driver, > virDomainObjPtr vm, > @@ -3481,6 +3505,9 @@ int qemuProcessStart(virConnectPtr conn, > vm->def->emulator))) > goto cleanup; > > + if (!qemuValidateCpuMax(vm->def, priv->qemuCaps)) > + goto cleanup; > + > if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0) > goto cleanup; > -- Michal Novotny <minovotn@xxxxxxxxxx>, RHCE, Red Hat Virtualization | libvirt-php bindings | php-virt-control.org -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list