mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06: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.
This commit is contained in:
parent
c7d5cdb15b
commit
17f3be079c
@ -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,
|
|||||||
data,
|
data,
|
||||||
nbytes);
|
nbytes);
|
||||||
|
|
||||||
cleanup:
|
remoteDriverLock(priv);
|
||||||
|
priv->localUses--;
|
||||||
remoteDriverUnlock(priv);
|
remoteDriverUnlock(priv);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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,
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user