mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
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%2BhUKGKqKrCV5xKWfh9rnm%3Do%3DDwZLTLtnsj_XpUi9g5%3DV%2B9oyg%40mail.gmail.com
This commit is contained in:
parent
e24615a005
commit
fb81a93a64
@ -261,7 +261,7 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
|
|||||||
if ((fd = shm_open(name, flags, PG_FILE_MODE_OWNER)) == -1)
|
if ((fd = shm_open(name, flags, PG_FILE_MODE_OWNER)) == -1)
|
||||||
{
|
{
|
||||||
ReleaseExternalFD();
|
ReleaseExternalFD();
|
||||||
if (errno != EEXIST)
|
if (op == DSM_OP_ATTACH || errno != EEXIST)
|
||||||
ereport(elevel,
|
ereport(elevel,
|
||||||
(errcode_for_dynamic_shared_memory(),
|
(errcode_for_dynamic_shared_memory(),
|
||||||
errmsg("could not open shared memory segment \"%s\": %m",
|
errmsg("could not open shared memory segment \"%s\": %m",
|
||||||
@ -500,7 +500,7 @@ dsm_impl_sysv(dsm_op op, dsm_handle handle, Size request_size,
|
|||||||
|
|
||||||
if ((ident = shmget(key, segsize, flags)) == -1)
|
if ((ident = shmget(key, segsize, flags)) == -1)
|
||||||
{
|
{
|
||||||
if (errno != EEXIST)
|
if (op == DSM_OP_ATTACH || errno != EEXIST)
|
||||||
{
|
{
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
|
|
||||||
@ -822,7 +822,7 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
|
|||||||
flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
|
flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
|
||||||
if ((fd = OpenTransientFile(name, flags)) == -1)
|
if ((fd = OpenTransientFile(name, flags)) == -1)
|
||||||
{
|
{
|
||||||
if (errno != EEXIST)
|
if (op == DSM_OP_ATTACH || errno != EEXIST)
|
||||||
ereport(elevel,
|
ereport(elevel,
|
||||||
(errcode_for_dynamic_shared_memory(),
|
(errcode_for_dynamic_shared_memory(),
|
||||||
errmsg("could not open shared memory segment \"%s\": %m",
|
errmsg("could not open shared memory segment \"%s\": %m",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user