This patch adds a new --details option to the virsh pool-list command, making its output more useful to people who use virsh for significant lengths of time. ---
Output from the new option (hopefully this doesn't wrap): virsh # pool-list Name State Autostart ----------------------------------------- default active yes image_dir active yes virsh # pool-list --all Name State Autostart ----------------------------------------- default active yes image_dir active yes tmp inactive no virsh # pool-list --details Name State Autostart Persistent Capacity Allocation Available -------------------------------------------------------------------------------------- default running yes yes 1.79 TB 1.47 TB 326.02 GB image_dir running yes yes 1.79 TB 1.47 TB 326.02 GB virsh # pool-list --all --details Name State Autostart Persistent Capacity Allocation Available -------------------------------------------------------------------------------------- default running yes yes 1.79 TB 1.47 TB 326.02 GB image_dir running yes yes 1.79 TB 1.47 TB 326.02 GB tmp inactive no yes - - - virsh # Much more practical than running pool-info individually on each pool. tools/virsh.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++------ tools/virsh.pod | 6 ++- 2 files changed, 119 insertions(+), 17 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index d8d2220..afa84e6 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -4882,14 +4882,17 @@ static const vshCmdInfo info_pool_list[] = { static const vshCmdOptDef opts_pool_list[] = { {"inactive", VSH_OT_BOOL, 0, N_("list inactive pools")}, {"all", VSH_OT_BOOL, 0, N_("list inactive & active pools")}, + {"details", VSH_OT_BOOL, 0, N_("display extended details for pools")}, {NULL, 0, 0, NULL} }; static int cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { + virStoragePoolInfo info; int inactive = vshCommandOptBool(cmd, "inactive"); int all = vshCommandOptBool(cmd, "all"); + int details = vshCommandOptBool(cmd, "details"); int active = !inactive || all ? 1 : 0; int maxactive = 0, maxinactive = 0, i; char **activeNames = NULL, **inactiveNames = NULL; @@ -4937,36 +4940,114 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) qsort(&inactiveNames[0], maxinactive, sizeof(char*), namesorter); } } - vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("State"), _("Autostart")); - vshPrintExtra(ctl, "-----------------------------------------\n"); + + /* Display the appropriate heading */ + if (details) { + vshPrintExtra(ctl, "%-20s %-10s %-10s %-11s %-9s %-11s %-10s\n", + _("Name"), _("State"), _("Autostart"), _("Persistent"), + _("Capacity"), _("Allocation"), _("Available")); + vshPrintExtra(ctl, + "--------------------------------------------------------------------------------------\n"); + } else { + 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; + const char *autostartStr, *persistentStr, *stateStr = NULL; + int autostart = 0, persistent = 0; /* this kind of work with pools is not atomic operation */ + virStoragePoolPtr pool = virStoragePoolLookupByName(ctl->conn, activeNames[i]); if (!pool) { VIR_FREE(activeNames[i]); continue; } + /* Retrieve the pool autostart status */ if (virStoragePoolGetAutostart(pool, &autostart) < 0) autostartStr = _("no autostart"); else autostartStr = autostart ? _("yes") : _("no"); - vshPrint(ctl, "%-20s %-10s %-10s\n", - virStoragePoolGetName(pool), - _("active"), - autostartStr); + /* If requested, collect the extended information for this pool */ + if (details) { + if (virStoragePoolGetInfo(pool, &info) != 0) { + vshError(ctl, "%s", _("Could not retrieve pool information")); + VIR_FREE(activeNames[i]); + continue; + } + + /* Decide which state string to display */ + switch (info.state) { + case VIR_STORAGE_POOL_INACTIVE: + stateStr = _("inactive"); + break; + case VIR_STORAGE_POOL_BUILDING: + stateStr = _("building"); + break; + case VIR_STORAGE_POOL_RUNNING: + stateStr = _("running"); + break; + case VIR_STORAGE_POOL_DEGRADED: + stateStr = _("degraded"); + break; + case VIR_STORAGE_POOL_INACCESSIBLE: + stateStr = _("inaccessible"); + break; + } + + /* Check if the pool is persistent or not */ + persistent = virStoragePoolIsPersistent(pool); + vshDebug(ctl, 5, "Persistent flag value: %d\n", persistent); + if (persistent < 0) + persistentStr = _("unknown"); + else + persistentStr = persistent ? _("yes") : _("no"); + + /* Display all information for this pool */ + vshPrint(ctl, "%-20s %-10s %-10s %-11s", + virStoragePoolGetName(pool), + stateStr, + autostartStr, + persistentStr); + + /* Display the capacity related quantities */ + if (info.state == VIR_STORAGE_POOL_RUNNING || + info.state == VIR_STORAGE_POOL_DEGRADED) { + double val; + const char *unit; + virBuffer infoBufStr = VIR_BUFFER_INITIALIZER; + + val = prettyCapacity(info.capacity, &unit); + virBufferVSprintf(&infoBufStr, "%.2lf %s", val, unit); + vshPrint(ctl, " %-9s", virBufferContentAndReset(&infoBufStr)); + + val = prettyCapacity(info.allocation, &unit); + virBufferVSprintf(&infoBufStr, "%.2lf %s", val, unit); + vshPrint(ctl, " %-11s", virBufferContentAndReset(&infoBufStr)); + + val = prettyCapacity(info.available, &unit); + virBufferVSprintf(&infoBufStr, "%.2lf %s", val, unit); + vshPrint(ctl, " %-10s\n", virBufferContentAndReset(&infoBufStr)); + } else + vshPrint(ctl, " %-9s %-11s %-10s\n", "-", "-", "-"); + } else { + /* Display basic information pool information */ + vshPrint(ctl, "%-20s %-10s %-10s\n", + virStoragePoolGetName(pool), + _("active"), + autostartStr); + } + virStoragePoolFree(pool); VIR_FREE(activeNames[i]); } for (i = 0; i < maxinactive; i++) { virStoragePoolPtr pool = virStoragePoolLookupByName(ctl->conn, inactiveNames[i]); - const char *autostartStr; - int autostart = 0; + const char *autostartStr, *persistentStr; + int autostart = 0, persistent = 0; /* this kind of work with pools is not atomic operation */ if (!pool) { @@ -4979,10 +5060,29 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) else autostartStr = autostart ? _("yes") : _("no"); - vshPrint(ctl, "%-20s %-10s %-10s\n", - inactiveNames[i], - _("inactive"), - autostartStr); + if (details) { + /* Check if the pool is persistent or not */ + persistent = virStoragePoolIsPersistent(pool); + vshDebug(ctl, 5, "Persistent flag value: %d\n", persistent); + if (persistent < 0) + persistentStr = _("unknown"); + else + persistentStr = persistent ? _("yes") : _("no"); + + /* Display detailed pool information */ + vshPrint(ctl, "%-20s %-10s %-10s %-11s %-9s %-11s %-10s\n", + inactiveNames[i], + _("inactive"), + autostartStr, + persistentStr, + "-", "-", "-"); + } else { + /* Display basic pool information */ + vshPrint(ctl, "%-20s %-10s %-10s\n", + inactiveNames[i], + _("inactive"), + autostartStr); + } virStoragePoolFree(pool); VIR_FREE(inactiveNames[i]); diff --git a/tools/virsh.pod b/tools/virsh.pod index b1917ee..cec07e3 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -732,11 +732,13 @@ variables, and defaults to C<vi>. Returns basic information about the I<pool> object. -=item B<pool-list> optional I<--inactive> I<--all> +=item B<pool-list> optional I<--inactive> I<--all> I<--details> List pool objects known to libvirt. By default, only pools in use by active domains are listed; I<--inactive> lists just the inactive -pools, and I<--all> lists all pools. +pools, and I<--all> lists all pools. The I<--details> option instructs +virsh to additionally display pool persistence and capacity related +information where available. =item B<pool-name> I<uuid> -- 1.7.0.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list