From: John Levon Date: Fri, 23 Jan 2009 19:18:24 +0000 (+0000) Subject: fix recursive lock hang in xenstore driver X-Git-Tag: LIBVIRT_0_6_0~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39e49ad7c97f2ca2becf16d0b243674ba4d67a73;p=thirdparty%2Flibvirt.git fix recursive lock hang in xenstore driver --- diff --git a/ChangeLog b/ChangeLog index 1641fb1367..f6e9af939d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Fri Jan 23 11:07:42 PST 2009 John Levon + + * src/xs_internal.c: fix recursive lock hang + Fri Jan 23 16:20:03 GMT 2009 Daniel P. Berrange * src/qemu_conf.c: Support driver format for setting disk diff --git a/src/xs_internal.c b/src/xs_internal.c index 55be057f99..dbbf7f26b7 100644 --- a/src/xs_internal.c +++ b/src/xs_internal.c @@ -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);