mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-04 20:15:19 +00:00
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 17f3be079c
)
This commit is contained in:
parent
cba63bbc22
commit
40b0176129
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user