This is worse with a database with is intended to be used by
different users (A and B):
This is pretty much never a use case we would worry about. In most
applications, a single userID creates and operates on the DB.
A opens the DB and creates the semaphores with e.g. mode 0660.
B opens it, A closes, B closes - and fails sem_unlink() which
only A and root can do.
Next, B (or C) fails mdb_env_open() because sem_unlink() fails
The work-around I can think of is a "multi-uid" mode which instead
resets the semaphore with sem_post() if sem_getvalue() returns 0.
I don't know how ugly that is considered to be. Could ask
comp.programming.unix, or check what Berkeley DB does.
That would be OK in general. It still leaves the question of how to remove the
semaphore if the DB is being destroyed. But it's probably not worth the
trouble to worry about this so much. Those OSes should just get their act
together and support the POSIX process-shared mutexes.
should use mode 0666 for the semaphores (temporarily setting umask
Definitely not. The caller specifies a mode; if they want 0666 they should
configure it as such.
or it should not sem_unlink() since next user may create
the semaphores with a group which gives the wrong users access.
Same as today where running slapadd with the wrong uid causes trouble for the
following slapd. The answer is obvious: use the right uid when accessing the DB.
Other matters with the current implementation - I'll patch
mdb_env_excl_lock() need not retry getting a non-exclusive lock when
closing. mdb_env_close() can pass *excl = -1 to tell it not to.
mdb_env_setup_locks() can sem_unlink both semaphores before doing
anything else, so that reopening a database as root will clean up.
Drop the error checks of sem_unlink (so both get called), instead
use O_EXCL in sem_open(,O_CREAT,,). Unless I'm missing something,
the error checks just work like an emulation of O_EXCL anyway.
The sem_unlink() and sem_open() sequence isn't ideal, certainly. I would
prefer to just use the existing semaphore.
Another possibility is to just use SysV semaphores instead of POSIX
semaphores. Then you can use the ipcs(1) command to manually cleanup.
BerkeleyDB uses SysV shared memory when you specify a shared memory
environment and it appears that SysV semaphore support is actually more
widespread than POSIX semaphores.
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/