unix-stream-server: create unix domain socket under lock
commit9fd19027621fc4f8beb2e57ba37d91465d1906f6
authorJeff Hostetler <jeffhost@microsoft.com>
Mon, 15 Mar 2021 21:08:27 +0000 (15 21:08 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Mar 2021 21:32:51 +0000 (15 14:32 -0700)
tree72e88d15033dd50ec434f003c0d68e7431fece43
parent77e522caaeebe8c6378dcf7045b19cbd22c8b2fb
unix-stream-server: create unix domain socket under lock

Create a wrapper class for `unix_stream_listen()` that uses a ".lock"
lockfile to create the unix domain socket in a race-free manner.

Unix domain sockets have a fundamental problem on Unix systems because
they persist in the filesystem until they are deleted.  This is
independent of whether a server is actually listening for connections.
Well-behaved servers are expected to delete the socket when they
shutdown.  A new server cannot easily tell if a found socket is
attached to an active server or is leftover cruft from a dead server.
The traditional solution used by `unix_stream_listen()` is to force
delete the socket pathname and then create a new socket.  This solves
the latter (cruft) problem, but in the case of the former, it orphans
the existing server (by stealing the pathname associated with the
socket it is listening on).

We cannot directly use a .lock lockfile to create the socket because
the socket is created by `bind(2)` rather than the `open(2)` mechanism
used by `tempfile.c`.

As an alternative, we hold a plain lockfile ("<path>.lock") as a
mutual exclusion device.  Under the lock, we test if an existing
socket ("<path>") is has an active server.  If not, we create a new
socket and begin listening.  Then we use "rollback" to delete the
lockfile in all cases.

This wrapper code conceptually exists at a higher-level than the core
unix_stream_connect() and unix_stream_listen() routines that it
consumes.  It is isolated in a wrapper class for clarity.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Makefile
contrib/buildsystems/CMakeLists.txt
unix-stream-server.c [new file with mode: 0644]
unix-stream-server.h [new file with mode: 0644]