mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 12:05:17 +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 17f3be079c3c421eff203fcd311b0357ec42d801)
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…
x
Reference in New Issue
Block a user