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