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