fixup remote control so most commands work in nonthreaded environment.

git-svn-id: file:///svn/unbound/trunk@1382 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-12-03 15:20:56 +00:00
parent bcf49eaf96
commit 4ac7881829
8 changed files with 99 additions and 20 deletions

View 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);
} else if(strncmp(p, "local_zone_remove", 17) == 0) {
do_zone_remove(ssl, rc->worker, skipwhite(p+17));
} else if(strncmp(p, "local_zone", 10) == 0) {
do_zone_add(ssl, rc->worker, skipwhite(p+10));
} else if(strncmp(p, "local_data_remove", 17) == 0) {
do_data_remove(ssl, rc->worker, skipwhite(p+17));
} else if(strncmp(p, "local_data", 10) == 0) {
do_data_add(ssl, rc->worker, skipwhite(p+10));
return;
} else if(strncmp(p, "dump_cache", 10) == 0) {
(void)dump_cache(ssl, rc->worker);
(void)dump_cache(ssl, worker);
return;
} else if(strncmp(p, "load_cache", 10) == 0) {
if(load_cache(ssl, rc->worker)) send_ok(ssl);
if(load_cache(ssl, worker)) send_ok(ssl);
return;
} else if(strncmp(p, "lookup", 6) == 0) {
do_lookup(ssl, rc->worker, skipwhite(p+6));
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, worker, skipwhite(p+17));
} else if(strncmp(p, "local_zone", 10) == 0) {
do_zone_add(ssl, worker, skipwhite(p+10));
} else if(strncmp(p, "local_data_remove", 17) == 0) {
do_data_remove(ssl, worker, skipwhite(p+17));
} else if(strncmp(p, "local_data", 10) == 0) {
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,

View 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*);

View 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;

View 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
};
/**

View 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,

View 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;

View 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 ***********/

Binary file not shown.