I am using libvirt for large scale deployment of virtual machines. I ran into
an issue where virConnectListStoragePools and virConnectListDefinedStoragePools
return an error if there are more than 256 pools. The following patch increases
this limitation. Currently, I am only using in the neighborhood of 500 pools,
but this is likely to grow into the tens of thousands.
This patch did not cause any test failures. I wrote some test code to verify
the fix worked. The test code and the results follow.
TEST CODE:
/* pool-test src code */
#include <libvirt.h>
#include <stdlib.h>
#include <stdio.h>
static int get_active_pools(virConnectPtr vir_conn)
{
int ret_code = -1;
int rc = -1;
int num_pools = -1;
char** pools = NULL;
printf("Before virConnectNumOfStoragePools\n");
num_pools = virConnectNumOfStoragePools(vir_conn);
printf("After virConnectNumOfStoragePools\n");
if(0 >= num_pools) goto cleanup;
pools = malloc(sizeof(*pools) * num_pools);
printf("Before virConnectListStoragePools\n");
rc = virConnectListStoragePools(vir_conn, pools, num_pools);
printf("After virConnectListStoragePools\n");
if(-1 == rc) goto cleanup;
for(int i = 0; i < num_pools; ++i) {
if(NULL != pools[i]) free(pools[i]);
}
ret_code = num_pools;
cleanup:
if(NULL != pools) free(pools);
return ret_code;
}
static int get_inactive_pools(virConnectPtr vir_conn)
{
int ret_code = -1;
int rc = -1;
int num_pools = -1;
char** pools = NULL;
printf("Before virConnectNumOfDefinedStoragePools\n");
num_pools = virConnectNumOfDefinedStoragePools(vir_conn);
printf("After virConnectNumOfDefinedStoragePools\n");
if(0 >= num_pools) goto cleanup;
pools = malloc(sizeof(*pools) * num_pools);
printf("Before virConnectListDefinedStoragePools\n");
rc = virConnectListDefinedStoragePools(vir_conn, pools, num_pools);
printf("After virConnectListDefinedStoragePools\n");
if(-1 == rc) goto cleanup;
for(int i = 0; i < num_pools; ++i) {
if(NULL != pools[i]) free(pools[i]);
}
ret_code = num_pools;
cleanup:
if(NULL != pools) free(pools);
return ret_code;
}
int main(int argc, char** argv)
{
virConnectPtr conn = virConnectOpen("qemu:///system");
printf("Active: %d\n" , get_active_pools(conn ));
printf("Inactive: %d\n", get_inactive_pools(conn));
virConnectClose(conn);
return 0;
}
TEST RESULTS PRE-PATCH:
# for i in `ls -1 /etc/libvirt/storage/*`; do virsh pool-start $(basename $i .xml); done
&>/dev/null
# ~/pool-test
Before virConnectNumOfStoragePools
After virConnectNumOfStoragePools
Before virConnectListStoragePools
libvir: Remote error : too many remote undefineds: 407 > 256
After virConnectListStoragePools
Active: -1
Before virConnectNumOfDefinedStoragePools
After virConnectNumOfDefinedStoragePools
Inactive: -1
# for i in `ls -1 /etc/libvirt/storage/*`; do virsh pool-destroy $(basename $i .xml); done
&>/dev/null
# ~/pool-test
Before virConnectNumOfStoragePools
After virConnectNumOfStoragePools
Active: -1
Before virConnectNumOfDefinedStoragePools
After virConnectNumOfDefinedStoragePools
Before virConnectListDefinedStoragePools
libvir: Remote error : too many remote undefineds: 407 > 256
After virConnectListDefinedStoragePools
Inactive: -1
TEST RESULTS POST-PATCH:
# for i in `ls -1 /etc/libvirt/storage/*`; do virsh pool-start $(basename $i .xml); done
&>/dev/null
# ~/pool-test
Before virConnectNumOfStoragePools
After virConnectNumOfStoragePools
Before virConnectListStoragePools
After virConnectListStoragePools
Active: 407
Before virConnectNumOfDefinedStoragePools
After virConnectNumOfDefinedStoragePools
Inactive: -1
# for i in `ls -1 /etc/libvirt/storage/*`; do virsh pool-destroy $(basename $i .xml); done
&>/dev/null
# ~/pool-test
Before virConnectNumOfStoragePools
After virConnectNumOfStoragePools
Active: -1
Before virConnectNumOfDefinedStoragePools
After virConnectNumOfDefinedStoragePools
Before virConnectListDefinedStoragePools
After virConnectListDefinedStoragePools
Inactive: 407