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 --- src/xen/xen_hypervisor.c | 22 ++++++++++++++++++++++ src/xen/xen_hypervisor.h | 4 +++- src/xen/xs_internal.c | 35 ++++++++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 3aa3c30..6ab2431 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -2780,6 +2780,28 @@ xenHypervisorDomainGetOSType (virDomainPtr dom) return strdup("linux"); } +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 766f676..5971a90 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 0fabcf8..c83cfda 100644 --- a/src/xen/xs_internal.c +++ b/src/xen/xs_internal.c @@ -545,8 +545,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) { @@ -559,10 +560,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); } @@ -579,7 +592,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; @@ -597,7 +610,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: @@ -629,7 +646,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); @@ -1275,7 +1292,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); @@ -1356,7 +1373,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); -- 1.6.2.5 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list