[libvirt] [PATCH 3/4] virsh: support blockbackup in virsh command

Rudy Zhang rudyflyzhang at gmail.com
Wed Jun 8 06:21:43 UTC 2016


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 at 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




More information about the libvir-list mailing list