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