diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c index 4814323f0b..165639d31b 100644 --- a/bin/check/named-checkzone.c +++ b/bin/check/named-checkzone.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/lib/isc/Makefile.am b/lib/isc/Makefile.am index d0822ff73b..5e4f7db42f 100644 --- a/lib/isc/Makefile.am +++ b/lib/isc/Makefile.am @@ -6,7 +6,6 @@ libisc_ladir = $(includedir)/isc libisc_la_HEADERS = \ include/isc/aes.h \ include/isc/align.h \ - include/isc/app.h \ include/isc/assertions.h \ include/isc/astack.h \ include/isc/async.h \ @@ -117,7 +116,6 @@ libisc_la_SOURCES = \ netmgr/tlsdns.c \ netmgr/udp.c \ aes.c \ - app.c \ assertions.c \ astack.c \ async.c \ diff --git a/lib/isc/app.c b/lib/isc/app.c deleted file mode 100644 index c60fd9a671..0000000000 --- a/lib/isc/app.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * SPDX-License-Identifier: MPL-2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*% - * For BIND9 applications built with threads, we use a single app - * context and let multiple taskmgr and netmgr threads do actual jobs. - */ - -static isc_thread_t blockedthread; -static atomic_bool is_running = 0; - -/* - * The application context of this module. - */ -#define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x') -#define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC) - -struct isc_appctx { - unsigned int magic; - isc_mem_t *mctx; - isc_mutex_t lock; - isc_eventlist_t on_run; - atomic_bool shutdown_requested; - atomic_bool running; - atomic_bool want_shutdown; - atomic_bool want_reload; - atomic_bool blocked; - isc_mutex_t readylock; - isc_condition_t ready; -}; - -static isc_appctx_t isc_g_appctx; - -static void -handle_signal(int sig, void (*handler)(int)) { - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = handler; - - if (sigfillset(&sa.sa_mask) != 0 || sigaction(sig, &sa, NULL) < 0) { - char strbuf[ISC_STRERRORSIZE]; - strerror_r(errno, strbuf, sizeof(strbuf)); - isc_error_fatal(__FILE__, __LINE__, - "handle_signal() %d setup: %s", sig, strbuf); - } -} - -isc_result_t -isc_app_ctxstart(isc_appctx_t *ctx) { - int presult; - sigset_t sset; - char strbuf[ISC_STRERRORSIZE]; - - REQUIRE(VALID_APPCTX(ctx)); - - /* - * Start an ISC library application. - */ - - isc_mutex_init(&ctx->lock); - - isc_mutex_init(&ctx->readylock); - isc_condition_init(&ctx->ready); - - ISC_LIST_INIT(ctx->on_run); - - atomic_init(&ctx->shutdown_requested, false); - atomic_init(&ctx->running, false); - atomic_init(&ctx->want_shutdown, false); - atomic_init(&ctx->want_reload, false); - atomic_init(&ctx->blocked, false); - - /* - * Always ignore SIGPIPE. - */ - handle_signal(SIGPIPE, SIG_IGN); - - handle_signal(SIGHUP, SIG_DFL); - handle_signal(SIGTERM, SIG_DFL); - handle_signal(SIGINT, SIG_DFL); - - /* - * Block SIGHUP, SIGINT, SIGTERM. - * - * If isc_app_start() is called from the main thread before any other - * threads have been created, then the pthread_sigmask() call below - * will result in all threads having SIGHUP, SIGINT and SIGTERM - * blocked by default, ensuring that only the thread that calls - * sigwait() for them will get those signals. - */ - if (sigemptyset(&sset) != 0 || sigaddset(&sset, SIGHUP) != 0 || - sigaddset(&sset, SIGINT) != 0 || sigaddset(&sset, SIGTERM) != 0) - { - strerror_r(errno, strbuf, sizeof(strbuf)); - isc_error_fatal(__FILE__, __LINE__, - "isc_app_start() sigsetops: %s", strbuf); - } - presult = pthread_sigmask(SIG_BLOCK, &sset, NULL); - if (presult != 0) { - strerror_r(presult, strbuf, sizeof(strbuf)); - isc_error_fatal(__FILE__, __LINE__, - "isc_app_start() pthread_sigmask: %s", strbuf); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_start(void) { - isc_g_appctx.magic = APPCTX_MAGIC; - isc_g_appctx.mctx = NULL; - /* The remaining members will be initialized in ctxstart() */ - - return (isc_app_ctxstart(&isc_g_appctx)); -} - -isc_result_t -isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, - void *arg) { - return (isc_app_ctxonrun(&isc_g_appctx, mctx, task, action, arg)); -} - -isc_result_t -isc_app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task, - isc_taskaction_t action, void *arg) { - isc_event_t *event; - isc_task_t *cloned_task = NULL; - - if (atomic_load_acquire(&ctx->running)) { - return (ISC_R_ALREADYRUNNING); - } - - /* - * Note that we store the task to which we're going to send the event - * in the event's "sender" field. - */ - isc_task_attach(task, &cloned_task); - event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN, - action, arg, sizeof(*event)); - - LOCK(&ctx->lock); - ISC_LINK_INIT(event, ev_link); - ISC_LIST_APPEND(ctx->on_run, event, ev_link); - UNLOCK(&ctx->lock); - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_ctxrun(isc_appctx_t *ctx) { - isc_event_t *event, *next_event; - isc_task_t *task; - - REQUIRE(VALID_APPCTX(ctx)); - - if (atomic_compare_exchange_strong_acq_rel(&ctx->running, - &(bool){ false }, true)) - { - /* - * Post any on-run events (in FIFO order). - */ - LOCK(&ctx->lock); - for (event = ISC_LIST_HEAD(ctx->on_run); event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(ctx->on_run, event, ev_link); - task = event->ev_sender; - event->ev_sender = NULL; - isc_task_sendanddetach(&task, &event); - } - UNLOCK(&ctx->lock); - } - - /* - * There is no danger if isc_app_shutdown() is called before we - * wait for signals. Signals are blocked, so any such signal will - * simply be made pending and we will get it when we call - * sigwait(). - */ - while (!atomic_load_acquire(&ctx->want_shutdown)) { - if (ctx == &isc_g_appctx) { - sigset_t sset; - int sig; - /* - * Wait for SIGHUP, SIGINT, or SIGTERM. - */ - if (sigemptyset(&sset) != 0 || - sigaddset(&sset, SIGHUP) != 0 || - sigaddset(&sset, SIGINT) != 0 || - sigaddset(&sset, SIGTERM) != 0) - { - char strbuf[ISC_STRERRORSIZE]; - strerror_r(errno, strbuf, sizeof(strbuf)); - isc_error_fatal(__FILE__, __LINE__, - "isc_app_run() sigsetops: %s", - strbuf); - } - - if (sigwait(&sset, &sig) == 0) { - switch (sig) { - case SIGINT: - case SIGTERM: - atomic_store_release( - &ctx->want_shutdown, true); - break; - case SIGHUP: - atomic_store_release(&ctx->want_reload, - true); - break; - default: - UNREACHABLE(); - } - } - } else { - /* - * Tools using multiple contexts don't - * rely on a signal, just wait until woken - * up. - */ - if (atomic_load_acquire(&ctx->want_shutdown)) { - break; - } - if (!atomic_load_acquire(&ctx->want_reload)) { - LOCK(&ctx->readylock); - WAIT(&ctx->ready, &ctx->readylock); - UNLOCK(&ctx->readylock); - } - } - if (atomic_compare_exchange_strong_acq_rel( - &ctx->want_reload, &(bool){ true }, false)) - { - return (ISC_R_RELOAD); - } - - if (atomic_load_acquire(&ctx->want_shutdown) && - atomic_load_acquire(&ctx->blocked)) - { - exit(1); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_app_run(void) { - isc_result_t result; - - atomic_compare_exchange_enforced(&is_running, &(bool){ false }, true); - - result = isc_app_ctxrun(&isc_g_appctx); - atomic_store_release(&is_running, false); - - return (result); -} - -bool -isc_app_isrunning(void) { - return (atomic_load_acquire(&is_running)); -} - -void -isc_app_ctxshutdown(isc_appctx_t *ctx) { - REQUIRE(VALID_APPCTX(ctx)); - - REQUIRE(atomic_load_acquire(&ctx->running)); - - /* If ctx->shutdown_requested == true, we are already shutting - * down and we want to just bail out. - */ - if (atomic_compare_exchange_strong_acq_rel(&ctx->shutdown_requested, - &(bool){ false }, true)) - { - if (ctx != &isc_g_appctx) { - /* Tool using multiple contexts */ - atomic_store_release(&ctx->want_shutdown, true); - SIGNAL(&ctx->ready); - } else { - /* Normal single BIND9 context */ - if (kill(getpid(), SIGTERM) < 0) { - char strbuf[ISC_STRERRORSIZE]; - strerror_r(errno, strbuf, sizeof(strbuf)); - isc_error_fatal(__FILE__, __LINE__, - "isc_app_shutdown() " - "kill: %s", - strbuf); - } - } - } -} - -void -isc_app_shutdown(void) { - isc_app_ctxshutdown(&isc_g_appctx); -} - -void -isc_app_ctxsuspend(isc_appctx_t *ctx) { - REQUIRE(VALID_APPCTX(ctx)); - - REQUIRE(atomic_load(&ctx->running)); - - /* - * Don't send the reload signal if we're shutting down. - */ - if (!atomic_load_acquire(&ctx->shutdown_requested)) { - if (ctx != &isc_g_appctx) { - /* Tool using multiple contexts */ - atomic_store_release(&ctx->want_reload, true); - SIGNAL(&ctx->ready); - } else { - /* Normal single BIND9 context */ - if (kill(getpid(), SIGHUP) < 0) { - char strbuf[ISC_STRERRORSIZE]; - strerror_r(errno, strbuf, sizeof(strbuf)); - isc_error_fatal(__FILE__, __LINE__, - "isc_app_reload() " - "kill: %s", - strbuf); - } - } - } -} - -void -isc_app_reload(void) { - isc_app_ctxsuspend(&isc_g_appctx); -} - -void -isc_app_ctxfinish(isc_appctx_t *ctx) { - REQUIRE(VALID_APPCTX(ctx)); - - isc_mutex_destroy(&ctx->lock); - isc_mutex_destroy(&ctx->readylock); - isc_condition_destroy(&ctx->ready); -} - -void -isc_app_finish(void) { - isc_app_ctxfinish(&isc_g_appctx); -} - -void -isc_app_block(void) { - sigset_t sset; - - REQUIRE(atomic_load_acquire(&isc_g_appctx.running)); - - atomic_compare_exchange_enforced(&isc_g_appctx.blocked, - &(bool){ false }, true); - - blockedthread = pthread_self(); - RUNTIME_CHECK(sigemptyset(&sset) == 0 && - sigaddset(&sset, SIGINT) == 0 && - sigaddset(&sset, SIGTERM) == 0); - RUNTIME_CHECK(pthread_sigmask(SIG_UNBLOCK, &sset, NULL) == 0); -} - -void -isc_app_unblock(void) { - sigset_t sset; - - REQUIRE(atomic_load_acquire(&isc_g_appctx.running)); - REQUIRE(blockedthread == pthread_self()); - - atomic_compare_exchange_enforced(&isc_g_appctx.blocked, &(bool){ true }, - false); - - RUNTIME_CHECK(sigemptyset(&sset) == 0 && - sigaddset(&sset, SIGINT) == 0 && - sigaddset(&sset, SIGTERM) == 0); - RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0); -} - -isc_result_t -isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) { - isc_appctx_t *ctx; - - REQUIRE(mctx != NULL); - REQUIRE(ctxp != NULL && *ctxp == NULL); - - ctx = isc_mem_get(mctx, sizeof(*ctx)); - *ctx = (isc_appctx_t){ .magic = 0 }; - - isc_mem_attach(mctx, &ctx->mctx); - ctx->magic = APPCTX_MAGIC; - - *ctxp = ctx; - - return (ISC_R_SUCCESS); -} - -void -isc_appctx_destroy(isc_appctx_t **ctxp) { - isc_appctx_t *ctx; - - REQUIRE(ctxp != NULL); - ctx = *ctxp; - *ctxp = NULL; - REQUIRE(VALID_APPCTX(ctx)); - - ctx->magic = 0; - - isc_mem_putanddetach(&ctx->mctx, ctx, sizeof(*ctx)); -} diff --git a/lib/isc/include/isc/app.h b/lib/isc/include/isc/app.h deleted file mode 100644 index 5f5f04b08f..0000000000 --- a/lib/isc/include/isc/app.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * SPDX-License-Identifier: MPL-2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#pragma once - -/***** -***** Module Info -*****/ - -/*! \file isc/app.h - * \brief ISC Application Support - * - * Dealing with program termination can be difficult, especially in a - * multithreaded program. The routines in this module help coordinate - * the shutdown process. They are used as follows by the initial (main) - * thread of the application: - * - *\li isc_app_start(); Call very early in main(), before - * any other threads have been created. - * - *\li isc_app_run(); This will post any on-run events, - * and then block until application - * shutdown is requested. A shutdown - * request is made by calling - * isc_app_shutdown(), or by sending - * SIGINT or SIGTERM to the process. - * After isc_app_run() returns, the - * application should shutdown itself. - * - *\li isc_app_finish(); Call very late in main(). - * - * Applications that want to use SIGHUP/isc_app_reload() to trigger reloading - * should check the result of isc_app_run() and call the reload routine if - * the result is ISC_R_RELOAD. They should then call isc_app_run() again - * to resume waiting for reload or termination. - * - * Use of this module is not required. In particular, isc_app_start() is - * NOT an ISC library initialization routine. - * - * This module also supports per-thread 'application contexts'. With this - * mode, a thread-based application will have a separate context, in which - * it uses other ISC library services such as tasks or timers. Signals are - * not caught in this mode, so that the application can handle the signals - * in its preferred way. - * - * \li MP: - * Clients must ensure that isc_app_start(), isc_app_run(), and - * isc_app_finish() are called at most once. isc_app_shutdown() - * is safe to use by any thread (provided isc_app_start() has been - * called previously). - * - * The same note applies to isc_app_ctxXXX() functions, but in this case - * it's a per-thread restriction. For example, a thread with an - * application context must ensure that isc_app_ctxstart() with the - * context is called at most once. - * - * \li Reliability: - * No anticipated impact. - * - * \li Resources: - * None. - * - * \li Security: - * No anticipated impact. - * - * \li Standards: - * None. - */ - -#include - -#include -#include -#include -#include -#include - -/*** - *** Types - ***/ - -typedef isc_event_t isc_appevent_t; - -#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 0) - -ISC_LANG_BEGINDECLS - -isc_result_t -isc_app_ctxstart(isc_appctx_t *ctx); - -isc_result_t -isc_app_start(void); -/*!< - * \brief Start an ISC library application. - * - * Notes: - * This call should be made before any other ISC library call, and as - * close to the beginning of the application as possible. - * - * Requires: - *\li 'ctx' is a valid application context (for app_ctxstart()). - */ - -isc_result_t -isc_app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task, - isc_taskaction_t action, void *arg); -isc_result_t -isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, - void *arg); -/*!< - * \brief Request delivery of an event when the application is run. - * - * Requires: - *\li isc_app_start() has been called. - *\li 'ctx' is a valid application context (for app_ctxonrun()). - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - */ - -isc_result_t -isc_app_ctxrun(isc_appctx_t *ctx); - -isc_result_t -isc_app_run(void); -/*!< - * \brief Run an ISC library application. - * - * Notes: - *\li The caller (typically the initial thread of an application) will - * block until shutdown is requested. When the call returns, the - * caller should start shutting down the application. - * - * Requires: - *\li isc_app_[ctx]start() has been called. - * - * Ensures: - *\li Any events requested via isc_app_onrun() will have been posted (in - * FIFO order) before isc_app_run() blocks. - *\li 'ctx' is a valid application context (for app_ctxrun()). - * - * Returns: - *\li ISC_R_SUCCESS Shutdown has been requested. - *\li ISC_R_RELOAD Reload has been requested. - */ - -bool -isc_app_isrunning(void); -/*!< - * \brief Return if the ISC library application is running. - * - * Returns: - *\li true App is running. - *\li false App is not running. - */ - -void -isc_app_ctxshutdown(isc_appctx_t *ctx); - -void -isc_app_shutdown(void); -/*!< - * \brief Request application shutdown. - * - * Notes: - *\li It is safe to call isc_app_shutdown() multiple times. Shutdown will - * only be triggered once. - * - * Requires: - *\li isc_app_[ctx]run() has been called. - *\li 'ctx' is a valid application context (for app_ctxshutdown()). - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_UNEXPECTED - */ - -void -isc_app_ctxsuspend(isc_appctx_t *ctx); -/*!< - * \brief This has the same behavior as isc_app_ctxsuspend(). - */ - -void -isc_app_reload(void); -/*!< - * \brief Request application reload. - * - * Requires: - *\li isc_app_run() has been called. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_UNEXPECTED - */ - -void -isc_app_ctxfinish(isc_appctx_t *ctx); - -void -isc_app_finish(void); -/*!< - * \brief Finish an ISC library application. - * - * Notes: - *\li This call should be made at or near the end of main(). - * - * Requires: - *\li isc_app_start() has been called. - *\li 'ctx' is a valid application context (for app_ctxfinish()). - * - * Ensures: - *\li Any resources allocated by isc_app_start() have been released. - */ - -void -isc_app_block(void); -/*!< - * \brief Indicate that a blocking operation will be performed. - * - * Notes: - *\li If a blocking operation is in process, a call to isc_app_shutdown() - * or an external signal will abort the program, rather than allowing - * clean shutdown. This is primarily useful for reading user input. - * - * Requires: - * \li isc_app_start() has been called. - * \li No other blocking operations are in progress. - */ - -void -isc_app_unblock(void); -/*!< - * \brief Indicate that a blocking operation is complete. - * - * Notes: - * \li When a blocking operation has completed, return the program to a - * state where a call to isc_app_shutdown() or an external signal will - * shutdown normally. - * - * Requires: - * \li isc_app_start() has been called. - * \li isc_app_block() has been called by the same thread. - */ - -isc_result_t -isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp); -/*!< - * \brief Create an application context. - * - * Requires: - *\li 'mctx' is a valid memory context. - *\li 'ctxp' != NULL && *ctxp == NULL. - */ - -void -isc_appctx_destroy(isc_appctx_t **ctxp); -/*!< - * \brief Destroy an application context. - * - * Requires: - *\li '*ctxp' is a valid application context. - * - * Ensures: - *\li *ctxp == NULL. - */ - -ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/eventclass.h b/lib/isc/include/isc/eventclass.h index b8be2ff31d..f9c4c079e4 100644 --- a/lib/isc/include/isc/eventclass.h +++ b/lib/isc/include/isc/eventclass.h @@ -37,9 +37,8 @@ #define ISC_EVENTCLASS_SOCKET ISC_EVENTCLASS(2) #define ISC_EVENTCLASS_FILE ISC_EVENTCLASS(3) #define ISC_EVENTCLASS_DNS ISC_EVENTCLASS(4) -#define ISC_EVENTCLASS_APP ISC_EVENTCLASS(5) -#define ISC_EVENTCLASS_OMAPI ISC_EVENTCLASS(6) -#define ISC_EVENTCLASS_RATELIMITER ISC_EVENTCLASS(7) -#define ISC_EVENTCLASS_ISCCC ISC_EVENTCLASS(8) -#define ISC_EVENTCLASS_NS ISC_EVENTCLASS(9) +#define ISC_EVENTCLASS_OMAPI ISC_EVENTCLASS(5) +#define ISC_EVENTCLASS_RATELIMITER ISC_EVENTCLASS(6) +#define ISC_EVENTCLASS_ISCCC ISC_EVENTCLASS(7) +#define ISC_EVENTCLASS_NS ISC_EVENTCLASS(8) /*@}*/ diff --git a/lib/isc/include/isc/types.h b/lib/isc/include/isc/types.h index f8fd98af24..35aa615e3f 100644 --- a/lib/isc/include/isc/types.h +++ b/lib/isc/include/isc/types.h @@ -34,7 +34,6 @@ /* Core Types. Alphabetized by defined type. */ typedef struct isc_astack isc_astack_t; /*%< Array-based fast stack */ -typedef struct isc_appctx isc_appctx_t; /*%< Application context */ typedef struct isc_buffer isc_buffer_t; /*%< Buffer */ typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */ typedef struct isc_constregion isc_constregion_t; /*%< Const region */