On a Thursday in 2025, Nikolai Barybin via Devel wrote:
This new API is a combination of virDomainBlockPull and
virDomainBlockRebase (without copy mode) which supports extendable
list of virTypedParameterPtr params.

It is designed to allow more configurable use of underlying
'block-stream' QMP command.

If "base" == NULL and flags == 0 it is equivalent to virDomainBlockPull.

Signed-off-by: Nikolai Barybin <[email protected]>
---
include/libvirt/libvirt-domain.h | 34 +++++++++++++++++
src/driver-hypervisor.h          |  8 ++++
src/libvirt-domain.c             | 63 ++++++++++++++++++++++++++++++++
src/libvirt_public.syms          |  5 +++
src/remote/remote_driver.c       |  1 +
src/remote/remote_protocol.x     | 17 ++++++++-
src/remote_protocol-structs      | 10 +++++
7 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 71bb49fe6c..7dae8987a2 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4459,6 +4459,40 @@ int virDomainBlockRebase(virDomainPtr dom, const char 
*disk,
                         const char *base, unsigned long bandwidth,
                         unsigned int flags);

+/**
+ * VIR_DOMAIN_BLOCK_REBASE_PARAM_BASE:
+ * Macro for the virDomainBlockRebaseParams parameter 'base'.
+ * Expects string specifying new base block device.
+ *
+ * Since: 11.8.0
+ */
+#define VIR_DOMAIN_BLOCK_REBASE_PARAM_BASE "base"
+
+/**
+ * VIR_DOMAIN_BLOCK_REBASE_PARAM_BANDWIDTH:
+ * Macro for the virDomainBlockRebaseParams parameter 'bandwidth'.
+ * Expects unsigned long long bandwidth value in Bytes/s.

*bytes

no need to capitalize the b

+ *
+ * Since: 11.8.0
+ */
+#define VIR_DOMAIN_BLOCK_REBASE_PARAM_BANDWIDTH "bandwidth"
+
+/**
+ * virDomainBlockRebaseParamsFlags:
+ *
+ * Flags available for virDomainBlockRebaseParams().
+ *
+ * Since: 11.8.0
+ */
+typedef enum {
+    /* Keep backing chain  referenced using relative names (Since: 11.8.0) */
+    VIR_DOMAIN_BLOCK_REBASE_PARAMS_RELATIVE  = 1 << 4,
+} virDomainBlockRebaseParamsFlags;
+
+int virDomainBlockRebaseParams(virDomainPtr dom, const char *disk,
+                               virTypedParameterPtr params, int nparams,
+                               unsigned int flags);
+
/**
 * virDomainBlockCopyFlags:
 *
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 6a43688b0c..83cf5c6205 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1089,6 +1089,13 @@ typedef int
                           unsigned long bandwidth,
                           unsigned int flags);

+typedef int
+(*virDrvDomainBlockRebaseParams)(virDomainPtr dom,
+                                 const char *path,
+                                 virTypedParameterPtr params,
+                                 int nparams,
+                                 unsigned int flags);
+
typedef int
(*virDrvDomainBlockCopy)(virDomainPtr dom,
                         const char *path,
@@ -1681,6 +1688,7 @@ struct _virHypervisorDriver {
    virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed;
    virDrvDomainBlockPull domainBlockPull;
    virDrvDomainBlockRebase domainBlockRebase;
+    virDrvDomainBlockRebaseParams domainBlockRebaseParams;
    virDrvDomainBlockCopy domainBlockCopy;
    virDrvDomainBlockCommit domainBlockCommit;
    virDrvConnectSetKeepAlive connectSetKeepAlive;
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index ca110bdf85..27ba0bac45 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11197,6 +11197,69 @@ virDomainBlockRebase(virDomainPtr dom, const char 
*disk,
}


+/**
+ * virDomainBlockRebaseParams:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @params: pointer to block rebase parameter

parameters

+ * @nparams: number of block rebase parameters
+ * @flags: bitwise-OR of virDomainBlockRebaseParamsFlags
+ *
+ * Generelized version of virDomainBlockPull with more precise params setting.

Generalized

+ *
+ * VIR_DOMAIN_BLOCK_REBASE_PARAM_BASE in @params specifies intermidiate block 
device

intermediate

+ * in a disk backing chain which will result in a new base for a given disk. 
If ommitted

omitted

+ * or NULL it is equavivalent to normal block pull, when whole backing chain 
is pulled

equivalent
when the whole

+ * into top image.
+ *
+ * VIR_DOMAIN_BLOCK_REBASE_PARAM_BANDWIDTH in @params specifies bandwidth in 
Bytes/s.
+ *

bytes

+ * If @flags contains VIR_DOMAIN_BLOCK_REBASE_PARAMS_RELATIVE, the name 
recorded
+ * into the active disk as the location for @base will be kept relative.
+ * The operation will fail if libvirt can't infer the name.
+ *
+ * Returns 0 if the operation has started, -1 on failure.
+ *
+ * Since: 11.8.0
+ */
+int
+virDomainBlockRebaseParams(virDomainPtr dom,
+                           const char *disk,
+                           virTypedParameterPtr params,
+                           int nparams,
+                           unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(dom, "disk=%s, nparams=%u, flags=0x%x",
+                     disk, nparams, flags);
+    VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+    virResetLastError();
+
+    virCheckDomainReturn(dom, -1);
+    conn = dom->conn;
+
+    virCheckReadOnlyGoto(conn->flags, error);
+    virCheckNonNullArgGoto(disk, error);
+
+    if (conn->driver->domainBlockRebaseParams) {
+        int ret;
+        ret = conn->driver->domainBlockRebaseParams(dom, disk, params, nparams,
+                                                    flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(dom->conn);
+    return -1;
+}
+
+
/**
 * virDomainBlockCopy:
 * @dom: pointer to domain object
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index c506acd2ed..0b8365cd2c 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -956,4 +956,9 @@ LIBVIRT_11.2.0 {
        virDomainDelThrottleGroup;
} LIBVIRT_10.2.0;

+LIBVIRT_11.8.0 {
+    global:
+        virDomainBlockRebaseParams;
+} LIBVIRT_11.2.0;
+
# .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index ec71eaed87..d9ca026aef 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -7865,6 +7865,7 @@ static virHypervisorDriver hypervisor_driver = {
    .domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */
    .domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */
    .domainBlockRebase = remoteDomainBlockRebase, /* 0.9.10 */
+    .domainBlockRebaseParams = remoteDomainBlockRebaseParams, /* 11.8.0 */

11.9.0 in the whole patch

    .domainBlockCopy = remoteDomainBlockCopy, /* 1.2.9 */
    .domainBlockCommit = remoteDomainBlockCommit, /* 0.10.2 */
    .connectSetKeepAlive = remoteConnectSetKeepAlive, /* 0.9.8 */

Reviewed-by: Ján Tomko <[email protected]>

Jano

Attachment: signature.asc
Description: PGP signature

Reply via email to