8000 Provide a way to control SysV shmem attach address in EXEC_BACKEND bu… · anrs/postgres@0d7591c · GitHub
[go: up one dir, main page]

Skip to content

Commit 0d7591c

Browse files
committed
Provide a way to control SysV shmem attach address in EXEC_BACKEND builds.
In standard non-Windows builds, there's no particular reason to care what address the kernel chooses to map the shared memory segment at. However, when building with EXEC_BACKEND, there's a risk that the chosen address won't be available in all child processes. Linux with ASLR enabled (which it is by default) seems particularly at risk because it puts shmem segments into the same area where it maps shared libraries. We can work around that by specifying a mapping address that's outside the range where shared libraries could get mapped. On x86_64 Linux, 0x7e0000000000 seems to work well. This is only meant for testing/debugging purposes, so it doesn't seem necessary to go as far as providing a GUC (or any user-visible documentation, though we might change that later). Instead, it's just controlled by setting an environment variable PG_SHMEM_ADDR to the desired attach address. Back-patch to all supported branches, since the point here is to remove intermittent buildfarm failures on EXEC_BACKEND animals. Owners of affected animals will need to add a suitable setting of PG_SHMEM_ADDR to their build_env configuration. Discussion: https://postgr.es/m/7036.1492231361@sss.pgh.pa.us
1 parent ba0a0f3 commit 0d7591c

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

src/backend/port/sysv_shmem.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,28 @@ static void *
7070
InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
7171
{
7272
IpcMemoryId shmid;
73+
void *requestedAddress = NULL;
7374
void *memAddress;
7475

76+
/*
77+
* Normally we just pass requestedAddress = NULL to shmat(), allowing the
78+
* system to choose where the segment gets mapped. But in an EXEC_BACKEND
79+
* build, it's possible for whatever is chosen in the postmaster to not
80+
* work for backends, due to variations in address space layout. As a
81+
* rather klugy workaround, allow the user to specify the address to use
82+
* via setting the environment variable PG_SHMEM_ADDR. (If this were of
83+
* interest for anything except debugging, we'd probably create a cleaner
84+
* and better-documented way to set it, such as a GUC.)
85+
*/
86+
#ifdef EXEC_BACKEND
87+
{
88+
char *pg_shmem_addr = getenv("PG_SHMEM_ADDR");
89+
90+
if (pg_shmem_addr)
91+
requestedAddress = (void *) strtoul(pg_shmem_addr, NULL, 0);
92+
}
93+
#endif
94+
7595
shmid = shmget(memKey, size, IPC_CREAT | IPC_EXCL | IPCProtection);
7696

7797
if (shmid < 0)
@@ -185,10 +205,11 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
185205
on_shmem_exit(IpcMemoryDelete, Int32GetDatum(shmid));
186206

187207
/* OK, should be able to attach to the segment */
188-
memAddress = shmat(shmid, NULL, PG_SHMAT_FLAGS);
208+
memAddress = shmat(shmid, requestedAddress, PG_SHMAT_FLAGS);
189209

190210
if (memAddress == (void *) -1)
191-
elog(FATAL, "shmat(id=%d) failed: %m", shmid);
211+
elog(FATAL, "shmat(id=%d, addr=%p, flags=0x%x) failed: %m",
212+
shmid, requestedAddress, PG_SHMAT_FLAGS);
192213

193214
/* Register on-exit routine to detach new segment before deleting */
194215
on_shmem_exit(IpcMemoryDetach, PointerGetDatum(memAddress));

0 comm 308A it comments

Comments
 (0)
0