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.
This commit is contained in:
Robert Haas 2013-10-10 19:38:56 -04:00
parent 15e46fd1dd
commit 7195fb3cec
1 changed files with 60 additions and 0 deletions

View File

@ -56,6 +56,10 @@
#include <signal.h>
#include <time.h>
#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);