On Fri, Oct 09, 2009 at 10:35:49AM +0100, Daniel P. Berrange wrote: > 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); Okay so we filter out though an hypervisor call instead of slow xend lookup, ACK ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list