Since virRaiseErrorFull needs to lock the conn, we must take care to call it with the lock *not* held. If this patch is approved, similar patches need to be done for other types in datatypes.c --- src/datatypes.c | 29 +++++++++++++++++++---------- 1 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/datatypes.c b/src/datatypes.c index 000fa66..ba5401d 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -568,16 +568,19 @@ virGetInterface(virConnectPtr conn, const char *name, const char *mac) { } } else { if (VIR_ALLOC(ret) < 0) { + virMutexUnlock(&conn->lock); virReportOOMError(conn); goto error; } ret->name = strdup(name); if (ret->name == NULL) { + virMutexUnlock(&conn->lock); virReportOOMError(conn); goto error; } ret->mac = strdup(mac); if (ret->mac == NULL) { + virMutexUnlock(&conn->lock); virReportOOMError(conn); goto error; } @@ -586,6 +589,7 @@ virGetInterface(virConnectPtr conn, const char *name, const char *mac) { ret->conn = conn; if (virHashAddEntry(conn->interfaces, name, ret) < 0) { + virMutexUnlock(&conn->lock); virLibConnError(conn, VIR_ERR_INTERNAL_ERROR, _("failed to add interface to connection hash table")); goto error; @@ -597,7 +601,6 @@ virGetInterface(virConnectPtr conn, const char *name, const char *mac) { return(ret); error: - virMutexUnlock(&conn->lock); if (ret != NULL) { VIR_FREE(ret->name); VIR_FREE(ret->mac); @@ -623,24 +626,30 @@ virReleaseInterface(virInterfacePtr iface) { virConnectPtr conn = iface->conn; DEBUG("release interface %p %s", iface, iface->name); - if (virHashRemoveEntry(conn->interfaces, iface->name, NULL) < 0) + if (virHashRemoveEntry(conn->interfaces, iface->name, NULL) < 0) { + /* unlock before reporting error because error report grabs lock */ + virMutexUnlock(&conn->lock); virLibConnError(conn, VIR_ERR_INTERNAL_ERROR, _("interface missing from connection hash table")); + /* don't decr the conn refct if we weren't connected to it */ + conn = NULL; + } iface->magic = -1; VIR_FREE(iface->name); VIR_FREE(iface->mac); VIR_FREE(iface); - DEBUG("unref connection %p %d", conn, conn->refs); - conn->refs--; - if (conn->refs == 0) { - virReleaseConnect(conn); - /* Already unlocked mutex */ - return; + if (conn) { + DEBUG("unref connection %p %d", conn, conn->refs); + conn->refs--; + if (conn->refs == 0) { + virReleaseConnect(conn); + /* Already unlocked mutex */ + return; + } + virMutexUnlock(&conn->lock); } - - virMutexUnlock(&conn->lock); } -- 1.6.0.6 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list