5656#include <signal.h>
5757#include <time.h>
5858
59+ #ifdef HAVE_SHM_OPEN
60+ #include "sys/mman.h"
61+ #endif
62+
5963#include "mb/pg_wchar.h"
6064#include "getaddrinfo.h"
6165#include "getopt_long.h"
@@ -150,6 +154,7 @@ static char *pgdata_native;
150154/* defaults */
151155static int n_connections = 10 ;
152156static int n_buffers = 50 ;
157+ static char * dynamic_shared_memory_type = NULL ;
153158
154159/*
155160 * Warning messages for authentication methods
@@ -1076,6 +1081,50 @@ set_null_conf(void)
10761081 free (path );
10771082}
10781083
1084+ /*
1085+ * Determine which dynamic shared memory implementation should be used on
1086+ * this platform. POSIX shared memory is preferable because the default
1087+ * allocation limits are much higher than the limits for System V on most
1088+ * systems that support both, but the fact that a platform has shm_open
1089+ * doesn't guarantee that that call will succeed when attempted. So, we
1090+ * attempt to reproduce what the postmaster will do when allocating a POSIX
1091+ * segment in dsm_impl.c; if it doesn't work, we assume it won't work for
1092+ * the postmaster either, and configure the cluster for System V shared
1093+ * memory instead.
1094+ */
1095+ static char *
1096+ choose_dsm_implementation (void )
1097+ {
1098+ #ifdef HAVE_SHM_OPEN
1099+ int ntries = 10 ;
1100+
1101+ while (ntries > 0 )
1102+ {
1103+ uint32 handle ;
1104+ char name [64 ];
1105+ int fd ;
1106+
1107+ handle = random ();
1108+ snprintf (name , 64 , "/PostgreSQL.%u" , handle );
1109+ if ((fd = shm_open (name , O_CREAT | O_RDWR | O_EXCL , 0600 )) != -1 )
1110+ {
1111+ close (fd );
1112+ shm_unlink (name );
1113+ return "posix" ;
1114+ }
1115+ if (errno != EEXIST )
1116+ break ;
1117+ -- ntries ;
1118+ }
1119+ #endif
1120+
1121+ #ifdef WIN32
1122+ return "windows" ;
1123+ #else
1124+ return "sysv" ;
1125+ #endif
1126+ }
1127+
10791128/*
10801129 * Determine platform-specific config settings
10811130 *
@@ -1157,6 +1206,7 @@ test_config_settings(void)
11571206 SYSTEMQUOTE "\"%s\" --boot -x0 %s "
11581207 "-c max_connections=%d "
11591208 "-c shared_buffers=%d "
1209+ "-c dynamic_shared_memory_type=none "
11601210 "< \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE ,
11611211 backend_exec , boot_options ,
11621212 n_connections , test_buffs ,
@@ -1171,6 +1221,11 @@ test_config_settings(void)
11711221 printf ("%dMB\n" , (n_buffers * (BLCKSZ / 1024 )) / 1024 );
11721222 else
11731223 printf ("%dkB\n" , n_buffers * (BLCKSZ / 1024 ));
1224+
1225+ printf (_ ("selecting dynamic shared memory implementation ... " ));
1226+ fflush (stdout );
1227+ dynamic_shared_memory_type = choose_dsm_implementation ();
1228+ printf ("%s\n" , dynamic_shared_memory_type );
11741229}
11751230
11761231/*
@@ -1265,6 +1320,11 @@ setup_config(void)
12651320 conflines = replace_token (conflines , "#log_timezone = 'GMT'" , repltok );
12661321 }
12671322
1323+ snprintf (repltok , sizeof (repltok ), "dynamic_shared_memory_type = %s" ,
1324+ dynamic_shared_memory_type );
1325+ conflines = replace_token (conflines , "#dynamic_shared_memory_type = posix" ,
1326+ repltok );
1327+
12681328 snprintf (path , sizeof (path ), "%s/postgresql.conf" , pg_data );
12691329
12701330 writefile (path , conflines );
0 commit comments