diff --git a/src/libvirt.c b/src/libvirt.c index e144ab0253..08c413456f 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -18344,6 +18344,10 @@ error: * messages. Failure to do so may result in connections being closed * unexpectedly. * + * Note: This API function controls only keepalive messages sent by the client. + * If the server is configured to use keepalive you still need to run the event + * loop to respond to them, even if you disable keepalives by this function. + * * Returns -1 on error, 0 on success, 1 when remote party doesn't support * keepalive messages. */ @@ -18363,12 +18367,6 @@ int virConnectSetKeepAlive(virConnectPtr conn, return -1; } - if (interval <= 0) { - virLibConnError(VIR_ERR_INVALID_ARG, - _("negative or zero interval make no sense")); - goto error; - } - if (conn->driver->setKeepAlive) { ret = conn->driver->setKeepAlive(conn, interval, count); if (ret < 0) diff --git a/src/probes.d b/src/probes.d index 9d70cc9726..e56dc3e264 100644 --- a/src/probes.d +++ b/src/probes.d @@ -78,7 +78,7 @@ provider libvirt { probe rpc_keepalive_ref(void *ka, void *client, int refs); probe rpc_keepalive_free(void *ka, void *client, int refs); probe rpc_keepalive_start(void *ka, void *client, int interval, int count); - probe rpc_keepalive_stop(void *ka, void *client); + probe rpc_keepalive_stop(void *ka, void *client, bool all); probe rpc_keepalive_send(void *ka, void *client, int prog, int vers, int proc); probe rpc_keepalive_received(void *ka, void *client, int prog, int vers, int proc); probe rpc_keepalive_timeout(void *ka, void *client, int coundToDeath, int idle); diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 0f8d6071f3..a19a86b53e 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -4647,7 +4647,12 @@ remoteSetKeepAlive(virConnectPtr conn, int interval, unsigned int count) goto cleanup; } - ret = virNetClientKeepAliveStart(priv->client, interval, count); + if (interval > 0) { + ret = virNetClientKeepAliveStart(priv->client, interval, count); + } else { + virNetClientKeepAliveStop(priv->client); + ret = 0; + } cleanup: remoteDriverUnlock(priv); diff --git a/src/rpc/virkeepalive.c b/src/rpc/virkeepalive.c index 06b8e632ce..a5c2b1aada 100644 --- a/src/rpc/virkeepalive.c +++ b/src/rpc/virkeepalive.c @@ -372,32 +372,48 @@ cleanup: } -void -virKeepAliveStop(virKeepAlivePtr ka) +static void +virKeepAliveStopInternal(virKeepAlivePtr ka, bool all) { virKeepAliveLock(ka); PROBE(RPC_KEEPALIVE_STOP, - "ka=%p client=%p", - ka, ka->client); + "ka=%p client=%p all=%d", + ka, ka->client, all); if (ka->timer > 0) { virEventRemoveTimeout(ka->timer); ka->timer = -1; } - if (ka->responseTimer > 0) { - virEventRemoveTimeout(ka->responseTimer); - ka->responseTimer = -1; + if (all) { + if (ka->responseTimer > 0) { + virEventRemoveTimeout(ka->responseTimer); + ka->responseTimer = -1; + } + + virNetMessageFree(ka->response); + ka->response = NULL; } - virNetMessageFree(ka->response); - ka->response = NULL; - virKeepAliveUnlock(ka); } +void +virKeepAliveStop(virKeepAlivePtr ka) +{ + virKeepAliveStopInternal(ka, true); +} + + +void +virKeepAliveStopSending(virKeepAlivePtr ka) +{ + virKeepAliveStopInternal(ka, false); +} + + bool virKeepAliveCheckMessage(virKeepAlivePtr ka, virNetMessagePtr msg) diff --git a/src/rpc/virkeepalive.h b/src/rpc/virkeepalive.h index f1654eb25a..af9e722297 100644 --- a/src/rpc/virkeepalive.h +++ b/src/rpc/virkeepalive.h @@ -49,6 +49,7 @@ int virKeepAliveStart(virKeepAlivePtr ka, int interval, unsigned int count); void virKeepAliveStop(virKeepAlivePtr ka); +void virKeepAliveStopSending(virKeepAlivePtr ka); bool virKeepAliveCheckMessage(virKeepAlivePtr ka, virNetMessagePtr msg); diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 33b770146a..d88288d920 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -248,6 +248,14 @@ virNetClientKeepAliveStart(virNetClientPtr client, return ret; } +void +virNetClientKeepAliveStop(virNetClientPtr client) +{ + virNetClientLock(client); + virKeepAliveStopSending(client->keepalive); + virNetClientUnlock(client); +} + static void virNetClientKeepAliveDeadCB(void *opaque) { diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h index 7c30d2bac3..13b4f96ccd 100644 --- a/src/rpc/virnetclient.h +++ b/src/rpc/virnetclient.h @@ -104,4 +104,6 @@ int virNetClientKeepAliveStart(virNetClientPtr client, int interval, unsigned int count); +void virNetClientKeepAliveStop(virNetClientPtr client); + #endif /* __VIR_NET_CLIENT_H__ */