| 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-2019, 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(__NetBSD__) |
| 26 | #include <sys/param.h> |
| 27 | #endif |
| 28 | |
| 29 | #if defined(_M_AMD64) && _MSC_VER == 1800 |
| 30 | #include <math.h> |
| 31 | #include <versionhelpers.h> |
| 32 | #endif |
| 33 | |
| 34 | #include "bootstrap/bootstrap.h" |
| 35 | #include "common/username.h" |
| 36 | #include "port/atomics.h" |
| 37 | #include "postmaster/postmaster.h" |
| 38 | #include "storage/s_lock.h" |
| 39 | #include "storage/spin.h" |
| 40 | #include "tcop/tcopprot.h" |
| 41 | #include "utils/help_config.h" |
| 42 | #include "utils/memutils.h" |
| 43 | #include "utils/pg_locale.h" |
| 44 | #include "utils/ps_status.h" |
| 45 | |
| 46 | |
| 47 | const char *progname; |
| 48 | |
| 49 | |
| 50 | static void startup_hacks(const char *progname); |
| 51 | static void init_locale(const char *categoryname, int category, const char *locale); |
| 52 | static void help(const char *progname); |
| 53 | static void check_root(const char *progname); |
| 54 | |
| 55 | |
| 56 | /* |
| 57 | * Any Postgres server process begins execution here. |
| 58 | */ |
| 59 | int |
| 60 | main(int argc, char *argv[]) |
| 61 | { |
| 62 | bool do_check_root = 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) && defined(HAVE_MINIDUMP_TYPE) |
| 69 | pgwin32_install_crashdump_handler(); |
| 70 | #endif |
| 71 | |
| 72 | progname = get_progname(argv[0]); |
| 73 | |
| 74 | /* |
| 75 | * Platform-specific startup hacks |
| 76 | */ |
| 77 | startup_hacks(progname); |
| 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 | */ |
| 99 | MemoryContextInit(); |
| 100 | |
| 101 | /* |
| 102 | * Set up locale information from environment. Note that LC_CTYPE and |
| 103 | * LC_COLLATE will be overridden later from pg_control if we are in an |
| 104 | * already-initialized database. We set them here so that they will be |
| 105 | * available to fill pg_control during initdb. LC_MESSAGES will get set |
| 106 | * later during GUC option processing, but we set it here to allow startup |
| 107 | * error messages to be localized. |
| 108 | */ |
| 109 | |
| 110 | set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres" )); |
| 111 | |
| 112 | #ifdef WIN32 |
| 113 | |
| 114 | /* |
| 115 | * Windows uses codepages rather than the environment, so we work around |
| 116 | * that by querying the environment explicitly first for LC_COLLATE and |
| 117 | * LC_CTYPE. We have to do this because initdb passes those values in the |
| 118 | * environment. If there is nothing there we fall back on the codepage. |
| 119 | */ |
| 120 | { |
| 121 | char *env_locale; |
| 122 | |
| 123 | if ((env_locale = getenv("LC_COLLATE" )) != NULL) |
| 124 | init_locale("LC_COLLATE" , LC_COLLATE, env_locale); |
| 125 | else |
| 126 | init_locale("LC_COLLATE" , LC_COLLATE, "" ); |
| 127 | |
| 128 | if ((env_locale = getenv("LC_CTYPE" )) != NULL) |
| 129 | init_locale("LC_CTYPE" , LC_CTYPE, env_locale); |
| 130 | else |
| 131 | init_locale("LC_CTYPE" , LC_CTYPE, "" ); |
| 132 | } |
| 133 | #else |
| 134 | init_locale("LC_COLLATE" , LC_COLLATE, "" ); |
| 135 | init_locale("LC_CTYPE" , LC_CTYPE, "" ); |
| 136 | #endif |
| 137 | |
| 138 | #ifdef LC_MESSAGES |
| 139 | init_locale("LC_MESSAGES" , LC_MESSAGES, "" ); |
| 140 | #endif |
| 141 | |
| 142 | /* |
| 143 | * We keep these set to "C" always, except transiently in pg_locale.c; see |
| 144 | * that file for explanations. |
| 145 | */ |
| 146 | init_locale("LC_MONETARY" , LC_MONETARY, "C" ); |
| 147 | init_locale("LC_NUMERIC" , LC_NUMERIC, "C" ); |
| 148 | init_locale("LC_TIME" , LC_TIME, "C" ); |
| 149 | |
| 150 | /* |
| 151 | * Now that we have absorbed as much as we wish to from the locale |
| 152 | * environment, remove any LC_ALL setting, so that the environment |
| 153 | * variables installed by pg_perm_setlocale have force. |
| 154 | */ |
| 155 | unsetenv("LC_ALL" ); |
| 156 | |
| 157 | check_strxfrm_bug(); |
| 158 | |
| 159 | /* |
| 160 | * Catch standard options before doing much else, in particular before we |
| 161 | * insist on not being root. |
| 162 | */ |
| 163 | if (argc > 1) |
| 164 | { |
| 165 | if (strcmp(argv[1], "--help" ) == 0 || strcmp(argv[1], "-?" ) == 0) |
| 166 | { |
| 167 | help(progname); |
| 168 | exit(0); |
| 169 | } |
| 170 | if (strcmp(argv[1], "--version" ) == 0 || strcmp(argv[1], "-V" ) == 0) |
| 171 | { |
| 172 | fputs(PG_BACKEND_VERSIONSTR, stdout); |
| 173 | exit(0); |
| 174 | } |
| 175 | |
| 176 | /* |
| 177 | * In addition to the above, we allow "--describe-config" and "-C var" |
| 178 | * to be called by root. This is reasonably safe since these are |
| 179 | * read-only activities. The -C case is important because pg_ctl may |
| 180 | * try to invoke it while still holding administrator privileges on |
| 181 | * Windows. Note that while -C can normally be in any argv position, |
| 182 | * if you want to bypass the root check you must put it first. This |
| 183 | * reduces the risk that we might misinterpret some other mode's -C |
| 184 | * switch as being the postmaster/postgres one. |
| 185 | */ |
| 186 | if (strcmp(argv[1], "--describe-config" ) == 0) |
| 187 | do_check_root = false; |
| 188 | else if (argc > 2 && strcmp(argv[1], "-C" ) == 0) |
| 189 | do_check_root = false; |
| 190 | } |
| 191 | |
| 192 | /* |
| 193 | * Make sure we are not running as root, unless it's safe for the selected |
| 194 | * option. |
| 195 | */ |
| 196 | if (do_check_root) |
| 197 | check_root(progname); |
| 198 | |
| 199 | /* |
| 200 | * Dispatch to one of various subprograms depending on first argument. |
| 201 | */ |
| 202 | |
| 203 | #ifdef EXEC_BACKEND |
| 204 | if (argc > 1 && strncmp(argv[1], "--fork" , 6) == 0) |
| 205 | SubPostmasterMain(argc, argv); /* does not return */ |
| 206 | #endif |
| 207 | |
| 208 | #ifdef WIN32 |
| 209 | |
| 210 | /* |
| 211 | * Start our win32 signal implementation |
| 212 | * |
| 213 | * SubPostmasterMain() will do this for itself, but the remaining modes |
| 214 | * need it here |
| 215 | */ |
| 216 | pgwin32_signal_initialize(); |
| 217 | #endif |
| 218 | |
| 219 | if (argc > 1 && strcmp(argv[1], "--boot" ) == 0) |
| 220 | AuxiliaryProcessMain(argc, argv); /* does not return */ |
| 221 | else if (argc > 1 && strcmp(argv[1], "--describe-config" ) == 0) |
| 222 | GucInfoMain(); /* does not return */ |
| 223 | else if (argc > 1 && strcmp(argv[1], "--single" ) == 0) |
| 224 | PostgresMain(argc, argv, |
| 225 | NULL, /* no dbname */ |
| 226 | strdup(get_user_name_or_exit(progname))); /* does not return */ |
| 227 | else |
| 228 | PostmasterMain(argc, argv); /* does not return */ |
| 229 | abort(); /* should not get here */ |
| 230 | } |
| 231 | |
| 232 | |
| 233 | |
| 234 | /* |
| 235 | * Place platform-specific startup hacks here. This is the right |
| 236 | * place to put code that must be executed early in the launch of any new |
| 237 | * server process. Note that this code will NOT be executed when a backend |
| 238 | * or sub-bootstrap process is forked, unless we are in a fork/exec |
| 239 | * environment (ie EXEC_BACKEND is defined). |
| 240 | * |
| 241 | * XXX The need for code here is proof that the platform in question |
| 242 | * is too brain-dead to provide a standard C execution environment |
| 243 | * without help. Avoid adding more here, if you can. |
| 244 | */ |
| 245 | static void |
| 246 | startup_hacks(const char *progname) |
| 247 | { |
| 248 | /* |
| 249 | * Windows-specific execution environment hacking. |
| 250 | */ |
| 251 | #ifdef WIN32 |
| 252 | { |
| 253 | WSADATA wsaData; |
| 254 | int err; |
| 255 | |
| 256 | /* Make output streams unbuffered by default */ |
| 257 | setvbuf(stdout, NULL, _IONBF, 0); |
| 258 | setvbuf(stderr, NULL, _IONBF, 0); |
| 259 | |
| 260 | /* Prepare Winsock */ |
| 261 | err = WSAStartup(MAKEWORD(2, 2), &wsaData); |
| 262 | if (err != 0) |
| 263 | { |
| 264 | write_stderr("%s: WSAStartup failed: %d\n" , |
| 265 | progname, err); |
| 266 | exit(1); |
| 267 | } |
| 268 | |
| 269 | /* In case of general protection fault, don't show GUI popup box */ |
| 270 | SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); |
| 271 | |
| 272 | #if defined(_M_AMD64) && _MSC_VER == 1800 |
| 273 | |
| 274 | /*---------- |
| 275 | * Avoid crashing in certain floating-point operations if we were |
| 276 | * compiled for x64 with MS Visual Studio 2013 and are running on |
| 277 | * Windows prior to 7/2008R2 SP1 on an AVX2-capable CPU. |
| 278 | * |
| 279 | * Ref: https://connect.microsoft.com/VisualStudio/feedback/details/811093/visual-studio-2013-rtm-c-x64-code-generation-bug-for-avx2-instructions |
| 280 | *---------- |
| 281 | */ |
| 282 | if (!IsWindows7SP1OrGreater()) |
| 283 | { |
| 284 | _set_FMA3_enable(0); |
| 285 | } |
| 286 | #endif /* defined(_M_AMD64) && _MSC_VER == 1800 */ |
| 287 | |
| 288 | } |
| 289 | #endif /* WIN32 */ |
| 290 | |
| 291 | /* |
| 292 | * Initialize dummy_spinlock, in case we are on a platform where we have |
| 293 | * to use the fallback implementation of pg_memory_barrier(). |
| 294 | */ |
| 295 | SpinLockInit(&dummy_spinlock); |
| 296 | } |
| 297 | |
| 298 | |
| 299 | /* |
| 300 | * Make the initial permanent setting for a locale category. If that fails, |
| 301 | * perhaps due to LC_foo=invalid in the environment, use locale C. If even |
| 302 | * that fails, perhaps due to out-of-memory, the entire startup fails with it. |
| 303 | * When this returns, we are guaranteed to have a setting for the given |
| 304 | * category's environment variable. |
| 305 | */ |
| 306 | static void |
| 307 | init_locale(const char *categoryname, int category, const char *locale) |
| 308 | { |
| 309 | if (pg_perm_setlocale(category, locale) == NULL && |
| 310 | pg_perm_setlocale(category, "C" ) == NULL) |
| 311 | elog(FATAL, "could not adopt \"%s\" locale nor C locale for %s" , |
| 312 | locale, categoryname); |
| 313 | } |
| 314 | |
| 315 | |
| 316 | |
| 317 | /* |
| 318 | * Help display should match the options accepted by PostmasterMain() |
| 319 | * and PostgresMain(). |
| 320 | * |
| 321 | * XXX On Windows, non-ASCII localizations of these messages only display |
| 322 | * correctly if the console output code page covers the necessary characters. |
| 323 | * Messages emitted in write_console() do not exhibit this problem. |
| 324 | */ |
| 325 | static void |
| 326 | help(const char *progname) |
| 327 | { |
| 328 | printf(_("%s is the PostgreSQL server.\n\n" ), progname); |
| 329 | printf(_("Usage:\n %s [OPTION]...\n\n" ), progname); |
| 330 | printf(_("Options:\n" )); |
| 331 | printf(_(" -B NBUFFERS number of shared buffers\n" )); |
| 332 | printf(_(" -c NAME=VALUE set run-time parameter\n" )); |
| 333 | printf(_(" -C NAME print value of run-time parameter, then exit\n" )); |
| 334 | printf(_(" -d 1-5 debugging level\n" )); |
| 335 | printf(_(" -D DATADIR database directory\n" )); |
| 336 | printf(_(" -e use European date input format (DMY)\n" )); |
| 337 | printf(_(" -F turn fsync off\n" )); |
| 338 | printf(_(" -h HOSTNAME host name or IP address to listen on\n" )); |
| 339 | printf(_(" -i enable TCP/IP connections\n" )); |
| 340 | printf(_(" -k DIRECTORY Unix-domain socket location\n" )); |
| 341 | #ifdef USE_SSL |
| 342 | printf(_(" -l enable SSL connections\n" )); |
| 343 | #endif |
| 344 | printf(_(" -N MAX-CONNECT maximum number of allowed connections\n" )); |
| 345 | printf(_(" -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\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|n|m|h forbid use of some plan types\n" )); |
| 356 | printf(_(" -n do not reinitialize shared memory after abnormal exit\n" )); |
| 357 | printf(_(" -O allow system table structure changes\n" )); |
| 358 | printf(_(" -P disable system indexes\n" )); |
| 359 | printf(_(" -t pa|pl|ex show timings after each query\n" )); |
| 360 | printf(_(" -T send SIGSTOP to all backend processes if one dies\n" )); |
| 361 | printf(_(" -W NUM wait NUM seconds to allow attach from a debugger\n" )); |
| 362 | |
| 363 | printf(_("\nOptions for single-user mode:\n" )); |
| 364 | printf(_(" --single selects single-user mode (must be first argument)\n" )); |
| 365 | printf(_(" DBNAME database name (defaults to user name)\n" )); |
| 366 | printf(_(" -d 0-5 override debugging level\n" )); |
| 367 | printf(_(" -E echo statement before execution\n" )); |
| 368 | printf(_(" -j do not use newline as interactive query delimiter\n" )); |
| 369 | printf(_(" -r FILENAME send stdout and stderr to given file\n" )); |
| 370 | |
| 371 | printf(_("\nOptions for bootstrapping mode:\n" )); |
| 372 | printf(_(" --boot selects bootstrapping 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 | printf(_(" -x NUM internal use\n" )); |
| 376 | |
| 377 | printf(_("\nPlease read the documentation for the complete list of run-time\n" |
| 378 | "configuration settings and how to set them on the command line or in\n" |
| 379 | "the configuration file.\n\n" |
| 380 | "Report bugs to <pgsql-bugs@lists.postgresql.org>.\n" )); |
| 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 | |