mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 16:15:27 +00:00
netmgr:
- make tcp listening IPC pipe name saner - put the pipe in /tmp on unices - add pid to the pipe name to avoid conflicts between processes - fsync directory in which the pipe resides to make sure that the child threads will see it and be able to open it
This commit is contained in:
@@ -339,7 +339,7 @@ struct isc_nmsocket {
|
|||||||
|
|
||||||
/*% Used to transfer listening TCP sockets to children */
|
/*% Used to transfer listening TCP sockets to children */
|
||||||
uv_pipe_t ipc;
|
uv_pipe_t ipc;
|
||||||
char ipc_pipe_name[32];
|
char ipc_pipe_name[64];
|
||||||
atomic_int_fast32_t schildren;
|
atomic_int_fast32_t schildren;
|
||||||
|
|
||||||
/*% Extra data allocated at the end of each isc_nmhandle_t */
|
/*% Extra data allocated at the end of each isc_nmhandle_t */
|
||||||
|
@@ -44,9 +44,9 @@
|
|||||||
ISC_THREAD_LOCAL int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
|
ISC_THREAD_LOCAL int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define NAMED_PIPE_PREFIX "\\\\.\\pipe\\named-ipc"
|
#define NAMED_PIPE_PATTERN "\\\\.\\pipe\\named-%d-%u.pipe"
|
||||||
#else
|
#else
|
||||||
#define NAMED_PIPE_PREFIX ".named-ipc"
|
#define NAMED_PIPE_PATTERN "/tmp/named-%d-%u.pipe"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -840,14 +840,14 @@ isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXXWPK Maybe it should be in tmp, maybe it should not
|
* Use a random number in the named pipe name. Also add getpid()
|
||||||
* be random?
|
* to the name to make sure we don't get a conflict between
|
||||||
|
* different unit tests running at the same time, where the PRNG
|
||||||
|
* is initialized to a constant seed.
|
||||||
*/
|
*/
|
||||||
strcpy(sock->ipc_pipe_name, NAMED_PIPE_PREFIX);
|
snprintf(sock->ipc_pipe_name, sizeof(sock->ipc_pipe_name),
|
||||||
for (int i = strlen(sock->ipc_pipe_name); i < 31; i++) {
|
NAMED_PIPE_PATTERN, getpid(), isc_random32());
|
||||||
sock->ipc_pipe_name[i] = isc_random8() % 24 + 'a';
|
sock->ipc_pipe_name[sizeof(sock->ipc_pipe_name) - 1] = '\0';
|
||||||
}
|
|
||||||
sock->ipc_pipe_name[31] = '\0';
|
|
||||||
|
|
||||||
isc_mutex_init(&sock->lock);
|
isc_mutex_init(&sock->lock);
|
||||||
isc_condition_init(&sock->cond);
|
isc_condition_init(&sock->cond);
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
#include <isc/atomic.h>
|
#include <isc/atomic.h>
|
||||||
@@ -203,6 +204,25 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
/*
|
||||||
|
* Run fsync() on the directory containing a socket's IPC pipe, to
|
||||||
|
* ensure that all threads can see the pipe.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
syncdir(const isc_nmsocket_t *sock) {
|
||||||
|
char *pipe = isc_mem_strdup(sock->mgr->mctx, sock->ipc_pipe_name);
|
||||||
|
int fd = open(dirname(pipe), O_RDONLY);
|
||||||
|
|
||||||
|
RUNTIME_CHECK(fd >= 0);
|
||||||
|
|
||||||
|
isc_mem_free(sock->mgr->mctx, pipe);
|
||||||
|
|
||||||
|
fsync(fd);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For TCP listening, we create a single socket, bind it, and then
|
* For TCP listening, we create a single socket, bind it, and then
|
||||||
* pass it to `ncpu` child sockets - the passing is done over IPC.
|
* pass it to `ncpu` child sockets - the passing is done over IPC.
|
||||||
@@ -274,7 +294,17 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ievent0) {
|
|||||||
r = uv_listen((uv_stream_t *) &sock->ipc, sock->nchildren,
|
r = uv_listen((uv_stream_t *) &sock->ipc, sock->nchildren,
|
||||||
ipc_connection_cb);
|
ipc_connection_cb);
|
||||||
INSIST(r == 0);
|
INSIST(r == 0);
|
||||||
|
#ifndef WIN32
|
||||||
|
/*
|
||||||
|
* On Unices a child thread might not see the pipe yet;
|
||||||
|
* that happened quite often in unit tests on FreeBSD.
|
||||||
|
* Syncing the directory ensures that the pipe is visible
|
||||||
|
* to everyone.
|
||||||
|
* This isn't done on Windows because named pipes exist
|
||||||
|
* within a different namespace, not on VFS.
|
||||||
|
*/
|
||||||
|
syncdir(sock);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* We launch n 'tcpchildlistener' that will receive
|
* We launch n 'tcpchildlistener' that will receive
|
||||||
* sockets to be listened on over ipc.
|
* sockets to be listened on over ipc.
|
||||||
|
Reference in New Issue
Block a user