[libvirt] [PATCH v2 2/3] qemu_process: setting QEMU_CAPS_QUERY_CURRENT_MACHINE caps

Michal Privoznik mprivozn at redhat.com
Thu Apr 11 08:11:27 UTC 2019


On 4/9/19 6:18 PM, Daniel Henrique Barboza wrote:
> The new QMP API query-current-machine reports VM capabilities that
> can vary depending on the VM configuration, in contrast to most
> QEMU caps that can be set once during libvirtd init as exposed in
> qemu_capabilities.c.
> 
> As such, to properly set the runtime capabilities exposed by this
> API, we must query them at VM launch time. To do that, a new function
> called qemuProcessSetCurrentMachineCaps is called in qemuProcessLaunch.
> A new struct called qemuMonitorCurrentMachineInfo was created to host
> the output of the API (which contains only the wakeup-suspend-support
> flag for now, but can be expanded in the future). This struct is
> populated by qemuMonitorGetCurrentMachineInfo, which does the heavy
> work - executes query-current-machine, parses the result and populates
> the qemuMonitorCurrentMachineInfo struct.
> 
> qemuProcessSetCurrentMachineCaps can then read the structure and
> set the capabilities accordingly.
> 
> Signed-off-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
> ---
>   src/qemu/qemu_monitor.c      | 17 ++++++++++++
>   src/qemu/qemu_monitor.h      | 11 ++++++++
>   src/qemu/qemu_monitor_json.c | 53 ++++++++++++++++++++++++++++++++++++
>   src/qemu/qemu_monitor_json.h |  5 ++++
>   src/qemu/qemu_process.c      | 36 ++++++++++++++++++++++++
>   5 files changed, 122 insertions(+)
> 
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index babcbde878..d4222f0bcc 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -4472,3 +4472,20 @@ qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon,
>       virHashFree(info);
>       return ret;
>   }
> +
> +int
> +qemuMonitorGetCurrentMachineInfo(qemuMonitorPtr mon,
> +                                 qemuMonitorCurrentMachineInfoPtr info)
> +{
> +    int ret = -1;
> +
> +    QEMU_CHECK_MONITOR(mon);
> +
> +    if (qemuMonitorJSONGetCurrentMachineInfo(mon, info) < 0)
> +        goto cleanup;
> +
> +    ret = 0;
> +
> + cleanup:
> +    return ret;
> +}
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 086195ff98..fcd5a022b5 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -1220,4 +1220,15 @@ struct _qemuMonitorPRManagerInfo {
>   int qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon,
>                                   virHashTablePtr *retinfo);
>   
> +struct _qemuMonitorCurrentMachineInfo {
> +    bool wakeupSuspendSupport;
> +};
> +
> +typedef struct  _qemuMonitorCurrentMachineInfo qemuMonitorCurrentMachineInfo;
> +typedef qemuMonitorCurrentMachineInfo *qemuMonitorCurrentMachineInfoPtr;
> +
> +int
> +qemuMonitorGetCurrentMachineInfo(qemuMonitorPtr mon,
> +                                 qemuMonitorCurrentMachineInfoPtr info);
> +
>   #endif /* LIBVIRT_QEMU_MONITOR_H */
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 8e6c3ccd63..c6a2a59e6b 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -8449,3 +8449,56 @@ qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon,
>       return ret;
>   
>   }
> +
> +static int
> +qemuMonitorJSONExtractCurrentMachineInfo(virJSONValuePtr reply,
> +                                         qemuMonitorCurrentMachineInfoPtr info)
> +{
> +    virJSONValuePtr data;
> +    int ret = -1;
> +
> +    data = virJSONValueObjectGetObject(reply, "return");
> +    if (!data)
> +        goto malformed;
> +
> +    if (virJSONValueObjectGetBoolean(data, "wakeup-suspend-support",
> +                                     &info->wakeupSuspendSupport) < 0) {
> +        goto malformed;
> +    }
> +
> +    ret = 0;
> +
> + out:
> +    return ret;
> +
> + malformed:
> +    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                   _("malformed qemu-current-machine reply"));
> +    goto out;
> +}
> +
> +int
> +qemuMonitorJSONGetCurrentMachineInfo(qemuMonitorPtr mon,
> +                                     qemuMonitorCurrentMachineInfoPtr info)
> +{
> +    int ret = -1;
> +    virJSONValuePtr cmd;
> +    virJSONValuePtr reply = NULL;
> +
> +    if (!(cmd = qemuMonitorJSONMakeCommand("query-current-machine",
> +                                           NULL)))
> +        return -1;
> +
> +    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
> +        goto cleanup;
> +
> +    if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
> +        goto cleanup;
> +
> +    ret = qemuMonitorJSONExtractCurrentMachineInfo(reply, info);
> +
> + cleanup:
> +    virJSONValueFree(cmd);
> +    virJSONValueFree(reply);
> +    return ret;
> +}
> diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
> index c10513da15..746b7072ca 100644
> --- a/src/qemu/qemu_monitor_json.h
> +++ b/src/qemu/qemu_monitor_json.h
> @@ -576,4 +576,9 @@ int qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon,
>                                       virHashTablePtr info)
>       ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
>   
> +int
> +qemuMonitorJSONGetCurrentMachineInfo(qemuMonitorPtr mon,
> +                                     qemuMonitorCurrentMachineInfoPtr info)
> +    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> +
>   #endif /* LIBVIRT_QEMU_MONITOR_JSON_H */
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 47d8ca2ff1..b60c1ecfbe 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -6461,6 +6461,39 @@ qemuProcessSetupDiskThrottlingBlockdev(virQEMUDriverPtr driver,
>       return ret;
>   }
>   
> +static int
> +qemuProcessSetCurrentMachineCaps(virQEMUDriverPtr driver,
> +                                 virDomainObjPtr vm,
> +                                 qemuDomainAsyncJob asyncJob)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    qemuMonitorCurrentMachineInfoPtr info;
> +    int ret = -1;
> +
> +    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_CURRENT_MACHINE))
> +        return 0;
> +
> +    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
> +        return -1;
> +
> +    if (VIR_ALLOC(info) < 0)
> +        return -1;
> +
> +    ret = qemuMonitorGetCurrentMachineInfo(priv->mon, info);
> +
> +    if (qemuDomainObjExitMonitor(driver, vm) < 0)
> +        ret = -1;
> +
> +    if (ret < 0)
> +        goto cleanup;
> +
> +    if (info->wakeupSuspendSupport)
> +        virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_PM_WAKEUP_SUPPORT);
> +
> + cleanup:
> +    VIR_FREE(info);
> +    return ret;
> +}
>   
>   /**
>    * qemuProcessLaunch:
> @@ -6778,6 +6811,9 @@ qemuProcessLaunch(virConnectPtr conn,
>       if (qemuProcessSetupDiskThrottlingBlockdev(driver, vm, asyncJob) < 0)
>           goto cleanup;
>   
> +    if (qemuProcessSetCurrentMachineCaps(driver, vm, asyncJob) < 0)
> +        goto cleanup;


Oh, we don't query for qemu capabilities in ProcessLaunch. Maybe it 
doesn't matter right now because there is no decission to be made when 
building the cmd line, but nevertheless this must be done in 
virQEMUCapsInitQMPMonitor() or in one of the function it's calling.

Michal




More information about the libvir-list mailing list