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