Release conn lock before reporting interface errors

* src/datatypes.c: fix a lock problem on error handling, as the
  error report takes the lock, it must be released before, fixes
  the problem but just for Interface objects
This commit is contained in:
Laine Stump 2009-07-22 16:15:52 +02:00 committed by Daniel Veillard
parent fb1b7d8ed0
commit 528d37bdfe

View File

@ -568,16 +568,19 @@ _("Failed to change interface mac address from %s to %s due to differing lengths
} }
} else { } else {
if (VIR_ALLOC(ret) < 0) { if (VIR_ALLOC(ret) < 0) {
virMutexUnlock(&conn->lock);
virReportOOMError(conn); virReportOOMError(conn);
goto error; goto error;
} }
ret->name = strdup(name); ret->name = strdup(name);
if (ret->name == NULL) { if (ret->name == NULL) {
virMutexUnlock(&conn->lock);
virReportOOMError(conn); virReportOOMError(conn);
goto error; goto error;
} }
ret->mac = strdup(mac); ret->mac = strdup(mac);
if (ret->mac == NULL) { if (ret->mac == NULL) {
virMutexUnlock(&conn->lock);
virReportOOMError(conn); virReportOOMError(conn);
goto error; goto error;
} }
@ -586,6 +589,7 @@ _("Failed to change interface mac address from %s to %s due to differing lengths
ret->conn = conn; ret->conn = conn;
if (virHashAddEntry(conn->interfaces, name, ret) < 0) { if (virHashAddEntry(conn->interfaces, name, ret) < 0) {
virMutexUnlock(&conn->lock);
virLibConnError(conn, VIR_ERR_INTERNAL_ERROR, virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
_("failed to add interface to connection hash table")); _("failed to add interface to connection hash table"));
goto error; goto error;
@ -597,7 +601,6 @@ _("Failed to change interface mac address from %s to %s due to differing lengths
return(ret); return(ret);
error: error:
virMutexUnlock(&conn->lock);
if (ret != NULL) { if (ret != NULL) {
VIR_FREE(ret->name); VIR_FREE(ret->name);
VIR_FREE(ret->mac); VIR_FREE(ret->mac);
@ -623,24 +626,30 @@ virReleaseInterface(virInterfacePtr iface) {
virConnectPtr conn = iface->conn; virConnectPtr conn = iface->conn;
DEBUG("release interface %p %s", iface, iface->name); 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, virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
_("interface missing from connection hash table")); _("interface missing from connection hash table"));
/* don't decr the conn refct if we weren't connected to it */
conn = NULL;
}
iface->magic = -1; iface->magic = -1;
VIR_FREE(iface->name); VIR_FREE(iface->name);
VIR_FREE(iface->mac); VIR_FREE(iface->mac);
VIR_FREE(iface); VIR_FREE(iface);
DEBUG("unref connection %p %d", conn, conn->refs); if (conn) {
conn->refs--; DEBUG("unref connection %p %d", conn, conn->refs);
if (conn->refs == 0) { conn->refs--;
virReleaseConnect(conn); if (conn->refs == 0) {
/* Already unlocked mutex */ virReleaseConnect(conn);
return; /* Already unlocked mutex */
return;
}
virMutexUnlock(&conn->lock);
} }
virMutexUnlock(&conn->lock);
} }