mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
list: Use virStoragePoolListAllVolumes in virsh
tools/virsh-volume.c: * vshStorageVolSorter to sort storage vols by name * vshStorageVolumeListFree to free the volume objects list * vshStorageVolumeListCollect to collect the volume objects, trying to use new API first, fall back to older APIs if it's not supported.
This commit is contained in:
parent
a4d7f4a0d9
commit
7e9548fce3
@ -966,6 +966,133 @@ cmdVolDumpXML(vshControl *ctl, const vshCmd *cmd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vshStorageVolSorter(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
virStorageVolPtr *va = (virStorageVolPtr *) a;
|
||||||
|
virStorageVolPtr *vb = (virStorageVolPtr *) b;
|
||||||
|
|
||||||
|
if (*va && !*vb)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!*va)
|
||||||
|
return *vb != NULL;
|
||||||
|
|
||||||
|
return vshStrcasecmp(virStorageVolGetName(*va),
|
||||||
|
virStorageVolGetName(*vb));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vshStorageVolList {
|
||||||
|
virStorageVolPtr *vols;
|
||||||
|
size_t nvols;
|
||||||
|
};
|
||||||
|
typedef struct vshStorageVolList *vshStorageVolListPtr;
|
||||||
|
|
||||||
|
static void
|
||||||
|
vshStorageVolListFree(vshStorageVolListPtr list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (list && list->vols) {
|
||||||
|
for (i = 0; i < list->nvols; i++) {
|
||||||
|
if (list->vols[i])
|
||||||
|
virStorageVolFree(list->vols[i]);
|
||||||
|
}
|
||||||
|
VIR_FREE(list->vols);
|
||||||
|
}
|
||||||
|
VIR_FREE(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static vshStorageVolListPtr
|
||||||
|
vshStorageVolListCollect(vshControl *ctl,
|
||||||
|
virStoragePoolPtr pool,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
vshStorageVolListPtr list = vshMalloc(ctl, sizeof(*list));
|
||||||
|
int i;
|
||||||
|
char **names = NULL;
|
||||||
|
virStorageVolPtr vol = NULL;
|
||||||
|
bool success = false;
|
||||||
|
size_t deleted = 0;
|
||||||
|
int nvols = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
/* try the list with flags support (0.10.0 and later) */
|
||||||
|
if ((ret = virStoragePoolListAllVolumes(pool,
|
||||||
|
&list->vols,
|
||||||
|
flags)) >= 0) {
|
||||||
|
list->nvols = ret;
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if the command is actually supported */
|
||||||
|
if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) {
|
||||||
|
vshResetLibvirtError();
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* there was an error during the call */
|
||||||
|
vshError(ctl, "%s", _("Failed to list volumes"));
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
/* fall back to old method (0.9.13 and older) */
|
||||||
|
vshResetLibvirtError();
|
||||||
|
|
||||||
|
/* Determine the number of volumes in the pool */
|
||||||
|
if ((nvols = virStoragePoolNumOfVolumes(pool)) < 0) {
|
||||||
|
vshError(ctl, "%s", _("Failed to list storage volumes"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvols == 0) {
|
||||||
|
success = true;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve the list of volume names in the pool */
|
||||||
|
names = vshCalloc(ctl, nvols, sizeof(*names));
|
||||||
|
if ((nvols = virStoragePoolListVolumes(pool, names, nvols)) < 0) {
|
||||||
|
vshError(ctl, "%s", _("Failed to list storage volumes"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->vols = vshMalloc(ctl, sizeof(virStorageVolPtr) * (nvols));
|
||||||
|
list->nvols = 0;
|
||||||
|
|
||||||
|
/* get the vols */
|
||||||
|
for (i = 0; i < nvols; i++) {
|
||||||
|
if (!(vol = virStorageVolLookupByName(pool, names[i])))
|
||||||
|
continue;
|
||||||
|
list->vols[list->nvols++] = vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* truncate the list for not found vols */
|
||||||
|
deleted = nvols - list->nvols;
|
||||||
|
|
||||||
|
finished:
|
||||||
|
/* sort the list */
|
||||||
|
if (list->vols && list->nvols)
|
||||||
|
qsort(list->vols, list->nvols, sizeof(*list->vols), vshStorageVolSorter);
|
||||||
|
|
||||||
|
if (deleted)
|
||||||
|
VIR_SHRINK_N(list->vols, list->nvols, deleted);
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
for (i = 0; i < nvols; i++)
|
||||||
|
VIR_FREE(names[i]);
|
||||||
|
VIR_FREE(names);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
vshStorageVolListFree(list);
|
||||||
|
list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "vol-list" command
|
* "vol-list" command
|
||||||
*/
|
*/
|
||||||
@ -986,14 +1113,13 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
{
|
{
|
||||||
virStorageVolInfo volumeInfo;
|
virStorageVolInfo volumeInfo;
|
||||||
virStoragePoolPtr pool;
|
virStoragePoolPtr pool;
|
||||||
char **activeNames = NULL;
|
|
||||||
char *outputStr = NULL;
|
char *outputStr = NULL;
|
||||||
const char *unit;
|
const char *unit;
|
||||||
double val;
|
double val;
|
||||||
bool details = vshCommandOptBool(cmd, "details");
|
bool details = vshCommandOptBool(cmd, "details");
|
||||||
int numVolumes = 0, i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
bool functionReturn;
|
bool functionReturn = false;
|
||||||
int stringLength = 0;
|
int stringLength = 0;
|
||||||
size_t allocStrLength = 0, capStrLength = 0;
|
size_t allocStrLength = 0, capStrLength = 0;
|
||||||
size_t nameStrLength = 0, pathStrLength = 0;
|
size_t nameStrLength = 0, pathStrLength = 0;
|
||||||
@ -1005,43 +1131,22 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
char *type;
|
char *type;
|
||||||
};
|
};
|
||||||
struct volInfoText *volInfoTexts = NULL;
|
struct volInfoText *volInfoTexts = NULL;
|
||||||
|
vshStorageVolListPtr list = NULL;
|
||||||
|
|
||||||
/* Look up the pool information given to us by the user */
|
/* Look up the pool information given to us by the user */
|
||||||
if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
|
if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Determine the number of volumes in the pool */
|
if (!(list = vshStorageVolListCollect(ctl, pool, 0)))
|
||||||
numVolumes = virStoragePoolNumOfVolumes(pool);
|
goto cleanup;
|
||||||
|
|
||||||
if (numVolumes < 0) {
|
if (list->nvols > 0)
|
||||||
vshError(ctl, "%s", _("Failed to list storage volumes"));
|
volInfoTexts = vshCalloc(ctl, list->nvols, sizeof(*volInfoTexts));
|
||||||
virStoragePoolFree(pool);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve the list of volume names in the pool */
|
|
||||||
if (numVolumes > 0) {
|
|
||||||
activeNames = vshCalloc(ctl, numVolumes, sizeof(*activeNames));
|
|
||||||
if ((numVolumes = virStoragePoolListVolumes(pool, activeNames,
|
|
||||||
numVolumes)) < 0) {
|
|
||||||
vshError(ctl, "%s", _("Failed to list active vols"));
|
|
||||||
VIR_FREE(activeNames);
|
|
||||||
virStoragePoolFree(pool);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort the volume names */
|
|
||||||
qsort(&activeNames[0], numVolumes, sizeof(*activeNames), vshNameSorter);
|
|
||||||
|
|
||||||
/* Set aside memory for volume information pointers */
|
|
||||||
volInfoTexts = vshCalloc(ctl, numVolumes, sizeof(*volInfoTexts));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Collect the rest of the volume information for display */
|
/* Collect the rest of the volume information for display */
|
||||||
for (i = 0; i < numVolumes; i++) {
|
for (i = 0; i < list->nvols; i++) {
|
||||||
/* Retrieve volume info */
|
/* Retrieve volume info */
|
||||||
virStorageVolPtr vol = virStorageVolLookupByName(pool,
|
virStorageVolPtr vol = list->vols[i];
|
||||||
activeNames[i]);
|
|
||||||
|
|
||||||
/* Retrieve the volume path */
|
/* Retrieve the volume path */
|
||||||
if ((volInfoTexts[i].path = virStorageVolGetPath(vol)) == NULL) {
|
if ((volInfoTexts[i].path = virStorageVolGetPath(vol)) == NULL) {
|
||||||
@ -1099,7 +1204,7 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Keep the length of name string if longest so far */
|
/* Keep the length of name string if longest so far */
|
||||||
stringLength = strlen(activeNames[i]);
|
stringLength = strlen(virStorageVolGetName(list->vols[i]));
|
||||||
if (stringLength > nameStrLength)
|
if (stringLength > nameStrLength)
|
||||||
nameStrLength = stringLength;
|
nameStrLength = stringLength;
|
||||||
|
|
||||||
@ -1123,9 +1228,6 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
if (stringLength > allocStrLength)
|
if (stringLength > allocStrLength)
|
||||||
allocStrLength = stringLength;
|
allocStrLength = stringLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup memory allocation */
|
|
||||||
virStorageVolFree(vol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the --details option wasn't selected, we output the volume
|
/* If the --details option wasn't selected, we output the volume
|
||||||
@ -1138,8 +1240,8 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
/* The old output format */
|
/* The old output format */
|
||||||
vshPrintExtra(ctl, "%-20s %-40s\n", _("Name"), _("Path"));
|
vshPrintExtra(ctl, "%-20s %-40s\n", _("Name"), _("Path"));
|
||||||
vshPrintExtra(ctl, "-----------------------------------------\n");
|
vshPrintExtra(ctl, "-----------------------------------------\n");
|
||||||
for (i = 0; i < numVolumes; i++) {
|
for (i = 0; i < list->nvols; i++) {
|
||||||
vshPrint(ctl, "%-20s %-40s\n", activeNames[i],
|
vshPrint(ctl, "%-20s %-40s\n", virStorageVolGetName(list->vols[i]),
|
||||||
volInfoTexts[i].path);
|
volInfoTexts[i].path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1210,9 +1312,9 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
|||||||
vshPrintExtra(ctl, "\n");
|
vshPrintExtra(ctl, "\n");
|
||||||
|
|
||||||
/* Display the volume info rows */
|
/* Display the volume info rows */
|
||||||
for (i = 0; i < numVolumes; i++) {
|
for (i = 0; i < list->nvols; i++) {
|
||||||
vshPrint(ctl, outputStr,
|
vshPrint(ctl, outputStr,
|
||||||
activeNames[i],
|
virStorageVolGetName(list->vols[i]),
|
||||||
volInfoTexts[i].path,
|
volInfoTexts[i].path,
|
||||||
volInfoTexts[i].type,
|
volInfoTexts[i].type,
|
||||||
volInfoTexts[i].capacity,
|
volInfoTexts[i].capacity,
|
||||||
@ -1240,20 +1342,21 @@ asprintf_failure:
|
|||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
/* Safely free the memory allocated in this function */
|
/* Safely free the memory allocated in this function */
|
||||||
for (i = 0; i < numVolumes; i++) {
|
if (list && list->nvols) {
|
||||||
/* Cleanup the memory for one volume info structure per loop */
|
for (i = 0; i < list->nvols; i++) {
|
||||||
VIR_FREE(volInfoTexts[i].path);
|
/* Cleanup the memory for one volume info structure per loop */
|
||||||
VIR_FREE(volInfoTexts[i].type);
|
VIR_FREE(volInfoTexts[i].path);
|
||||||
VIR_FREE(volInfoTexts[i].capacity);
|
VIR_FREE(volInfoTexts[i].type);
|
||||||
VIR_FREE(volInfoTexts[i].allocation);
|
VIR_FREE(volInfoTexts[i].capacity);
|
||||||
VIR_FREE(activeNames[i]);
|
VIR_FREE(volInfoTexts[i].allocation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup remaining memory */
|
/* Cleanup remaining memory */
|
||||||
VIR_FREE(outputStr);
|
VIR_FREE(outputStr);
|
||||||
VIR_FREE(volInfoTexts);
|
VIR_FREE(volInfoTexts);
|
||||||
VIR_FREE(activeNames);
|
|
||||||
virStoragePoolFree(pool);
|
virStoragePoolFree(pool);
|
||||||
|
vshStorageVolListFree(list);
|
||||||
|
|
||||||
/* Return the desired value */
|
/* Return the desired value */
|
||||||
return functionReturn;
|
return functionReturn;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user