提交 40b01761 编写于 作者: J Jiri Denemark 提交者: Cole Robinson

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.
(cherry picked from commit 17f3be07)
上级 cba63bbc
......@@ -3882,12 +3882,14 @@ remoteStreamSend(virStreamPtr st,
VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes);
struct private_data *priv = st->conn->privateData;
virNetClientStreamPtr privst = st->privateData;
int rv = -1;
remoteDriverLock(priv);
int rv;
if (virNetClientStreamRaiseError(privst))
goto cleanup;
return -1;
remoteDriverLock(priv);
priv->localUses++;
remoteDriverUnlock(priv);
rv = virNetClientStreamSendPacket(privst,
priv->client,
......@@ -3895,9 +3897,9 @@ remoteStreamSend(virStreamPtr st,
data,
nbytes);
cleanup:
remoteDriverLock(priv);
priv->localUses--;
remoteDriverUnlock(priv);
return rv;
}
......@@ -3910,12 +3912,14 @@ remoteStreamRecv(virStreamPtr st,
VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes);
struct private_data *priv = st->conn->privateData;
virNetClientStreamPtr privst = st->privateData;
int rv = -1;
remoteDriverLock(priv);
int rv;
if (virNetClientStreamRaiseError(privst))
goto cleanup;
return -1;
remoteDriverLock(priv);
priv->localUses++;
remoteDriverUnlock(priv);
rv = virNetClientStreamRecvPacket(privst,
priv->client,
......@@ -3925,9 +3929,9 @@ remoteStreamRecv(virStreamPtr st,
VIR_DEBUG("Done %d", rv);
cleanup:
remoteDriverLock(priv);
priv->localUses--;
remoteDriverUnlock(priv);
return rv;
}
......@@ -4044,12 +4048,18 @@ remoteStreamFinish(virStreamPtr st)
if (virNetClientStreamRaiseError(privst))
goto cleanup;
priv->localUses++;
remoteDriverUnlock(priv);
ret = virNetClientStreamSendPacket(privst,
priv->client,
VIR_NET_OK,
NULL,
0);
remoteDriverLock(priv);
priv->localUses--;
cleanup:
virNetClientRemoveStream(priv->client, privst);
virNetClientStreamFree(privst);
......@@ -4073,12 +4083,18 @@ remoteStreamAbort(virStreamPtr st)
if (virNetClientStreamRaiseError(privst))
goto cleanup;
priv->localUses++;
remoteDriverUnlock(priv);
ret = virNetClientStreamSendPacket(privst,
priv->client,
VIR_NET_ERROR,
NULL,
0);
remoteDriverLock(priv);
priv->localUses--;
cleanup:
virNetClientRemoveStream(priv->client, privst);
virNetClientStreamFree(privst);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册