From 2ab619fd90e545d3348ed61723a1a98a5deb936d Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 21 Mar 2024 14:03:02 +0100 Subject: [PATCH] - fast-reload, option for fast-reload commandline, +v verbosity option, with timing and memory use output. --- daemon/remote.c | 89 +++++++++++++------ daemon/remote.h | 6 +- doc/unbound-control.8.in | 8 +- smallapp/unbound-control.c | 2 +- .../fast_reload_fwd.tdir/fast_reload_fwd.test | 2 +- .../fast_reload_thread.test | 9 +- 6 files changed, 75 insertions(+), 41 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 9e0034b6c..ecd30af27 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -676,17 +676,36 @@ do_reload(RES* ssl, struct worker* worker, int reuse_cache) /** do the fast_reload command */ static void -do_fast_reload(RES* ssl, struct worker* worker, struct rc_state* s) +do_fast_reload(RES* ssl, struct worker* worker, struct rc_state* s, char* arg) { #ifdef THREADS_DISABLED if(!ssl_printf(ssl, "error: no threads for fast_reload, compiled without threads.\n")) return; (void)worker; (void)s; + (void)arg; #else - if(!ssl_printf(ssl, "start fast_reload\n")) - return; - fast_reload_thread_start(ssl, worker, s); + int fr_verb = 0; + if(arg[0] == '+') { + int i=1; + while(arg[i]!=0 && arg[i]!=' ' && arg[i]!='\t') { + if(arg[i] == 'v') + fr_verb++; + else { + if(!ssl_printf(ssl, + "error: unknown option '+%c'\n", + arg[i])) + return; + return; + } + i++; + } + } + if(fr_verb >= 1) { + if(!ssl_printf(ssl, "start fast_reload\n")) + return; + } + fast_reload_thread_start(ssl, worker, s, fr_verb); #endif } @@ -3100,7 +3119,7 @@ execute_cmd(struct daemon_remote* rc, struct rc_state* s, RES* ssl, char* cmd, do_reload(ssl, worker, 0); return; } else if(cmdcmp(p, "fast_reload", 11)) { - do_fast_reload(ssl, worker, s); + do_fast_reload(ssl, worker, s, skipwhite(p+11)); return; } else if(cmdcmp(p, "stats_noreset", 13)) { do_stats(ssl, worker, 0); @@ -3755,10 +3774,12 @@ fr_read_config(struct fast_reload_thread* fr, struct config_file** newcfg) } if(fr_poll_for_quit(fr)) return 1; - if(!fr_output_printf(fr, "done read config file %s\n", - fr->worker->daemon->cfgfile)) - return 0; - fr_send_notification(fr, fast_reload_notification_printout); + if(fr->fr_verb >= 1) { + if(!fr_output_printf(fr, "done read config file %s\n", + fr->worker->daemon->cfgfile)) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + } return 1; } @@ -4065,8 +4086,10 @@ fr_construct_from_config(struct fast_reload_thread* fr, log_err("out of memory"); return 0; } - if(!fr_printmem(fr, newcfg, ct)) - return 0; + if(fr->fr_verb >= 2) { + if(!fr_printmem(fr, newcfg, ct)) + return 0; + } return 1; } @@ -4294,18 +4317,22 @@ static void* fast_reload_thread_main(void* arg) log_thread_set(&fast_reload_thread->threadnum); verbose(VERB_ALGO, "start fast reload thread"); - fr_init_time(&time_start, &time_read, &time_construct, &time_reload, - &time_end); - if(fr_poll_for_quit(fast_reload_thread)) - goto done; + if(fast_reload_thread->fr_verb >= 1) { + fr_init_time(&time_start, &time_read, &time_construct, + &time_reload, &time_end); + if(fr_poll_for_quit(fast_reload_thread)) + goto done; + } /* print output to the client */ - if(!fr_output_printf(fast_reload_thread, "thread started\n")) - goto done_error; - fr_send_notification(fast_reload_thread, - fast_reload_notification_printout); - if(fr_poll_for_quit(fast_reload_thread)) - goto done; + if(fast_reload_thread->fr_verb >= 1) { + if(!fr_output_printf(fast_reload_thread, "thread started\n")) + goto done_error; + fr_send_notification(fast_reload_thread, + fast_reload_notification_printout); + if(fr_poll_for_quit(fast_reload_thread)) + goto done; + } if(!fr_load_config(fast_reload_thread, &time_read, &time_construct, &time_reload)) @@ -4313,11 +4340,13 @@ static void* fast_reload_thread_main(void* arg) if(fr_poll_for_quit(fast_reload_thread)) goto done; - if(!fr_finish_time(fast_reload_thread, &time_start, &time_read, - &time_construct, &time_reload, &time_end)) - goto done_error; - if(fr_poll_for_quit(fast_reload_thread)) - goto done; + if(fast_reload_thread->fr_verb >= 1) { + if(!fr_finish_time(fast_reload_thread, &time_start, &time_read, + &time_construct, &time_reload, &time_end)) + goto done_error; + if(fr_poll_for_quit(fast_reload_thread)) + goto done; + } if(!fr_output_printf(fast_reload_thread, "ok\n")) goto done_error; @@ -4624,7 +4653,7 @@ create_socketpair(int* pair, struct ub_randstate* rand) /** fast reload thread. setup the thread info */ static int -fast_reload_thread_setup(struct worker* worker) +fast_reload_thread_setup(struct worker* worker, int fr_verb) { struct fast_reload_thread* fr; int numworkers = worker->daemon->num; @@ -4633,6 +4662,7 @@ fast_reload_thread_setup(struct worker* worker) if(!worker->daemon->fast_reload_thread) return 0; fr = worker->daemon->fast_reload_thread; + fr->fr_verb = fr_verb; /* The thread id printed in logs, numworker+1 is the dnstap thread. * This is numworkers+2. */ fr->threadnum = numworkers+2; @@ -5376,13 +5406,14 @@ fr_send_stop(struct fast_reload_thread* fr) } void -fast_reload_thread_start(RES* ssl, struct worker* worker, struct rc_state* s) +fast_reload_thread_start(RES* ssl, struct worker* worker, struct rc_state* s, + int fr_verb) { if(worker->daemon->fast_reload_thread) { log_err("fast reload thread already running"); return; } - if(!fast_reload_thread_setup(worker)) { + if(!fast_reload_thread_setup(worker, fr_verb)) { if(!ssl_printf(ssl, "error could not setup thread\n")) return; return; diff --git a/daemon/remote.h b/daemon/remote.h index 3121f696a..d508385ba 100644 --- a/daemon/remote.h +++ b/daemon/remote.h @@ -187,6 +187,8 @@ struct fast_reload_thread { int started; /** if the thread has to quit */ int need_to_quit; + /** verbosity of the fast_reload command, the number of +v options */ + int fr_verb; /** the event that listens on the remote service worker to the * commpair, it receives content from the fast reload thread. */ @@ -309,9 +311,11 @@ int ssl_read_line(RES* ssl, char* buf, size_t max); * @param s: the rc_state that is servicing the remote control connection to * the remote control client. It needs to be moved away to stay connected * while the fast reload is running. + * @param fr_verb: verbosity to print output at. 0 is nothing, 1 is some + * and 2 is more detail. */ void fast_reload_thread_start(RES* ssl, struct worker* worker, - struct rc_state* s); + struct rc_state* s, int fr_verb); /** * Stop fast reload thread diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index 2fc72fe16..901636c11 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -60,7 +60,7 @@ Reload the server but try to keep the RRset and message cache if That means the caches sizes and the number of threads must not change between reloads. .TP -.B fast_reload +.B fast_reload \fR[\fI+v\fR] Reload the server, but keep downtime to a minimum, so that user queries keep seeing service. This needs the code compiled with threads. The config is loaded in a thread, and prepared, then it briefly pauses the existing @@ -68,6 +68,12 @@ server and updates config options. The intent is that the pause does not impact the service of user queries. The cache is kept. Also user queries worked on are kept and continue, but with the new config options. Not all options are changed, but it changes like forwards and stubs. +.IP +The '+v' option makes the output verbose. With '+vv' it is more verbose. +That includes the time it took to do the reload. And with more verbose output +the amount of memory that was allocated temporarily to perform the reload, +this amount of memory can be big if the config has large contents. In the +timing output the 'reload' time is the time during which the server was paused. .TP .B verbosity \fInumber Change verbosity value for logging. Same values as \fBverbosity\fR keyword in diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index 5e88e8083..ded85a175 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -109,7 +109,7 @@ usage(void) printf(" That means the caches sizes and\n"); printf(" the number of threads must not\n"); printf(" change between reloads.\n"); - printf(" fast_reload reloads the server but only briefly stops\n"); + printf(" fast_reload [+v] reloads the server but only briefly stops\n"); printf(" server processing, keeps cache, and only\n"); printf(" changes some options, like forwards\n"); printf(" and stubs.\n"); diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test index a71ca96ef..b1212c96b 100644 --- a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test @@ -47,7 +47,7 @@ mv ub.conf ub.conf.orig mv ub.conf2 ub.conf echo "" echo "> unbound-control fast_reload" -$PRE/unbound-control -c ub.conf fast_reload 2>&1 | tee output +$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output if test $? -ne 0; then echo "wrong exit value." exit 1 diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.test b/testdata/fast_reload_thread.tdir/fast_reload_thread.test index 135578fc1..d2ef25880 100644 --- a/testdata/fast_reload_thread.tdir/fast_reload_thread.test +++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.test @@ -28,14 +28,7 @@ wait_logfile unbound.log "start fast reload thread" 60 wait_logfile unbound.log "stop fast reload thread" 60 wait_logfile unbound.log "joined with fastreload thread" 60 -if grep "start fast_reload" output; then - echo "OK" -else - echo "output not correct" - exit 1 -fi - -if grep "thread started" output; then +if grep "ok" output; then echo "OK" else echo "output not correct" -- 2.47.2