On Wed, Apr 29, 2026 at 17:43:28 +0530, Akash Kulhalli via Devel wrote:
> Add VIR_DOMAIN_VCPU_ASYNC_UNPLUG for virDomainSetVcpusFlags().
>
> With this flag, success indicates that QEMU accepted the unplug
> request, while final completion is reported by the vcpu-removed
> event. Rejected requests continue to be reported by the
> device-removal-failed event.
>
> Wire the flag through the QEMU driver, document its semantics, and
> add virsh support for the async path in the setvcpus subcommand.
>
> Signed-off-by: Akash Kulhalli <[email protected]>
> ---
> docs/manpages/virsh.rst | 8 +++++++-
> include/libvirt/libvirt-domain.h | 1 +
> src/libvirt-domain.c | 10 ++++++++++
> src/qemu/qemu_driver.c | 12 ++++++++++--
> tools/virsh-domain.c | 8 ++++++++
> 5 files changed, 36 insertions(+), 3 deletions(-)
>
> diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
> index 80b0ea14a8b3..cc9028b2e540 100644
> --- a/docs/manpages/virsh.rst
> +++ b/docs/manpages/virsh.rst
> @@ -4810,7 +4810,7 @@ setvcpus
>
> ::
>
> - setvcpus domain count [--maximum] [[--config] [--live] | [--current]]
> [--guest] [--hotpluggable]
> + setvcpus domain count [--maximum] [[--config] [--live] | [--current]]
> [--guest] [--hotpluggable] [--async]
>
> Change the number of virtual CPUs active in a guest domain. By default,
> this command works on active guest domains. To change the settings for an
> @@ -4839,6 +4839,12 @@ is up to the hypervisor whether the *--config* flag is
> also assumed, and
> therefore whether the XML configuration is adjusted to make the change
> persistent.
>
> +If *--async* is specified, live vCPU unplug requests are fired without
> waiting
> +for the guest to comply. It may optionally be combined with *--config*. Final
I'll drop the 'It may optionally be combined with *--config*.' sentence.
> +completion is reported by the ``vcpu-removed`` domain event, while rejected
> +unplug requests continue to be reported by ``device-removal-failed``. This
> +flag cannot be combined with *--guest*.
> +
> If *--guest* is specified, then the count of cpus is modified in the guest
> instead of the hypervisor. This flag is usable only for live domains
> and may require guest agent to be configured in the guest.
> diff --git a/include/libvirt/libvirt-domain.h
> b/include/libvirt/libvirt-domain.h
> index 21336df85bd8..8902742a5ec8 100644
> --- a/include/libvirt/libvirt-domain.h
> +++ b/include/libvirt/libvirt-domain.h
> @@ -2605,6 +2605,7 @@ typedef enum {
> VIR_DOMAIN_VCPU_MAXIMUM = (1 << 2), /* Max rather than current count
> (Since: 0.8.5) */
> VIR_DOMAIN_VCPU_GUEST = (1 << 3), /* Modify state of the cpu in the
> guest (Since: 1.1.0) */
> VIR_DOMAIN_VCPU_HOTPLUGGABLE = (1 << 4), /* Make vcpus added
> hot(un)pluggable (Since: 2.4.0) */
> + VIR_DOMAIN_VCPU_ASYNC_UNPLUG = (1 << 5), /* Don't wait for the guest to
> comply with unplug request(s) (Since: 12.4.0) */
> } virDomainVcpuFlags;
>
> int virDomainSetVcpus (virDomainPtr domain,
> diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
> index db9eea57745c..97af1099f939 100644
> --- a/src/libvirt-domain.c
> +++ b/src/libvirt-domain.c
> @@ -7773,6 +7773,16 @@ virDomainSetVcpus(virDomainPtr domain, unsigned int
> nvcpus)
> * be used with live guests and is incompatible with VIR_DOMAIN_VCPU_MAXIMUM.
> * The usage of this flag may require a guest agent configured.
> *
> + * If @flags includes VIR_DOMAIN_VCPU_ASYNC_UNPLUG, live vCPU hot-unplug
> + * request(s) are fired without waiting for the guest to comply. Success in
> + * this mode only means that the unplug request(s) were accepted. Final
> + * completion is reported by VIR_DOMAIN_EVENT_ID_VCPU_REMOVED, carrying the
> + * XML ``<vcpu id='...'>`` value for each removed vCPU. Rejected unplug
> + * requests continue to be reported through the event
> + * VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED. The success event may be
> + * delivered before this API call returns. This flag has no effect when this
> + * operation results in an increase in the live vCPU count.
> + *
> * Not all hypervisors can support all flag combinations.
> *
> * Returns 0 in case of success, -1 in case of failure.
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 4d9be3d3a9e5..b9c08beb08a5 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -4269,6 +4269,7 @@ qemuDomainSetVcpusFlags(virDomainPtr dom,
> virDomainObj *vm = NULL;
> virDomainDef *def;
> virDomainDef *persistentDef;
> + bool async_unplug = !!(flags & VIR_DOMAIN_VCPU_ASYNC_UNPLUG);
> bool hotpluggable = !!(flags & VIR_DOMAIN_VCPU_HOTPLUGGABLE);
> bool useAgent = !!(flags & VIR_DOMAIN_VCPU_GUEST);
> int ret = -1;
Reviewed-by: Peter Krempa <[email protected]>