mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-02 11:49:28 -05:00
Signal solution
git-svn-id: file:///svn/unbound/trunk@152 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
78d01c6f48
commit
0e3a023540
7 changed files with 78 additions and 8 deletions
|
|
@ -48,11 +48,61 @@
|
|||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
|
||||
/* @@@ TODO remove */
|
||||
#include "pthread.h"
|
||||
#include <signal.h>
|
||||
|
||||
/** How many quit requests happened. */
|
||||
static int sig_record_quit = 0;
|
||||
/** How many reload requests happened. */
|
||||
static int sig_record_reload = 0;
|
||||
|
||||
/** used when no other sighandling happens, so we don't die
|
||||
* when multiple signals in quick succession are sent to us. */
|
||||
static RETSIGTYPE record_sigh(int sig)
|
||||
{
|
||||
switch(sig)
|
||||
{
|
||||
case SIGTERM:
|
||||
case SIGQUIT:
|
||||
case SIGINT:
|
||||
sig_record_quit++;
|
||||
break;
|
||||
case SIGHUP:
|
||||
sig_record_reload++;
|
||||
break;
|
||||
default:
|
||||
log_err("ignoring signal %d", sig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal handling during the time when netevent is disabled.
|
||||
* Stores signals to replay later.
|
||||
*/
|
||||
static void
|
||||
signal_handling_record()
|
||||
{
|
||||
if( signal(SIGTERM, record_sigh) == SIG_ERR ||
|
||||
signal(SIGQUIT, record_sigh) == SIG_ERR ||
|
||||
signal(SIGINT, record_sigh) == SIG_ERR ||
|
||||
signal(SIGHUP, record_sigh) == SIG_ERR)
|
||||
log_err("install sighandler: %s", strerror(errno));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replay old signals.
|
||||
* @param wrk: worker that handles signals.
|
||||
*/
|
||||
static void
|
||||
signal_handling_playback(struct worker* wrk)
|
||||
{
|
||||
if(sig_record_quit)
|
||||
worker_sighandler(SIGTERM, wrk);
|
||||
if(sig_record_reload)
|
||||
worker_sighandler(SIGHUP, wrk);
|
||||
sig_record_quit = 0;
|
||||
sig_record_reload = 0;
|
||||
}
|
||||
|
||||
struct daemon*
|
||||
daemon_init()
|
||||
{
|
||||
|
|
@ -60,6 +110,7 @@ daemon_init()
|
|||
sizeof(struct daemon));
|
||||
if(!daemon)
|
||||
return NULL;
|
||||
signal_handling_record();
|
||||
lock_basic_init(&daemon->lock);
|
||||
daemon->need_to_exit = 0;
|
||||
return daemon;
|
||||
|
|
@ -212,7 +263,7 @@ daemon_fork(struct daemon* daemon)
|
|||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports,
|
||||
BUFSZ, 1))
|
||||
fatal_exit("Could not initialize main thread");
|
||||
/* see if other threads have started correctly? */
|
||||
signal_handling_playback(daemon->workers[0]);
|
||||
|
||||
/* Start resolver service on main thread. */
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
|
|
@ -231,6 +282,9 @@ daemon_cleanup(struct daemon* daemon)
|
|||
{
|
||||
int i;
|
||||
log_assert(daemon);
|
||||
/* before stopping main worker, handle signals ourselves, so we
|
||||
don't die on multiple reload signals for example. */
|
||||
signal_handling_record();
|
||||
for(i=0; i<daemon->num; i++)
|
||||
worker_delete(daemon->workers[i]);
|
||||
free(daemon->workers);
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@ void daemon_fork(struct daemon* daemon);
|
|||
void daemon_cleanup(struct daemon* daemon);
|
||||
|
||||
/**
|
||||
* Delete worker.
|
||||
* Delete workers, close listening ports.
|
||||
* @param daemon: the daemon.
|
||||
*/
|
||||
void daemon_delete(struct daemon* daemon);
|
||||
|
||||
|
|
|
|||
|
|
@ -376,15 +376,18 @@ worker_delete(struct worker* worker)
|
|||
{
|
||||
if(!worker)
|
||||
return;
|
||||
close(worker->cmd_send_fd);
|
||||
if(worker->cmd_send_fd != -1)
|
||||
close(worker->cmd_send_fd);
|
||||
worker->cmd_send_fd = -1;
|
||||
close(worker->cmd_recv_fd);
|
||||
if(worker->cmd_recv_fd != -1)
|
||||
close(worker->cmd_recv_fd);
|
||||
worker->cmd_recv_fd = -1;
|
||||
listen_delete(worker->front);
|
||||
outside_network_delete(worker->back);
|
||||
comm_signal_delete(worker->comsig);
|
||||
comm_point_delete(worker->cmd_com);
|
||||
comm_base_delete(worker->base);
|
||||
ub_randfree(worker->rndstate);
|
||||
free(worker->rndstate);
|
||||
free(worker);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,4 +157,11 @@ int worker_set_fwd(struct worker* worker, const char* ip, int port);
|
|||
void worker_send_cmd(struct worker* worker, ldns_buffer* buffer,
|
||||
enum worker_commands cmd);
|
||||
|
||||
/**
|
||||
* Worker signal handler function. User argument is the worker itself.
|
||||
* @param sig: signal number.
|
||||
* @param arg: the worker (main worker) that handles signals.
|
||||
*/
|
||||
void worker_sighandler(int sig, void* arg);
|
||||
|
||||
#endif /* DAEMON_WORKER_H */
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
- forking is used if no threading is available.
|
||||
Tested, it works, since pipes work across processes as well.
|
||||
Thread_join is replaced with waitpid.
|
||||
- During reloads the daemon will temporarily handle signals,
|
||||
so that they do not result in problems.
|
||||
|
||||
26 February 2007: Wouter
|
||||
- ub_random code used to select ID and port.
|
||||
|
|
|
|||
|
|
@ -507,7 +507,8 @@ static void comm_point_local_handle_callback(int fd, short event, void* arg)
|
|||
|
||||
if(event&EV_READ) {
|
||||
if(!comm_point_tcp_handle_read(fd, c, 1)) {
|
||||
log_err("error in localhdl");
|
||||
(void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED,
|
||||
NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,5 +357,7 @@ ub_random (struct ub_randstate* s)
|
|||
|
||||
void ub_randfree(struct ub_randstate* state)
|
||||
{
|
||||
if(!state)
|
||||
return;
|
||||
free(state->state);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue