mirror of https://gitee.com/openkylin/libvirt.git
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:
parent
fb1b7d8ed0
commit
528d37bdfe
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue