diff options
Diffstat (limited to 'src/backend/port/sysv_sema.c')
-rw-r--r-- | src/backend/port/sysv_sema.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/backend/port/sysv_sema.c b/src/backend/port/sysv_sema.c index ac5106f39da..a1652cce59c 100644 --- a/src/backend/port/sysv_sema.c +++ b/src/backend/port/sysv_sema.c @@ -17,6 +17,7 @@ #include <signal.h> #include <unistd.h> #include <sys/file.h> +#include <sys/stat.h> #ifdef HAVE_SYS_IPC_H #include <sys/ipc.h> #endif @@ -301,10 +302,6 @@ PGSemaphoreShmemSize(int maxSemas) * are acquired here or in PGSemaphoreCreate, register an on_shmem_exit * callback to release them. * - * The port number is passed for possible use as a key (for SysV, we use - * it to generate the starting semaphore key). In a standalone backend, - * zero will be passed. - * * In the SysV implementation, we acquire semaphore sets on-demand; the * maxSemas parameter is just used to size the arrays. There is an array * of PGSemaphoreData structs in shared memory, and a postmaster-local array @@ -314,8 +311,22 @@ PGSemaphoreShmemSize(int maxSemas) * have clobbered.) */ void -PGReserveSemaphores(int maxSemas, int port) +PGReserveSemaphores(int maxSemas) { + struct stat statbuf; + + /* + * We use the data directory's inode number to seed the search for free + * semaphore keys. This minimizes the odds of collision with other + * postmasters, while maximizing the odds that we will detect and clean up + * semaphores left over from a crashed postmaster in our own directory. + */ + if (stat(DataDir, &statbuf) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not stat data directory \"%s\": %m", + DataDir))); + /* * We must use ShmemAllocUnlocked(), since the spinlock protecting * ShmemAlloc() won't be ready yet. (This ordering is necessary when we @@ -332,7 +343,7 @@ PGReserveSemaphores(int maxSemas, int port) if (mySemaSets == NULL) elog(PANIC, "out of memory"); numSemaSets = 0; - nextSemaKey = port * 1000; + nextSemaKey = statbuf.st_ino; nextSemaNumber = SEMAS_PER_SET; /* force sema set alloc on 1st call */ on_shmem_exit(ReleaseSemaphores, 0); |