This API starts asynchronous live copy of a block device (specified by target element of the xml argument) into a new source (which must already exist). The process can be controlled in the same way as migration: monitored with virDomainJobInfo() and canceled using virDomainAbortJob(). I don't particularly like the name (but I wasn't able to come up with a better one) since it doesn't reflect the fact that once a block device is switched to use the new source once copying finishes. In other words, the goal of this API is to update the device to use new source (just like virDomainUpdateDeviceFlags) but before doing so all data is copied from the old source into the new one (unlike the UpdateDevice API). --- include/libvirt/libvirt.h.in | 4 +++ src/driver.h | 6 ++++ src/libvirt.c | 54 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 65 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index cb9e8ca..41f6b2e 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2983,6 +2983,10 @@ typedef struct _virTypedParameter virMemoryParameter; */ typedef virMemoryParameter *virMemoryParameterPtr; +int virDomainBlockCopy(virDomainPtr domain, + const char *xml, + unsigned int flags); + #ifdef __cplusplus } #endif diff --git a/src/driver.h b/src/driver.h index 62bbc1d..8731d68 100644 --- a/src/driver.h +++ b/src/driver.h @@ -666,6 +666,11 @@ typedef int virDomainBlockPullInfoPtr info, unsigned int flags); +typedef int + (*virDrvDomainBlockCopy)(virDomainPtr domain, + const char *xml, + unsigned int flags); + /** * _virDriver: * @@ -809,6 +814,7 @@ struct _virDriver { virDrvDomainBlockPullAll domainBlockPullAll; virDrvDomainBlockPullAbort domainBlockPullAbort; virDrvDomainGetBlockPullInfo domainGetBlockPullInfo; + virDrvDomainBlockCopy domainBlockCopy; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index c57e0c3..ad5da9b 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -15548,3 +15548,57 @@ error: virDispatchError(dom->conn); return -1; } + +/** + * virDomainBlockCopy: + * @domain: pointer to domain object + * @xml: pointer to XML description of the block device to copy + * @flags: currently unused, use 0 + * + * Starts asynchronous live copy of a block device (specified by target element + * of the xml) into a new source (which must already exist). The process can be + * controlled in the same way as migration: monitored with virDomainJobInfo() + * and canceled using virDomainAbortJob(). + * + * Returns -1 in case of failure, 0 when successful. + */ +int +virDomainBlockCopy(virDomainPtr domain, const char *xml, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%d", xml, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (xml == NULL) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainBlockCopy) { + int ret; + ret = conn->driver->domainBlockCopy(domain, xml, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index b2915f6..3028e15 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -452,6 +452,7 @@ LIBVIRT_0.9.2 { LIBVIRT_0.9.3 { global: + virDomainBlockCopy; virDomainBlockPull; virDomainBlockPullAbort; virDomainBlockPullAll; -- 1.7.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list