PostgreSQL Source Code  git master
main.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * main.c
4  * Stub main() routine for the postgres executable.
5  *
6  * This does some essential startup tasks for any incarnation of postgres
7  * (postmaster, standalone backend, standalone bootstrap process, or a
8  * separately exec'd child of a postmaster) and then dispatches to the
9  * proper FooMain() routine for the incarnation.
10  *
11  *
12  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  * src/backend/main/main.c
18  *
19  *-------------------------------------------------------------------------
20  */
21 #include "postgres.h"
22 
23 #include <unistd.h>
24 
25 #if defined(WIN32)
26 #include <crtdbg.h>
27 #endif
28 
29 #if defined(__NetBSD__)
30 #include <sys/param.h>
31 #endif
32 
33 #if defined(_M_AMD64) && _MSC_VER == 1800
34 #include <math.h>
35 #include <versionhelpers.h>
36 #endif
37 
38 #include "bootstrap/bootstrap.h"
39 #include "common/username.h"
40 #include "port/atomics.h"
41 #include "postmaster/postmaster.h"
42 #include "storage/spin.h"
43 #include "tcop/tcopprot.h"
44 #include "utils/help_config.h"
45 #include "utils/memutils.h"
46 #include "utils/pg_locale.h"
47 #include "utils/ps_status.h"
48 
49 
50 const char *progname;
51 
52 
53 static void startup_hacks(const char *progname);
54 static void init_locale(const char *categoryname, int category, const char *locale);
55 static void help(const char *progname);
56 static void check_root(const char *progname);
57 
58 
59 /*
60  * Any Postgres server process begins execution here.
61  */
62 int
63 main(int argc, char *argv[])
64 {
65  bool do_check_root = true;
66 
67  /*
68  * If supported on the current platform, set up a handler to be called if
69  * the backend/postmaster crashes with a fatal signal or exception.
70  */
71 #if defined(WIN32) && defined(HAVE_MINIDUMP_TYPE)
73 #endif
74 
75  progname = get_progname(argv[0]);
76 
77  /*
78  * Platform-specific startup hacks
79  */
81 
82  /*
83  * Remember the physical location of the initially given argv[] array for
84  * possible use by ps display. On some platforms, the argv[] storage must
85  * be overwritten in order to set the process title for ps. In such cases
86  * save_ps_display_args makes and returns a new copy of the argv[] array.
87  *
88  * save_ps_display_args may also move the environment strings to make
89  * extra room. Therefore this should be done as early as possible during
90  * startup, to avoid entanglements with code that might save a getenv()
91  * result pointer.
92  */
93  argv = save_ps_display_args(argc, argv);
94 
95  /*
96  * Fire up essential subsystems: error and memory management
97  *
98  * Code after this point is allowed to use elog/ereport, though
99  * localization of messages may not work right away, and messages won't go
100  * anywhere but stderr until GUC settings get loaded.
101  */
103 
104  /*
105  * Set up locale information
106  */
107  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
108 
109  /*
110  * In the postmaster, absorb the environment values for LC_COLLATE and
111  * LC_CTYPE. Individual backends will change these later to settings
112  * taken from pg_database, but the postmaster cannot do that. If we leave
113  * these set to "C" then message localization might not work well in the
114  * postmaster.
115  */
116  init_locale("LC_COLLATE", LC_COLLATE, "");
117  init_locale("LC_CTYPE", LC_CTYPE, "");
118 
119  /*
120  * LC_MESSAGES will get set later during GUC option processing, but we set
121  * it here to allow startup error messages to be localized.
122  */
123 #ifdef LC_MESSAGES
124  init_locale("LC_MESSAGES", LC_MESSAGES, "");
125 #endif
126 
127  /*
128  * We keep these set to "C" always, except transiently in pg_locale.c; see
129  * that file for explanations.
130  */
131  init_locale("LC_MONETARY", LC_MONETARY, "C");
132  init_locale("LC_NUMERIC", LC_NUMERIC, "C");
133  init_locale("LC_TIME", LC_TIME, "C");
134 
135  /*
136  * Now that we have absorbed as much as we wish to from the locale
137  * environment, remove any LC_ALL setting, so that the environment
138  * variables installed by pg_perm_setlocale have force.
139  */
140  unsetenv("LC_ALL");
141 
143 
144  /*
145  * Catch standard options before doing much else, in particular before we
146  * insist on not being root.
147  */
148  if (argc > 1)
149  {
150  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
151  {
152  help(progname);
153  exit(0);
154  }
155  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
156  {
158  exit(0);
159  }
160 
161  /*
162  * In addition to the above, we allow "--describe-config" and "-C var"
163  * to be called by root. This is reasonably safe since these are
164  * read-only activities. The -C case is important because pg_ctl may
165  * try to invoke it while still holding administrator privileges on
166  * Windows. Note that while -C can normally be in any argv position,
167  * if you want to bypass the root check you must put it first. This
168  * reduces the risk that we might misinterpret some other mode's -C
169  * switch as being the postmaster/postgres one.
170  */
171  if (strcmp(argv[1], "--describe-config") == 0)
172  do_check_root = false;
173  else if (argc > 2 && strcmp(argv[1], "-C") == 0)
174  do_check_root = false;
175  }
176 
177  /*
178  * Make sure we are not running as root, unless it's safe for the selected
179  * option.
180  */
181  if (do_check_root)
183 
184  /*
185  * Dispatch to one of various subprograms depending on first argument.
186  */
187 
188  if (argc > 1 && strcmp(argv[1], "--check") == 0)
189  BootstrapModeMain(argc, argv, true);
190  else if (argc > 1 && strcmp(argv[1], "--boot") == 0)
191  BootstrapModeMain(argc, argv, false);
192 #ifdef EXEC_BACKEND
193  else if (argc > 1 && strncmp(argv[1], "--fork", 6) == 0)
194  SubPostmasterMain(argc, argv);
195 #endif
196  else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
197  GucInfoMain();
198  else if (argc > 1 && strcmp(argv[1], "--single") == 0)
199  PostgresSingleUserMain(argc, argv,
201  else
202  PostmasterMain(argc, argv);
203  /* the functions above should not return */
204  abort();
205 }
206 
207 
208 
209 /*
210  * Place platform-specific startup hacks here. This is the right
211  * place to put code that must be executed early in the launch of any new
212  * server process. Note that this code will NOT be executed when a backend
213  * or sub-bootstrap process is forked, unless we are in a fork/exec
214  * environment (ie EXEC_BACKEND is defined).
215  *
216  * XXX The need for code here is proof that the platform in question
217  * is too brain-dead to provide a standard C execution environment
218  * without help. Avoid adding more here, if you can.
219  */
220 static void
222 {
223  /*
224  * Windows-specific execution environment hacking.
225  */
226 #ifdef WIN32
227  {
228  WSADATA wsaData;
229  int err;
230 
231  /* Make output streams unbuffered by default */
232  setvbuf(stdout, NULL, _IONBF, 0);
233  setvbuf(stderr, NULL, _IONBF, 0);
234 
235  /* Prepare Winsock */
236  err = WSAStartup(MAKEWORD(2, 2), &wsaData);
237  if (err != 0)
238  {
239  write_stderr("%s: WSAStartup failed: %d\n",
240  progname, err);
241  exit(1);
242  }
243 
244  /*
245  * By default abort() only generates a crash-dump in *non* debug
246  * builds. As our Assert() / ExceptionalCondition() uses abort(),
247  * leaving the default in place would make debugging harder.
248  *
249  * MINGW's own C runtime doesn't have _set_abort_behavior(). When
250  * targeting Microsoft's UCRT with mingw, it never links to the debug
251  * version of the library and thus doesn't need the call to
252  * _set_abort_behavior() either.
253  */
254 #if !defined(__MINGW32__) && !defined(__MINGW64__)
255  _set_abort_behavior(_CALL_REPORTFAULT | _WRITE_ABORT_MSG,
256  _CALL_REPORTFAULT | _WRITE_ABORT_MSG);
257 #endif /* !defined(__MINGW32__) &&
258  * !defined(__MINGW64__) */
259 
260  /*
261  * SEM_FAILCRITICALERRORS causes more errors to be reported to
262  * callers.
263  *
264  * We used to also specify SEM_NOGPFAULTERRORBOX, but that prevents
265  * windows crash reporting from working. Which includes registered
266  * just-in-time debuggers, making it unnecessarily hard to debug
267  * problems on windows. Now we try to disable sources of popups
268  * separately below (note that SEM_NOGPFAULTERRORBOX did not actually
269  * prevent all sources of such popups).
270  */
271  SetErrorMode(SEM_FAILCRITICALERRORS);
272 
273  /*
274  * Show errors on stderr instead of popup box (note this doesn't
275  * affect errors originating in the C runtime, see below).
276  */
277  _set_error_mode(_OUT_TO_STDERR);
278 
279  /*
280  * In DEBUG builds, errors, including assertions, C runtime errors are
281  * reported via _CrtDbgReport. By default such errors are displayed
282  * with a popup (even with NOGPFAULTERRORBOX), preventing forward
283  * progress. Instead report such errors stderr (and the debugger).
284  * This is C runtime specific and thus the above incantations aren't
285  * sufficient to suppress these popups.
286  */
287  _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
288  _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
289  _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
290  _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
291  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
292  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
293 
294 #if defined(_M_AMD64) && _MSC_VER == 1800
295 
296  /*----------
297  * Avoid crashing in certain floating-point operations if we were
298  * compiled for x64 with MS Visual Studio 2013 and are running on
299  * Windows prior to 7/2008R2 SP1 on an AVX2-capable CPU.
300  *
301  * Ref: https://connect.microsoft.com/VisualStudio/feedback/details/811093/visual-studio-2013-rtm-c-x64-code-generation-bug-for-avx2-instructions
302  *----------
303  */
304  if (!IsWindows7SP1OrGreater())
305  {
306  _set_FMA3_enable(0);
307  }
308 #endif /* defined(_M_AMD64) && _MSC_VER == 1800 */
309 
310  }
311 #endif /* WIN32 */
312 
313  /*
314  * Initialize dummy_spinlock, in case we are on a platform where we have
315  * to use the fallback implementation of pg_memory_barrier().
316  */
318 }
319 
320 
321 /*
322  * Make the initial permanent setting for a locale category. If that fails,
323  * perhaps due to LC_foo=invalid in the environment, use locale C. If even
324  * that fails, perhaps due to out-of-memory, the entire startup fails with it.
325  * When this returns, we are guaranteed to have a setting for the given
326  * category's environment variable.
327  */
328 static void
329 init_locale(const char *categoryname, int category, const char *locale)
330 {
331  if (pg_perm_setlocale(category, locale) == NULL &&
332  pg_perm_setlocale(category, "C") == NULL)
333  elog(FATAL, "could not adopt \"%s\" locale nor C locale for %s",
334  locale, categoryname);
335 }
336 
337 
338 
339 /*
340  * Help display should match the options accepted by PostmasterMain()
341  * and PostgresMain().
342  *
343  * XXX On Windows, non-ASCII localizations of these messages only display
344  * correctly if the console output code page covers the necessary characters.
345  * Messages emitted in write_console() do not exhibit this problem.
346  */
347 static void
348 help(const char *progname)
349 {
350  printf(_("%s is the PostgreSQL server.\n\n"), progname);
351  printf(_("Usage:\n %s [OPTION]...\n\n"), progname);
352  printf(_("Options:\n"));
353  printf(_(" -B NBUFFERS number of shared buffers\n"));
354  printf(_(" -c NAME=VALUE set run-time parameter\n"));
355  printf(_(" -C NAME print value of run-time parameter, then exit\n"));
356  printf(_(" -d 1-5 debugging level\n"));
357  printf(_(" -D DATADIR database directory\n"));
358  printf(_(" -e use European date input format (DMY)\n"));
359  printf(_(" -F turn fsync off\n"));
360  printf(_(" -h HOSTNAME host name or IP address to listen on\n"));
361  printf(_(" -i enable TCP/IP connections\n"));
362  printf(_(" -k DIRECTORY Unix-domain socket location\n"));
363 #ifdef USE_SSL
364  printf(_(" -l enable SSL connections\n"));
365 #endif
366  printf(_(" -N MAX-CONNECT maximum number of allowed connections\n"));
367  printf(_(" -p PORT port number to listen on\n"));
368  printf(_(" -s show statistics after each query\n"));
369  printf(_(" -S WORK-MEM set amount of memory for sorts (in kB)\n"));
370  printf(_(" -V, --version output version information, then exit\n"));
371  printf(_(" --NAME=VALUE set run-time parameter\n"));
372  printf(_(" --describe-config describe configuration parameters, then exit\n"));
373  printf(_(" -?, --help show this help, then exit\n"));
374 
375  printf(_("\nDeveloper options:\n"));
376  printf(_(" -f s|i|n|m|h forbid use of some plan types\n"));
377  printf(_(" -n do not reinitialize shared memory after abnormal exit\n"));
378  printf(_(" -O allow system table structure changes\n"));
379  printf(_(" -P disable system indexes\n"));
380  printf(_(" -t pa|pl|ex show timings after each query\n"));
381  printf(_(" -T send SIGSTOP to all backend processes if one dies\n"));
382  printf(_(" -W NUM wait NUM seconds to allow attach from a debugger\n"));
383 
384  printf(_("\nOptions for single-user mode:\n"));
385  printf(_(" --single selects single-user mode (must be first argument)\n"));
386  printf(_(" DBNAME database name (defaults to user name)\n"));
387  printf(_(" -d 0-5 override debugging level\n"));
388  printf(_(" -E echo statement before execution\n"));
389  printf(_(" -j do not use newline as interactive query delimiter\n"));
390  printf(_(" -r FILENAME send stdout and stderr to given file\n"));
391 
392  printf(_("\nOptions for bootstrapping mode:\n"));
393  printf(_(" --boot selects bootstrapping mode (must be first argument)\n"));
394  printf(_(" --check selects check mode (must be first argument)\n"));
395  printf(_(" DBNAME database name (mandatory argument in bootstrapping mode)\n"));
396  printf(_(" -r FILENAME send stdout and stderr to given file\n"));
397 
398  printf(_("\nPlease read the documentation for the complete list of run-time\n"
399  "configuration settings and how to set them on the command line or in\n"
400  "the configuration file.\n\n"
401  "Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
402  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
403 }
404 
405 
406 
407 static void
408 check_root(const char *progname)
409 {
410 #ifndef WIN32
411  if (geteuid() == 0)
412  {
413  write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
414  "The server must be started under an unprivileged user ID to prevent\n"
415  "possible system security compromise. See the documentation for\n"
416  "more information on how to properly start the server.\n");
417  exit(1);
418  }
419 
420  /*
421  * Also make sure that real and effective uids are the same. Executing as
422  * a setuid program from a root shell is a security hole, since on many
423  * platforms a nefarious subroutine could setuid back to root if real uid
424  * is root. (Since nobody actually uses postgres as a setuid program,
425  * trying to actively fix this situation seems more trouble than it's
426  * worth; we'll just expend the effort to check for it.)
427  */
428  if (getuid() != geteuid())
429  {
430  write_stderr("%s: real and effective user IDs must match\n",
431  progname);
432  exit(1);
433  }
434 #else /* WIN32 */
435  if (pgwin32_is_admin())
436  {
437  write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n"
438  "permitted.\n"
439  "The server must be started under an unprivileged user ID to prevent\n"
440  "possible system security compromises. See the documentation for\n"
441  "more information on how to properly start the server.\n");
442  exit(1);
443  }
444 #endif /* WIN32 */
445 }
#define write_stderr(str)
Definition: parallel.c:186
void BootstrapModeMain(int argc, char *argv[], bool check_only)
Definition: bootstrap.c:203
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1223
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:446
void pgwin32_install_crashdump_handler(void)
Definition: crashdump.c:178
#define _(x)
Definition: elog.c:89
#define FATAL
Definition: elog.h:35
void GucInfoMain(void)
Definition: help_config.c:46
static char * locale
Definition: initdb.c:128
exit(1)
static void init_locale(const char *categoryname, int category, const char *locale)
Definition: main.c:329
static void check_root(const char *progname)
Definition: main.c:408
int main(int argc, char *argv[])
Definition: main.c:63
static void help(const char *progname)
Definition: main.c:348
static void startup_hacks(const char *progname)
Definition: main.c:221
const char * progname
Definition: main.c:50
void MemoryContextInit(void)
Definition: mcxt.c:99
void check_strxfrm_bug(void)
Definition: pg_locale.c:1177
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:143
const char * get_progname(const char *argv0)
Definition: path.c:574
#define PG_BACKEND_VERSIONSTR
Definition: port.h:139
#define printf(...)
Definition: port.h:231
void PostgresSingleUserMain(int argc, char *argv[], const char *username)
Definition: postgres.c:3961
void PostmasterMain(int argc, char *argv[])
Definition: postmaster.c:574
char ** save_ps_display_args(int argc, char **argv)
Definition: ps_status.c:131
slock_t dummy_spinlock
Definition: s_lock.c:64
#define SpinLockInit(lock)
Definition: spin.h:60
const char * get_user_name_or_exit(const char *progname)
Definition: username.c:74
#define unsetenv(x)
Definition: win32_port.h:508
int pgwin32_is_admin(void)
Definition: win32security.c:49