]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- fast-reload, option for fast-reload commandline, +p does not pause threads.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 21 Mar 2024 14:06:38 +0000 (15:06 +0100)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 21 Mar 2024 14:06:38 +0000 (15:06 +0100)
daemon/remote.c
daemon/remote.h
doc/unbound-control.8.in
smallapp/unbound-control.c

index ecd30af27fe66955a395d7af5ee7b4698e1dc696..5ee3d4d32d9c1eae8945bb836e83696d22eaaf9d 100644 (file)
@@ -674,6 +674,39 @@ do_reload(RES* ssl, struct worker* worker, int reuse_cache)
        send_ok(ssl);
 }
 
+#ifndef THREADS_DISABLED
+/** parse fast reload command options. */
+static int
+fr_parse_options(RES* ssl, char* arg, int* fr_verb, int* fr_nopause)
+{
+       char* argp = arg;
+       while(*argp=='+') {
+               argp++;
+               while(*argp!=0 && *argp!=' ' && *argp!='\t') {
+                       if(*argp == 'v') {
+                               (*fr_verb)++;
+                       } else if(*argp == 'p') {
+                               (*fr_nopause) = 1;
+                       } else {
+                               if(!ssl_printf(ssl,
+                                       "error: unknown option '+%c'\n",
+                                       *argp))
+                                       return 0;
+                               return 0;
+                       }
+                       argp++;
+               }
+               argp = skipwhite(argp);
+       }
+       if(*argp!=0) {
+               if(!ssl_printf(ssl, "error: unknown option '%s'\n", argp))
+                       return 0;
+               return 0;
+       }
+       return 1;
+}
+#endif /* !THREADS_DISABLED */
+
 /** do the fast_reload command */
 static void
 do_fast_reload(RES* ssl, struct worker* worker, struct rc_state* s, char* arg)
@@ -685,27 +718,14 @@ do_fast_reload(RES* ssl, struct worker* worker, struct rc_state* s, char* arg)
        (void)s;
        (void)arg;
 #else
-       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++;
-               }
-       }
+       int fr_verb = 0, fr_nopause = 0;
+       if(!fr_parse_options(ssl, arg, &fr_verb, &fr_nopause))
+               return;
        if(fr_verb >= 1) {
                if(!ssl_printf(ssl, "start fast_reload\n"))
                        return;
        }
-       fast_reload_thread_start(ssl, worker, s, fr_verb);
+       fast_reload_thread_start(ssl, worker, s, fr_verb, fr_nopause);
 #endif
 }
 
@@ -4244,12 +4264,16 @@ fr_reload_ipc(struct fast_reload_thread* fr, struct config_file* newcfg,
        struct fast_reload_construct* ct)
 {
        int result = 1;
-       fr_send_notification(fr, fast_reload_notification_reload_stop);
-       fr_poll_for_ack(fr);
+       if(!fr->fr_nopause) {
+               fr_send_notification(fr, fast_reload_notification_reload_stop);
+               fr_poll_for_ack(fr);
+       }
        if(!fr_reload_config(fr, newcfg, ct)) {
                result = 0;
        }
-       fr_send_notification(fr, fast_reload_notification_reload_start);
+       if(!fr->fr_nopause) {
+               fr_send_notification(fr, fast_reload_notification_reload_start);
+       }
        return result;
 }
 
@@ -4653,7 +4677,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, int fr_verb)
+fast_reload_thread_setup(struct worker* worker, int fr_verb, int fr_nopause)
 {
        struct fast_reload_thread* fr;
        int numworkers = worker->daemon->num;
@@ -4663,6 +4687,7 @@ fast_reload_thread_setup(struct worker* worker, int fr_verb)
                return 0;
        fr = worker->daemon->fast_reload_thread;
        fr->fr_verb = fr_verb;
+       fr->fr_nopause = fr_nopause;
        /* The thread id printed in logs, numworker+1 is the dnstap thread.
         * This is numworkers+2. */
        fr->threadnum = numworkers+2;
@@ -5407,13 +5432,13 @@ fr_send_stop(struct fast_reload_thread* fr)
 
 void
 fast_reload_thread_start(RES* ssl, struct worker* worker, struct rc_state* s,
-       int fr_verb)
+       int fr_verb, int fr_nopause)
 {
        if(worker->daemon->fast_reload_thread) {
                log_err("fast reload thread already running");
                return;
        }
-       if(!fast_reload_thread_setup(worker, fr_verb)) {
+       if(!fast_reload_thread_setup(worker, fr_verb, fr_nopause)) {
                if(!ssl_printf(ssl, "error could not setup thread\n"))
                        return;
                return;
index d508385bad1db53dd33bc8108f82e4a0de077265..0c7209e510d8a559ba258d28c7b873e446c71466 100644 (file)
@@ -189,6 +189,8 @@ struct fast_reload_thread {
        int need_to_quit;
        /** verbosity of the fast_reload command, the number of +v options */
        int fr_verb;
+       /** option to not pause threads during reload */
+       int fr_nopause;
 
        /** the event that listens on the remote service worker to the
         * commpair, it receives content from the fast reload thread. */
@@ -313,9 +315,10 @@ int ssl_read_line(RES* ssl, char* buf, size_t max);
  *     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.
+ * @param fr_nopause: option to not pause threads during reload.
  */
 void fast_reload_thread_start(RES* ssl, struct worker* worker,
-       struct rc_state* s, int fr_verb);
+       struct rc_state* s, int fr_verb, int fr_nopause);
 
 /**
  * Stop fast reload thread
index 901636c11e0fac49a1725da7f2a436fad643c5ac..c2df9e182d47773742f6c75ebb978fd4c8b9e503 100644 (file)
@@ -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 \fR[\fI+v\fR]
+.B fast_reload \fR[\fI+vp\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
@@ -74,6 +74,17 @@ 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.
+.IP
+The '+p' option makes the reload not pause threads, they keep running.
+Locks are acquired, but items are updated in sequence, so it is possible
+for threads to see an inconsistent state with some options from the old
+and some options from the new config, such as cache TTL parameters from the
+old config and forwards from the new config. The stubs and forwards are
+updated at the same time, so that they are viewed consistently, either old
+or new values together. The option makes the reload time take eg. 3
+microseconds instead of 0.3 milliseconds during which the worker threads are
+interrupted. So, the interruption is much shorter, at the expense of some
+inconsistency.
 .TP
 .B verbosity \fInumber
 Change verbosity value for logging. Same values as \fBverbosity\fR keyword in
index ded85a175f01b1f220f34e568c018420d9dff467..e7f5797978a0ca4449d0c84def3f83d4b7afcf78 100644 (file)
@@ -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 [+v             reloads the server but only briefly stops\n");
+       printf("  fast_reload [+vp]             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");