support blockbackup in virsh command. Use it as:
blockbackup <domain> <path> <dest> [--mode <string>] [--bandwidth
<number>]
[--format <string>] [--wait] [--verbose]
Signed-off-by: longyou <longyou(a)mogujie.com>
---
tools/virsh-domain.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 8d7ff61..40181da 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -2922,6 +2922,149 @@ cmdBlockResize(vshControl *ctl, const vshCmd *cmd)
return ret;
}
+/*
+ * "blockbackup" command
+ */
+static const vshCmdInfo info_block_backup[] = {
+ {.name = "help",
+ .data = N_("Start a block backup operation.")
+ },
+ {.name = "desc",
+ .data = N_("Backup a disk image chain to dest image.")
+ },
+ {.name = NULL}
+};
+
+static const vshCmdOptDef opts_block_backup[] = {
+ {.name = "domain",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("domain name, id or uuid")
+ },
+ {.name = "path",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("fully-qualified path of source disk")
+ },
+ {.name = "dest",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("path of the backup image to create")
+ },
+ {.name = "mode",
+ .type = VSH_OT_STRING,
+ .help = N_("image backup mode")
+ },
+ {.name = "bandwidth",
+ .type = VSH_OT_INT,
+ .help = N_("bandwidth limit in MiB/s")
+ },
+ {.name = "format",
+ .type = VSH_OT_STRING,
+ .help = N_("dest image format")
+ },
+ {.name = "wait",
+ .type = VSH_OT_BOOL,
+ .help = N_("wait for job to reach backup phase")
+ },
+ {.name = "verbose",
+ .type = VSH_OT_BOOL,
+ .help = N_("with --wait, display the progress")
+ },
+ {.name = NULL}
+};
+
+static bool
+cmdBlockBackup(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ const char *path = NULL;
+ const char *dest = NULL;
+ const char *mode = NULL;
+ const char *format = NULL;
+ unsigned long bandwidth = 0;
+ unsigned int flags = 0;
+ bool ret = false;
+ bool verbose = vshCommandOptBool(cmd, "verbose");
+ bool blocking = vshCommandOptBool(cmd, "wait") || verbose;
+ virshBlockJobWaitDataPtr bjWait = NULL;
+ unsigned long long limit = MIN(ULONG_MAX, ULLONG_MAX >> 20);
+
+ if (vshCommandOptStringReq(ctl, cmd, "path", &path) < 0)
+ return false;
+ if (vshCommandOptStringReq(ctl, cmd, "dest", &dest) < 0)
+ return false;
+ if (vshCommandOptStringReq(ctl, cmd, "mode", &mode) < 0)
+ return false;
+ if (vshCommandOptStringReq(ctl, cmd, "format", &format) < 0)
+ return false;
+
+ if (vshCommandOptULWrap(ctl, cmd, "bandwidth", &bandwidth) < 0)
+ return false;
+
+ if (!mode || !strcmp(mode, "full")) {
+ flags |= VIR_DOMAIN_BLOCK_BACKUP_FULL;
+ } else if (!strcmp(mode, "top")) {
+ flags |= VIR_DOMAIN_BLOCK_BACKUP_TOP;
+ } else if (!strcmp(mode, "incremental")) {
+ flags |= VIR_DOMAIN_BLOCK_BACKUP_INCREMENTAL;
+ } else {
+ return false;
+ }
+
+ if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
+ return false;
+
+ if (blocking &&
+ !(bjWait = virshBlockJobWaitInit(ctl, dom, path, _("Block
Backup"),
+ verbose, 0, 0)))
+ goto cleanup;
+
+ /* bandwidth is ulong MiB/s, but the typed parameter is
+ * ullong bytes/s; make sure we don't overflow */
+ if (bandwidth > limit) {
+ vshError(ctl, _("bandwidth must be less than %llu"), limit);
+ goto cleanup;
+ }
+
+ if (virDomainBlockBackup(dom, path, dest,
+ bandwidth, format, flags) < 0)
+ goto cleanup;
+
+ if (!blocking) {
+ vshPrint(ctl, "%s", _("Block Backup started"));
+ ret = true;
+ goto cleanup;
+ }
+
+ /* Execution continues here only if --wait or friends were specified */
+ switch (virshBlockJobWait(bjWait)) {
+ case -1:
+ goto cleanup;
+
+ case VIR_DOMAIN_BLOCK_JOB_CANCELED:
+ vshPrint(ctl, "\n%s", _("Backup aborted"));
+ goto cleanup;
+ break;
+
+ case VIR_DOMAIN_BLOCK_JOB_FAILED:
+ vshPrint(ctl, "\n%s", _("Backup failed"));
+ goto cleanup;
+ break;
+
+ case VIR_DOMAIN_BLOCK_JOB_READY:
+ case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
+ break;
+ }
+
+ ret = true;
+
+cleanup:
+ virDomainFree(dom);
+ virshBlockJobWaitFree(bjWait);
+ return ret;
+}
+
#ifndef WIN32
/*
* "console" command
@@ -13074,6 +13217,12 @@ const vshCmdDef domManagementCmds[] = {
.info = info_block_resize,
.flags = 0
},
+ {.name = "blockbackup",
+ .handler = cmdBlockBackup,
+ .opts = opts_block_backup,
+ .info = info_block_backup,
+ .flags = 0
+ },
{.name = "change-media",
.handler = cmdChangeMedia,
.opts = opts_change_media,
--
2.6.4