From 5a7f83af84d2a08f69ce1629c7609c98f43411ab Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Fri, 17 Feb 2023 16:23:52 +0100 Subject: [PATCH] BUG/MINOR: mworker: prevent incorrect values in uptime Since the recent changes on the clocks, now.tv_sec is not to be used between processes because it's a clock which is local to the process and does not contain a real unix timestamp. This patch fixes the issue by using "data.tv_sec" which is the wall clock instead of "now.tv_sec'. It prevents having incoherent timestamps. It also introduces some checks on negatives values in order to never displays a netative value if it was computed from a wrong value set by a previous haproxy version. It must be backported as far as 2.0. --- src/haproxy.c | 4 ++-- src/mworker.c | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/haproxy.c b/src/haproxy.c index fe612b0c1..804e092d2 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -2147,7 +2147,7 @@ static void init(int argc, char **argv) } tmproc->options |= PROC_O_TYPE_MASTER; /* master */ tmproc->pid = pid; - tmproc->timestamp = start_time.tv_sec; + tmproc->timestamp = start_date.tv_sec; proc_self = tmproc; LIST_APPEND(&proc_list, &tmproc->list); @@ -3563,7 +3563,7 @@ int main(int argc, char **argv) if (child->reloads == 0 && child->options & PROC_O_TYPE_WORKER && child->pid == -1) { - child->timestamp = now.tv_sec; + child->timestamp = date.tv_sec; child->pid = ret; child->version = strdup(haproxy_version); break; diff --git a/src/mworker.c b/src/mworker.c index 8b3be1916..4bc224ee7 100644 --- a/src/mworker.c +++ b/src/mworker.c @@ -530,13 +530,16 @@ static int cli_io_handler_show_proc(struct appctx *appctx) struct stconn *sc = appctx_sc(appctx); struct mworker_proc *child; int old = 0; - int up = now.tv_sec - proc_self->timestamp; + int up = date.tv_sec - proc_self->timestamp; char *uptime = NULL; char *reloadtxt = NULL; if (unlikely(sc_ic(sc)->flags & CF_SHUTW)) return 1; + if (up < 0) /* must never be negative because of clock drift */ + up = 0; + chunk_reset(&trash); memprintf(&reloadtxt, "%d [failed: %d]", proc_self->reloads, proc_self->failedreloads); @@ -550,7 +553,9 @@ static int cli_io_handler_show_proc(struct appctx *appctx) chunk_appendf(&trash, "# workers\n"); list_for_each_entry(child, &proc_list, list) { - up = now.tv_sec - child->timestamp; + up = date.tv_sec - child->timestamp; + if (up < 0) /* must never be negative because of clock drift */ + up = 0; if (!(child->options & PROC_O_TYPE_WORKER)) continue; @@ -571,7 +576,9 @@ static int cli_io_handler_show_proc(struct appctx *appctx) chunk_appendf(&trash, "# old workers\n"); list_for_each_entry(child, &proc_list, list) { - up = now.tv_sec - child->timestamp; + up = date.tv_sec - child->timestamp; + if (up <= 0) /* must never be negative because of clock drift */ + up = 0; if (!(child->options & PROC_O_TYPE_WORKER)) continue; @@ -589,7 +596,9 @@ static int cli_io_handler_show_proc(struct appctx *appctx) chunk_appendf(&trash, "# programs\n"); old = 0; list_for_each_entry(child, &proc_list, list) { - up = now.tv_sec - child->timestamp; + up = date.tv_sec - child->timestamp; + if (up < 0) /* must never be negative because of clock drift */ + up = 0; if (!(child->options & PROC_O_TYPE_PROG)) continue; @@ -606,7 +615,9 @@ static int cli_io_handler_show_proc(struct appctx *appctx) if (old) { chunk_appendf(&trash, "# old programs\n"); list_for_each_entry(child, &proc_list, list) { - up = now.tv_sec - child->timestamp; + up = date.tv_sec - child->timestamp; + if (up < 0) /* must never be negative because of clock drift */ + up = 0; if (!(child->options & PROC_O_TYPE_PROG)) continue;