[libvirt] [PATCH 2/2] Filter out stale domains from xenstore listing

Daniel P. Berrange berrange at redhat.com
Fri Oct 9 09:35:49 UTC 2009


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




More information about the libvir-list mailing list