[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 5/6] Add new disk streaming commands to virsh



Define two new virsh commands: one to control disk streaming and one to print
the status of active disk streams.

* tools/virsh.c: implement the new commands

Signed-off-by: Adam Litke <agl us ibm com>
---
 tools/virsh.c |  157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 157 insertions(+), 0 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index ab83976..17957ac 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -229,6 +229,8 @@ static char *vshCommandOptString(const vshCmd *cmd, const char *name,
                                  int *found);
 static long long vshCommandOptLongLong(const vshCmd *cmd, const char *name,
                                        int *found);
+static unsigned long long vshCommandOptULL(const vshCmd *cmd, const char *name,
+                                           int *found);
 static int vshCommandOptBool(const vshCmd *cmd, const char *name);
 static char *vshCommandOptArgv(const vshCmd *cmd, int count);
 
@@ -3490,6 +3492,141 @@ done:
 }
 
 /*
+ * "domstreamdisk" command
+ */
+static const vshCmdInfo info_domstreamdisk[] = {
+    {"help", gettext_noop("Stream data to a disk")},
+    {"desc", gettext_noop("Stream data to a disk connected to a running domain")},
+    { NULL, NULL },
+};
+
+static const vshCmdOptDef opts_domstreamdisk[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
+    {"start", VSH_OT_BOOL, VSH_OFLAG_NONE, N_("Start streaming a disk") },
+    {"stop", VSH_OT_BOOL, VSH_OFLAG_NONE, N_("Stop streaming a disk") },
+    {"incremental", VSH_OT_BOOL, VSH_OFLAG_NONE, N_("Perform an incremental stream") },
+    {"path", VSH_OT_DATA, VSH_OFLAG_REQ, N_("block device")},
+    {"offset", VSH_OT_DATA, VSH_OFLAG_NONE, N_("Device offset for incremental stream")},
+    { NULL, 0, 0, NULL },
+};
+
+static int
+cmdDomStreamDisk(vshControl *ctl, const vshCmd *cmd)
+{
+    virDomainPtr dom;
+    char *name;
+    const char *path;
+    int found;
+    unsigned long long offset, next;
+    unsigned int flags, start, stop, incr;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return FALSE;
+
+    flags = start = stop = incr = 0;
+    if (vshCommandOptBool(cmd, "start")) {
+        start = 1;
+        flags = VIR_STREAM_DISK_START;
+    }
+    if (vshCommandOptBool(cmd, "stop")) {
+        stop = 1;
+        flags = VIR_STREAM_DISK_STOP;
+    }
+    if (vshCommandOptBool(cmd, "incremental")) {
+        incr = 1;
+        flags = VIR_STREAM_DISK_ONE;
+    }
+    if (start + stop + incr != 1) {
+        vshError(ctl, _("Exactly one mode: --start, --stop, --incremental, "
+                        "is required"));
+        return FALSE;
+    }
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
+        return FALSE;
+
+    path = vshCommandOptString(cmd, "path", NULL);
+
+    if (flags == VIR_STREAM_DISK_ONE) {
+        offset = vshCommandOptULL(cmd, "offset", &found);
+        if (!found) {
+            vshError(ctl, _("An offset is required for incremental streaming"));
+            virDomainFree(dom);
+            return FALSE;
+        }
+    } else {
+        offset = 0;
+    }
+
+    next = virDomainStreamDisk(dom, path, offset, flags);
+    if (next == (unsigned long long) -1) {
+        vshError(ctl, _("Stream operation failed for the device"
+                        "'%s' connected to the domain '%s'"), path, name);
+        virDomainFree(dom);
+        return FALSE;
+    }
+
+    if (flags == VIR_STREAM_DISK_START)
+        vshPrint (ctl, "Stream successfully started\n");
+    else if (flags == VIR_STREAM_DISK_STOP)
+        vshPrint (ctl, "Stream successfully stopped\n");
+    else
+        vshPrint (ctl, "Strem successful.  Continue at offset %llu\n", next);
+
+    virDomainFree(dom);
+    return TRUE;
+}
+
+/*
+ * "domstreamdiskinfo" command
+ */
+static const vshCmdInfo info_domstreamdiskinfo[] = {
+    {"help", gettext_noop("Get disk streaming status for a domain")},
+    {"desc", gettext_noop("Get disk streaming status for a running domain")},
+    { NULL, NULL },
+};
+
+static const vshCmdOptDef opts_domstreamdiskinfo[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
+    { NULL, 0, 0, NULL },
+};
+
+static int
+cmdDomStreamDiskInfo(vshControl *ctl, const vshCmd *cmd)
+{
+    virDomainPtr dom;
+    char *name;
+    struct _virStreamDiskState streams[VIR_STREAM_DISK_MAX_STREAMS];
+    int nr_streams, i;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return FALSE;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
+        return FALSE;
+
+    nr_streams = virDomainStreamDiskInfo(dom, streams,
+                                        VIR_STREAM_DISK_MAX_STREAMS, 0);
+    if (nr_streams < 0) {
+        vshError(ctl, _("Failed to get disk stream information for domain %s"),
+            name);
+        virDomainFree(dom);
+        return FALSE;
+    }
+
+    vshPrint (ctl, "%-30s %-10s %-10s\n", _("Device"), _("Offset"),
+              _("Size"));
+    vshPrint (ctl, "----------------------------------------------------\n");
+    for (i = 0; i < nr_streams; i++) {
+        vshPrint (ctl, "%-30s %-10llu %-10llu\n", streams[i].path,
+                  streams[i].offset, streams[i].size);
+    }
+
+    virDomainFree(dom);
+    return TRUE;
+}
+
+/*
  * "net-autostart" command
  */
 static const vshCmdInfo info_network_autostart[] = {
@@ -9854,6 +9991,8 @@ static const vshCmdDef commands[] = {
     {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus},
     {"migrate", cmdMigrate, opts_migrate, info_migrate},
     {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime},
+    {"domstreamdisk", cmdDomStreamDisk, opts_domstreamdisk, info_domstreamdisk},
+    {"domstreamdiskinfo", cmdDomStreamDiskInfo, opts_domstreamdiskinfo, info_domstreamdiskinfo},
 
     {"net-autostart", cmdNetworkAutostart, opts_network_autostart, info_network_autostart},
     {"net-create", cmdNetworkCreate, opts_network_create, info_network_create},
@@ -10288,6 +10427,24 @@ vshCommandOptLongLong(const vshCmd *cmd, const char *name, int *found)
 }
 
 /*
+ * Returns option as unsigned long long
+ */
+static unsigned long long
+vshCommandOptULL(const vshCmd *cmd, const char *name, int *found)
+{
+    vshCmdOpt *arg = vshCommandOpt(cmd, name);
+    int num_found = FALSE;
+    unsigned long long res = 0;
+    char *end_p = NULL;
+
+    if ((arg != NULL) && (arg->data != NULL))
+        num_found = !virStrToLong_ull(arg->data, &end_p, 10, &res);
+    if (found)
+        *found = num_found;
+    return res;
+}
+
+/*
  * Returns TRUE/FALSE if the option exists
  */
 static int
-- 
1.7.3.2.164.g6f10c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]