From: Miroslav Lichvar Date: Wed, 15 Aug 2018 10:21:36 +0000 (+0200) Subject: chrony: Ignore late responses X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=33d79024cf9dc514608883f704dd40ee5e41f008;ds=sidebyside chrony: Ignore late responses If a response from chronyd was not received before the timeout (e.g. on a busy system), it would wait in the receive queue and be processed as a response of the next request. It would fail the sequence check and cause the plugin to return with an error. The latest response would wait in the receive queue and this would repeat forever. Flush the receive queue before sending a new batch of requests to prevent this situation from happening. --- diff --git a/src/chrony.c b/src/chrony.c index 6fb369a2..913aab94 100644 --- a/src/chrony.c +++ b/src/chrony.c @@ -38,6 +38,11 @@ #include /* ntohs/ntohl */ #endif +/* AIX doesn't have MSG_DONTWAIT */ +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT MSG_NONBLOCK +#endif + #define CONFIG_KEY_HOST "Host" #define CONFIG_KEY_PORT "Port" #define CONFIG_KEY_TIMEOUT "Timeout" @@ -440,6 +445,15 @@ static int chrony_recv_response(tChrony_Response *p_resp, } } +static void chrony_flush_recv_queue(void) { + char buf[1]; + + if (g_chrony_is_connected) { + while (recv(g_chrony_socket, buf, sizeof(buf), MSG_DONTWAIT) > 0) + ; + } +} + static int chrony_query(const int p_command, tChrony_Request *p_req, tChrony_Response *p_resp, size_t *p_resp_size) { /* Check connection. We simply perform one try as collectd already handles @@ -964,6 +978,9 @@ static int chrony_read(void) { g_chrony_seq_is_initialized = 1; } + /* Ignore late responses that may have been received */ + chrony_flush_recv_queue(); + /* Get daemon stats */ rc = chrony_request_daemon_stats(); if (rc != CHRONY_RC_OK)