diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index c5ca5ade25..f9e736f2db 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: controlconf.c,v 1.5 2001/05/07 21:57:25 gson Exp $ */ +/* $Id: controlconf.c,v 1.6 2001/05/08 03:42:27 gson Exp $ */ #include @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -79,6 +78,7 @@ struct controlconnection { }; struct controllistener { + ns_controls_t * controls; isc_mem_t * mctx; isc_task_t * task; isc_sockaddr_t address; @@ -91,18 +91,14 @@ struct controllistener { ISC_LINK(controllistener_t) link; }; -static controllistenerlist_t listeners; -static isc_mutex_t listeners_lock; -static isc_once_t once = ISC_ONCE_INIT; +struct ns_controls { + ns_server_t *server; + controllistenerlist_t listeners; +}; static void control_newconn(isc_task_t *task, isc_event_t *event); static void control_recvmessage(isc_task_t *task, isc_event_t *event); -static void -initialize_mutex(void) { - RUNTIME_CHECK(isc_mutex_init(&listeners_lock) == ISC_R_SUCCESS); -} - static void free_controlkey(controlkey_t *key, isc_mem_t *mctx) { if (key->keyname != NULL) @@ -494,22 +490,11 @@ control_newconn(isc_task_t *task, isc_event_t *event) { } void -ns_control_shutdown(isc_boolean_t exiting) { +ns_controls_shutdown(ns_controls_t *controls) { controllistener_t *listener; controllistener_t *next; - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - if (exiting) { - /* - * When not exiting, this function is called from - * ns_control_configure(), which already holds the lock. - */ - LOCK(&listeners_lock); - } - - - for (listener = ISC_LIST_HEAD(listeners); + for (listener = ISC_LIST_HEAD(controls->listeners); listener != NULL; listener = next) { @@ -518,12 +503,9 @@ ns_control_shutdown(isc_boolean_t exiting) { * call their callbacks. */ next = ISC_LIST_NEXT(listener, link); - ISC_LIST_UNLINK(listeners, listener, link); + ISC_LIST_UNLINK(controls->listeners, listener, link); shutdown_listener(listener); } - - if (exiting) - UNLOCK(&listeners_lock); } static isc_result_t @@ -670,7 +652,8 @@ register_keys(cfg_obj_t *control, cfg_obj_t *keylist, } static void -update_listener(controllistener_t **listenerp, cfg_obj_t *control, +update_listener(ns_controls_t *cp, + controllistener_t **listenerp, cfg_obj_t *control, cfg_obj_t *config, isc_sockaddr_t *addr, ns_aclconfctx_t *aclconfctx, char *socktext) { @@ -681,7 +664,7 @@ update_listener(controllistener_t **listenerp, cfg_obj_t *control, controlkeylist_t keys; isc_result_t result; - for (listener = ISC_LIST_HEAD(listeners); + for (listener = ISC_LIST_HEAD(cp->listeners); listener != NULL; listener = ISC_LIST_NEXT(listener, link)) if (isc_sockaddr_equal(addr, &listener->address)) @@ -729,10 +712,11 @@ update_listener(controllistener_t **listenerp, cfg_obj_t *control, } static void -add_listener(isc_mem_t *mctx, controllistener_t **listenerp, +add_listener(ns_controls_t *cp, controllistener_t **listenerp, cfg_obj_t *control, cfg_obj_t *config, isc_sockaddr_t *addr, ns_aclconfctx_t *aclconfctx, char *socktext) { + isc_mem_t *mctx = cp->server->mctx; controllistener_t *listener; cfg_obj_t *allow; cfg_obj_t *keys; @@ -744,8 +728,9 @@ add_listener(isc_mem_t *mctx, controllistener_t **listenerp, result = ISC_R_NOMEMORY; if (result == ISC_R_SUCCESS) { + listener->controls = cp; listener->mctx = mctx; - listener->task = ns_g_server->task; + listener->task = cp->server->task; listener->address = *addr; listener->sock = NULL; listener->listening = ISC_FALSE; @@ -823,8 +808,9 @@ add_listener(isc_mem_t *mctx, controllistener_t **listenerp, } isc_result_t -ns_control_configure(isc_mem_t *mctx, cfg_obj_t *config, - ns_aclconfctx_t *aclconfctx) +ns_controls_configure(ns_controls_t *cp, + cfg_obj_t *config, + ns_aclconfctx_t *aclconfctx) { controllistener_t *listener; controllistenerlist_t new_listeners; @@ -833,8 +819,6 @@ ns_control_configure(isc_mem_t *mctx, cfg_obj_t *config, cfg_listelt_t *element, *element2; char socktext[ISC_SOCKADDR_FORMATSIZE]; - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - ISC_LIST_INIT(new_listeners); /* @@ -842,7 +826,6 @@ ns_control_configure(isc_mem_t *mctx, cfg_obj_t *config, */ (void)cfg_map_get(config, "controls", &controlslist); - LOCK(&listeners_lock); /* * Run through the new control channel list, noting sockets that * are already being listened on and moving them to the new list. @@ -930,7 +913,7 @@ ns_control_configure(isc_mem_t *mctx, cfg_obj_t *config, "processing control channel %s", socktext); - update_listener(&listener, control, config, + update_listener(cp, &listener, control, config, addr, aclconfctx, socktext); if (listener != NULL) @@ -938,13 +921,14 @@ ns_control_configure(isc_mem_t *mctx, cfg_obj_t *config, * Remove the listener from the old * list, so it won't be shut down. */ - ISC_LIST_UNLINK(listeners, listener, + ISC_LIST_UNLINK(cp->listeners, listener, link); else /* * This is a new listener. */ - add_listener(mctx, &listener, control, + add_listener(cp, &listener, + control, config, addr, aclconfctx, socktext); @@ -967,16 +951,36 @@ ns_control_configure(isc_mem_t *mctx, cfg_obj_t *config, * configuration (if any) that do not remain in the current * configuration. */ - ns_control_shutdown(ISC_FALSE); + ns_controls_shutdown(cp); /* * Put all of the valid listeners on the listeners list. * Anything already on listeners in the process of shutting down * will be taken care of by listen_done(). */ - ISC_LIST_APPENDLIST(listeners, new_listeners, link); - - UNLOCK(&listeners_lock); + ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link); return (ISC_R_SUCCESS); } + +isc_result_t +ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) { + isc_mem_t *mctx = server->mctx; + ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls)); + if (controls == NULL) + return (ISC_R_NOMEMORY); + controls->server = server; + ISC_LIST_INIT(controls->listeners); + *ctrlsp = controls; + return (ISC_R_SUCCESS); +} + +void +ns_controls_destroy(ns_controls_t **ctrlsp) { + ns_controls_t *controls = *ctrlsp; + + REQUIRE(ISC_LIST_EMPTY(controls->listeners)); + + isc_mem_put(controls->server->mctx, controls, sizeof(*controls)); + *ctrlsp = NULL; +} diff --git a/bin/named/include/named/control.h b/bin/named/include/named/control.h index 291c4e18d3..bd68d10929 100644 --- a/bin/named/include/named/control.h +++ b/bin/named/include/named/control.h @@ -15,14 +15,19 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: control.h,v 1.4 2001/05/07 23:34:01 gson Exp $ */ +/* $Id: control.h,v 1.5 2001/05/08 03:42:31 gson Exp $ */ #ifndef NAMED_CONTROL_H #define NAMED_CONTROL_H 1 +/* + * The name server command channel. + */ + #include #include +#include #define NS_CONTROL_PORT 953 @@ -39,14 +44,35 @@ #define NS_COMMAND_FLUSH "flush" isc_result_t -ns_control_init(void); - -isc_result_t -ns_control_configure(isc_mem_t *mctx, cfg_obj_t *config, - ns_aclconfctx_t *aclconfctx); +ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp); +/* + * Create an initial, empty set of command channels for 'server'. + */ void -ns_control_shutdown(isc_boolean_t exiting); +ns_controls_destroy(ns_controls_t **ctrlsp); +/* + * Destroy a set of command channels. + * + * Requires: + * Shutdown of the channels has completed. + */ + +isc_result_t +ns_controls_configure(ns_controls_t *controls, cfg_obj_t *config, + ns_aclconfctx_t *aclconfctx); +/* + * Configure zero or more command channels into 'controls' + * as defined in the configuration parse tree 'config'. + * The channels will evaluate ACLs in the context of + * 'aclconfctx'. + */ + +void +ns_controls_shutdown(ns_controls_t *controls); +/* + * Initiate shutdown of all the command channels in 'controls'. + */ isc_result_t ns_control_docommand(isccc_sexpr_t *message); diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 7c2ad5ff42..9a1e935371 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.h,v 1.54 2001/05/07 23:34:02 gson Exp $ */ +/* $Id: server.h,v 1.55 2001/05/08 03:42:33 gson Exp $ */ #ifndef NAMED_SERVER_H #define NAMED_SERVER_H 1 @@ -77,6 +77,8 @@ struct ns_server { isc_uint64_t * querystats; /* Query statistics counters */ char * dumpfile; /* Dump file name */ + + ns_controls_t * controls; /* Control channels */ }; #define NS_SERVER_MAGIC 0x53564552 /* SVER */ diff --git a/bin/named/include/named/types.h b/bin/named/include/named/types.h index de6d65ab4a..6b8158beb7 100644 --- a/bin/named/include/named/types.h +++ b/bin/named/include/named/types.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.18 2001/01/09 21:40:32 bwelling Exp $ */ +/* $Id: types.h,v 1.19 2001/05/08 03:42:34 gson Exp $ */ #ifndef NAMED_TYPES_H #define NAMED_TYPES_H 1 @@ -34,5 +34,6 @@ typedef struct ns_lwdclient ns_lwdclient_t; typedef struct ns_lwdclientmgr ns_lwdclientmgr_t; typedef struct ns_lwsearchlist ns_lwsearchlist_t; typedef struct ns_lwsearchctx ns_lwsearchctx_t; +typedef struct ns_controls ns_controls_t; #endif /* NAMED_TYPES_H */ diff --git a/bin/named/main.c b/bin/named/main.c index 42179b3f84..652c9f52bf 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: main.c,v 1.107 2001/03/29 04:23:51 gson Exp $ */ +/* $Id: main.c,v 1.108 2001/05/08 03:42:28 gson Exp $ */ #include @@ -419,13 +419,6 @@ create_managers(void) { static void destroy_managers(void) { - if (!ns_g_lwresdonly) - /* - * The command channel listeners need to be stopped here so - * that isc_taskmgr_destroy() won't block on the server task. - */ - ns_control_shutdown(ISC_TRUE); - ns_lwresd_shutdown(); isc_entropy_detach(&ns_g_entropy); diff --git a/bin/named/server.c b/bin/named/server.c index 32131afcac..819640a91c 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.320 2001/05/08 00:26:24 gson Exp $ */ +/* $Id: server.c,v 1.321 2001/05/08 03:42:30 gson Exp $ */ #include @@ -1863,7 +1863,8 @@ load_configuration(const char *filename, ns_server_t *server, /* * Bind the control port(s). */ - CHECKM(ns_control_configure(ns_g_mctx, config, &aclconfctx), + CHECKM(ns_controls_configure(ns_g_server->controls, config, + &aclconfctx), "binding control channel(s)"); /* @@ -2160,6 +2161,8 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { ISC_LOG_INFO, "shutting down%s", flush ? ": flushing changes" : ""); + ns_controls_shutdown(server->controls); + cfg_obj_destroy(ns_g_parser, &ns_g_config); cfg_parser_destroy(&ns_g_parser); @@ -2284,6 +2287,10 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { server->flushonshutdown = ISC_FALSE; server->log_queries = ISC_FALSE; + server->controls = NULL; + CHECKFATAL(ns_controls_create(server, &server->controls), + "ns_controls_create"); + server->magic = NS_SERVER_MAGIC; *serverp = server; } @@ -2293,6 +2300,8 @@ ns_server_destroy(ns_server_t **serverp) { ns_server_t *server = *serverp; REQUIRE(NS_SERVER_VALID(server)); + ns_controls_destroy(&server->controls); + dns_stats_freecounters(server->mctx, &server->querystats); isc_mem_free(server->mctx, server->statsfile);