Filter out stale domains from xenstore listing

The xenstore database sometimes has stale domain IDs which are not
present in the hypervisor anymore. Filter these out to avoid causing
confusion

* src/xen/xs_internal.c: Filter domain IDs against HV's list
* src/xen/xen_hypervisor.h, src/xen/xen_hypervisor.c: Add new
  xenHypervisorHasDomain() method for checking ID validity
This commit is contained in:
Daniel P. Berrange 2009-10-09 10:32:37 +01:00
parent 2659b3f5aa
commit 7c34bb2681
3 changed files with 51 additions and 10 deletions

View File

@ -2789,6 +2789,28 @@ xenHypervisorDomainGetOSType (virDomainPtr dom)
return ostype;
}
int
xenHypervisorHasDomain(virConnectPtr conn,
int id)
{
xenUnifiedPrivatePtr priv;
xen_getdomaininfo dominfo;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->handle < 0)
return 0;
XEN_GETDOMAININFO_CLEAR(dominfo);
if (virXen_getdomaininfo(priv->handle, id, &dominfo) < 0)
return 0;
if (XEN_GETDOMAININFO_DOMAIN(dominfo) != id)
return 0;
return 1;
}
virDomainPtr
xenHypervisorLookupDomainByID(virConnectPtr conn,
int id)

View File

@ -23,7 +23,9 @@ int xenHypervisorInit (void);
virCapsPtr xenHypervisorMakeCapabilities (virConnectPtr conn);
/* The following calls are made directly by the Xen proxy: */
int
xenHypervisorHasDomain(virConnectPtr conn,
int id);
virDomainPtr
xenHypervisorLookupDomainByID (virConnectPtr conn,
int id);

View File

@ -543,8 +543,9 @@ int
xenStoreNumOfDomains(virConnectPtr conn)
{
unsigned int num;
char **idlist;
int ret = -1;
char **idlist = NULL, *endptr;
int i, ret = -1, realnum = 0;
long id;
xenUnifiedPrivatePtr priv;
if (conn == NULL) {
@ -557,10 +558,22 @@ xenStoreNumOfDomains(virConnectPtr conn)
virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
idlist = xs_directory(priv->xshandle, 0, "/local/domain", &num);
if (idlist) {
free(idlist);
ret = num;
for (i = 0; i < num; i++) {
id = strtol(idlist[i], &endptr, 10);
if ((endptr == idlist[i]) || (*endptr != 0))
goto out;
/* Sometimes xenstore has stale domain IDs, so filter
against the hypervisor's info */
if (xenHypervisorHasDomain(conn, (int)id))
realnum++;
}
out:
VIR_FREE (idlist);
ret = realnum;
}
return(ret);
}
@ -577,7 +590,7 @@ xenStoreNumOfDomains(virConnectPtr conn)
* Returns the number of domain found or -1 in case of error
*/
static int
xenStoreDoListDomains(xenUnifiedPrivatePtr priv, int *ids, int maxids)
xenStoreDoListDomains(virConnectPtr conn, xenUnifiedPrivatePtr priv, int *ids, int maxids)
{
char **idlist = NULL, *endptr;
unsigned int num, i;
@ -595,7 +608,11 @@ xenStoreDoListDomains(xenUnifiedPrivatePtr priv, int *ids, int maxids)
id = strtol(idlist[i], &endptr, 10);
if ((endptr == idlist[i]) || (*endptr != 0))
goto out;
ids[ret++] = (int) id;
/* Sometimes xenstore has stale domain IDs, so filter
against the hypervisor's info */
if (xenHypervisorHasDomain(conn, (int)id))
ids[ret++] = (int) id;
}
out:
@ -627,7 +644,7 @@ xenStoreListDomains(virConnectPtr conn, int *ids, int maxids)
priv = (xenUnifiedPrivatePtr) conn->privateData;
xenUnifiedLock(priv);
ret = xenStoreDoListDomains(priv, ids, maxids);
ret = xenStoreDoListDomains(conn, priv, ids, maxids);
xenUnifiedUnlock(priv);
return(ret);
@ -1299,7 +1316,7 @@ retry:
virReportOOMError(NULL);
return -1;
}
nread = xenStoreDoListDomains(priv, new_domids, new_domain_cnt);
nread = xenStoreDoListDomains(conn, priv, new_domids, new_domain_cnt);
if (nread != new_domain_cnt) {
// mismatch. retry this read
VIR_FREE(new_domids);
@ -1380,7 +1397,7 @@ retry:
virReportOOMError(NULL);
return -1;
}
nread = xenStoreDoListDomains(priv, new_domids, new_domain_cnt);
nread = xenStoreDoListDomains(conn, priv, new_domids, new_domain_cnt);
if (nread != new_domain_cnt) {
// mismatch. retry this read
VIR_FREE(new_domids);