
On 02/26/2013 07:54 PM, Eric Blake wrote:
On 02/26/2013 07:20 AM, John Ferlan wrote:
I would have put '---' here, since...
The information was only in the email not part of the git history. In the future I'll remember to put that after the '---'.
examples/hellolibvirt/hellolibvirt.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
@@ -93,7 +94,7 @@ showDomains(virConnectPtr conn) char **nameList = NULL;
numActiveDomains = virConnectNumOfDomains(conn); - if (-1 == numActiveDomains) { + if (numActiveDomains == -1) { ret = 1; printf("Failed to get number of active domains\n"); showError(conn);
virConnectNumOfDomains is inherently racy. Wouldn't it be better to just drop this section of our example?
Considering the back and forth I decided to make "less" change because it's just an example, but I suppose I took too much off the top. So below are proposed adjustments.
@@ -101,7 +102,7 @@ showDomains(virConnectPtr conn) }
numInactiveDomains = virConnectNumOfDefinedDomains(conn); - if (-1 == numInactiveDomains) { + if (numInactiveDomains == -1) { ret = 1; printf("Failed to get number of inactive domains\n"); showError(conn);
Same question.
@@ -113,17 +114,20 @@ showDomains(virConnectPtr conn)
nameList = malloc(sizeof(*nameList) * numInactiveDomains);
- if (NULL == nameList) { + if (!nameList) { ret = 1; printf("Could not allocate memory for list of inactive domains\n"); goto out; }
+ /* The virConnectListDomains() will return a list of the active domains. + * Alternatively the virConnectListAllDomains() API would return a list + * of both active and inactive domains */ numNames = virConnectListDefinedDomains(conn, nameList, numInactiveDomains);
I think it would be better to update the example to JUST use virConnectListAllDomains(), and completely avoid virConnectListDefinedDomains.
- if (-1 == numNames) { + if (numNames == -1) { ret = 1; printf("Could not get list of defined domains from hypervisor\n"); showError(conn); @@ -136,9 +140,7 @@ showDomains(virConnectPtr conn)
for (i = 0 ; i < numNames ; i++) { printf(" %s\n", *(nameList + i)); - /* The API documentation doesn't say so, but the names - * returned by virConnectListDefinedDomains are strdup'd and - * must be freed here. */ + /* must free the returned named per the API documentation */ free(*(nameList + i));
Pre-existing, but '*(nameList + i)' looks odd; 'nameList[i]' looks nicer.
Here's the differences from the v3 to what seems to be a happy medium. The virConnectNum* functions are still used just to "show" they exist and how to use them. There's a comment before the usage. diff --git a/examples/hellolibvirt/hellolibvirt.c b/examples/hellolibvirt/hellol index 335a75e..26dd67f 100644 --- a/examples/hellolibvirt/hellolibvirt.c +++ b/examples/hellolibvirt/hellolibvirt.c @@ -91,8 +91,14 @@ static int showDomains(virConnectPtr conn) { int ret = 0, i, numNames, numInactiveDomains, numActiveDomains; - char **nameList = NULL; - + int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_INACTIVE; + virDomainPtr *nameList = NULL; + * the current call. A domain could be started or stopped and any + * assumptions made purely on these return values could result in + * unexpected results */ numActiveDomains = virConnectNumOfDomains(conn); if (numActiveDomains == -1) { ret = 1; @@ -112,40 +118,24 @@ showDomains(virConnectPtr conn) printf("There are %d active and %d inactive domains\n", numActiveDomains, numInactiveDomains); - nameList = malloc(sizeof(*nameList) * numInactiveDomains); - - if (!nameList) { - ret = 1; - printf("Could not allocate memory for list of inactive domains\n"); - goto out; - } - - /* The virConnectListDomains() will return a list of the active domains. - * Alternatively the virConnectListAllDomains() API would return a list - * of both active and inactive domains */ - numNames = virConnectListDefinedDomains(conn, - nameList, - numInactiveDomains); - - if (numNames == -1) { - ret = 1; - printf("Could not get list of defined domains from hypervisor\n"); - showError(conn); - goto out; - } - - if (numNames > 0) { - printf("Inactive domains:\n"); - } - - for (i = 0 ; i < numNames ; i++) { - printf(" %s\n", *(nameList + i)); + /* Return a list of all active and inactive domains. Using this API + * instead of virConnectListDomains() and virConnectListDefinedDomains() + * is preferred since it "solves" an inherit race between separated API + * calls if domains are started or stopped between calls */ + numNames = virConnectListAllDomains(conn, + &nameList, + flags); + for (i = 0; i < numNames; i++) { + int active = virDomainIsActive(nameList[i]); + printf(" %8s (%s)\n", + virDomainGetName(nameList[i]), + (active == 1 ? "active" : "non-active")); /* must free the returned named per the API documentation */ - free(*(nameList + i)); + virDomainFree(nameList[i]); } + free(nameList); out: - free(nameList); return ret; } This changes the output from: Attempting to connect to hypervisor Connected to hypervisor at "qemu:///system" Hypervisor: "QEMU" version: 0.32.656 There are 0 active and 2 inactive domains Inactive domains: foo bar Disconnected from hypervisor to Attempting to connect to hypervisor Connected to hypervisor at "qemu:///system" Hypervisor: "QEMU" version: 0.32.656 There are 0 active and 2 inactive domains foo (non-active) bar (non-active) Disconnected from hypervisor John