From fd6f688120e4f18decee6a49120837f27df53b35 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Mon, 30 Aug 2021 14:54:50 +0400 Subject: backoff.c: added dcc_backof_is_enabled() helper function --- src/backoff.c | 33 +++++++++++++++++---------------- src/distcc.h | 1 + 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/backoff.c b/src/backoff.c index b3d656c..5aaf45a 100644 --- a/src/backoff.c +++ b/src/backoff.c @@ -52,6 +52,19 @@ static int dcc_backoff_period = 60; /* seconds */ +static int dcc_get_backoff_period(void) +{ + char *bp; + bp = getenv("DISTCC_BACKOFF_PERIOD"); + if (bp) + dcc_backoff_period = atoi(bp); + return dcc_backoff_period; +} + +int dcc_backoff_is_enabled(void) +{ + return dcc_get_backoff_period() != 0; +} /** * Remember that this host is working OK. @@ -61,23 +74,17 @@ static int dcc_backoff_period = 60; /* seconds */ **/ int dcc_enjoyed_host(const struct dcc_hostdef *host) { - char *bp; - /* special-case: if DISTCC_BACKOFF_PERIOD==0, don't manage backoff files */ - bp = getenv("DISTCC_BACKOFF_PERIOD"); - if (bp && (atoi(bp) == 0)) - return 0; + if (!dcc_backoff_is_enabled()) + return 0; return dcc_remove_timefile("backoff", host); } int dcc_disliked_host(const struct dcc_hostdef *host) { - char *bp; - /* special-case: if DISTCC_BACKOFF_PERIOD==0, don't manage backoff files */ - bp = getenv("DISTCC_BACKOFF_PERIOD"); - if (bp && (atoi(bp) == 0)) + if (!dcc_backoff_is_enabled()) return 0; /* i hate you (but only for dcc_backoff_period seconds) */ @@ -108,14 +115,8 @@ static int dcc_check_backoff(struct dcc_hostdef *host) int dcc_remove_disliked(struct dcc_hostdef **hostlist) { struct dcc_hostdef *h; - char *bp; - bp = getenv("DISTCC_BACKOFF_PERIOD"); - if (bp) - dcc_backoff_period = atoi(bp); - - /* special-case: if DISTCC_BACKOFF_PERIOD==0, don't manage backoff files */ - if (dcc_backoff_period == 0) + if (!dcc_backoff_is_enabled()) return 0; while ((h = *hostlist) != NULL) { diff --git a/src/distcc.h b/src/distcc.h index 7860a2c..a4bfe26 100644 --- a/src/distcc.h +++ b/src/distcc.h @@ -190,6 +190,7 @@ int dcc_support_masquerade(char *argv[], char *progname, int *); int dcc_enjoyed_host(const struct dcc_hostdef *host); int dcc_disliked_host(const struct dcc_hostdef *host); int dcc_remove_disliked(struct dcc_hostdef **hostlist); +int dcc_backoff_is_enabled(void); -- cgit v1.2.1 From a59c8a58caa912e85867749cbd03861f4654acc1 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Mon, 30 Aug 2021 13:58:38 +0400 Subject: Restrict the number of retries when DISTCC_BACKOFF is disabled Since the commit a7dd5cf90e8c ("Try a new host after failing to connect instead of immediately falling back to localhost") distcc tries to choose a different host on connection/protocol errors. However when backoff is disabled (DISTCC_BACKOFF_PERIOD=0) distcc keeps retrying forever. To avoid the problem limit the number of retries (currently to 3) when backoff is disabled. Closes: #434 --- src/compile.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/compile.c b/src/compile.c index 26d7d18..1fdee42 100644 --- a/src/compile.c +++ b/src/compile.c @@ -631,6 +631,18 @@ static int dcc_gcc_rewrite_fqn(char **argv) return -ENOENT; } +static int dcc_get_max_retries(void) +{ + if (dcc_backoff_is_enabled()) { + /* eventually distcc will either find a suitable host or mark + * all hosts as faulty (and fallback to a local compilation) + */ + return 0; /* no limit */ + } else { + return 3; /* somewhat arbitrary */ + } +} + /** * Execute the commands in argv remotely or locally as appropriate. * @@ -687,10 +699,13 @@ dcc_build_somewhere(char *argv[], int cpu_lock_fd = -1, local_cpu_lock_fd = -1; int ret; int remote_ret = 0; + int retry_count = 0, max_retries; struct dcc_hostdef *host = NULL; char *discrepancy_filename = NULL; char **new_argv; + max_retries = dcc_get_max_retries(); + if ((ret = dcc_expand_preprocessor_options(&argv)) != 0) goto clean_up; @@ -841,7 +856,14 @@ dcc_build_somewhere(char *argv[], /* dcc_compile_remote() already unlocked local_cpu_lock_fd. */ local_cpu_lock_fd = -1; bad_host(host, &cpu_lock_fd, &local_cpu_lock_fd); - goto choose_host; + retry_count++; + if (max_retries == 0 || retry_count < max_retries) + goto choose_host; + else { + rs_log_warning("Couldn't find a host in %d attempts, retrying locally", + retry_count); + goto fallback; + } } /* dcc_compile_remote() already unlocked local_cpu_lock_fd. */ local_cpu_lock_fd = -1; -- cgit v1.2.1