From 6f42946997a05b40d7261b11eb67f0a1ce8db1b5 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 24 Apr 2012 16:38:41 +0200 Subject: [PATCH] keepalive: Add ability to disable keepalive messages The docs for virConnectSetKeepAlive() advertise that this function should be able to disable keepalives on negative or zero interval time. This patch removes the check that prohibited this and adds code to disable keepalives on negative/zero interval. * src/libvirt.c: virConnectSetKeepAlive(): - remove check for negative values * src/rpc/virnetclient.c * src/rpc/virnetclient.h: - add virNetClientKeepAliveStop() to disable keepalive messages * src/remote/remote_driver.c: remoteSetKeepAlive(): -add ability to disable keepalives (cherry picked from commit 6446a9e20cc65561ce6061742baf35a3a63d5ba1) --- src/libvirt.c | 10 ++++------ src/probes.d | 2 +- src/remote/remote_driver.c | 7 ++++++- src/rpc/virkeepalive.c | 36 ++++++++++++++++++++++++++---------- src/rpc/virkeepalive.h | 1 + src/rpc/virnetclient.c | 8 ++++++++ src/rpc/virnetclient.h | 2 ++ 7 files changed, 48 insertions(+), 18 deletions(-) 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__ */ -- GitLab