From: Daniel P. Berrange Date: Fri, 9 Oct 2009 09:32:37 +0000 (+0100) Subject: Filter out stale domains from xenstore listing X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=7c34bb2681f48e2a4e76de7f54c58b630a861777;p=libvirt.git 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 --- diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index f25629af16..6d8bfdd517 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -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) diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 766f676836..5971a90eb8 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -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); diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c index f8ef00b616..0cca9b5807 100644 --- a/src/xen/xs_internal.c +++ b/src/xen/xs_internal.c @@ -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);