]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
fixup remote control so most commands work in nonthreaded environment.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 3 Dec 2008 15:20:56 +0000 (15:20 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 3 Dec 2008 15:20:56 +0000 (15:20 +0000)
git-svn-id: file:///svn/unbound/trunk@1382 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/remote.c
daemon/remote.h
daemon/worker.c
daemon/worker.h
doc/Changelog
services/localzone.c
testcode/fake_event.c
testdata/remote-threaded.tpkg

index 59cca80135296e0fed7bf62893c413a01aa5b6ef..e889ca4ddbfe533c53300e31cc64d621bd1a30c3 100644 (file)
@@ -445,6 +445,8 @@ int
 ssl_print_text(SSL* ssl, const char* text)
 {
        int r;
+       if(!ssl) 
+               return 0;
        ERR_clear_error();
        if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) {
                if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
@@ -483,6 +485,8 @@ ssl_read_line(SSL* ssl, char* buf, size_t max)
 {
        int r;
        size_t len = 0;
+       if(!ssl)
+               return 0;
        while(len < max) {
                ERR_clear_error();
                if((r=SSL_read(ssl, buf+len, 1)) <= 0) {
@@ -1182,45 +1186,96 @@ do_flush_name(SSL* ssl, struct worker* worker, char* arg)
        send_ok(ssl);
 }
 
+/** tell other processes to execute the command */
+void
+distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
+{
+       int i;
+       if(!cmd || !ssl) 
+               return;
+       /* skip i=0 which is me */
+       for(i=1; i<rc->worker->daemon->num; i++) {
+               worker_send_cmd(rc->worker->daemon->workers[i],
+                       worker_cmd_remote);
+               if(!tube_write_msg(rc->worker->daemon->workers[i]->cmd,
+                       (uint8_t*)cmd, strlen(cmd)+1, 0)) {
+                       ssl_printf(ssl, "error could not distribute cmd\n");
+                       return;
+               }
+       }
+}
+
 /** execute a remote control command */
 static void
-execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
+execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd, 
+       struct worker* worker)
 {
        char* p = skipwhite(cmd);
        /* compare command - check longer strings first in case of substrings*/
        if(strncmp(p, "stop", 4) == 0) {
                do_stop(ssl, rc);
+               return;
        } else if(strncmp(p, "reload", 6) == 0) {
                do_reload(ssl, rc);
-       } else if(strncmp(p, "verbosity", 9) == 0) {
-               do_verbosity(ssl, skipwhite(p+9));
+               return;
        } else if(strncmp(p, "stats", 5) == 0) {
                do_stats(ssl, rc);
+               return;
+       } else if(strncmp(p, "dump_cache", 10) == 0) {
+               (void)dump_cache(ssl, worker);
+               return;
+       } else if(strncmp(p, "load_cache", 10) == 0) {
+               if(load_cache(ssl, worker)) send_ok(ssl);
+               return;
+       } else if(strncmp(p, "lookup", 6) == 0) {
+               do_lookup(ssl, worker, skipwhite(p+6));
+               return;
+       }
+
+#ifdef THREADS_DISABLED
+       /* other processes must execute the command as well */
+       /* commands that should not be distributed, returned above. */
+       if(rc) { /* only if this thread is the master (rc) thread */
+               /* done before the code below, which may split the string */
+               distribute_cmd(rc, ssl, cmd);
+       }
+#endif
+       if(strncmp(p, "verbosity", 9) == 0) {
+               do_verbosity(ssl, skipwhite(p+9));
        } else if(strncmp(p, "local_zone_remove", 17) == 0) {
-               do_zone_remove(ssl, rc->worker, skipwhite(p+17));
+               do_zone_remove(ssl, worker, skipwhite(p+17));
        } else if(strncmp(p, "local_zone", 10) == 0) {
-               do_zone_add(ssl, rc->worker, skipwhite(p+10));
+               do_zone_add(ssl, worker, skipwhite(p+10));
        } else if(strncmp(p, "local_data_remove", 17) == 0) {
-               do_data_remove(ssl, rc->worker, skipwhite(p+17));
+               do_data_remove(ssl, worker, skipwhite(p+17));
        } else if(strncmp(p, "local_data", 10) == 0) {
-               do_data_add(ssl, rc->worker, skipwhite(p+10));
-       } else if(strncmp(p, "dump_cache", 10) == 0) {
-               (void)dump_cache(ssl, rc->worker);
-       } else if(strncmp(p, "load_cache", 10) == 0) {
-               if(load_cache(ssl, rc->worker)) send_ok(ssl);
-       } else if(strncmp(p, "lookup", 6) == 0) {
-               do_lookup(ssl, rc->worker, skipwhite(p+6));
+               do_data_add(ssl, worker, skipwhite(p+10));
        } else if(strncmp(p, "flush_zone", 10) == 0) {
-               do_flush_zone(ssl, rc->worker, skipwhite(p+10));
+               do_flush_zone(ssl, worker, skipwhite(p+10));
        } else if(strncmp(p, "flush_type", 10) == 0) {
-               do_flush_type(ssl, rc->worker, skipwhite(p+10));
+               do_flush_type(ssl, worker, skipwhite(p+10));
        } else if(strncmp(p, "flush", 5) == 0) {
-               do_flush_name(ssl, rc->worker, skipwhite(p+5));
+               do_flush_name(ssl, worker, skipwhite(p+5));
        } else {
                (void)ssl_printf(ssl, "error unknown command '%s'\n", p);
        }
 }
 
+void 
+daemon_remote_exec(struct worker* worker)
+{
+       /* read the cmd string */
+       uint8_t* msg = NULL;
+       size_t len = 0;
+       if(!tube_read_msg(worker->cmd, &msg, &len, 0)) {
+               log_err("daemon_remote_exec: tube_read_msg failed");
+               return;
+       }
+       verbose(VERB_ALGO, "remote exec distributed: %s", (char*)msg);
+       execute_cmd(NULL, NULL, (char*)msg, worker);
+       free(msg);
+}
+
 /** handle remote control request */
 static void
 handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
@@ -1256,7 +1311,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
        verbose(VERB_DETAIL, "control cmd: %s", buf);
 
        /* figure out what to do */
-       execute_cmd(rc, ssl, buf);
+       execute_cmd(rc, ssl, buf, rc->worker);
 }
 
 int remote_control_callback(struct comm_point* c, void* arg, int err, 
index ea30c803e8027d1e56170bcc4e3f4cb009b7bb2b..f47a9c62d86d77ea419e7868fa7c88766c13aab2 100644 (file)
@@ -124,6 +124,12 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg);
 int daemon_remote_open_accept(struct daemon_remote* rc, 
        struct listen_port* ports);
 
+/**
+ * Handle nonthreaded remote cmd execution.
+ * @param worker: this worker (the remote worker).
+ */
+void daemon_remote_exec(struct worker* worker);
+
 /** handle remote control accept callbacks */
 int remote_accept_callback(struct comm_point*, void*, int, struct comm_reply*);
 
index 856b0be9ac0990efb9e5d817ba02e882c4998252..911ad193e7c8453c9570e50055d32aad4e01c73f 100644 (file)
@@ -344,6 +344,12 @@ worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
                verbose(VERB_ALGO, "got control cmd stats");
                server_stats_reply(worker);
                break;
+#ifdef THREADS_DISABLED
+       case worker_cmd_remote:
+               verbose(VERB_ALGO, "got control cmd remote");
+               daemon_remote_exec(worker);
+               break;
+#endif
        default:
                log_err("bad command %d", (int)cmd);
                break;
index fd83b61c6db06bc6e0421dfa65312138c9096b92..84b43980bcb9750e5d7831cc79fa31dff181bf63 100644 (file)
@@ -66,7 +66,9 @@ enum worker_commands {
        /** make the worker quit */
        worker_cmd_quit,
        /** obtain statistics */
-       worker_cmd_stats
+       worker_cmd_stats,
+       /** execute remote control command */
+       worker_cmd_remote
 };
 
 /**
index 1be7e7132c324cb1dc241b3f7068c7b5a156c3b8..fb882bb47c9c3cacf7058bab4ad467772436b816 100644 (file)
@@ -4,6 +4,10 @@
          was using multiple processes.
        - iana portlist updated.
        - test for remote control with interprocess communication.
+       - created command distribution mechanism so that remote control
+         commands other than 'stats' work on all processes in a nonthreaded
+         compiled version. dump/load cache work, on the first process.
+       - fixup remote control local_data addition memory corruption bug.
 
 1 December 2008: Wouter
        - SElinux policy files in contrib/selinux for the unbound daemon,
index d0c7af8309945b2127139445ade57bc2c90f1c0e..354db66dfe9ca0be5099156ca2b3bb7098d7add9 100644 (file)
@@ -1233,10 +1233,11 @@ local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf)
                        lock_quick_unlock(&zones->lock);
                        return 0;
                }
+       } else {
+               free(rr_name);
        }
        lock_rw_wrlock(&z->lock);
        lock_quick_unlock(&zones->lock);
-       free(rr_name);
        r = lz_enter_rr_into_zone(z, buf, rr);
        lock_rw_unlock(&z->lock);
        return r;
index 3cc522ae02cad45600376065fb65b91f96b7a879..47a9a271d391c6c95ca2f1f8416658f6abbf4d7e 100644 (file)
@@ -57,6 +57,7 @@
 #include "testcode/ldns-testpkts.h"
 #include "util/log.h"
 #include <signal.h>
+struct worker;
 
 /** Global variable: the scenario. Saved here for when event_init is done. */
 static struct replay_scenario* saved_scenario = NULL;
@@ -1160,4 +1161,8 @@ struct event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b))
        return NULL;
 }
 
+void daemon_remote_exec(struct worker* ATTR_UNUSED(worker))
+{
+}
+
 /*********** End of Dummy routines ***********/
index 17947ce85d967303660b43384e49ae57821e54cc..8ff01f22057fa7027e795f85d0dd9756dbedbbb9 100644 (file)
Binary files a/testdata/remote-threaded.tpkg and b/testdata/remote-threaded.tpkg differ