For Backuping the disk image. It supports tree backup mode: full, top, incremental. Incremental backup mode must do full or top backup first, and it exists dirty bitmap to trace io. Signed-off-by: longyou <longyou@xxxxxxxxxxx> --- docs/apibuild.py | 3 ++- include/libvirt/libvirt-domain.h | 15 +++++++++++ src/driver-hypervisor.h | 9 +++++++ src/libvirt-domain.c | 56 ++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 17 +++++++++++- src/remote_protocol-structs | 9 +++++++ 8 files changed, 113 insertions(+), 2 deletions(-) diff --git a/docs/apibuild.py b/docs/apibuild.py index f5216ea..42ce538 100755 --- a/docs/apibuild.py +++ b/docs/apibuild.py @@ -1851,7 +1851,8 @@ class CParser: "virDomainBlockJobSetSpeed" : (False, ("bandwidth")), "virDomainBlockPull" : (False, ("bandwidth")), "virDomainBlockRebase" : (False, ("bandwidth")), - "virDomainMigrateGetMaxSpeed" : (False, ("bandwidth")) } + "virDomainMigrateGetMaxSpeed" : (False, ("bandwidth")), + "virDomainBlockBackup" : (False, ("bandwidth")) } def checkLongLegacyFunction(self, name, return_type, signature): if "long" in return_type and "long long" not in return_type: diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index cba4fa5..3a9ab6c 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2139,6 +2139,21 @@ int virDomainBlockCommit(virDomainPtr dom, const char *disk, const char *base, const char *top, unsigned long bandwidth, unsigned int flags); +/** + * virDomainBlockBackupFlags: + * + * Flags available for virDomainBlockBackup(). + */ +typedef enum { + VIR_DOMAIN_BLOCK_BACKUP_FULL = 1 << 1, /* Backup with full mode */ + VIR_DOMAIN_BLOCK_BACKUP_TOP = 1 << 2, /* Backup with top mode */ + VIR_DOMAIN_BLOCK_BACKUP_INCREMENTAL = 1 << 3, /* Backup with incremental + mode by dirty bitmap */ +} virDomainBlockBackupFlags; + +int virDomainBlockBackup(virDomainPtr dom, const char *path, const char *dest, + unsigned long bandwidth, const char *format, + unsigned int flags); /* Block I/O throttling support */ diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index d11ff7f..171eb14 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1020,6 +1020,14 @@ typedef int unsigned int flags); typedef int +(*virDrvDomainBlockBackup)(virDomainPtr dom, + const char *path, + const char *dest, + unsigned long long bandwidth, + const char *format, + unsigned int flags); + +typedef int (*virDrvConnectSetKeepAlive)(virConnectPtr conn, int interval, unsigned int count); @@ -1436,6 +1444,7 @@ struct _virHypervisorDriver { virDrvDomainBlockRebase domainBlockRebase; virDrvDomainBlockCopy domainBlockCopy; virDrvDomainBlockCommit domainBlockCommit; + virDrvDomainBlockBackup domainBlockBackup; virDrvConnectSetKeepAlive connectSetKeepAlive; virDrvConnectIsAlive connectIsAlive; virDrvNodeSuspendForDuration nodeSuspendForDuration; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 73ae369..18ef249 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -10473,6 +10473,62 @@ virDomainBlockCommit(virDomainPtr dom, const char *disk, /** + * virDomainBlockBackup: + * @dom: pointer to domain object + * @path: path to the block device, or device shorthand + * @dest: path to image for backup + * @bandwidth: (optional) specify bandwidth limit; flags determine the unit + * @format: (optional) the dest image format + * @flags: bitwise-OR of virDomainBlockBackupFlags + * + * Backup the path image to dest image, it supports three backup mode: + * "full" mode with flags VIR_DOMAIN_BLOCK_BACKUP_FULL, it will backup all + * data in the image chain. + * "top" mode with flags VIR_DOMAIN_BLOCK_BACKUP_TOP, it only backup the + * data of top image to dest image. + * "incremental" mode with flags VIR_DOMAIN_BLOCK_BACKUP_INCREMENTAL, it wosks + * with dirty bitmap when done the "full" or "top" mode backup. Incremental + * backup only backup the data in the dirty bitmap. + * + * Returns 0 if the operation has started, -1 on failure. + */ +int +virDomainBlockBackup(virDomainPtr dom, const char *path, + const char *dest, unsigned long bandwidth, + const char *format, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(dom, "path=%s, dest=%s, bandwidth=%lu, format=%s, flags=%x", + path, dest, bandwidth, format, flags); + + virResetLastError(); + + virCheckDomainReturn(dom, -1); + conn = dom->conn; + + virCheckReadOnlyGoto(conn->flags, error); + virCheckNonNullArgGoto(path, error); + virCheckNonNullArgGoto(dest, error); + + if (conn->driver->domainBlockBackup) { + int ret; + ret = conn->driver->domainBlockBackup(dom, path, dest, + bandwidth, format, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + +error: + virDispatchError(dom->conn); + return -1; +} + + +/** * virDomainOpenGraphics: * @dom: pointer to domain object * @idx: index of graphics config to open diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 1e920d6..34a2fff 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -732,4 +732,9 @@ LIBVIRT_1.3.3 { virDomainSetPerfEvents; } LIBVIRT_1.2.19; +LIBVIRT_1.3.6 { + global: + virDomainBlockBackup; +} LIBVIRT_1.3.3; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index e3cf5fb..7513a7f 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7796,6 +7796,7 @@ static virHypervisorDriver hypervisor_driver = { .domainBlockRebase = remoteDomainBlockRebase, /* 0.9.10 */ .domainBlockCopy = remoteDomainBlockCopy, /* 1.2.9 */ .domainBlockCommit = remoteDomainBlockCommit, /* 0.10.2 */ + .domainBlockBackup = remoteDomainBlockBackup, /* 1.3.6 */ .connectSetKeepAlive = remoteConnectSetKeepAlive, /* 0.9.8 */ .connectIsAlive = remoteConnectIsAlive, /* 0.9.8 */ .nodeSuspendForDuration = remoteNodeSuspendForDuration, /* 0.9.8 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index bab8ef2..0f3b29c 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1364,6 +1364,15 @@ struct remote_domain_block_commit_args { unsigned int flags; }; +struct remote_domain_block_backup_args { + remote_nonnull_domain dom; + remote_nonnull_string path; + remote_nonnull_string dest; + unsigned hyper bandwidth; + remote_string format; + unsigned int flags; +}; + struct remote_domain_set_block_io_tune_args { remote_nonnull_domain dom; remote_nonnull_string disk; @@ -5793,5 +5802,11 @@ enum remote_procedure { * @generate: both * @acl: none */ - REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED = 367 + REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED = 367, + + /** + * @generate: both + * @acl: domain:block_write + */ + REMOTE_PROC_DOMAIN_BLOCK_BACKUP = 368 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index fe1b8a8..e3cc5c5 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -996,6 +996,14 @@ struct remote_domain_block_commit_args { uint64_t bandwidth; u_int flags; }; +struct remote_domain_block_backup_args { + remote_nonnull_domain dom; + remote_nonnull_string path; + remote_nonnull_string dest; + uint64_t bandwidth; + remote_string format; + u_int flags; +}; struct remote_domain_set_block_io_tune_args { remote_nonnull_domain dom; remote_nonnull_string disk; @@ -3103,4 +3111,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_PERF_EVENTS = 365, REMOTE_PROC_DOMAIN_SET_PERF_EVENTS = 366, REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED = 367, + REMOTE_PROC_DOMAIN_BLOCK_BACKUP = 358, }; -- 2.6.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list