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