8000 Harden dsm_impl.c against unexpected EEXIST. · postgres/postgres@facfd04 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit facfd04

Browse files
committed
Harden dsm_impl.c against unexpected EEXIST.
Previously, we trusted the OS not to report EEXIST unless we'd passed in IPC_CREAT | IPC_EXCL or O_CREAT | O_EXCL, as appropriate. Solaris's shm_open() can in fact do that, causing us to crash because we didn't ereport and then we blithely assumed the mapping was successful. Let's treat EEXIST just like any other error, unless we're actually trying to create a new segment. This applies to shm_open(), where this behavior has been seen, and also to the equivalent operations for our sysv and mmap modes just on principle. Based on the underlying reason for the error, namely contention on a lock file managed by Solaris librt for each distinct name, this problem is only likely to happen on 15 and later, because the new shared memory stats system produces shm_open() calls for the same path from potentially large numbers of backends concurrently during authentication. Earlier releases only shared memory segments between a small number of parallel workers under one Gather node. You could probably hit it if you tried hard enough though, and we should have been more defensive in the first place. Therefore, back-patch to all supported releases. Per build farm animal margay. This isn't the end of the story, though, it just changes random crashes into random "File exists" errors; more work needed for a green build farm. Reviewed-by: Robert Haas <robertmhaas@gmail.com> Discussion: https://postgr.es/m/CA% 8000 2BhUKGKqKrCV5xKWfh9rnm%3Do%3DDwZLTLtnsj_XpUi9g5%3DV%2B9oyg%40mail.gmail.com
1 parent b49889f commit facfd04

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

src/backend/storage/ipc/dsm_impl.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
289289
flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
290290
if ((fd = shm_open(name, flags, PG_FILE_MODE_OWNER)) == -1)
291291
{
292-
if (errno != EEXIST)
292+
if (op == DSM_OP_ATTACH || errno != EEXIST)
293293
ereport(elevel,
294294
(errcode_for_dynamic_shared_memory(),
295295
errmsg("could not open shared memory segment \"%s\": %m",
@@ -565,7 +565,7 @@ dsm_impl_sysv(dsm_op op, dsm_handle handle, Size request_size,
565565

566566
if ((ident = shmget(key, segsize, flags)) == -1)
567567
{
568-
if (errno != EEXIST)
568+
if (op == DSM_OP_ATTACH || errno != EEXIST)
569569
{
570570
int save_errno = errno;
571571

@@ -898,7 +898,7 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
898898
flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
899899
if ((fd = OpenTransientFile(name, flags)) == -1)
900900
{
901-
if (errno != EEXIST)
901+
if (op == DSM_OP_ATTACH || errno != EEXIST)
902902
ereport(elevel,
903903
(errcode_for_dynamic_shared_memory(),
904904
errmsg("could not open shared memory segment \"%s\": %m",

0 commit comments

Comments
 (0)
0