mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
list: Use virConnectListAllStoragePools in virsh
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.
This commit is contained in:
parent
fc122e1a40
commit
93a346d353
@ -36,6 +36,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
#include "conf/storage_conf.h"
|
||||||
|
|
||||||
virStoragePoolPtr
|
virStoragePoolPtr
|
||||||
vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname,
|
vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname,
|
||||||
@ -551,6 +552,232 @@ cmdPoolDumpXML(vshControl *ctl, const vshCmd *cmd)
|
|||||||
return ret;
|
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
|
* "pool-list" command
|
||||||
*/
|
*/
|
||||||
@ -563,6 +790,11 @@ static const vshCmdInfo info_pool_list[] = {
|
|||||||
static const vshCmdOptDef opts_pool_list[] = {
|
static const vshCmdOptDef opts_pool_list[] = {
|
||||||
{"inactive", VSH_OT_BOOL, 0, N_("list inactive pools")},
|
{"inactive", VSH_OT_BOOL, 0, N_("list inactive pools")},
|
||||||
{"all", VSH_OT_BOOL, 0, N_("list inactive & active 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")},
|
{"details", VSH_OT_BOOL, 0, N_("display extended details for pools")},
|
||||||
{NULL, 0, 0, NULL}
|
{NULL, 0, 0, NULL}
|
||||||
};
|
};
|
||||||
@ -571,10 +803,8 @@ static bool
|
|||||||
cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
virStoragePoolInfo info;
|
virStoragePoolInfo info;
|
||||||
char **poolNames = NULL;
|
|
||||||
int i, ret;
|
int i, ret;
|
||||||
bool functionReturn;
|
bool functionReturn = false;
|
||||||
int numActivePools = 0, numInactivePools = 0, numAllPools = 0;
|
|
||||||
size_t stringLength = 0, nameStrLength = 0;
|
size_t stringLength = 0, nameStrLength = 0;
|
||||||
size_t autostartStrLength = 0, persistStrLength = 0;
|
size_t autostartStrLength = 0, persistStrLength = 0;
|
||||||
size_t stateStrLength = 0, capStrLength = 0;
|
size_t stateStrLength = 0, capStrLength = 0;
|
||||||
@ -588,80 +818,99 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
char *available;
|
char *available;
|
||||||
};
|
};
|
||||||
struct poolInfoText *poolInfoTexts = NULL;
|
struct poolInfoText *poolInfoTexts = NULL;
|
||||||
|
unsigned int flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE;
|
||||||
/* Determine the options passed by the user */
|
vshStoragePoolListPtr list = NULL;
|
||||||
bool all = vshCommandOptBool(cmd, "all");
|
const char *type = NULL;
|
||||||
bool details = vshCommandOptBool(cmd, "details");
|
bool details = vshCommandOptBool(cmd, "details");
|
||||||
bool inactive = vshCommandOptBool(cmd, "inactive");
|
bool inactive, all;
|
||||||
bool active = !inactive || all;
|
|
||||||
inactive |= all;
|
|
||||||
|
|
||||||
/* Retrieve the number of active storage pools */
|
inactive = vshCommandOptBool(cmd, "inactive");
|
||||||
if (active) {
|
all = vshCommandOptBool(cmd, "all");
|
||||||
numActivePools = virConnectNumOfStoragePools(ctl->conn);
|
|
||||||
if (numActivePools < 0) {
|
if (inactive)
|
||||||
vshError(ctl, "%s", _("Failed to list active pools"));
|
flags = VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE;
|
||||||
return false;
|
|
||||||
}
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve the number of inactive storage pools */
|
if (type) {
|
||||||
if (inactive) {
|
int poolType = -1;
|
||||||
numInactivePools = virConnectNumOfDefinedStoragePools(ctl->conn);
|
char **poolTypes = NULL;
|
||||||
if (numInactivePools < 0) {
|
int npoolTypes = 0;
|
||||||
vshError(ctl, "%s", _("Failed to list inactive pools"));
|
|
||||||
return false;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine the total number of pools to list */
|
if (!(list = vshStoragePoolListCollect(ctl, flags)))
|
||||||
numAllPools = numActivePools + numInactivePools;
|
goto cleanup;
|
||||||
|
|
||||||
/* Allocate memory for arrays of storage pool names and info */
|
poolInfoTexts = vshCalloc(ctl, list->npools, sizeof(*poolInfoTexts));
|
||||||
poolNames = vshCalloc(ctl, numAllPools, sizeof(*poolNames));
|
|
||||||
poolInfoTexts =
|
|
||||||
vshCalloc(ctl, numAllPools, sizeof(*poolInfoTexts));
|
|
||||||
|
|
||||||
/* Retrieve a list of active storage pool names */
|
|
||||||
if (active) {
|
|
||||||
if (virConnectListStoragePools(ctl->conn,
|
|
||||||
poolNames, numActivePools) < 0) {
|
|
||||||
vshError(ctl, "%s", _("Failed to list active pools"));
|
|
||||||
VIR_FREE(poolInfoTexts);
|
|
||||||
VIR_FREE(poolNames);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the inactive storage pools to the end of the name list */
|
|
||||||
if (inactive) {
|
|
||||||
if (virConnectListDefinedStoragePools(ctl->conn,
|
|
||||||
&poolNames[numActivePools],
|
|
||||||
numInactivePools) < 0) {
|
|
||||||
vshError(ctl, "%s", _("Failed to list inactive pools"));
|
|
||||||
VIR_FREE(poolInfoTexts);
|
|
||||||
VIR_FREE(poolNames);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort the storage pool names */
|
|
||||||
qsort(poolNames, numAllPools, sizeof(*poolNames), vshNameSorter);
|
|
||||||
|
|
||||||
/* Collect the storage pool information for display */
|
/* Collect the storage pool information for display */
|
||||||
for (i = 0; i < numAllPools; i++) {
|
for (i = 0; i < list->npools; i++) {
|
||||||
int autostart = 0, persistent = 0;
|
int autostart = 0, persistent = 0;
|
||||||
|
|
||||||
/* Retrieve a pool object, looking it up by name */
|
|
||||||
virStoragePoolPtr pool = virStoragePoolLookupByName(ctl->conn,
|
|
||||||
poolNames[i]);
|
|
||||||
if (!pool) {
|
|
||||||
VIR_FREE(poolNames[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve the autostart status of the pool */
|
/* Retrieve the autostart status of the pool */
|
||||||
if (virStoragePoolGetAutostart(pool, &autostart) < 0)
|
if (virStoragePoolGetAutostart(list->pools[i], &autostart) < 0)
|
||||||
poolInfoTexts[i].autostart = vshStrdup(ctl, _("no autostart"));
|
poolInfoTexts[i].autostart = vshStrdup(ctl, _("no autostart"));
|
||||||
else
|
else
|
||||||
poolInfoTexts[i].autostart = vshStrdup(ctl, autostart ?
|
poolInfoTexts[i].autostart = vshStrdup(ctl, autostart ?
|
||||||
@ -669,7 +918,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
|
|
||||||
/* Retrieve the persistence status of the pool */
|
/* Retrieve the persistence status of the pool */
|
||||||
if (details) {
|
if (details) {
|
||||||
persistent = virStoragePoolIsPersistent(pool);
|
persistent = virStoragePoolIsPersistent(list->pools[i]);
|
||||||
vshDebug(ctl, VSH_ERR_DEBUG, "Persistent flag value: %d\n",
|
vshDebug(ctl, VSH_ERR_DEBUG, "Persistent flag value: %d\n",
|
||||||
persistent);
|
persistent);
|
||||||
if (persistent < 0)
|
if (persistent < 0)
|
||||||
@ -685,7 +934,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Collect further extended information about the pool */
|
/* Collect further extended information about the pool */
|
||||||
if (virStoragePoolGetInfo(pool, &info) != 0) {
|
if (virStoragePoolGetInfo(list->pools[i], &info) != 0) {
|
||||||
/* Something went wrong retrieving pool info, cope with it */
|
/* Something went wrong retrieving pool info, cope with it */
|
||||||
vshError(ctl, "%s", _("Could not retrieve pool information"));
|
vshError(ctl, "%s", _("Could not retrieve pool information"));
|
||||||
poolInfoTexts[i].state = vshStrdup(ctl, _("unknown"));
|
poolInfoTexts[i].state = vshStrdup(ctl, _("unknown"));
|
||||||
@ -727,28 +976,25 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
val = vshPrettyCapacity(info.capacity, &unit);
|
val = vshPrettyCapacity(info.capacity, &unit);
|
||||||
ret = virAsprintf(&poolInfoTexts[i].capacity,
|
ret = virAsprintf(&poolInfoTexts[i].capacity,
|
||||||
"%.2lf %s", val, unit);
|
"%.2lf %s", val, unit);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
/* An error occurred creating the string, return */
|
/* An error occurred creating the string, return */
|
||||||
goto asprintf_failure;
|
goto asprintf_failure;
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the allocation output string */
|
/* Create the allocation output string */
|
||||||
val = vshPrettyCapacity(info.allocation, &unit);
|
val = vshPrettyCapacity(info.allocation, &unit);
|
||||||
ret = virAsprintf(&poolInfoTexts[i].allocation,
|
ret = virAsprintf(&poolInfoTexts[i].allocation,
|
||||||
"%.2lf %s", val, unit);
|
"%.2lf %s", val, unit);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
/* An error occurred creating the string, return */
|
/* An error occurred creating the string, return */
|
||||||
goto asprintf_failure;
|
goto asprintf_failure;
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the available space output string */
|
/* Create the available space output string */
|
||||||
val = vshPrettyCapacity(info.available, &unit);
|
val = vshPrettyCapacity(info.available, &unit);
|
||||||
ret = virAsprintf(&poolInfoTexts[i].available,
|
ret = virAsprintf(&poolInfoTexts[i].available,
|
||||||
"%.2lf %s", val, unit);
|
"%.2lf %s", val, unit);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
/* An error occurred creating the string, return */
|
/* An error occurred creating the string, return */
|
||||||
goto asprintf_failure;
|
goto asprintf_failure;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* Capacity related information isn't available */
|
/* Capacity related information isn't available */
|
||||||
poolInfoTexts[i].capacity = vshStrdup(ctl, _("-"));
|
poolInfoTexts[i].capacity = vshStrdup(ctl, _("-"));
|
||||||
@ -772,16 +1018,16 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
availStrLength = stringLength;
|
availStrLength = stringLength;
|
||||||
} else {
|
} else {
|
||||||
/* --details option was not specified, only active/inactive
|
/* --details option was not specified, only active/inactive
|
||||||
* state strings are used */
|
* state strings are used */
|
||||||
if (info.state == VIR_STORAGE_POOL_INACTIVE)
|
if (virStoragePoolIsActive(list->pools[i]))
|
||||||
poolInfoTexts[i].state = vshStrdup(ctl, _("inactive"));
|
|
||||||
else
|
|
||||||
poolInfoTexts[i].state = vshStrdup(ctl, _("active"));
|
poolInfoTexts[i].state = vshStrdup(ctl, _("active"));
|
||||||
}
|
else
|
||||||
|
poolInfoTexts[i].state = vshStrdup(ctl, _("inactive"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep the length of name string if longest so far */
|
/* Keep the length of name string if longest so far */
|
||||||
stringLength = strlen(poolNames[i]);
|
stringLength = strlen(virStoragePoolGetName(list->pools[i]));
|
||||||
if (stringLength > nameStrLength)
|
if (stringLength > nameStrLength)
|
||||||
nameStrLength = stringLength;
|
nameStrLength = stringLength;
|
||||||
|
|
||||||
@ -794,9 +1040,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
stringLength = strlen(poolInfoTexts[i].autostart);
|
stringLength = strlen(poolInfoTexts[i].autostart);
|
||||||
if (stringLength > autostartStrLength)
|
if (stringLength > autostartStrLength)
|
||||||
autostartStrLength = stringLength;
|
autostartStrLength = stringLength;
|
||||||
|
|
||||||
/* Free the pool object */
|
|
||||||
virStoragePoolFree(pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the --details option wasn't selected, we output the pool
|
/* If the --details option wasn't selected, we output the pool
|
||||||
@ -812,9 +1055,10 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
vshPrintExtra(ctl, "-----------------------------------------\n");
|
vshPrintExtra(ctl, "-----------------------------------------\n");
|
||||||
|
|
||||||
/* Output old style pool info */
|
/* Output old style pool info */
|
||||||
for (i = 0; i < numAllPools; i++) {
|
for (i = 0; i < list->npools; i++) {
|
||||||
|
const char *name = virStoragePoolGetName(list->pools[i]);
|
||||||
vshPrint(ctl, "%-20s %-10s %-10s\n",
|
vshPrint(ctl, "%-20s %-10s %-10s\n",
|
||||||
poolNames[i],
|
name,
|
||||||
poolInfoTexts[i].state,
|
poolInfoTexts[i].state,
|
||||||
poolInfoTexts[i].autostart);
|
poolInfoTexts[i].autostart);
|
||||||
}
|
}
|
||||||
@ -906,9 +1150,9 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
vshPrintExtra(ctl, "\n");
|
vshPrintExtra(ctl, "\n");
|
||||||
|
|
||||||
/* Display the pool info rows */
|
/* Display the pool info rows */
|
||||||
for (i = 0; i < numAllPools; i++) {
|
for (i = 0; i < list->npools; i++) {
|
||||||
vshPrint(ctl, outputStr,
|
vshPrint(ctl, outputStr,
|
||||||
poolNames[i],
|
virStoragePoolGetName(list->pools[i]),
|
||||||
poolInfoTexts[i].state,
|
poolInfoTexts[i].state,
|
||||||
poolInfoTexts[i].autostart,
|
poolInfoTexts[i].autostart,
|
||||||
poolInfoTexts[i].persistent,
|
poolInfoTexts[i].persistent,
|
||||||
@ -922,7 +1166,6 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
asprintf_failure:
|
asprintf_failure:
|
||||||
|
|
||||||
/* Display an appropriate error message then cleanup and return */
|
/* Display an appropriate error message then cleanup and return */
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
@ -936,24 +1179,19 @@ asprintf_failure:
|
|||||||
functionReturn = false;
|
functionReturn = false;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
if (list && list->npools) {
|
||||||
/* Safely free the memory allocated in this function */
|
for (i = 0; i < list->npools; i++) {
|
||||||
for (i = 0; i < numAllPools; i++) {
|
VIR_FREE(poolInfoTexts[i].state);
|
||||||
/* Cleanup the memory for one pool info structure */
|
VIR_FREE(poolInfoTexts[i].autostart);
|
||||||
VIR_FREE(poolInfoTexts[i].state);
|
VIR_FREE(poolInfoTexts[i].persistent);
|
||||||
VIR_FREE(poolInfoTexts[i].autostart);
|
VIR_FREE(poolInfoTexts[i].capacity);
|
||||||
VIR_FREE(poolInfoTexts[i].persistent);
|
VIR_FREE(poolInfoTexts[i].allocation);
|
||||||
VIR_FREE(poolInfoTexts[i].capacity);
|
VIR_FREE(poolInfoTexts[i].available);
|
||||||
VIR_FREE(poolInfoTexts[i].allocation);
|
}
|
||||||
VIR_FREE(poolInfoTexts[i].available);
|
|
||||||
VIR_FREE(poolNames[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup the memory for the initial arrays*/
|
|
||||||
VIR_FREE(poolInfoTexts);
|
VIR_FREE(poolInfoTexts);
|
||||||
VIR_FREE(poolNames);
|
|
||||||
|
|
||||||
/* Return the desired value */
|
vshStoragePoolListFree(list);
|
||||||
return functionReturn;
|
return functionReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2186,13 +2186,33 @@ variables, and defaults to C<vi>.
|
|||||||
|
|
||||||
Returns basic information about the I<pool> object.
|
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
|
List pool objects known to libvirt. By default, only active pools
|
||||||
are listed; I<--inactive> lists just the inactive pools, and I<--all>
|
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.
|
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>
|
=item B<pool-name> I<uuid>
|
||||||
|
|
||||||
Convert the I<uuid> to a pool name.
|
Convert the I<uuid> to a pool name.
|
||||||
|
Loading…
Reference in New Issue
Block a user