[PATCH 1/3] api: remote: introduce virDomainBlockRebaseParams API

Nikolai Barybin via Devel posted 3 patches 1 week, 2 days ago
[PATCH 1/3] api: remote: introduce virDomainBlockRebaseParams API
Posted by Nikolai Barybin via Devel 1 week, 2 days ago
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 <nikolai.barybin@virtuozzo.com>
---
 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.
+ *
+ * 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
+ * @nparams: number of block rebase parameters
+ * @flags: bitwise-OR of virDomainBlockRebaseParamsFlags
+ *
+ * Generelized version of virDomainBlockPull with more precise params setting.
+ *
+ * VIR_DOMAIN_BLOCK_REBASE_PARAM_BASE in @params specifies intermidiate block device
+ * in a disk backing chain which will result in a new base for a given disk. If ommitted
+ * or NULL it is equavivalent to normal block pull, when whole backing chain is pulled
+ * into top image.
+ *
+ * VIR_DOMAIN_BLOCK_REBASE_PARAM_BANDWIDTH in @params specifies bandwidth in Bytes/s.
+ *
+ * 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 */
     .domainBlockCopy = remoteDomainBlockCopy, /* 1.2.9 */
     .domainBlockCommit = remoteDomainBlockCommit, /* 0.10.2 */
     .connectSetKeepAlive = remoteConnectSetKeepAlive, /* 0.9.8 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 3c93203210..762614b1fa 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -119,6 +119,9 @@ const REMOTE_DOMAIN_NUMA_PARAMETERS_MAX = 16;
 /* Upper limit on list of perf events. */
 const REMOTE_DOMAIN_PERF_EVENTS_MAX = 64;
 
+/* Upper limit on block_rebase_params tunable parameters. */
+const REMOTE_DOMAIN_BLOCK_REBASE_PARAMS_PARAMETERS_MAX = 16;
+
 /* Upper limit on block copy tunable parameters. */
 const REMOTE_DOMAIN_BLOCK_COPY_PARAMETERS_MAX = 16;
 
@@ -1440,6 +1443,12 @@ struct remote_domain_block_rebase_args {
     unsigned hyper bandwidth;
     unsigned int flags;
 };
+struct remote_domain_block_rebase_params_args {
+    remote_nonnull_domain dom;
+    remote_nonnull_string path;
+    remote_typed_param params<REMOTE_DOMAIN_BLOCK_REBASE_PARAMS_PARAMETERS_MAX>;
+    unsigned int flags;
+};
 struct remote_domain_block_copy_args {
     remote_nonnull_domain dom;
     remote_nonnull_string path;
@@ -7119,5 +7128,11 @@ enum remote_procedure {
      * @generate: both
      * @acl: none
      */
-    REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE = 453
+    REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE = 453,
+
+    /**
+     * @generate: both
+     * @acl: domain:block_write
+     */
+    REMOTE_PROC_DOMAIN_BLOCK_REBASE_PARAMS = 454
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 0f87d13a5a..ec0963550a 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1010,6 +1010,15 @@ struct remote_domain_block_rebase_args {
         uint64_t                   bandwidth;
         u_int                      flags;
 };
+struct remote_domain_block_rebase_params_args {
+        remote_nonnull_domain      dom;
+        remote_nonnull_string      path;
+        struct {
+                u_int              params_len;
+                remote_typed_param * params_val;
+        } params;
+        u_int                      flags;
+};
 struct remote_domain_block_copy_args {
         remote_nonnull_domain      dom;
         remote_nonnull_string      path;
@@ -3791,4 +3800,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_SET_THROTTLE_GROUP = 451,
         REMOTE_PROC_DOMAIN_DEL_THROTTLE_GROUP = 452,
         REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE = 453,
+        REMOTE_PROC_DOMAIN_BLOCK_REBASE_PARAMS = 454,
 };
-- 
2.43.5
Re: [PATCH 1/3] api: remote: introduce virDomainBlockRebaseParams API
Posted by Ján Tomko via Devel 1 week, 1 day ago
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 <nikolai.barybin@virtuozzo.com>
>---
> 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 <jtomko@redhat.com>

Jano