提交 17f3be07 编写于 作者: J Jiri Denemark

remote: Fix locking in stream APIs

Remote driver needs to make sure the driver lock is released before
entering client IO loop as that may block indefinitely in poll(). As a
direct consequence of not following this in stream APIs, tunneled
migration to a destination host which becomes non-responding may block
qemu driver. Luckily, if keepalive is turned for p2p migrations, both
remote and qemu drivers will get automagically unblocked after keepalive
timeout.
上级 c7d5cdb1
...@@ -3976,12 +3976,14 @@ remoteStreamSend(virStreamPtr st, ...@@ -3976,12 +3976,14 @@ remoteStreamSend(virStreamPtr st,
VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes); VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes);
struct private_data *priv = st->conn->privateData; struct private_data *priv = st->conn->privateData;
virNetClientStreamPtr privst = st->privateData; virNetClientStreamPtr privst = st->privateData;
int rv = -1; int rv;
remoteDriverLock(priv);
if (virNetClientStreamRaiseError(privst)) if (virNetClientStreamRaiseError(privst))
goto cleanup; return -1;
remoteDriverLock(priv);
priv->localUses++;
remoteDriverUnlock(priv);
rv = virNetClientStreamSendPacket(privst, rv = virNetClientStreamSendPacket(privst,
priv->client, priv->client,
...@@ -3989,9 +3991,9 @@ remoteStreamSend(virStreamPtr st, ...@@ -3989,9 +3991,9 @@ remoteStreamSend(virStreamPtr st,
data, data,
nbytes); nbytes);
cleanup: remoteDriverLock(priv);
priv->localUses--;
remoteDriverUnlock(priv); remoteDriverUnlock(priv);
return rv; return rv;
} }
...@@ -4004,12 +4006,14 @@ remoteStreamRecv(virStreamPtr st, ...@@ -4004,12 +4006,14 @@ remoteStreamRecv(virStreamPtr st,
VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes); VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes);
struct private_data *priv = st->conn->privateData; struct private_data *priv = st->conn->privateData;
virNetClientStreamPtr privst = st->privateData; virNetClientStreamPtr privst = st->privateData;
int rv = -1; int rv;
remoteDriverLock(priv);
if (virNetClientStreamRaiseError(privst)) if (virNetClientStreamRaiseError(privst))
goto cleanup; return -1;
remoteDriverLock(priv);
priv->localUses++;
remoteDriverUnlock(priv);
rv = virNetClientStreamRecvPacket(privst, rv = virNetClientStreamRecvPacket(privst,
priv->client, priv->client,
...@@ -4019,9 +4023,9 @@ remoteStreamRecv(virStreamPtr st, ...@@ -4019,9 +4023,9 @@ remoteStreamRecv(virStreamPtr st,
VIR_DEBUG("Done %d", rv); VIR_DEBUG("Done %d", rv);
cleanup: remoteDriverLock(priv);
priv->localUses--;
remoteDriverUnlock(priv); remoteDriverUnlock(priv);
return rv; return rv;
} }
...@@ -4138,12 +4142,18 @@ remoteStreamFinish(virStreamPtr st) ...@@ -4138,12 +4142,18 @@ remoteStreamFinish(virStreamPtr st)
if (virNetClientStreamRaiseError(privst)) if (virNetClientStreamRaiseError(privst))
goto cleanup; goto cleanup;
priv->localUses++;
remoteDriverUnlock(priv);
ret = virNetClientStreamSendPacket(privst, ret = virNetClientStreamSendPacket(privst,
priv->client, priv->client,
VIR_NET_OK, VIR_NET_OK,
NULL, NULL,
0); 0);
remoteDriverLock(priv);
priv->localUses--;
cleanup: cleanup:
virNetClientRemoveStream(priv->client, privst); virNetClientRemoveStream(priv->client, privst);
virNetClientStreamFree(privst); virNetClientStreamFree(privst);
...@@ -4167,12 +4177,18 @@ remoteStreamAbort(virStreamPtr st) ...@@ -4167,12 +4177,18 @@ remoteStreamAbort(virStreamPtr st)
if (virNetClientStreamRaiseError(privst)) if (virNetClientStreamRaiseError(privst))
goto cleanup; goto cleanup;
priv->localUses++;
remoteDriverUnlock(priv);
ret = virNetClientStreamSendPacket(privst, ret = virNetClientStreamSendPacket(privst,
priv->client, priv->client,
VIR_NET_ERROR, VIR_NET_ERROR,
NULL, NULL,
0); 0);
remoteDriverLock(priv);
priv->localUses--;
cleanup: cleanup:
virNetClientRemoveStream(priv->client, privst); virNetClientRemoveStream(priv->client, privst);
virNetClientStreamFree(privst); virNetClientStreamFree(privst);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册