On Mon, Jun 22, 2026 at 07:24:10PM +0200, Peter Krempa wrote:
> On Mon, Jun 22, 2026 at 18:06:18 +0100, Daniel P. Berrangé wrote:
> > On Wed, Apr 01, 2026 at 04:31:22PM +0200, Peter Krempa wrote:
> > > On Wed, Apr 01, 2026 at 15:17:29 +0100, Daniel P. Berrangé wrote:
> > > > 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.
> > > 
> > > I thought about this but I don't expect that this would be too widely
> > > used, so the inability to query flags in bulk shouldn't be a problem.
> > > 
> > > I don't think there's a reasonable possibility to do this within the API
> > > itself, and would thus require a new API.
> > > 
> > > > 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.
> > > 
> > > I didn't think about this but if used in close proximity with the real
> > > call I don't think there are many options where the probing call would
> > > error out but then the further real call would succeed.
> > > 
> > > > 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 ? 
> > > 
> > > The unfortunate thing and the reason I've picked this approach is that 
> > > the code that follows here liberally uses VIR_ERR_INVALID_ARG. Even on
> > > code paths where it makes sense to report error:
> > > 
> > >     if (!(disk = virDomainDiskByName(vm->def, path, false))) {
> > >         virReportError(VIR_ERR_INVALID_ARG,
> > >                        _("disk '%1$s' was not found in the domain 
> > > config"), path);
> > >         goto endjob;
> > >     }
> > > 
> > > The caller (visible later in series) wouldn't be able to determine if
> > > this is a case where the user messed up the disk and needs to see error
> > > or is a case where the failure is from the real think we want to prevent
> > > (accidental shrinking of the disk).
> > > 
> > > It would be possible to add a new error code for the 'unallowed shrink'
> > > though to sidestep that problem although it would really be specific to
> > > this scenario.
> > 
> > This isn't the first time where "INVALID ARG" has not been as helpful
> > as it should have been.  It is pretty hard to do control flow off
> > very generic errors codes like this, especially when we use it in
> > examples like the one above that are arguably inappropriate.
> > 
> > Is there mileage in adding a highly tailored error code
> > "UNSUPPORTED_FLAGS" ? We are lucky in that we use virCheckFlags as a
> > macro everywhere which would make changing the code fairly easy.
> 
> This doesn't really help detecting if the daemon is too old to support
> the new UNSUPPORTED_FLAGS code. A caller who needs to know if the daemon
> is too old would need to try an existing API with a nonsense flag first
> risking that the flag does make sense.

Yes, it only helps probing for flags added from this point onwards,
not probing our pre-existing set. IOW, it would solve the immediate
problem for block resize but not a broader set.


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