[libvirt] [PATCH v3] qemu: Implement CPUs check against machine type's cpu-max

Michal Novotny minovotn at redhat.com
Mon Apr 22 10:57:29 UTC 2013


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 at redhat.com>
> ---
>  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 at redhat.com>, RHCE, Red Hat
Virtualization | libvirt-php bindings | php-virt-control.org




More information about the libvir-list mailing list