diff options
author | Shawn Routhier <sar@isc.org> | 2013-10-30 13:52:36 -0700 |
---|---|---|
committer | Shawn Routhier <sar@isc.org> | 2013-10-30 13:52:36 -0700 |
commit | 47e8308dea6ee44ce19edf4fdf3331fa41a986f7 (patch) | |
tree | c2801fff3fff0639b504de72675ea62b0d1cab65 | |
parent | 58cb5d861d6f412475722381723dc788c314c39f (diff) | |
download | isc-dhcp-47e8308dea6ee44ce19edf4fdf3331fa41a986f7.tar.gz |
[master]
[32692] Signal handlers added: sigint (ctrl-c) and sigterm (default kill)
-rw-r--r-- | RELNOTES | 3 | ||||
-rw-r--r-- | client/dhclient.c | 6 | ||||
-rw-r--r-- | common/dispatch.c | 13 | ||||
-rw-r--r-- | includes/omapip/isclib.h | 4 | ||||
-rw-r--r-- | omapip/dispatch.c | 60 | ||||
-rw-r--r-- | omapip/isclib.c | 20 | ||||
-rw-r--r-- | relay/dhcrelay.c | 6 | ||||
-rw-r--r-- | server/dhcpd.c | 16 |
8 files changed, 110 insertions, 18 deletions
@@ -129,6 +129,9 @@ work on other platforms. Please report any problems and suggested fixes to for the bug report and a potential patch. [ISC-Bugs #34784] +- Added support for gentle shutdown after signal is received. + [ISC-BUGS #32692] + Changes since 4.2.4 - Correct code to calculate timing values in client to compare diff --git a/client/dhclient.c b/client/dhclient.c index c303f7e3..f131e393 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -691,6 +691,10 @@ main(int argc, char **argv) { dmalloc_outstanding = 0; #endif + /* install signal handlers */ + signal(SIGINT, dhcp_signal_handler); /* control-c */ + signal(SIGTERM, dhcp_signal_handler); /* kill */ + /* If we're not supposed to wait before getting the address, don't. */ if (nowait) @@ -704,7 +708,6 @@ main(int argc, char **argv) { /* Start dispatching packets and timeouts... */ dispatch(); - /*NOTREACHED*/ return 0; } @@ -807,7 +810,6 @@ void run_stateless(int exit_mode) /* Start dispatching packets and timeouts... */ dispatch(); - /*NOTREACHED*/ #endif /* DHCPv6 */ return; } diff --git a/common/dispatch.c b/common/dispatch.c index 7c4434e7..976d37e2 100644 --- a/common/dispatch.c +++ b/common/dispatch.c @@ -3,7 +3,7 @@ Network input dispatcher... */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2011,2013 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -112,8 +112,15 @@ dispatch(void) status = isc_app_ctxrun(dhcp_gbl_ctx.actx); - log_fatal ("Dispatch routine failed: %s -- exiting", - isc_result_totext (status)); + /* + * isc_app_ctxrun can be stopped by receiving a signal. It will + * return ISC_R_SUCCESS in that case. That is a normal behavior. + */ + + if (status != ISC_R_SUCCESS) { + log_fatal ("Dispatch routine failed: %s -- exiting", + isc_result_totext (status)); + } } void diff --git a/includes/omapip/isclib.h b/includes/omapip/isclib.h index ddefeb5f..7fd30fea 100644 --- a/includes/omapip/isclib.h +++ b/includes/omapip/isclib.h @@ -3,7 +3,7 @@ connections to the isc and dns libraries */ /* - * Copyright (c) 2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009,2013 by Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -119,4 +119,6 @@ isclib_make_dst_key(char *inname, isc_result_t dhcp_context_create(void); void isclib_cleanup(void); +void dhcp_signal_handler(int signal); + #endif /* ISCLIB_H */ diff --git a/omapip/dispatch.c b/omapip/dispatch.c index e6aae453..dcef3248 100644 --- a/omapip/dispatch.c +++ b/omapip/dispatch.c @@ -3,7 +3,7 @@ I/O dispatcher. */ /* - * Copyright (c) 2004,2007-2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004,2007-2009,2013 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -901,19 +901,65 @@ isc_result_t omapi_waiter_signal_handler (omapi_object_t *h, return ISC_R_NOTFOUND; } +/** @brief calls a given function on every object + * + * @param func function to be called + * @param p parameter to be passed to each function instance + * + * @return result (ISC_R_SUCCESS if successful, error code otherwise) + */ isc_result_t omapi_io_state_foreach (isc_result_t (*func) (omapi_object_t *, void *), void *p) { - omapi_io_object_t *io; + omapi_io_object_t *io = NULL; isc_result_t status; + omapi_io_object_t *next = NULL; - for (io = omapi_io_states.next; io; io = io -> next) { - if (io -> inner) { - status = (*func) (io -> inner, p); - if (status != ISC_R_SUCCESS) - return status; + /* + * This just calls func on every inner object on the list. It would + * be much simpler in general case, but one of the operations could be + * release of the objects. Therefore we need to ref count the io and + * io->next pointers. + */ + + if (omapi_io_states.next) { + omapi_object_reference((omapi_object_t**)&io, + (omapi_object_t*)omapi_io_states.next, + MDL); + } + + while(io) { + /* If there's a next object, save it */ + if (io->next) { + omapi_object_reference((omapi_object_t**)&next, + (omapi_object_t*)io->next, MDL); + } + if (io->inner) { + status = (*func) (io->inner, p); + if (status != ISC_R_SUCCESS) { + /* Something went wrong. Let's stop using io & next pointer + * and bail out */ + omapi_object_dereference((omapi_object_t**)&io, MDL); + if (next) { + omapi_object_dereference((omapi_object_t**)&next, MDL); + } + return status; } + } + /* Update the io pointer and free the next pointer */ + omapi_object_dereference((omapi_object_t**)&io, MDL); + if (next) { + omapi_object_reference((omapi_object_t**)&io, + (omapi_object_t*)next, + MDL); + omapi_object_dereference((omapi_object_t**)&next, MDL); + } } + + /* + * The only way to get here is when next is NULL. There's no need + * to dereference it. + */ return ISC_R_SUCCESS; } diff --git a/omapip/isclib.c b/omapip/isclib.c index 1534dde5..5dcb12c0 100644 --- a/omapip/isclib.c +++ b/omapip/isclib.c @@ -1,5 +1,5 @@ /* - * Copyright(c) 2009-2010 by Internet Systems Consortium, Inc.("ISC") + * Copyright(c) 2009-2010,2013 by Internet Systems Consortium, Inc.("ISC") * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -28,6 +28,7 @@ #include "dhcpd.h" #include <sys/time.h> +#include <signal.h> dhcp_context_t dhcp_gbl_ctx; @@ -217,3 +218,20 @@ isclib_make_dst_key(char *inname, &b, dhcp_gbl_ctx.mctx, dstkey)); } +/** + * signal handler that initiates server shutdown + * + * @param signal signal code that we received + */ +void dhcp_signal_handler(int signal) { + isc_appctx_t *ctx = dhcp_gbl_ctx.actx; + if (ctx && ctx->methods && ctx->methods->ctxshutdown) { + /* + * Let's not use standard log facilities here. They may not be + * signal safe, e.g. we could get the signal in the middle of + * another log call + */ + printf("Received signal %d, initiating shutdown.\n", signal); + ctx->methods->ctxshutdown(ctx); + } +} diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 06a36d24..a218dece 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -34,6 +34,7 @@ #include "dhcpd.h" #include <syslog.h> +#include <signal.h> #include <sys/time.h> TIME default_lease_time = 43200; /* 12 hours... */ @@ -577,10 +578,13 @@ main(int argc, char **argv) { dhcpv6_packet_handler = do_packet6; #endif + /* install signal handlers */ + signal(SIGINT, dhcp_signal_handler); /* control-c */ + signal(SIGTERM, dhcp_signal_handler); /* kill */ + /* Start dispatching packets and timeouts... */ dispatch(); - /* Not reached */ return (0); } diff --git a/server/dhcpd.c b/server/dhcpd.c index e052301b..29d4f527 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -42,11 +42,11 @@ static const char url [] = #include "dhcpd.h" #include <omapip/omapip_p.h> #include <syslog.h> +#include <signal.h> #include <errno.h> #include <limits.h> #include <sys/types.h> #include <sys/time.h> -#include <signal.h> #if defined (PARANOIA) # include <sys/types.h> @@ -780,10 +780,20 @@ main(int argc, char **argv) { omapi_set_int_value ((omapi_object_t *)dhcp_control_object, (omapi_object_t *)0, "state", server_running); - /* Receive packets and dispatch them... */ + /* install signal handlers */ + signal(SIGINT, dhcp_signal_handler); /* control-c */ + signal(SIGTERM, dhcp_signal_handler); /* kill */ + + /* + * Receive packets and dispatch them... + * dispatch() will return only when we are shutting down. + */ dispatch (); - /* Not reached */ + log_info("Shutting down."); + dhcp_set_control_state(server_shutdown/*ignored*/, server_shutdown); + + /* Let's return status code */ return 0; } #endif /* !UNIT_TEST */ |