@@ -73,15 +73,17 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
73
73
74
74
if (shmid < 0 )
75
75
{
76
+ int shmget_errno = errno ;
77
+
76
78
/*
77
79
* Fail quietly if error indicates a collision with existing segment.
78
80
* One would expect EEXIST, given that we said IPC_EXCL, but perhaps
79
81
* we could get a permission violation instead? Also, EIDRM might
80
82
* occur if an old seg is slated for destruction but not gone yet.
81
83
*/
82
- if (errno == EEXIST || errno == EACCES
84
+ if (shmget_errno == EEXIST || shmget_errno == EACCES
83
85
#ifdef EIDRM
84
- || errno == EIDRM
86
+ || shmget_errno == EIDRM
85
87
#endif
86
88
)
87
89
return NULL ;
@@ -95,10 +97,8 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
95
97
* against SHMMIN in the preexisting-segment case, so we will not get
96
98
* EINVAL a second time if there is such a segment.
97
99
*/
98
- if (errno == EINVAL )
100
+ if (shmget_errno == EINVAL )
99
101
{
100
- int save_errno = errno ;
101
-
102
102
shmid = shmget (memKey , 0 , IPC_CREAT | IPC_EXCL | IPCProtection );
103
103
104
104
if (shmid < 0 )
@@ -124,8 +124,6 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
124
124
elog (LOG , "shmctl(%d, %d, 0) failed: %m" ,
125
125
(int ) shmid , IPC_RMID );
126
126
}
127
-
128
- errno = save_errno ;
129
127
}
130
128
131
129
/*
@@ -137,25 +135,26 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
137
135
* it should be. SHMMNI violation is ENOSPC, per spec. Just plain
138
136
* not-enough-RAM is ENOMEM.
139
137
*/
138
+ errno = shmget_errno ;
140
139
ereport (FATAL ,
141
140
(errmsg ("could not create shared memory segment: %m" ),
142
141
errdetail ("Failed system call was shmget(key=%lu, size=%zu, 0%o)." ,
143
142
(unsigned long ) memKey , size ,
144
143
IPC_CREAT | IPC_EXCL | IPCProtection ),
145
- (errno == EINVAL ) ?
144
+ (shmget_errno == EINVAL ) ?
146
145
errhint ("This error usually means that PostgreSQL's request for a shared memory "
147
146
"segment exceeded your kernel's SHMMAX parameter, or possibly that "
148
147
"it is less than "
149
148
"your kernel's SHMMIN parameter.\n"
150
149
"The PostgreSQL documentation contains more information about shared "
151
150
"memory configuration." ) : 0 ,
152
- (errno == ENOMEM ) ?
151
+ (shmget_errno == ENOMEM ) ?
153
152
errhint ("This error usually means that PostgreSQL's request for a shared "
154
153
"memory segment exceeded your kernel's SHMALL parameter. You might need "
155
154
"to reconfigure the kernel with larger SHMALL.\n"
156
155
"The PostgreSQL documentation contains more information about shared "
157
156
"memory configuration." ) : 0 ,
158
- (errno == ENOSPC ) ?
157
+ (shmget_errno == ENOSPC ) ?
159
158
errhint ("This error does *not* mean that you have run out of disk space. "
160
159
"It occurs either if all available shared memory IDs have been taken, "
161
160
"in which case you need to raise the SHMMNI parameter in your kernel, "
@@ -331,6 +330,7 @@ CreateAnonymousSegment(Size *size)
331
330
{
332
331
Size allocsize = * size ;
333
332
void * ptr = MAP_FAILED ;
333
+ int mmap_errno = 0 ;
334
334
335
335
#ifndef MAP_HUGETLB
336
336
if (huge_tlb_pages == HUGE_TLB_ON )
@@ -363,6 +363,7 @@ CreateAnonymousSegment(Size *size)
363
363
364
364
ptr = mmap (NULL , allocsize , PROT_READ | PROT_WRITE ,
365
365
PG_MMAP_FLAGS | MAP_HUGETLB , -1 , 0 );
366
+ mmap_errno = errno ;
366
367
if (huge_tlb_pages == HUGE_TLB_TRY && ptr == MAP_FAILED )
367
368
elog (DEBUG1 , "mmap with MAP_HUGETLB failed, huge pages disabled: %m" );
368
369
}
@@ -376,20 +377,25 @@ CreateAnonymousSegment(Size *size)
376
377
* back to non-huge pages.
377
378
*/
378
379
allocsize = * size ;
379
- ptr = mmap (NULL , allocsize , PROT_READ | PROT_WRITE , PG_MMAP_FLAGS , -1 , 0 );
380
+ ptr = mmap (NULL , allocsize , PROT_READ | PROT_WRITE ,
381
+ PG_MMAP_FLAGS , -1 , 0 );
382
+ mmap_errno = errno ;
380
383
}
381
384
382
385
if (ptr == MAP_FAILED )
386
+ {
387
+ errno = mmap_errno ;
383
388
ereport (FATAL ,
384
389
(errmsg ("could not map anonymous shared memory: %m" ),
385
- (errno == ENOMEM ) ?
390
+ (mmap_errno == ENOMEM ) ?
386
391
errhint ("This error usually means that PostgreSQL's request "
387
392
"for a shared memory segment exceeded available memory, "
388
393
"swap space or huge pages. To reduce the request size "
389
394
"(currently %zu bytes), reduce PostgreSQL's shared "
390
395
"memory usage, perhaps by reducing shared_buffers or "
391
396
"max_connections." ,
392
397
* size ) : 0 ));
398
+ }
393
399
394
400
* size = allocsize ;
395
401
return ptr ;
0 commit comments