
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 | 43 +++++++++++++++++++++ src/driver-hypervisor.h | 8 ++++ src/libvirt-domain.c | 65 ++++++++++++++++++++++++++++++++ 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, 148 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 71bb49fe6c..1124c9d58f 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -4459,6 +4459,49 @@ 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 virDomainBlockRebase2 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_MIB: + * Macro for the virDomainBlockRebase2 parameter 'bandwidth-mib'. + * Expects desired bandwidth in MiB/s. + * + * Since: 11.8.0 + */ +#define VIR_DOMAIN_BLOCK_REBASE_PARAM_BANDWIDTH_MIB "bandwidth-mib" + +/** + * VIR_DOMAIN_BLOCK_REBASE_PARAM_BANDWIDTH_BYTES: + * Macro for the virDomainBlockRebase2 parameter 'bandwidth-bytes'. + * Expects desired bandwidth in Bytes/s. + * + * Since: 11.8.0 + */ +#define VIR_DOMAIN_BLOCK_REBASE_PARAM_BANDWIDTH_BYTES "bandwidth-bytes" + +/** + * virDomainBlockRebase2Flags: + * + * Flags available for virDomainBlockRebase2(). + * + * Since: 11.8.0 + */ +typedef enum { + /* Keep backing chain referenced using relative names (Since: 11.8.0) */ + VIR_DOMAIN_BLOCK_REBASE_2_RELATIVE = 1 << 4, +} virDomainBlockRebase2Flags; + +int virDomainBlockRebase2(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..e64e00674c 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 +(*virDrvDomainBlockRebase2)(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; + virDrvDomainBlockRebase2 domainBlockRebase2; virDrvDomainBlockCopy domainBlockCopy; virDrvDomainBlockCommit domainBlockCommit; virDrvConnectSetKeepAlive connectSetKeepAlive; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index ca110bdf85..58e3746a09 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11197,6 +11197,71 @@ virDomainBlockRebase(virDomainPtr dom, const char *disk, } +/** + * virDomainBlockRebase2: + * @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 virDomainBlockRebase2Flags + * + * Generelized version of virDomainBlockPull with more precise params setting + * for underlying QMP 'block-stream'. + * + * 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_MIB and VIR_DOMAIN_BLOCK_REBASE_PARAM_BANDWIDTH_BYTES + * in @params specify bandwidth in MiB/s or Bytes/s respectively. + * + * If @flags contains VIR_DOMAIN_BLOCK_REBASE_2_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 +virDomainBlockRebase2(virDomainPtr dom, + const char *disk, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%u, flags=0x%x", + disk, params, 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->domainBlockRebase2) { + int ret; + ret = conn->driver->domainBlockRebase2(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..aba336c6c3 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: + virDomainBlockRebase2; +} 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..efda3255c0 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 */ + .domainBlockRebase2 = remoteDomainBlockRebase2, /* 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..506cd146ad 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 rebase2 tunable parameters. */ +const REMOTE_DOMAIN_BLOCK_REBASE2_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_rebase2_args { + remote_nonnull_domain dom; + remote_nonnull_string path; + remote_typed_param params<REMOTE_DOMAIN_BLOCK_REBASE2_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_REBASE2 = 454 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 0f87d13a5a..9cfb476fd9 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_rebase2_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_REBASE2 = 454, }; -- 2.43.5