[Libvir] PATCH: 6/7 add virsh commands for storage management

Daniel P. Berrange berrange at redhat.com
Mon Oct 29 03:59:39 UTC 2007


This adds a bunch of new virsh commands to expose all the capabilities of
the storage APIs

For dealing with storage pools:

    pool-autostart  autostart a pool
    pool-create     create a pool from an XML file
    pool-define     define (but don't start) a pool from an XML file
    pool-destroy    destroy a pool
    pool-dumpxml    pool information in XML
    pool-list       list pools
    pool-name       convert a pool UUID to pool name
    pool-start      start a (previously defined) inactive pool
    pool-undefine   undefine an inactive pool
    pool-uuid       convert a pool name to pool UUID

NB, there is a 'pool-info' command missing here which would get usage
stats.

For dealing with volumes within a pool

    vol-create      create a vol from an XML file
    vol-delete      destroy a vol
    vol-dumpxml     vol information in XML
    vol-list        list vols
    vol-path        convert a vol UUID to vol path
    vol-name        convert a vol UUID to vol name
    vol-uuid        convert a vol name to vol UUID

NB, there is a 'vol-info' command missing here which would get usage
stats. Both the missing methods will be added.

See the next mail for example usage of some of these commands.

The actual implementation is pretty uninteresting - its basically
the same way the corresponding net-XXXX commands are implemented.


 virsh.c |  989 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 989 insertions(+)



diff -r 20927d94d31e src/virsh.c
--- a/src/virsh.c	Sat Oct 27 18:23:02 2007 -0400
+++ b/src/virsh.c	Sat Oct 27 19:15:10 2007 -0400
@@ -252,6 +252,23 @@ static virNetworkPtr vshCommandOptNetwor
 /* default is lookup by Name and UUID */
 #define vshCommandOptNetwork(_ctl, _cmd, _optname, _name)           \
     vshCommandOptNetworkBy(_ctl, _cmd, _optname, _name,             \
+                           VSH_BYUUID|VSH_BYNAME)
+
+static virStoragePoolPtr vshCommandOptPoolBy(vshControl * ctl, vshCmd * cmd,
+                            const char *optname, char **name, int flag);
+
+/* default is lookup by Name and UUID */
+#define vshCommandOptPool(_ctl, _cmd, _optname, _name)           \
+    vshCommandOptPoolBy(_ctl, _cmd, _optname, _name,             \
+                           VSH_BYUUID|VSH_BYNAME)
+
+static virStorageVolPtr vshCommandOptVolBy(vshControl * ctl, vshCmd * cmd,
+                                           virStoragePoolPtr pool,
+                                           const char *optname, char **name, int flag);
+
+/* default is lookup by Name and UUID */
+#define vshCommandOptVol(_ctl, _cmd, _pool, _optname, _name)     \
+    vshCommandOptVolBy(_ctl, _cmd, _pool, _optname, _name,       \
                            VSH_BYUUID|VSH_BYNAME)
 
 static void vshPrintExtra(vshControl * ctl, const char *format, ...);
@@ -2754,6 +2771,881 @@ cmdNetworkUuid(vshControl * ctl, vshCmd 
 
     return TRUE;
 }
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+ * "pool-autostart" command
+ */
+static vshCmdInfo info_pool_autostart[] = {
+    {"syntax", "pool-autostart [--disable] <pool>"},
+    {"help", gettext_noop("autostart a pool")},
+    {"desc",
+     gettext_noop("Configure a pool to be automatically started at boot.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_autostart[] = {
+    {"pool",  VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {"disable", VSH_OT_BOOL, 0, gettext_noop("disable autostarting")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolAutostart(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    char *name;
+    int autostart;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name)))
+        return FALSE;
+
+    autostart = !vshCommandOptBool(cmd, "disable");
+
+    if (virStoragePoolSetAutostart(pool, autostart) < 0) {
+        if (autostart)
+	    vshError(ctl, FALSE, _("failed to mark pool %s as autostarted"),
+                                   name);
+	else
+	    vshError(ctl, FALSE,_("failed to unmark pool %s as autostarted"),
+                                   name);
+        virStoragePoolFree(pool);
+        return FALSE;
+    }
+
+    if (autostart)
+	vshPrint(ctl, _("Pool %s marked as autostarted\n"), name);
+    else
+	vshPrint(ctl, _("Pool %s unmarked as autostarted\n"), name);
+
+    return TRUE;
+}
+
+/*
+ * "pool-create" command
+ */
+static vshCmdInfo info_pool_create[] = {
+    {"syntax", "create a pool from an XML <file>"},
+    {"help", gettext_noop("create a pool from an XML file")},
+    {"desc", gettext_noop("Create a pool.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_create[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file containing an XML pool description")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolCreate(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    char *from;
+    int found;
+    int ret = TRUE;
+    char *buffer;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    from = vshCommandOptString(cmd, "file", &found);
+    if (!found)
+        return FALSE;
+
+    buffer = readFile (ctl, from);
+    if (buffer == NULL) return FALSE;
+
+    pool = virStoragePoolCreateXML(ctl->conn, buffer);
+    free (buffer);
+
+    if (pool != NULL) {
+        vshPrint(ctl, _("Pool %s created from %s\n"),
+                 virStoragePoolGetName(pool), from);
+    } else {
+        vshError(ctl, FALSE, _("Failed to create pool from %s"), from);
+        ret = FALSE;
+    }
+    return ret;
+}
+
+
+/*
+ * "pool-define" command
+ */
+static vshCmdInfo info_pool_define[] = {
+    {"syntax", "define a pool from an XML <file>"},
+    {"help", gettext_noop("define (but don't start) a pool from an XML file")},
+    {"desc", gettext_noop("Define a pool.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_define[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file containing an XML pool description")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolDefine(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    char *from;
+    int found;
+    int ret = TRUE;
+    char *buffer;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    from = vshCommandOptString(cmd, "file", &found);
+    if (!found)
+        return FALSE;
+
+    buffer = readFile (ctl, from);
+    if (buffer == NULL) return FALSE;
+
+    pool = virStoragePoolDefineXML(ctl->conn, buffer);
+    free (buffer);
+
+    if (pool != NULL) {
+        vshPrint(ctl, _("Pool %s defined from %s\n"),
+                 virStoragePoolGetName(pool), from);
+    } else {
+        vshError(ctl, FALSE, _("Failed to define pool from %s"), from);
+        ret = FALSE;
+    }
+    return ret;
+}
+
+
+/*
+ * "pool-destroy" command
+ */
+static vshCmdInfo info_pool_destroy[] = {
+    {"syntax", "pool-destroy <pool>"},
+    {"help", gettext_noop("destroy a pool")},
+    {"desc", gettext_noop("Destroy a given pool.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_destroy[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name, id or uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolDestroy(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    int ret = TRUE;
+    char *name;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name)))
+        return FALSE;
+
+    if (virStoragePoolDestroy(pool) == 0) {
+        vshPrint(ctl, _("Pool %s destroyed\n"), name);
+    } else {
+        vshError(ctl, FALSE, _("Failed to destroy pool %s"), name);
+        ret = FALSE;
+        virStoragePoolFree(pool);
+    }
+
+    return ret;
+}
+
+
+/*
+ * "pool-dumpxml" command
+ */
+static vshCmdInfo info_pool_dumpxml[] = {
+    {"syntax", "pool-dumpxml <pool>"},
+    {"help", gettext_noop("pool information in XML")},
+    {"desc", gettext_noop("Output the pool information as an XML dump to stdout.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_dumpxml[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name, id or uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolDumpXML(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    int ret = TRUE;
+    char *dump;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
+        return FALSE;
+
+    dump = virStoragePoolGetXMLDesc(pool, 0);
+    if (dump != NULL) {
+        printf("%s", dump);
+        free(dump);
+    } else {
+        ret = FALSE;
+    }
+
+    virStoragePoolFree(pool);
+    return ret;
+}
+
+
+/*
+ * "pool-list" command
+ */
+static vshCmdInfo info_pool_list[] = {
+    {"syntax", "pool-list [ --inactive | --all ]"},
+    {"help", gettext_noop("list pools")},
+    {"desc", gettext_noop("Returns list of pools.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_list[] = {
+    {"inactive", VSH_OT_BOOL, 0, gettext_noop("list inactive pools")},
+    {"all", VSH_OT_BOOL, 0, gettext_noop("list inactive & active pools")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolList(vshControl * ctl, vshCmd * cmd ATTRIBUTE_UNUSED)
+{
+    int inactive = vshCommandOptBool(cmd, "inactive");
+    int all = vshCommandOptBool(cmd, "all");
+    int active = !inactive || all ? 1 : 0;
+    int maxactive = 0, maxinactive = 0, i;
+    char **activeNames = NULL, **inactiveNames = NULL;
+    inactive |= all;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (active) {
+        maxactive = virConnectNumOfStoragePools(ctl->conn);
+        if (maxactive < 0) {
+            vshError(ctl, FALSE, _("Failed to list active pools"));
+            return FALSE;
+        }
+        if (maxactive) {
+            activeNames = vshMalloc(ctl, sizeof(char *) * maxactive);
+
+            if ((maxactive = virConnectListStoragePools(ctl->conn, activeNames,
+                                                        maxactive)) < 0) {
+                vshError(ctl, FALSE, _("Failed to list active pools"));
+                free(activeNames);
+                return FALSE;
+            }
+
+            qsort(&activeNames[0], maxactive, sizeof(char *), namesorter);
+        }
+    }
+    if (inactive) {
+        maxinactive = virConnectNumOfDefinedStoragePools(ctl->conn);
+        if (maxinactive < 0) {
+            vshError(ctl, FALSE, _("Failed to list inactive pools"));
+            if (activeNames)
+                free(activeNames);
+            return FALSE;
+        }
+        if (maxinactive) {
+            inactiveNames = vshMalloc(ctl, sizeof(char *) * maxinactive);
+
+            if ((maxinactive = virConnectListDefinedStoragePools(ctl->conn, inactiveNames, maxinactive)) < 0) {
+                vshError(ctl, FALSE, _("Failed to list inactive pools"));
+                if (activeNames)
+                    free(activeNames);
+                free(inactiveNames);
+                return FALSE;
+            }
+
+            qsort(&inactiveNames[0], maxinactive, sizeof(char*), namesorter);
+        }
+    }
+    vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("State"), _("Autostart"));
+    vshPrintExtra(ctl, "-----------------------------------------\n");
+
+    for (i = 0; i < maxactive; i++) {
+        virStoragePoolPtr pool = virStoragePoolLookupByName(ctl->conn, activeNames[i]);
+        const char *autostartStr;
+        int autostart = 0;
+
+        /* this kind of work with pools is not atomic operation */
+        if (!pool) {
+            free(activeNames[i]);
+            continue;
+        }
+
+        if (virStoragePoolGetAutostart(pool, &autostart) < 0)
+            autostartStr = _("no autostart");
+        else
+            autostartStr = autostart ? "yes" : "no";
+
+        vshPrint(ctl, "%-20s %-10s %-10s\n",
+                 virStoragePoolGetName(pool),
+                 _("active"),
+                 autostartStr);
+        virStoragePoolFree(pool);
+        free(activeNames[i]);
+    }
+    for (i = 0; i < maxinactive; i++) {
+        virStoragePoolPtr pool = virStoragePoolLookupByName(ctl->conn, inactiveNames[i]);
+        const char *autostartStr;
+        int autostart = 0;
+
+        /* this kind of work with pools is not atomic operation */
+        if (!pool) {
+            free(inactiveNames[i]);
+            continue;
+        }
+
+        if (virStoragePoolGetAutostart(pool, &autostart) < 0)
+            autostartStr = _("no autostart");
+        else
+            autostartStr = autostart ? "yes" : "no";
+
+        vshPrint(ctl, "%-20s %s %s\n",
+                 inactiveNames[i],
+                 _("inactive"),
+                 autostartStr);
+
+        virStoragePoolFree(pool);
+        free(inactiveNames[i]);
+    }
+    if (activeNames)
+        free(activeNames);
+    if (inactiveNames)
+        free(inactiveNames);
+    return TRUE;
+}
+
+
+/*
+ * "pool-name" command
+ */
+static vshCmdInfo info_pool_name[] = {
+    {"syntax", "pool-name <pool>"},
+    {"help", gettext_noop("convert a pool UUID to pool name")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_name[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolName(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+    if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL,
+					   VSH_BYUUID)))
+        return FALSE;
+
+    vshPrint(ctl, "%s\n", virStoragePoolGetName(pool));
+    virStoragePoolFree(pool);
+    return TRUE;
+}
+
+
+/*
+ * "pool-start" command
+ */
+static vshCmdInfo info_pool_start[] = {
+    {"syntax", "start <pool>"},
+    {"help", gettext_noop("start a (previously defined) inactive pool")},
+    {"desc", gettext_noop("Start a pool.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_start[] = {
+    {"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name of the inactive pool")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolStart(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    int ret = TRUE;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPoolBy(ctl, cmd, "name", NULL, VSH_BYNAME)))
+         return FALSE;
+
+    if (virStoragePoolCreate(pool) == 0) {
+        vshPrint(ctl, _("Pool %s started\n"),
+                 virStoragePoolGetName(pool));
+    } else {
+        vshError(ctl, FALSE, _("Failed to start pool %s"),
+                 virStoragePoolGetName(pool));
+        ret = FALSE;
+    }
+    return ret;
+}
+
+
+/*
+ * "pool-undefine" command
+ */
+static vshCmdInfo info_pool_undefine[] = {
+    {"syntax", "pool-undefine <pool>"},
+    {"help", gettext_noop("undefine an inactive pool")},
+    {"desc", gettext_noop("Undefine the configuration for an inactive pool.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_undefine[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolUndefine(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    int ret = TRUE;
+    char *name;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name)))
+        return FALSE;
+
+    if (virStoragePoolUndefine(pool) == 0) {
+        vshPrint(ctl, _("Pool %s has been undefined\n"), name);
+    } else {
+        vshError(ctl, FALSE, _("Failed to undefine pool %s"), name);
+        ret = FALSE;
+    }
+
+    return ret;
+}
+
+
+/*
+ * "pool-uuid" command
+ */
+static vshCmdInfo info_pool_uuid[] = {
+    {"syntax", "pool-uuid <pool>"},
+    {"help", gettext_noop("convert a pool name to pool UUID")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_pool_uuid[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdPoolUuid(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    char uuid[VIR_UUID_STRING_BUFLEN];
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL,
+					   VSH_BYNAME)))
+        return FALSE;
+
+    if (virStoragePoolGetUUIDString(pool, uuid) != -1)
+        vshPrint(ctl, "%s\n", uuid);
+    else
+        vshError(ctl, FALSE, _("failed to get pool UUID"));
+
+    return TRUE;
+}
+
+
+
+
+/*
+ * "vol-create" command
+ */
+static vshCmdInfo info_vol_create[] = {
+    {"syntax", "create <pool> <file>"},
+    {"help", gettext_noop("create a vol from an XML file")},
+    {"desc", gettext_noop("Create a vol.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_vol_create[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file containing an XML vol description")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdVolCreate(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    virStorageVolPtr vol;
+    char *from;
+    int found;
+    int ret = TRUE;
+    char *buffer;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
+        return FALSE;
+
+    from = vshCommandOptString(cmd, "file", &found);
+    if (!found)
+        return FALSE;
+
+    buffer = readFile (ctl, from);
+    if (buffer == NULL) return FALSE;
+
+    vol = virStorageVolCreateXML(pool, buffer, 0);
+    free (buffer);
+    virStoragePoolFree(pool);
+
+    if (vol != NULL) {
+        vshPrint(ctl, _("Vol %s created from %s\n"),
+                 virStorageVolGetName(vol), from);
+    } else {
+        vshError(ctl, FALSE, _("Failed to create vol from %s"), from);
+        ret = FALSE;
+    }
+    return ret;
+}
+
+
+/*
+ * "vol-destroy" command
+ */
+static vshCmdInfo info_vol_destroy[] = {
+    {"syntax", "vol-destroy <pool> <vol>"},
+    {"help", gettext_noop("destroy a vol")},
+    {"desc", gettext_noop("Destroy a given vol.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_vol_destroy[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {"vol", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("vol name, id or uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdVolDestroy(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    virStorageVolPtr vol;
+    int ret = TRUE;
+    char *name;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
+        return FALSE;
+
+    if (!(vol = vshCommandOptVol(ctl, cmd, pool, "vol", &name))) {
+        virStoragePoolFree(pool);
+        return FALSE;
+    }
+    virStoragePoolFree(pool);
+
+    if (virStorageVolDestroy(vol) == 0) {
+        vshPrint(ctl, _("Vol %s destroyed\n"), name);
+    } else {
+        vshError(ctl, FALSE, _("Failed to destroy vol %s"), name);
+        ret = FALSE;
+        virStorageVolFree(vol);
+    }
+
+    return ret;
+}
+
+
+/*
+ * "vol-dumpxml" command
+ */
+static vshCmdInfo info_vol_dumpxml[] = {
+    {"syntax", "vol-dumpxml <pool> <vol>"},
+    {"help", gettext_noop("vol information in XML")},
+    {"desc", gettext_noop("Output the vol information as an XML dump to stdout.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_vol_dumpxml[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {"vol", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("vol name, id or uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdVolDumpXML(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    virStorageVolPtr vol;
+    int ret = TRUE;
+    char *dump;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
+        return FALSE;
+
+    if (!(vol = vshCommandOptVol(ctl, cmd, pool, "vol", NULL)))
+        return FALSE;
+    virStoragePoolFree(pool);
+
+    dump = virStorageVolGetXMLDesc(vol, 0);
+    if (dump != NULL) {
+        printf("%s", dump);
+        free(dump);
+    } else {
+        ret = FALSE;
+    }
+
+    virStorageVolFree(vol);
+    return ret;
+}
+
+
+/*
+ * "vol-list" command
+ */
+static vshCmdInfo info_vol_list[] = {
+    {"syntax", "vol-list <pool>"},
+    {"help", gettext_noop("list vols")},
+    {"desc", gettext_noop("Returns list of vols.")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_vol_list[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdVolList(vshControl * ctl, vshCmd * cmd ATTRIBUTE_UNUSED)
+{
+    virStoragePoolPtr pool;
+    int maxactive = 0, i;
+    char **activeNames = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
+        return FALSE;
+
+    maxactive = virStoragePoolNumOfVolumes(pool);
+    if (maxactive < 0) {
+        virStoragePoolFree(pool);
+        vshError(ctl, FALSE, _("Failed to list active vols"));
+        return FALSE;
+    }
+    if (maxactive) {
+        activeNames = vshMalloc(ctl, sizeof(char *) * maxactive);
+
+        if ((maxactive = virStoragePoolListVolumes(pool, activeNames,
+                                                   maxactive)) < 0) {
+            vshError(ctl, FALSE, _("Failed to list active vols"));
+            free(activeNames);
+            virStoragePoolFree(pool);
+            return FALSE;
+        }
+
+        qsort(&activeNames[0], maxactive, sizeof(char *), namesorter);
+    }
+    vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("Type"), _("Path"));
+    vshPrintExtra(ctl, "-----------------------------------------\n");
+
+    for (i = 0; i < maxactive; i++) {
+        virStorageVolPtr vol = virStorageVolLookupByName(pool, activeNames[i]);
+        char *path;
+        virStorageVolInfo info;
+
+        /* this kind of work with vols is not atomic operation */
+        if (!vol) {
+            free(activeNames[i]);
+            continue;
+        }
+
+        if (virStorageVolGetInfo(vol, &info) < 0) {
+            virStorageVolFree(vol);
+            continue;
+        }
+
+        if ((path = virStorageVolGetPath(vol)) == NULL) {
+            virStorageVolFree(vol);
+            continue;
+        }
+
+
+        vshPrint(ctl, "%-20s %-10s %-10s\n",
+                 virStorageVolGetName(vol),
+                 info.type == VIR_STORAGE_POOL_FILE ? "file" : "block",
+                 path);
+        free(path);
+        virStorageVolFree(vol);
+        free(activeNames[i]);
+    }
+    if (activeNames)
+        free(activeNames);
+    virStoragePoolFree(pool);
+    return TRUE;
+}
+
+
+/*
+ * "vol-name" command
+ */
+static vshCmdInfo info_vol_name[] = {
+    {"syntax", "vol-name <pool> <vol>"},
+    {"help", gettext_noop("convert a vol UUID to vol name")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_vol_name[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {"vol", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("vol uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdVolName(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    virStorageVolPtr vol;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
+        return FALSE;
+
+    if (!(vol = vshCommandOptVolBy(ctl, cmd, pool, "vol", NULL,
+                                   VSH_BYUUID))) {
+        virStoragePoolFree(pool);
+        return FALSE;
+    }
+    virStoragePoolFree(pool);
+
+    vshPrint(ctl, "%s\n", virStorageVolGetName(vol));
+    virStorageVolFree(vol);
+    return TRUE;
+}
+
+
+
+/*
+ * "vol-path" command
+ */
+static vshCmdInfo info_vol_path[] = {
+    {"syntax", "vol-path <pool> <vol>"},
+    {"help", gettext_noop("convert a vol UUID to vol path")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_vol_path[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {"vol", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("vol uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdVolPath(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    virStorageVolPtr vol;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
+        return FALSE;
+    if (!(vol = vshCommandOptVolBy(ctl, cmd, pool, "vol", NULL,
+                                   VSH_BYUUID))) {
+        virStoragePoolFree(pool);
+        return FALSE;
+    }
+    virStoragePoolFree(pool);
+
+    vshPrint(ctl, "%s\n", virStorageVolGetPath(vol));
+    virStorageVolFree(vol);
+    return TRUE;
+}
+
+
+
+
+/*
+ * "vol-uuid" command
+ */
+static vshCmdInfo info_vol_uuid[] = {
+    {"syntax", "vol-uuid <pool> <vol>"},
+    {"help", gettext_noop("convert a vol name to vol UUID")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_vol_uuid[] = {
+    {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
+    {"vol", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("vol name")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdVolUuid(vshControl * ctl, vshCmd * cmd)
+{
+    virStoragePoolPtr pool;
+    virStorageVolPtr vol;
+    char uuid[VIR_UUID_STRING_BUFLEN];
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
+        return FALSE;
+
+    if (!(vol = vshCommandOptVolBy(ctl, cmd, pool, "vol", NULL,
+                                   VSH_BYNAME))) {
+        virStoragePoolFree(pool);
+        return FALSE;
+    }
+    virStoragePoolFree(pool);
+
+    if (virStorageVolGetUUIDString(vol, uuid) != -1)
+        vshPrint(ctl, "%s\n", uuid);
+    else
+        vshError(ctl, FALSE, _("failed to get vol UUID"));
+
+    return TRUE;
+}
+
+
 
 
 /*
@@ -3707,6 +4599,7 @@ static vshCmdDef commands[] = {
     {"hostname", cmdHostname, NULL, info_hostname},
     {"list", cmdList, opts_list, info_list},
     {"migrate", cmdMigrate, opts_migrate, info_migrate},
+
     {"net-autostart", cmdNetworkAutostart, opts_network_autostart, info_network_autostart},
     {"net-create", cmdNetworkCreate, opts_network_create, info_network_create},
     {"net-define", cmdNetworkDefine, opts_network_define, info_network_define},
@@ -3718,6 +4611,18 @@ static vshCmdDef commands[] = {
     {"net-undefine", cmdNetworkUndefine, opts_network_undefine, info_network_undefine},
     {"net-uuid", cmdNetworkUuid, opts_network_uuid, info_network_uuid},
     {"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo},
+
+    {"pool-autostart", cmdPoolAutostart, opts_pool_autostart, info_pool_autostart},
+    {"pool-create", cmdPoolCreate, opts_pool_create, info_pool_create},
+    {"pool-define", cmdPoolDefine, opts_pool_define, info_pool_define},
+    {"pool-destroy", cmdPoolDestroy, opts_pool_destroy, info_pool_destroy},
+    {"pool-dumpxml", cmdPoolDumpXML, opts_pool_dumpxml, info_pool_dumpxml},
+    {"pool-list", cmdPoolList, opts_pool_list, info_pool_list},
+    {"pool-name", cmdPoolName, opts_pool_name, info_pool_name},
+    {"pool-start", cmdPoolStart, opts_pool_start, info_pool_start},
+    {"pool-undefine", cmdPoolUndefine, opts_pool_undefine, info_pool_undefine},
+    {"pool-uuid", cmdPoolUuid, opts_pool_uuid, info_pool_uuid},
+
     {"quit", cmdQuit, NULL, info_quit},
     {"reboot", cmdReboot, opts_reboot, info_reboot},
     {"restore", cmdRestore, opts_restore, info_restore},
@@ -3733,6 +4638,15 @@ static vshCmdDef commands[] = {
     {"ttyconsole", cmdTTYConsole, opts_ttyconsole, info_ttyconsole},
     {"undefine", cmdUndefine, opts_undefine, info_undefine},
     {"uri", cmdURI, NULL, info_uri},
+
+    {"vol-create", cmdVolCreate, opts_vol_create, info_vol_create},
+    {"vol-delete", cmdVolDestroy, opts_vol_destroy, info_vol_destroy},
+    {"vol-dumpxml", cmdVolDumpXML, opts_vol_dumpxml, info_vol_dumpxml},
+    {"vol-list", cmdVolList, opts_vol_list, info_vol_list},
+    {"vol-path", cmdVolPath, opts_vol_path, info_vol_path},
+    {"vol-name", cmdVolName, opts_vol_name, info_vol_name},
+    {"vol-uuid", cmdVolUuid, opts_vol_uuid, info_vol_uuid},
+
     {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
     {"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
     {"version", cmdVersion, NULL, info_version},
@@ -4058,6 +4972,81 @@ vshCommandOptNetworkBy(vshControl * ctl,
         vshError(ctl, FALSE, _("failed to get network '%s'"), n);
 
     return network;
+}
+
+static virStoragePoolPtr
+vshCommandOptPoolBy(vshControl * ctl, vshCmd * cmd, const char *optname,
+                    char **name, int flag)
+{
+    virStoragePoolPtr pool = NULL;
+    char *n;
+
+    if (!(n = vshCommandOptString(cmd, optname, NULL))) {
+        vshError(ctl, FALSE, _("undefined pool name"));
+        return NULL;
+    }
+
+    vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+             cmd->def->name, optname, n);
+
+    if (name)
+        *name = n;
+
+    /* try it by UUID */
+    if (pool==NULL && (flag & VSH_BYUUID) && strlen(n)==VIR_UUID_STRING_BUFLEN-1) {
+        vshDebug(ctl, 5, "%s: <%s> trying as pool UUID\n",
+		 cmd->def->name, optname);
+        pool = virStoragePoolLookupByUUIDString(ctl->conn, n);
+    }
+    /* try it by NAME */
+    if (pool==NULL && (flag & VSH_BYNAME)) {
+        vshDebug(ctl, 5, "%s: <%s> trying as pool NAME\n",
+                 cmd->def->name, optname);
+        pool = virStoragePoolLookupByName(ctl->conn, n);
+    }
+
+    if (!pool)
+        vshError(ctl, FALSE, _("failed to get pool '%s'"), n);
+
+    return pool;
+}
+
+static virStorageVolPtr
+vshCommandOptVolBy(vshControl * ctl, vshCmd * cmd, virStoragePoolPtr pool,
+                   const char *optname,
+                   char **name, int flag)
+{
+    virStorageVolPtr vol = NULL;
+    char *n;
+
+    if (!(n = vshCommandOptString(cmd, optname, NULL))) {
+        vshError(ctl, FALSE, _("undefined vol name"));
+        return NULL;
+    }
+
+    vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+             cmd->def->name, optname, n);
+
+    if (name)
+        *name = n;
+
+    /* try it by UUID */
+    if (vol==NULL && (flag & VSH_BYUUID) && strlen(n)==VIR_UUID_STRING_BUFLEN-1) {
+        vshDebug(ctl, 5, "%s: <%s> trying as vol UUID\n",
+		 cmd->def->name, optname);
+        vol = virStorageVolLookupByUUIDString(pool, n);
+    }
+    /* try it by NAME */
+    if (vol==NULL && (flag & VSH_BYNAME)) {
+        vshDebug(ctl, 5, "%s: <%s> trying as vol NAME\n",
+                 cmd->def->name, optname);
+        vol = virStorageVolLookupByName(pool, n);
+    }
+
+    if (!vol)
+        vshError(ctl, FALSE, _("failed to get vol '%s'"), n);
+
+    return vol;
 }
 
 /*

-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 




More information about the libvir-list mailing list