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