]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
fix recursive lock hang in xenstore driver
authorJohn Levon <john.levon@sun.com>
Fri, 23 Jan 2009 19:18:24 +0000 (19:18 +0000)
committerJohn Levon <john.levon@sun.com>
Fri, 23 Jan 2009 19:18:24 +0000 (19:18 +0000)
ChangeLog
src/xs_internal.c

index 1641fb1367bd55cc6df1aef25e364080fb139857..f6e9af939d8a1933384e1d6876362c8423766677 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Fri Jan 23 11:07:42 PST 2009 John Levon <john.levon@sun.com>
+
+       * src/xs_internal.c: fix recursive lock hang
+
 Fri Jan 23 16:20:03 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
 
        * src/qemu_conf.c: Support driver format for setting disk
index 55be057f9961db881312f97d57633eb136b947ad..dbbf7f26b7af262c29ad1aa78d4c6366a52ccc6a 100644 (file)
@@ -565,58 +565,73 @@ xenStoreNumOfDomains(virConnectPtr conn)
 }
 
 /**
- * xenStoreListDomains:
+ * xenStoreDoListDomains:
  * @conn: pointer to the hypervisor connection
  * @ids: array to collect the list of IDs of active domains
  * @maxids: size of @ids
  *
- * Collect the list of active domains, and store their ID in @maxids
+ * Internal API: collect the list of active domains, and store
+ * their ID in @maxids. The driver lock must be held.
  *
  * Returns the number of domain found or -1 in case of error
  */
-int
-xenStoreListDomains(virConnectPtr conn, int *ids, int maxids)
+static int
+xenStoreDoListDomains(xenUnifiedPrivatePtr priv, int *ids, int maxids)
 {
     char **idlist = NULL, *endptr;
     unsigned int num, i;
-    int ret;
+    int ret = -1;
     long id;
-    xenUnifiedPrivatePtr priv;
-
-    if ((conn == NULL) || (ids == NULL)) {
-        virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        return(-1);
-    }
-
-    priv = (xenUnifiedPrivatePtr) conn->privateData;
 
-    xenUnifiedLock(priv);
     if (priv->xshandle == NULL)
-        goto error;
+        goto out;
 
     idlist = xs_directory (priv->xshandle, 0, "/local/domain", &num);
     if (idlist == NULL)
-        goto error;
+        goto out;
 
     for (ret = 0, i = 0; (i < num) && (ret < maxids); i++) {
         id = strtol(idlist[i], &endptr, 10);
-        if ((endptr == idlist[i]) || (*endptr != 0)) {
-            ret = -1;
-            break;
-        }
-#if 0
-        if (virConnectCheckStoreID(conn, (int) id) < 0)
-            continue;
-#endif
+        if ((endptr == idlist[i]) || (*endptr != 0))
+            goto out;
         ids[ret++] = (int) id;
     }
+
     free(idlist);
-    xenUnifiedUnlock(priv);
-    return(ret);
 
-error:
+out:
+    VIR_FREE (idlist);
+    return ret;
+}
+
+/**
+ * xenStoreListDomains:
+ * @conn: pointer to the hypervisor connection
+ * @ids: array to collect the list of IDs of active domains
+ * @maxids: size of @ids
+ *
+ * Collect the list of active domains, and store their ID in @maxids
+ *
+ * Returns the number of domain found or -1 in case of error
+ */
+int
+xenStoreListDomains(virConnectPtr conn, int *ids, int maxids)
+{
+    xenUnifiedPrivatePtr priv;
+    int ret;
+
+    if ((conn == NULL) || (ids == NULL)) {
+        virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
+    xenUnifiedLock(priv);
+    ret = xenStoreDoListDomains(priv, ids, maxids);
     xenUnifiedUnlock(priv);
-    return -1;
+
+    return(ret);
 }
 
 /**
@@ -1260,7 +1275,7 @@ retry:
                                  "%s", _("failed to allocate domids"));
         return -1;
     }
-    nread = xenStoreListDomains(conn, new_domids, new_domain_cnt);
+    nread = xenStoreDoListDomains(priv, new_domids, new_domain_cnt);
     if (nread != new_domain_cnt) {
         // mismatch. retry this read
         VIR_FREE(new_domids);
@@ -1342,7 +1357,7 @@ retry:
                                  "%s", _("failed to allocate domids"));
         return -1;
     }
-    nread = xenStoreListDomains(conn, new_domids, new_domain_cnt);
+    nread = xenStoreDoListDomains(priv, new_domids, new_domain_cnt);
     if (nread != new_domain_cnt) {
         // mismatch. retry this read
         VIR_FREE(new_domids);