Header And Logo

PostgreSQL
| The world's most advanced open source database.

main.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * main.c
00004  *    Stub main() routine for the postgres executable.
00005  *
00006  * This does some essential startup tasks for any incarnation of postgres
00007  * (postmaster, standalone backend, standalone bootstrap process, or a
00008  * separately exec'd child of a postmaster) and then dispatches to the
00009  * proper FooMain() routine for the incarnation.
00010  *
00011  *
00012  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00013  * Portions Copyright (c) 1994, Regents of the University of California
00014  *
00015  *
00016  * IDENTIFICATION
00017  *    src/backend/main/main.c
00018  *
00019  *-------------------------------------------------------------------------
00020  */
00021 #include "postgres.h"
00022 
00023 #include <pwd.h>
00024 #include <unistd.h>
00025 
00026 #if defined(__alpha) && defined(__osf__)        /* no __alpha__ ? */
00027 #include <sys/sysinfo.h>
00028 #include "machine/hal_sysinfo.h"
00029 #define ASSEMBLER
00030 #include <sys/proc.h>
00031 #undef ASSEMBLER
00032 #endif
00033 
00034 #if defined(__NetBSD__)
00035 #include <sys/param.h>
00036 #endif
00037 
00038 #include "bootstrap/bootstrap.h"
00039 #include "postmaster/postmaster.h"
00040 #include "tcop/tcopprot.h"
00041 #include "utils/help_config.h"
00042 #include "utils/pg_locale.h"
00043 #include "utils/ps_status.h"
00044 
00045 
00046 const char *progname;
00047 
00048 
00049 static void startup_hacks(const char *progname);
00050 static void help(const char *progname);
00051 static void check_root(const char *progname);
00052 static char *get_current_username(const char *progname);
00053 
00054 
00055 /*
00056  * Any Postgres server process begins execution here.
00057  */
00058 int
00059 main(int argc, char *argv[])
00060 {
00061     progname = get_progname(argv[0]);
00062 
00063     /*
00064      * Platform-specific startup hacks
00065      */
00066     startup_hacks(progname);
00067 
00068     /*
00069      * Remember the physical location of the initially given argv[] array for
00070      * possible use by ps display.  On some platforms, the argv[] storage must
00071      * be overwritten in order to set the process title for ps. In such cases
00072      * save_ps_display_args makes and returns a new copy of the argv[] array.
00073      *
00074      * save_ps_display_args may also move the environment strings to make
00075      * extra room. Therefore this should be done as early as possible during
00076      * startup, to avoid entanglements with code that might save a getenv()
00077      * result pointer.
00078      */
00079     argv = save_ps_display_args(argc, argv);
00080 
00081     /*
00082      * If supported on the current platform, set up a handler to be called if
00083      * the backend/postmaster crashes with a fatal signal or exception.
00084      */
00085 #if defined(WIN32) && defined(HAVE_MINIDUMP_TYPE)
00086     pgwin32_install_crashdump_handler();
00087 #endif
00088 
00089     /*
00090      * Set up locale information from environment.  Note that LC_CTYPE and
00091      * LC_COLLATE will be overridden later from pg_control if we are in an
00092      * already-initialized database.  We set them here so that they will be
00093      * available to fill pg_control during initdb.  LC_MESSAGES will get set
00094      * later during GUC option processing, but we set it here to allow startup
00095      * error messages to be localized.
00096      */
00097 
00098     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
00099 
00100 #ifdef WIN32
00101 
00102     /*
00103      * Windows uses codepages rather than the environment, so we work around
00104      * that by querying the environment explicitly first for LC_COLLATE and
00105      * LC_CTYPE. We have to do this because initdb passes those values in the
00106      * environment. If there is nothing there we fall back on the codepage.
00107      */
00108     {
00109         char       *env_locale;
00110 
00111         if ((env_locale = getenv("LC_COLLATE")) != NULL)
00112             pg_perm_setlocale(LC_COLLATE, env_locale);
00113         else
00114             pg_perm_setlocale(LC_COLLATE, "");
00115 
00116         if ((env_locale = getenv("LC_CTYPE")) != NULL)
00117             pg_perm_setlocale(LC_CTYPE, env_locale);
00118         else
00119             pg_perm_setlocale(LC_CTYPE, "");
00120     }
00121 #else
00122     pg_perm_setlocale(LC_COLLATE, "");
00123     pg_perm_setlocale(LC_CTYPE, "");
00124 #endif
00125 
00126 #ifdef LC_MESSAGES
00127     pg_perm_setlocale(LC_MESSAGES, "");
00128 #endif
00129 
00130     /*
00131      * We keep these set to "C" always, except transiently in pg_locale.c; see
00132      * that file for explanations.
00133      */
00134     pg_perm_setlocale(LC_MONETARY, "C");
00135     pg_perm_setlocale(LC_NUMERIC, "C");
00136     pg_perm_setlocale(LC_TIME, "C");
00137 
00138     /*
00139      * Now that we have absorbed as much as we wish to from the locale
00140      * environment, remove any LC_ALL setting, so that the environment
00141      * variables installed by pg_perm_setlocale have force.
00142      */
00143     unsetenv("LC_ALL");
00144 
00145     /*
00146      * Catch standard options before doing much else
00147      */
00148     if (argc > 1)
00149     {
00150         if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
00151         {
00152             help(progname);
00153             exit(0);
00154         }
00155         if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
00156         {
00157             puts("postgres (PostgreSQL) " PG_VERSION);
00158             exit(0);
00159         }
00160     }
00161 
00162     /*
00163      * Make sure we are not running as root.
00164      */
00165     check_root(progname);
00166 
00167     /*
00168      * Dispatch to one of various subprograms depending on first argument.
00169      */
00170 
00171 #ifdef EXEC_BACKEND
00172     if (argc > 1 && strncmp(argv[1], "--fork", 6) == 0)
00173         SubPostmasterMain(argc, argv); /* does not return */
00174 #endif
00175 
00176 #ifdef WIN32
00177 
00178     /*
00179      * Start our win32 signal implementation
00180      *
00181      * SubPostmasterMain() will do this for itself, but the remaining modes
00182      * need it here
00183      */
00184     pgwin32_signal_initialize();
00185 #endif
00186 
00187     if (argc > 1 && strcmp(argv[1], "--boot") == 0)
00188         AuxiliaryProcessMain(argc, argv);       /* does not return */
00189     else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
00190         GucInfoMain();          /* does not return */
00191     else if (argc > 1 && strcmp(argv[1], "--single") == 0)
00192         PostgresMain(argc, argv,
00193                      NULL,      /* no dbname */
00194                      get_current_username(progname)); /* does not return */
00195     else
00196         PostmasterMain(argc, argv); /* does not return */
00197     abort();                        /* should not get here */
00198 }
00199 
00200 
00201 
00202 /*
00203  * Place platform-specific startup hacks here.  This is the right
00204  * place to put code that must be executed early in the launch of any new
00205  * server process.  Note that this code will NOT be executed when a backend
00206  * or sub-bootstrap process is forked, unless we are in a fork/exec
00207  * environment (ie EXEC_BACKEND is defined).
00208  *
00209  * XXX The need for code here is proof that the platform in question
00210  * is too brain-dead to provide a standard C execution environment
00211  * without help.  Avoid adding more here, if you can.
00212  */
00213 static void
00214 startup_hacks(const char *progname)
00215 {
00216     /*
00217      * On some platforms, unaligned memory accesses result in a kernel trap;
00218      * the default kernel behavior is to emulate the memory access, but this
00219      * results in a significant performance penalty.  We want PG never to make
00220      * such unaligned memory accesses, so this code disables the kernel
00221      * emulation: unaligned accesses will result in SIGBUS instead.
00222      */
00223 #ifdef NOFIXADE
00224 
00225 #if defined(__alpha)            /* no __alpha__ ? */
00226     {
00227         int         buffer[] = {SSIN_UACPROC, UAC_SIGBUS | UAC_NOPRINT};
00228 
00229         if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
00230                        (unsigned long) NULL) < 0)
00231             write_stderr("%s: setsysinfo failed: %s\n",
00232                          progname, strerror(errno));
00233     }
00234 #endif   /* __alpha */
00235 #endif   /* NOFIXADE */
00236 
00237     /*
00238      * Windows-specific execution environment hacking.
00239      */
00240 #ifdef WIN32
00241     {
00242         WSADATA     wsaData;
00243         int         err;
00244 
00245         /* Make output streams unbuffered by default */
00246         setvbuf(stdout, NULL, _IONBF, 0);
00247         setvbuf(stderr, NULL, _IONBF, 0);
00248 
00249         /* Prepare Winsock */
00250         err = WSAStartup(MAKEWORD(2, 2), &wsaData);
00251         if (err != 0)
00252         {
00253             write_stderr("%s: WSAStartup failed: %d\n",
00254                          progname, err);
00255             exit(1);
00256         }
00257 
00258         /* In case of general protection fault, don't show GUI popup box */
00259         SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
00260     }
00261 #endif   /* WIN32 */
00262 }
00263 
00264 
00265 /*
00266  * Help display should match the options accepted by PostmasterMain()
00267  * and PostgresMain().
00268  */
00269 static void
00270 help(const char *progname)
00271 {
00272     printf(_("%s is the PostgreSQL server.\n\n"), progname);
00273     printf(_("Usage:\n  %s [OPTION]...\n\n"), progname);
00274     printf(_("Options:\n"));
00275 #ifdef USE_ASSERT_CHECKING
00276     printf(_("  -A 1|0             enable/disable run-time assert checking\n"));
00277 #endif
00278     printf(_("  -B NBUFFERS        number of shared buffers\n"));
00279     printf(_("  -c NAME=VALUE      set run-time parameter\n"));
00280     printf(_("  -C NAME            print value of run-time parameter, then exit\n"));
00281     printf(_("  -d 1-5             debugging level\n"));
00282     printf(_("  -D DATADIR         database directory\n"));
00283     printf(_("  -e                 use European date input format (DMY)\n"));
00284     printf(_("  -F                 turn fsync off\n"));
00285     printf(_("  -h HOSTNAME        host name or IP address to listen on\n"));
00286     printf(_("  -i                 enable TCP/IP connections\n"));
00287     printf(_("  -k DIRECTORY       Unix-domain socket location\n"));
00288 #ifdef USE_SSL
00289     printf(_("  -l                 enable SSL connections\n"));
00290 #endif
00291     printf(_("  -N MAX-CONNECT     maximum number of allowed connections\n"));
00292     printf(_("  -o OPTIONS         pass \"OPTIONS\" to each server process (obsolete)\n"));
00293     printf(_("  -p PORT            port number to listen on\n"));
00294     printf(_("  -s                 show statistics after each query\n"));
00295     printf(_("  -S WORK-MEM        set amount of memory for sorts (in kB)\n"));
00296     printf(_("  -V, --version      output version information, then exit\n"));
00297     printf(_("  --NAME=VALUE       set run-time parameter\n"));
00298     printf(_("  --describe-config  describe configuration parameters, then exit\n"));
00299     printf(_("  -?, --help         show this help, then exit\n"));
00300 
00301     printf(_("\nDeveloper options:\n"));
00302     printf(_("  -f s|i|n|m|h       forbid use of some plan types\n"));
00303     printf(_("  -n                 do not reinitialize shared memory after abnormal exit\n"));
00304     printf(_("  -O                 allow system table structure changes\n"));
00305     printf(_("  -P                 disable system indexes\n"));
00306     printf(_("  -t pa|pl|ex        show timings after each query\n"));
00307     printf(_("  -T                 send SIGSTOP to all backend processes if one dies\n"));
00308     printf(_("  -W NUM             wait NUM seconds to allow attach from a debugger\n"));
00309 
00310     printf(_("\nOptions for single-user mode:\n"));
00311     printf(_("  --single           selects single-user mode (must be first argument)\n"));
00312     printf(_("  DBNAME             database name (defaults to user name)\n"));
00313     printf(_("  -d 0-5             override debugging level\n"));
00314     printf(_("  -E                 echo statement before execution\n"));
00315     printf(_("  -j                 do not use newline as interactive query delimiter\n"));
00316     printf(_("  -r FILENAME        send stdout and stderr to given file\n"));
00317 
00318     printf(_("\nOptions for bootstrapping mode:\n"));
00319     printf(_("  --boot             selects bootstrapping mode (must be first argument)\n"));
00320     printf(_("  DBNAME             database name (mandatory argument in bootstrapping mode)\n"));
00321     printf(_("  -r FILENAME        send stdout and stderr to given file\n"));
00322     printf(_("  -x NUM             internal use\n"));
00323 
00324     printf(_("\nPlease read the documentation for the complete list of run-time\n"
00325      "configuration settings and how to set them on the command line or in\n"
00326              "the configuration file.\n\n"
00327              "Report bugs to <[email protected]>.\n"));
00328 }
00329 
00330 
00331 
00332 static void
00333 check_root(const char *progname)
00334 {
00335 #ifndef WIN32
00336     if (geteuid() == 0)
00337     {
00338         write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
00339                      "The server must be started under an unprivileged user ID to prevent\n"
00340           "possible system security compromise.  See the documentation for\n"
00341                   "more information on how to properly start the server.\n");
00342         exit(1);
00343     }
00344 
00345     /*
00346      * Also make sure that real and effective uids are the same. Executing as
00347      * a setuid program from a root shell is a security hole, since on many
00348      * platforms a nefarious subroutine could setuid back to root if real uid
00349      * is root.  (Since nobody actually uses postgres as a setuid program,
00350      * trying to actively fix this situation seems more trouble than it's
00351      * worth; we'll just expend the effort to check for it.)
00352      */
00353     if (getuid() != geteuid())
00354     {
00355         write_stderr("%s: real and effective user IDs must match\n",
00356                      progname);
00357         exit(1);
00358     }
00359 #else                           /* WIN32 */
00360     if (pgwin32_is_admin())
00361     {
00362         write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n"
00363                      "permitted.\n"
00364                      "The server must be started under an unprivileged user ID to prevent\n"
00365          "possible system security compromises.  See the documentation for\n"
00366                   "more information on how to properly start the server.\n");
00367         exit(1);
00368     }
00369 #endif   /* WIN32 */
00370 }
00371 
00372 
00373 
00374 static char *
00375 get_current_username(const char *progname)
00376 {
00377 #ifndef WIN32
00378     struct passwd *pw;
00379 
00380     pw = getpwuid(geteuid());
00381     if (pw == NULL)
00382     {
00383         write_stderr("%s: invalid effective UID: %d\n",
00384                      progname, (int) geteuid());
00385         exit(1);
00386     }
00387     /* Allocate new memory because later getpwuid() calls can overwrite it. */
00388     return strdup(pw->pw_name);
00389 #else
00390     unsigned long namesize = 256 /* UNLEN */ + 1;
00391     char       *name;
00392 
00393     name = malloc(namesize);
00394     if (!GetUserName(name, &namesize))
00395     {
00396         write_stderr("%s: could not determine user name (GetUserName failed)\n",
00397                      progname);
00398         exit(1);
00399     }
00400 
00401     return name;
00402 #endif
00403 }