tools/virsh-pool.c: * vshStoragePoolSorter to sort the pool list by pool name. * struct vshStoragePoolList to present the pool list, pool info is collected by list->poolinfo if 'details' is specified by user. * vshStoragePoolListFree to free the pool list * vshStoragePoolListCollect to collect the pool list, new API virStorageListAllPools is tried first, if it's not supported, fall back to older APIs. * New options --persistent, --transient, --autostart, --no-autostart and --type for pool-list. --persistent or --transient is to filter the returned pool list by whether the pool is persistent or not. --autostart or --no-autostart is to filter the returned pool list by whether the pool is autostarting or not. --type is to filter the pools by pool types. E.g. % virsh pool-list --all --persistent --type dir,disk tools/virsh.pod: * Add documentations for the new options. --- tools/virsh-pool.c | 631 +++++++++++++++++++++++++++++++++++++++++++++++++++- tools/virsh.pod | 24 ++- 2 files changed, 652 insertions(+), 3 deletions(-) diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index fd239d2..0b328cc 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -36,6 +36,7 @@ #include "memory.h" #include "util.h" #include "xml.h" +#include "conf/storage_conf.h" virStoragePoolPtr vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, @@ -551,6 +552,232 @@ cmdPoolDumpXML(vshControl *ctl, const vshCmd *cmd) return ret; } +static int +vshStoragePoolSorter(const void *a, const void *b) +{ + virStoragePoolPtr *pa = (virStoragePoolPtr *) a; + virStoragePoolPtr *pb = (virStoragePoolPtr *) b; + + if (*pa && !*pb) + return -1; + + if (!*pa) + return *pb != NULL; + + return vshStrcasecmp(virStoragePoolGetName(*pa), + virStoragePoolGetName(*pb)); +} + +struct vshStoragePoolList { + virStoragePoolPtr *pools; + size_t npools; +}; +typedef struct vshStoragePoolList *vshStoragePoolListPtr; + +static void +vshStoragePoolListFree(vshStoragePoolListPtr list) +{ + int i; + + if (list && list->pools) { + for (i = 0; i < list->npools; i++) { + if (list->pools[i]) + virStoragePoolFree(list->pools[i]); + } + VIR_FREE(list->pools); + } + VIR_FREE(list); +} + +static vshStoragePoolListPtr +vshStoragePoolListCollect(vshControl *ctl, + unsigned int flags) +{ + vshStoragePoolListPtr list = vshMalloc(ctl, sizeof(*list)); + int i; + int ret; + char **names = NULL; + virStoragePoolPtr pool; + bool success = false; + size_t deleted = 0; + int persistent; + int autostart; + int nActivePools = 0; + int nInactivePools = 0; + int nAllPools = 0; + + /* try the list with flags support (0.10.0 and later) */ + if ((ret = virConnectListAllStoragePools(ctl->conn, + &list->pools, + flags)) >= 0) { + list->npools = ret; + goto finished; + } + + /* check if the command is actually supported */ + if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) { + vshResetLibvirtError(); + goto fallback; + } + + if (last_error && last_error->code == VIR_ERR_INVALID_ARG) { + /* try the new API again but mask non-guaranteed flags */ + unsigned int newflags = flags & (VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE | + VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE); + vshResetLibvirtError(); + if ((ret = virConnectListAllStoragePools(ctl->conn, &list->pools, + newflags)) >= 0) { + list->npools = ret; + goto filter; + } + } + + /* there was an error during the first or second call */ + vshError(ctl, "%s", _("Failed to list pools")); + goto cleanup; + + +fallback: + /* fall back to old method (0.9.13 and older) */ + vshResetLibvirtError(); + + /* There is no way to get the pool type */ + if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE)) { + vshError(ctl, "%s", _("Filtering using --type is not supported " + "by this libvirt")); + goto cleanup; + } + + /* Get the number of active pools */ + if (!MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) || + MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE)) { + if ((nActivePools = virConnectNumOfStoragePools(ctl->conn)) < 0) { + vshError(ctl, "%s", _("Failed to get the number of active pools ")); + goto cleanup; + } + } + + /* Get the number of inactive pools */ + if (!MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) || + MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE)) { + if ((nInactivePools = virConnectNumOfDefinedStoragePools(ctl->conn)) < 0) { + vshError(ctl, "%s", _("Failed to get the number of inactive pools")); + goto cleanup; + } + } + + nAllPools = nActivePools + nInactivePools; + + if (nAllPools == 0) + return list; + + names = vshMalloc(ctl, sizeof(char *) * nAllPools); + + /* Retrieve a list of active storage pool names */ + if (!MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) || + MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE)) { + if (virConnectListStoragePools(ctl->conn, + names, nActivePools) < 0) { + vshError(ctl, "%s", _("Failed to list active pools")); + goto cleanup; + } + } + + /* Add the inactive storage pools to the end of the name list */ + if (!MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) || + MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE)) { + if (virConnectListDefinedStoragePools(ctl->conn, + &names[nActivePools], + nInactivePools) < 0) { + vshError(ctl, "%s", _("Failed to list inactive pools")); + goto cleanup; + } + } + + list->pools = vshMalloc(ctl, sizeof(virStoragePoolPtr) * (nAllPools)); + list->npools = 0; + + /* get active pools */ + for (i = 0; i < nActivePools; i++) { + if (!(pool = virStoragePoolLookupByName(ctl->conn, names[i]))) + continue; + list->pools[list->npools++] = pool; + } + + /* get inactive pools */ + for (i = 0; i < nInactivePools; i++) { + if (!(pool = virStoragePoolLookupByName(ctl->conn, names[i]))) + continue; + list->pools[list->npools++] = pool; + } + + /* truncate pools that weren't found */ + deleted = nAllPools - list->npools; + +filter: + /* filter list the list if the list was acquired by fallback means */ + for (i = 0; i < list->npools; i++) { + pool = list->pools[i]; + + /* persistence filter */ + if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_PERSISTENT)) { + if ((persistent = virStoragePoolIsPersistent(pool)) < 0) { + vshError(ctl, "%s", _("Failed to get pool persistence info")); + goto cleanup; + } + + if (!((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT) && persistent) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT) && !persistent))) + goto remove_entry; + } + + /* autostart filter */ + if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART)) { + if (virStoragePoolGetAutostart(pool, &autostart) < 0) { + vshError(ctl, "%s", _("Failed to get pool autostart state")); + goto cleanup; + } + + if (!((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART) && autostart) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART) && !autostart))) + goto remove_entry; + } + + /* the pool matched all filters, it may stay */ + continue; + +remove_entry: + /* the pool has to be removed as it failed one of the filters */ + virStoragePoolFree(list->pools[i]); + list->pools[i] = NULL; + deleted++; + } + +finished: + /* sort the list */ + if (list->pools && list->npools) + qsort(list->pools, list->npools, + sizeof(*list->pools), vshStoragePoolSorter); + + /* truncate the list if filter simulation deleted entries */ + if (deleted) + VIR_SHRINK_N(list->pools, list->npools, deleted); + + success = true; + +cleanup: + for (i = 0; i < nAllPools; i++) + VIR_FREE(names[i]); + + if (!success) { + vshStoragePoolListFree(list); + list = NULL; + } + + VIR_FREE(names); + return list; +} + /* * "pool-list" command */ @@ -563,6 +790,11 @@ 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")}, + {"transient", VSH_OT_BOOL, 0, N_("list transient pools")}, + {"persistent", VSH_OT_BOOL, 0, N_("list persistent pools")}, + {"autostart", VSH_OT_BOOL, 0, N_("list pools with autostart enabled")}, + {"no-autostart", VSH_OT_BOOL, 0, N_("list pools with autostart disabled")}, + {"type", VSH_OT_STRING, 0, N_("only list pool of specified type(s) (if supported)")}, {"details", VSH_OT_BOOL, 0, N_("display extended details for pools")}, {NULL, 0, 0, NULL} }; @@ -571,7 +803,403 @@ static bool cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { virStoragePoolInfo info; - char **poolNames = NULL; + int i, ret; + bool functionReturn = false; + size_t stringLength = 0, nameStrLength = 0; + size_t autostartStrLength = 0, persistStrLength = 0; + size_t stateStrLength = 0, capStrLength = 0; + size_t allocStrLength = 0, availStrLength = 0; + struct poolInfoText { + char *state; + char *autostart; + char *persistent; + char *capacity; + char *allocation; + char *available; + }; + struct poolInfoText *poolInfoTexts = NULL; + unsigned int flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE; + vshStoragePoolListPtr list = NULL; + const char *type = NULL; + bool details = vshCommandOptBool(cmd, "details"); + bool inactive, all; + + inactive = vshCommandOptBool(cmd, "inactive"); + all = vshCommandOptBool(cmd, "all"); + + if (inactive) + flags = VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE; + + if (all) + flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE | + VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE; + + if (vshCommandOptBool(cmd, "autostart")) + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART; + + if (vshCommandOptBool(cmd, "no-autostart")) + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART; + + if (vshCommandOptBool(cmd, "persistent")) + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT; + + if (vshCommandOptBool(cmd, "transient")) + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT; + + if (vshCommandOptString(cmd, "type", &type) < 0) { + vshError(ctl, "%s", _("Invalid argument for 'type'")); + return false; + } + + if (type) { + int poolType = -1; + char **poolTypes = NULL; + int npoolTypes = 0; + + npoolTypes = vshStringToArray((char *)type, &poolTypes); + + for (i = 0; i < npoolTypes; i++) { + if ((poolType = virStoragePoolTypeFromString(poolTypes[i])) < 0) { + vshError(ctl, "%s", _("Invalid pool type")); + VIR_FREE(poolTypes); + return false; + } + + switch(poolType) { + case VIR_STORAGE_POOL_DIR: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_DIR; + break; + case VIR_STORAGE_POOL_FS: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_FS; + break; + case VIR_STORAGE_POOL_NETFS: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_NETFS; + break; + case VIR_STORAGE_POOL_LOGICAL: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL; + break; + case VIR_STORAGE_POOL_DISK: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_DISK; + break; + case VIR_STORAGE_POOL_ISCSI: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI; + break; + case VIR_STORAGE_POOL_SCSI: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_SCSI; + break; + case VIR_STORAGE_POOL_MPATH: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_MPATH; + break; + case VIR_STORAGE_POOL_RBD: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_RBD; + break; + default: + break; + } + } + VIR_FREE(poolTypes); + } + + if (!(list = vshStoragePoolListCollect(ctl, flags))) + goto cleanup; + + poolInfoTexts = vshCalloc(ctl, list->npools, sizeof(*poolInfoTexts)); + + /* Collect the storage pool information for display */ + for (i = 0; i < list->npools; i++) { + int autostart = 0, persistent = 0; + + /* Retrieve the autostart status of the pool */ + if (virStoragePoolGetAutostart(list->pools[i], &autostart) < 0) + poolInfoTexts[i].autostart = vshStrdup(ctl, _("no autostart")); + else + poolInfoTexts[i].autostart = vshStrdup(ctl, autostart ? + _("yes") : _("no")); + + /* Retrieve the persistence status of the pool */ + if (details) { + persistent = virStoragePoolIsPersistent(list->pools[i]); + vshDebug(ctl, VSH_ERR_DEBUG, "Persistent flag value: %d\n", + persistent); + if (persistent < 0) + poolInfoTexts[i].persistent = vshStrdup(ctl, _("unknown")); + else + poolInfoTexts[i].persistent = vshStrdup(ctl, persistent ? + _("yes") : _("no")); + + /* Keep the length of persistent string if longest so far */ + stringLength = strlen(poolInfoTexts[i].persistent); + if (stringLength > persistStrLength) + persistStrLength = stringLength; + } + + /* Collect further extended information about the pool */ + if (virStoragePoolGetInfo(list->pools[i], &info) != 0) { + /* Something went wrong retrieving pool info, cope with it */ + vshError(ctl, "%s", _("Could not retrieve pool information")); + poolInfoTexts[i].state = vshStrdup(ctl, _("unknown")); + if (details) { + poolInfoTexts[i].capacity = vshStrdup(ctl, _("unknown")); + poolInfoTexts[i].allocation = vshStrdup(ctl, _("unknown")); + poolInfoTexts[i].available = vshStrdup(ctl, _("unknown")); + } + } else { + /* Decide which state string to display */ + if (details) { + /* --details option was specified, we're using detailed state + * strings */ + switch (info.state) { + case VIR_STORAGE_POOL_INACTIVE: + poolInfoTexts[i].state = vshStrdup(ctl, _("inactive")); + break; + case VIR_STORAGE_POOL_BUILDING: + poolInfoTexts[i].state = vshStrdup(ctl, _("building")); + break; + case VIR_STORAGE_POOL_RUNNING: + poolInfoTexts[i].state = vshStrdup(ctl, _("running")); + break; + case VIR_STORAGE_POOL_DEGRADED: + poolInfoTexts[i].state = vshStrdup(ctl, _("degraded")); + break; + case VIR_STORAGE_POOL_INACCESSIBLE: + poolInfoTexts[i].state = vshStrdup(ctl, _("inaccessible")); + break; + } + + /* Create the pool size related strings */ + if (info.state == VIR_STORAGE_POOL_RUNNING || + info.state == VIR_STORAGE_POOL_DEGRADED) { + double val; + const char *unit; + + /* Create the capacity output string */ + val = vshPrettyCapacity(info.capacity, &unit); + ret = virAsprintf(&poolInfoTexts[i].capacity, + "%.2lf %s", val, unit); + if (ret < 0) + /* An error occurred creating the string, return */ + goto asprintf_failure; + + /* Create the allocation output string */ + val = vshPrettyCapacity(info.allocation, &unit); + ret = virAsprintf(&poolInfoTexts[i].allocation, + "%.2lf %s", val, unit); + if (ret < 0) + /* An error occurred creating the string, return */ + goto asprintf_failure; + + /* Create the available space output string */ + val = vshPrettyCapacity(info.available, &unit); + ret = virAsprintf(&poolInfoTexts[i].available, + "%.2lf %s", val, unit); + if (ret < 0) + /* An error occurred creating the string, return */ + goto asprintf_failure; + } else { + /* Capacity related information isn't available */ + poolInfoTexts[i].capacity = vshStrdup(ctl, _("-")); + poolInfoTexts[i].allocation = vshStrdup(ctl, _("-")); + poolInfoTexts[i].available = vshStrdup(ctl, _("-")); + } + + /* Keep the length of capacity string if longest so far */ + stringLength = strlen(poolInfoTexts[i].capacity); + if (stringLength > capStrLength) + capStrLength = stringLength; + + /* Keep the length of allocation string if longest so far */ + stringLength = strlen(poolInfoTexts[i].allocation); + if (stringLength > allocStrLength) + allocStrLength = stringLength; + + /* Keep the length of available string if longest so far */ + stringLength = strlen(poolInfoTexts[i].available); + if (stringLength > availStrLength) + availStrLength = stringLength; + } else { + /* --details option was not specified, only active/inactive + * state strings are used */ + if (virStoragePoolIsActive(list->pools[i])) + poolInfoTexts[i].state = vshStrdup(ctl, _("active")); + else + poolInfoTexts[i].state = vshStrdup(ctl, _("inactive")); + } + } + + /* Keep the length of name string if longest so far */ + stringLength = strlen(virStoragePoolGetName(list->pools[i])); + if (stringLength > nameStrLength) + nameStrLength = stringLength; + + /* Keep the length of state string if longest so far */ + stringLength = strlen(poolInfoTexts[i].state); + if (stringLength > stateStrLength) + stateStrLength = stringLength; + + /* Keep the length of autostart string if longest so far */ + stringLength = strlen(poolInfoTexts[i].autostart); + if (stringLength > autostartStrLength) + autostartStrLength = stringLength; + } + + /* If the --details option wasn't selected, we output the pool + * info using the fixed string format from previous versions to + * maintain backward compatibility. + */ + + /* Output basic info then return if --details option not selected */ + if (!details) { + /* Output old style header */ + vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("State"), + _("Autostart")); + vshPrintExtra(ctl, "-----------------------------------------\n"); + + /* Output old style pool info */ + for (i = 0; i < list->npools; i++) { + const char *name = virStoragePoolGetName(list->pools[i]); + vshPrint(ctl, "%-20s %-10s %-10s\n", + name, + poolInfoTexts[i].state, + poolInfoTexts[i].autostart); + } + + /* Cleanup and return */ + functionReturn = true; + goto cleanup; + } + + /* We only get here if the --details option was selected. */ + + /* Use the length of name header string if it's longest */ + stringLength = strlen(_("Name")); + if (stringLength > nameStrLength) + nameStrLength = stringLength; + + /* Use the length of state header string if it's longest */ + stringLength = strlen(_("State")); + if (stringLength > stateStrLength) + stateStrLength = stringLength; + + /* Use the length of autostart header string if it's longest */ + stringLength = strlen(_("Autostart")); + if (stringLength > autostartStrLength) + autostartStrLength = stringLength; + + /* Use the length of persistent header string if it's longest */ + stringLength = strlen(_("Persistent")); + if (stringLength > persistStrLength) + persistStrLength = stringLength; + + /* Use the length of capacity header string if it's longest */ + stringLength = strlen(_("Capacity")); + if (stringLength > capStrLength) + capStrLength = stringLength; + + /* Use the length of allocation header string if it's longest */ + stringLength = strlen(_("Allocation")); + if (stringLength > allocStrLength) + allocStrLength = stringLength; + + /* Use the length of available header string if it's longest */ + stringLength = strlen(_("Available")); + if (stringLength > availStrLength) + availStrLength = stringLength; + + /* Display the string lengths for debugging. */ + vshDebug(ctl, VSH_ERR_DEBUG, "Longest name string = %lu chars\n", + (unsigned long) nameStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest state string = %lu chars\n", + (unsigned long) stateStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest autostart string = %lu chars\n", + (unsigned long) autostartStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest persistent string = %lu chars\n", + (unsigned long) persistStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest capacity string = %lu chars\n", + (unsigned long) capStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest allocation string = %lu chars\n", + (unsigned long) allocStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest available string = %lu chars\n", + (unsigned long) availStrLength); + + /* Create the output template. Each column is sized according to + * the longest string. + */ + char *outputStr; + ret = virAsprintf(&outputStr, + "%%-%lus %%-%lus %%-%lus %%-%lus %%%lus %%%lus %%%lus\n", + (unsigned long) nameStrLength, + (unsigned long) stateStrLength, + (unsigned long) autostartStrLength, + (unsigned long) persistStrLength, + (unsigned long) capStrLength, + (unsigned long) allocStrLength, + (unsigned long) availStrLength); + if (ret < 0) { + /* An error occurred creating the string, return */ + goto asprintf_failure; + } + + /* Display the header */ + vshPrint(ctl, outputStr, _("Name"), _("State"), _("Autostart"), + _("Persistent"), _("Capacity"), _("Allocation"), _("Available")); + for (i = nameStrLength + stateStrLength + autostartStrLength + + persistStrLength + capStrLength + + allocStrLength + availStrLength + + 12; i > 0; i--) + vshPrintExtra(ctl, "-"); + vshPrintExtra(ctl, "\n"); + + /* Display the pool info rows */ + for (i = 0; i < list->npools; i++) { + vshPrint(ctl, outputStr, + virStoragePoolGetName(list->pools[i]), + poolInfoTexts[i].state, + poolInfoTexts[i].autostart, + poolInfoTexts[i].persistent, + poolInfoTexts[i].capacity, + poolInfoTexts[i].allocation, + poolInfoTexts[i].available); + } + + /* Cleanup and return */ + functionReturn = true; + goto cleanup; + +asprintf_failure: + /* Display an appropriate error message then cleanup and return */ + switch (errno) { + case ENOMEM: + /* Couldn't allocate memory */ + vshError(ctl, "%s", _("Out of memory")); + break; + default: + /* Some other error */ + vshError(ctl, _("virAsprintf failed (errno %d)"), errno); + } + functionReturn = false; + +cleanup: + if (list && list->npools) { + for (i = 0; i < list->npools; i++) { + VIR_FREE(poolInfoTexts[i].state); + VIR_FREE(poolInfoTexts[i].autostart); + VIR_FREE(poolInfoTexts[i].persistent); + VIR_FREE(poolInfoTexts[i].capacity); + VIR_FREE(poolInfoTexts[i].allocation); + VIR_FREE(poolInfoTexts[i].available); + } + } + VIR_FREE(poolInfoTexts); + + vshStoragePoolListFree(list); + return functionReturn; +} + +#if 0 +static bool +cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + virStoragePoolInfo info; int i, ret; bool functionReturn; int numActivePools = 0, numInactivePools = 0, numAllPools = 0; @@ -956,6 +1584,7 @@ cleanup: /* Return the desired value */ return functionReturn; } +#endif /* * "find-storage-pool-sources-as" command diff --git a/tools/virsh.pod b/tools/virsh.pod index 98ed4b0..9aeb47e 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2185,13 +2185,33 @@ variables, and defaults to C<vi>. Returns basic information about the I<pool> object. -=item B<pool-list> [I<--inactive> | I<--all>] [I<--details>] +=item B<pool-list> [I<--inactive>] [I<--all>] + [I<--persistent>] [I<--transient>] + [I<--autostart>] [I<--no-autostart>] + [[I<--details>] [<type>] List pool objects known to libvirt. By default, only active pools are listed; I<--inactive> lists just the inactive pools, and I<--all> -lists all pools. The I<--details> option instructs virsh to additionally +lists all pools. + +Except the default, I<--inactive>, and I<--all>, you may want to specify more +filtering flags. I<--persistent> is to list the persistent pools, I<--transient> +is to list the transient pools. I<--autostart> is to list the autostarting pools, +I<--no-autostart> is to list the pools with autostarting disabled. + +You may also want to list pools with specified types using I<type>, the +pool types must be separated by comma, e.g. --type dir,disk. The valid pool +types include 'dir', 'fs', 'netfs', 'logical', 'disk', 'iscsi', 'scsi', +'mpath', 'rbd', and 'sheepdog'. + +The I<--details> option instructs virsh to additionally display pool persistence and capacity related information where available. +NOTE: When talking to older servers, this command is forced to use a series of +API calls with an inherent race, where a pool might not be listed or might appear +more than once if it changed state between calls while the list was being +collected. Newer servers do not have this problem. + =item B<pool-name> I<uuid> Convert the I<uuid> to a pool name. -- 1.7.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list