On Wed, Apr 01, 2026 at 03:27:15PM +0200, Peter Krempa via Devel wrote:
> From: Peter Krempa <[email protected]>
> 
> In certain cases it's useful for the caller to be able to determine if
> given API supports some flags.
> 
> To do this with 'virDomainBlockResize', if
> 'VIR_DOMAIN_BLOCK_RESIZE_PROBE_FLAGS' is specified, the API will return
> success right after flag verification, regardless of other input
> arguments and without modifying anything.
> 
> Signed-off-by: Peter Krempa <[email protected]>
> ---
>  include/libvirt/libvirt-domain.h |  9 +++++++++
>  src/libvirt-domain.c             | 12 ++++++++++++
>  src/qemu/qemu_driver.c           |  7 ++++++-
>  src/vz/vz_driver.c               |  7 ++++++-
>  4 files changed, 33 insertions(+), 2 deletions(-)
> 
> diff --git a/include/libvirt/libvirt-domain.h 
> b/include/libvirt/libvirt-domain.h
> index 4a8e3114b3..113c7eefe6 100644
> --- a/include/libvirt/libvirt-domain.h
> +++ b/include/libvirt/libvirt-domain.h
> @@ -2354,6 +2354,15 @@ typedef enum {
> 
>      /* Disallow shrinking (Since: 12.3.0) */
>      VIR_DOMAIN_BLOCK_RESIZE_EXTEND = 1 << 2,
> +
> +    /* Ensures that the 'virDomainBlockResize' API returns success after
> +     * checking support of 'flags' regardless of other arguments without
> +     * actually modifying any aspect of the domain.
> +     *
> +     * Use of the flag thus allows probing for support of other flags of this
> +     * API. (Since: 12.3.0) */
> +    VIR_DOMAIN_BLOCK_RESIZE_PROBE_FLAGS = 1 << 3,
> +
>  } virDomainBlockResizeFlags;
> 
>  int                     virDomainBlockResize (virDomainPtr dom,
> diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
> index db9eea5774..1b49d2f7e5 100644
> --- a/src/libvirt-domain.c
> +++ b/src/libvirt-domain.c
> @@ -6469,6 +6469,18 @@ virDomainBlockPeek(virDomainPtr dom,
>   * can be found by calling virDomainGetXMLDesc() and inspecting
>   * elements within //domain/devices/disk.
>   *
> + * If @flags contains VIR_DOMAIN_BLOCK_RESIZE_PROBE_FLAGS (since 12.3.0) the
> + * API will return success right after checking flags for support without
> + * modifying the disk in any way, thus allowing probing of flags with the
> + * following algorithm
> + *
> + *   supp = virDomainBlockResize(dom, "", 0, 
> VIR_DOMAIN_BLOCK_RESIZE_PROBE_FLAGS | VIR_DOMAIN_BLOCK_RESIZE_EXTEND);
> + *
> + *   if (supp == 0)
> + *      //flag supported
> + *   else
> + *     virResetLastError();

This suggests "flag" (singular), but if you pass many flags at once,
then the error only tells you that at least 1 flag is invalid, but
not which flag is invalid. So we need O(n) calls with PROBE_FLAGS
if we want to check n different flags as distinct things.

Also the "else" branch can also still be an error for non-probe
related issues. eg there are many errors that the remote driver
can raise from a transport POV.

How much better is this than simply trying the RESIZE_EXTEND usage
unconditionally, and then falling back to a different code path if
seeing  INVALID_ARG error ? 

> + *
>   * Note that this call may fail if the underlying virtualization hypervisor
>   * does not support it; this call requires privileged access to the
>   * hypervisor.
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 551553df14..aa064ca7a9 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -9449,7 +9449,12 @@ qemuDomainBlockResize(virDomainPtr dom,
> 
>      virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES |
>                    VIR_DOMAIN_BLOCK_RESIZE_CAPACITY |
> -                  VIR_DOMAIN_BLOCK_RESIZE_EXTEND, -1);
> +                  VIR_DOMAIN_BLOCK_RESIZE_EXTEND |
> +                  VIR_DOMAIN_BLOCK_RESIZE_PROBE_FLAGS, -1);
> +
> +    /* Assume success if flag probing is requested */
> +    if (flags & VIR_DOMAIN_BLOCK_RESIZE_PROBE_FLAGS)
> +        return 0;
> 
>      /* We prefer operating on bytes.  */
>      if ((flags & VIR_DOMAIN_BLOCK_RESIZE_BYTES) == 0) {
> diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
> index 2d8878fe7f..efb0144093 100644
> --- a/src/vz/vz_driver.c
> +++ b/src/vz/vz_driver.c
> @@ -3901,7 +3901,12 @@ vzDomainBlockResize(virDomainPtr domain,
>      int ret = -1;
>      bool job = false;
> 
> -    virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES, -1);
> +    virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES |
> +                  VIR_DOMAIN_BLOCK_RESIZE_PROBE_FLAGS, -1);
> +
> +    /* Assume success if flag probing is requested */
> +    if (flags & VIR_DOMAIN_BLOCK_RESIZE_PROBE_FLAGS)
> +        return 0;
> 
>      if (!(dom = vzDomObjFromDomain(domain)))
>          goto cleanup;
> -- 
> 2.53.0
> 

With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|

Reply via email to