mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
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:
parent
bcf49eaf96
commit
4ac7881829
@ -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,
|
||||
|
@ -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*);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 ***********/
|
||||
|
BIN
testdata/remote-threaded.tpkg
vendored
BIN
testdata/remote-threaded.tpkg
vendored
Binary file not shown.
Loading…
Reference in New Issue
Block a user