[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: Using LMDB safely with fork() and exec()
- To: Lorenz Bauer <lmb@cloudflare.com>
- Subject: Re: Using LMDB safely with fork() and exec()
- From: Hallvard Breien Furuseth <h.b.furuseth@usit.uio.no>
- Date: Sat, 17 Sep 2016 12:20:09 +0200
- Cc: openldap-technical@openldap.org
- In-reply-to: <CACAyw9-Ep_5fknhXsAhw+BTk0_fZSn=P=LEtVXgC4Fp+ze=VZQ@mail.gmail.com>
- References: <CACAyw99UKOXtHKxHToAg2aheQbEREpecuEC=w6zjBcPpS-jV-g@mail.gmail.com> <4f48fc59-b11e-8ed7-38ac-8c5091eb7776@usit.uio.no> <CACAyw98dQu0cHYxQnAaNyU0x-isAhBqDBHK+NiW82uK=4g5CYw@mail.gmail.com> <2fdda0a0-fe55-97dd-59ac-8adb4b760933@usit.uio.no> <CACAyw98+93HRNLAYjypeRg3pyjMwfbkJCduP3e76bX6GxG7FYQ@mail.gmail.com> <06b7d04d-4a10-b3d6-1587-cb7a5932f877@usit.uio.no> <27925844-a6b0-eb07-e1bd-a1d4ffce3536@usit.uio.no> <CACAyw9-Ep_5fknhXsAhw+BTk0_fZSn=P=LEtVXgC4Fp+ze=VZQ@mail.gmail.com>
- User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0
Duh - the mdb_env_copy() FD should have FD_CLOEXEC, since the
point was the user can't get at it. Fixed after an off-list
discussion. OTOH MDB_env.me_fd should not: mdb_env_get_fd()
exposes it, so CLOEXEC would break existing programs.
Another issue is with fork() without exec(). This breaks LMDB:
if (fork() == 0) pthread_exit(NULL);
because the child's me_txkey destructor releases the reader slot.
This can happen if a single-threaded LMDB process forks a multi-
threaded child, which is one way to deal with threads vs. fork().
pthread_atfork() is the official way to deal with that. I'm a bit
wary of it since there is no way to unregister an atfork handler.
I wonder what happens if the LMDB module was dynamically loaded
and then gets unloaded. A simpler way is in any case to check
if (reader->mr_pid == getpid()) in mdb_env_reader_dest().
I suppose there could be an mdb_env_fork_cleanup() function which
at least closes the FDs, and takes an arg to say whether to free
memory too (safe if parent was single-threaded).