From: Robert Haas Date: Thu, 10 Oct 2013 23:38:56 +0000 (-0400) Subject: initdb: Select working dynamic shared memory implementation. X-Git-Tag: REL9_4_BETA1~1068 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7195fb3cec9a7cf60f203edfa224ec632f16a101;p=postgresql 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. --- 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);