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(a)mogujie.com>
---
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