mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
prevent a deadlock in the shutdown system test
The shutdown test sends 'rdnc status' commands in parallel with 'rndc stop' A new rndc connection arriving will reference the ACL environment to see whether the client is allowed to connect. Commitc0995bc380added a mutex lock to ns_interfacemgr_getaclenv(), but if the new connection arrives while the interfaces are being purged during shutdown, that lock is already being held. If the the connection event slips in ahead of one of the netmgr's "stop listening" events on a worker thread, a deadlock can occur. The fix is not to hold the interfacemgr lock while shutting down interfaces; only while actually traversing the interface list to identify interfaces needing shutdown. (cherry picked from commit5c4cf3fcc4)
This commit is contained in:
parent
5c97200cfb
commit
af37c6f60c
1 changed files with 19 additions and 15 deletions
|
|
@ -740,10 +740,6 @@ interface_destroy(ns_interface_t **interfacep) {
|
|||
|
||||
ns_interface_shutdown(ifp);
|
||||
|
||||
if (ISC_LINK_LINKED(ifp, link)) {
|
||||
ISC_LIST_UNLINK(mgr->interfaces, ifp, link);
|
||||
}
|
||||
|
||||
ifp->magic = 0;
|
||||
isc_mutex_destroy(&ifp->lock);
|
||||
ns_interfacemgr_detach(&ifp->mgr);
|
||||
|
|
@ -777,26 +773,34 @@ find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {
|
|||
*/
|
||||
static void
|
||||
purge_old_interfaces(ns_interfacemgr_t *mgr) {
|
||||
ns_interface_t *ifp, *next;
|
||||
ns_interface_t *ifp = NULL, *next = NULL;
|
||||
ISC_LIST(ns_interface_t) interfaces;
|
||||
|
||||
ISC_LIST_INIT(interfaces);
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) {
|
||||
INSIST(NS_INTERFACE_VALID(ifp));
|
||||
next = ISC_LIST_NEXT(ifp, link);
|
||||
if (ifp->generation != mgr->generation) {
|
||||
ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);
|
||||
if (LISTENING(ifp)) {
|
||||
char sabuf[256];
|
||||
isc_sockaddr_format(&ifp->addr, sabuf,
|
||||
sizeof(sabuf));
|
||||
isc_log_write(
|
||||
IFMGR_COMMON_LOGARGS, ISC_LOG_INFO,
|
||||
"no longer listening on %s", sabuf);
|
||||
ns_interface_shutdown(ifp);
|
||||
}
|
||||
interface_destroy(&ifp);
|
||||
ISC_LIST_APPEND(interfaces, ifp, link);
|
||||
}
|
||||
}
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
for (ifp = ISC_LIST_HEAD(interfaces); ifp != NULL; ifp = next) {
|
||||
next = ISC_LIST_NEXT(ifp, link);
|
||||
if (LISTENING(ifp)) {
|
||||
char sabuf[256];
|
||||
isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO,
|
||||
"no longer listening on %s", sabuf);
|
||||
ns_interface_shutdown(ifp);
|
||||
}
|
||||
ISC_LIST_UNLINK(interfaces, ifp, link);
|
||||
interface_destroy(&ifp);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
Loading…
Reference in a new issue