From 7195fb3cec9a7cf60f203edfa224ec632f16a101 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Thu, 10 Oct 2013 19:38:56 -0400 Subject: [PATCH] initdb: Select working dynamic shared memory implementation. If POSIX shared memory is supported and works, we prefer it. Otherwise, we prefer System V, except on Windows, where we use the implementation specific to that platform. --- src/bin/initdb/initdb.c | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index a6eb0d8061..ebe8a67c0b 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -56,6 +56,10 @@ #include #include +#ifdef HAVE_SHM_OPEN +#include "sys/mman.h" +#endif + #include "mb/pg_wchar.h" #include "getaddrinfo.h" #include "getopt_long.h" @@ -150,6 +154,7 @@ static char *pgdata_native; /* defaults */ static int n_connections = 10; static int n_buffers = 50; +static char *dynamic_shared_memory_type = NULL; /* * Warning messages for authentication methods @@ -1076,6 +1081,50 @@ set_null_conf(void) free(path); } +/* + * Determine which dynamic shared memory implementation should be used on + * this platform. POSIX shared memory is preferable because the default + * allocation limits are much higher than the limits for System V on most + * systems that support both, but the fact that a platform has shm_open + * doesn't guarantee that that call will succeed when attempted. So, we + * attempt to reproduce what the postmaster will do when allocating a POSIX + * segment in dsm_impl.c; if it doesn't work, we assume it won't work for + * the postmaster either, and configure the cluster for System V shared + * memory instead. + */ +static char * +choose_dsm_implementation(void) +{ +#ifdef HAVE_SHM_OPEN + int ntries = 10; + + while (ntries > 0) + { + uint32 handle; + char name[64]; + int fd; + + handle = random(); + snprintf(name, 64, "/PostgreSQL.%u", handle); + if ((fd = shm_open(name, O_CREAT | O_RDWR | O_EXCL, 0600)) != -1) + { + close(fd); + shm_unlink(name); + return "posix"; + } + if (errno != EEXIST) + break; + --ntries; + } +#endif + +#ifdef WIN32 + return "windows"; +#else + return "sysv"; +#endif +} + /* * Determine platform-specific config settings * @@ -1157,6 +1206,7 @@ test_config_settings(void) SYSTEMQUOTE "\"%s\" --boot -x0 %s " "-c max_connections=%d " "-c shared_buffers=%d " + "-c dynamic_shared_memory_type=none " "< \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE, backend_exec, boot_options, n_connections, test_buffs, @@ -1171,6 +1221,11 @@ test_config_settings(void) printf("%dMB\n", (n_buffers * (BLCKSZ / 1024)) / 1024); else printf("%dkB\n", n_buffers * (BLCKSZ / 1024)); + + printf(_("selecting dynamic shared memory implementation ... ")); + fflush(stdout); + dynamic_shared_memory_type = choose_dsm_implementation(); + printf("%s\n", dynamic_shared_memory_type); } /* @@ -1265,6 +1320,11 @@ setup_config(void) conflines = replace_token(conflines, "#log_timezone = 'GMT'", repltok); } + snprintf(repltok, sizeof(repltok), "dynamic_shared_memory_type = %s", + dynamic_shared_memory_type); + conflines = replace_token(conflines, "#dynamic_shared_memory_type = posix", + repltok); + snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data); writefile(path, conflines);