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 <pkrempa@redhat.com>
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 <pkrempa@redhat.com> --- 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 :|