[libvirt] [PATCH 25/34] qemu: refactor qemuDomainHotunplugVcpus

John Ferlan jferlan at redhat.com
Mon Nov 23 21:52:07 UTC 2015



On 11/20/2015 10:22 AM, Peter Krempa wrote:
> Refactor the code flow so that 'exit_monitor:' can be removed.
> 
> This patch moves the auditing functions into places where it's certain
> that hotunplug was or was not successful and reports errors from
> qemuMonitorGetCPUInfo properly.
> ---
>  src/qemu/qemu_driver.c | 50 +++++++++++++++-----------------------------------
>  1 file changed, 15 insertions(+), 35 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 9e0e334..614c7f8 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -4798,48 +4798,36 @@ qemuDomainHotunplugVcpus(virQEMUDriverPtr driver,
>  {
>      qemuDomainObjPrivatePtr priv = vm->privateData;
>      int ret = -1;
> +    int rc;
>      int oldvcpus = virDomainDefGetVCpus(vm->def);
> -    int vcpus = oldvcpus;
>      pid_t *cpupids = NULL;
> -    int ncpupids;
> +    int ncpupids = 0;
> 
>      qemuDomainObjEnterMonitor(driver, vm);
> 
> -    if (qemuMonitorSetCPU(priv->mon, vcpu, false) < 0)
> -        goto exit_monitor;
> +    rc = qemuMonitorSetCPU(priv->mon, vcpu, false);
> 
> -    vcpus--;
> +    if (rc == 0)
> +        ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids);
> 
> -    /* After hotplugging the CPUs we need to re-detect threads corresponding
> -     * to the virtual CPUs. Some older versions don't provide the thread ID
> -     * or don't have the "info cpus" command (and they don't support multiple
> -     * CPUs anyways), so errors in the re-detection will not be treated
> -     * fatal */
> -    if ((ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids)) <= 0) {
> -        virResetLastError();
> -        ret = 0;
> -        goto exit_monitor;
> -    }
>      if (qemuDomainObjExitMonitor(driver, vm) < 0)
>          goto cleanup;
> 
> -    /* check if hotunplug has failed */
> -    if (ncpupids == oldvcpus) {
> -        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
> -                       _("qemu didn't unplug the vCPUs properly"));
> -        vcpus = oldvcpus;
> +    virDomainAuditVcpu(vm, oldvcpus, oldvcpus - 1, "update",
> +                       rc == 0 && ncpupids == oldvcpus -1);
> +

Similar comments to 24 w/r/t ExitMonitor failure and lack of Audit and
overwritten last message possible from GetCPUInfo failure.

w/r/t "&& ncpupids == oldvcpus - 1" in the audit message - if ncpupids
== 0 here, then unless we've dropped to zero vcpu's, this will always
trip strangely.

IOW: The ncpupids == 0 has been lost...

> +    if (rc < 0 || ncpupids < 0)
>          goto cleanup;
> -    }
> 
> -    if (ncpupids != vcpus) {
> -        virReportError(VIR_ERR_INTERNAL_ERROR,
> -                       _("got wrong number of vCPU pids from QEMU monitor. "
> -                         "got %d, wanted %d"),
> -                       ncpupids, vcpus);
> -        vcpus = oldvcpus;
> +    /* check if hotunplug has failed */
> +    if (ncpupids != oldvcpus - 1) {
> +        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
> +                       _("qemu didn't unplug vCPU '%u' properly"), vcpu);
>          goto cleanup;
>      }
> 
> +    ignore_value(virDomainDefSetVCpus(vm->def, oldvcpus - 1));
> +

Again - I would hope it wouldn't fail and not sure why ignore_value
should be used... I would think we'd have after the (rc < 0 || ncpupids
< 0) check (e.g. similar to Hotplug order):

    if (virDomainDefSetVCpus(vm->def, oldvcpus - 1) < 0)
        goto cleanup;

    /* Gratuitous comment here ... */
    if (ncpupids == 0) {
        ret = 0;
        goto cleanup;
    }

I'm sure you'll figure out a better order for an ACK...

John
>      if (qemuDomainDelCgroupForThread(priv->cgroup,
>                                       VIR_CGROUP_THREAD_VCPU, vcpu) < 0)
>          goto cleanup;
> @@ -4858,15 +4846,7 @@ qemuDomainHotunplugVcpus(virQEMUDriverPtr driver,
> 
>   cleanup:
>      VIR_FREE(cpupids);
> -    if (virDomainObjIsActive(vm) &&
> -        virDomainDefSetVCpus(vm->def, vcpus) < 0)
> -        ret = -1;
> -    virDomainAuditVcpu(vm, oldvcpus, vcpus, "update", ret == 0);
>      return ret;
> -
> - exit_monitor:
> -    ignore_value(qemuDomainObjExitMonitor(driver, vm));
> -    goto cleanup;
>  }
> 
> 




More information about the libvir-list mailing list