diff --git a/CHANGES b/CHANGES index 953ad25c7b..d0d278bfc8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +6040. [bug] Speed up the named shutdown time by explicitly + canceling all recursing ns_client objects for + each ns_clientmgr. [GL #3183] + 6039. [bug] Removing a catalog zone from catalog-zones without also removing the referenced zone could leave a dangling pointer. [GL #3683] diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index 45d6fa9b0d..9383fdc4d7 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -70,6 +70,9 @@ Bug Fixes cases a dangling pointer could cause a :iscman:`named` process crash. This has been fixed. :gl:`#3683` +- The ``named`` would wait for some outstanding recursing queries + to finish before shutting down. This has been fixed. :gl:`#3183` + Known Issues ~~~~~~~~~~~~ diff --git a/lib/ns/client.c b/lib/ns/client.c index 2b3da21b21..39ac87f540 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -121,8 +121,6 @@ atomic_uint_fast64_t ns_client_requests = 0; static void clientmgr_attach(ns_clientmgr_t *source, ns_clientmgr_t **targetp); static void -clientmgr_detach(ns_clientmgr_t **mp); -static void clientmgr_destroy(ns_clientmgr_t *manager); static void ns_client_endrequest(ns_client_t *client); @@ -1665,7 +1663,7 @@ ns__client_put_cb(void *client0) { dns_message_detach(&client->message); if (client->manager != NULL) { - clientmgr_detach(&client->manager); + ns_clientmgr_detach(&client->manager); } /* @@ -2408,7 +2406,7 @@ cleanup: } if (client->manager != NULL) { - clientmgr_detach(&client->manager); + ns_clientmgr_detach(&client->manager); } isc_mem_detach(&client->mctx); if (client->sctx != NULL) { @@ -2442,8 +2440,8 @@ clientmgr_attach(ns_clientmgr_t *source, ns_clientmgr_t **targetp) { *targetp = source; } -static void -clientmgr_detach(ns_clientmgr_t **mp) { +void +ns_clientmgr_detach(ns_clientmgr_t **mp) { int32_t oldrefs; ns_clientmgr_t *mgr = *mp; *mp = NULL; @@ -2517,20 +2515,20 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr, } void -ns_clientmgr_destroy(ns_clientmgr_t **managerp) { - ns_clientmgr_t *manager; +ns_clientmgr_shutdown(ns_clientmgr_t *manager) { + ns_client_t *client; - REQUIRE(managerp != NULL); - REQUIRE(VALID_MANAGER(*managerp)); - - manager = *managerp; - *managerp = NULL; + REQUIRE(VALID_MANAGER(manager)); MTRACE("destroy"); - if (isc_refcount_decrement(&manager->references) == 1) { - clientmgr_destroy(manager); + LOCK(&manager->reclock); + for (client = ISC_LIST_HEAD(manager->recursing); client != NULL; + client = ISC_LIST_NEXT(client, rlink)) + { + ns_query_cancel(client); } + UNLOCK(&manager->reclock); } isc_sockaddr_t * diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h index 8e1d5cfb10..e937f0acec 100644 --- a/lib/ns/include/ns/client.h +++ b/lib/ns/include/ns/client.h @@ -348,10 +348,16 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr, */ void -ns_clientmgr_destroy(ns_clientmgr_t **managerp); +ns_clientmgr_shutdown(ns_clientmgr_t *manager); /*%< - * Destroy a client manager and all ns_client_t objects - * managed by it. + * Shutdown a client manager and all ns_client_t objects + * managed by it + */ + +void +ns_clientmgr_detach(ns_clientmgr_t **managerp); +/*%< + * Detach from a client manager. */ isc_sockaddr_t * diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index 06f23628d0..be98841cea 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -386,7 +386,7 @@ ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) { clearlistenon(mgr); isc_mutex_destroy(&mgr->lock); for (size_t i = 0; i < (size_t)mgr->ncpus; i++) { - ns_clientmgr_destroy(&mgr->clientmgrs[i]); + ns_clientmgr_detach(&mgr->clientmgrs[i]); } isc_mem_put(mgr->mctx, mgr->clientmgrs, mgr->ncpus * sizeof(mgr->clientmgrs[0])); @@ -455,6 +455,10 @@ ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { if (mgr->route != NULL) { isc_nm_cancelread(mgr->route); } + + for (size_t i = 0; i < (size_t)mgr->ncpus; i++) { + ns_clientmgr_shutdown(mgr->clientmgrs[i]); + } } static void