LCOV - code coverage report
Current view: top level - src/backend/postmaster - startup.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 20 71 28.2 %
Date: 2017-09-29 15:12:54 Functions: 1 11 9.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * startup.c
       4             :  *
       5             :  * The Startup process initialises the server and performs any recovery
       6             :  * actions that have been specified. Notice that there is no "main loop"
       7             :  * since the Startup process ends as soon as initialisation is complete.
       8             :  * (in standby mode, one can think of the replay loop as a main loop,
       9             :  * though.)
      10             :  *
      11             :  *
      12             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
      13             :  *
      14             :  *
      15             :  * IDENTIFICATION
      16             :  *    src/backend/postmaster/startup.c
      17             :  *
      18             :  *-------------------------------------------------------------------------
      19             :  */
      20             : #include "postgres.h"
      21             : 
      22             : #include <signal.h>
      23             : #include <unistd.h>
      24             : 
      25             : #include "access/xlog.h"
      26             : #include "libpq/pqsignal.h"
      27             : #include "miscadmin.h"
      28             : #include "pgstat.h"
      29             : #include "postmaster/startup.h"
      30             : #include "storage/ipc.h"
      31             : #include "storage/latch.h"
      32             : #include "storage/pmsignal.h"
      33             : #include "storage/standby.h"
      34             : #include "utils/guc.h"
      35             : #include "utils/timeout.h"
      36             : 
      37             : 
      38             : /*
      39             :  * Flags set by interrupt handlers for later service in the redo loop.
      40             :  */
      41             : static volatile sig_atomic_t got_SIGHUP = false;
      42             : static volatile sig_atomic_t shutdown_requested = false;
      43             : static volatile sig_atomic_t promote_triggered = false;
      44             : 
      45             : /*
      46             :  * Flag set when executing a restore command, to tell SIGTERM signal handler
      47             :  * that it's safe to just proc_exit.
      48             :  */
      49             : static volatile sig_atomic_t in_restore_command = false;
      50             : 
      51             : /* Signal handlers */
      52             : static void startupproc_quickdie(SIGNAL_ARGS);
      53             : static void StartupProcSigUsr1Handler(SIGNAL_ARGS);
      54             : static void StartupProcTriggerHandler(SIGNAL_ARGS);
      55             : static void StartupProcSigHupHandler(SIGNAL_ARGS);
      56             : 
      57             : 
      58             : /* --------------------------------
      59             :  *      signal handler routines
      60             :  * --------------------------------
      61             :  */
      62             : 
      63             : /*
      64             :  * startupproc_quickdie() occurs when signalled SIGQUIT by the postmaster.
      65             :  *
      66             :  * Some backend has bought the farm,
      67             :  * so we need to stop what we're doing and exit.
      68             :  */
      69             : static void
      70           0 : startupproc_quickdie(SIGNAL_ARGS)
      71             : {
      72           0 :     PG_SETMASK(&BlockSig);
      73             : 
      74             :     /*
      75             :      * We DO NOT want to run proc_exit() callbacks -- we're here because
      76             :      * shared memory may be corrupted, so we don't want to try to clean up our
      77             :      * transaction.  Just nail the windows shut and get out of town.  Now that
      78             :      * there's an atexit callback to prevent third-party code from breaking
      79             :      * things by calling exit() directly, we have to reset the callbacks
      80             :      * explicitly to make this work as intended.
      81             :      */
      82           0 :     on_exit_reset();
      83             : 
      84             :     /*
      85             :      * Note we do exit(2) not exit(0).  This is to force the postmaster into a
      86             :      * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
      87             :      * backend.  This is necessary precisely because we don't clean up our
      88             :      * shared memory state.  (The "dead man switch" mechanism in pmsignal.c
      89             :      * should ensure the postmaster sees this as a crash, too, but no harm in
      90             :      * being doubly sure.)
      91             :      */
      92           0 :     exit(2);
      93             : }
      94             : 
      95             : 
      96             : /* SIGUSR1: let latch facility handle the signal */
      97             : static void
      98           0 : StartupProcSigUsr1Handler(SIGNAL_ARGS)
      99             : {
     100           0 :     int         save_errno = errno;
     101             : 
     102           0 :     latch_sigusr1_handler();
     103             : 
     104           0 :     errno = save_errno;
     105           0 : }
     106             : 
     107             : /* SIGUSR2: set flag to finish recovery */
     108             : static void
     109           0 : StartupProcTriggerHandler(SIGNAL_ARGS)
     110             : {
     111           0 :     int         save_errno = errno;
     112             : 
     113           0 :     promote_triggered = true;
     114           0 :     WakeupRecovery();
     115             : 
     116           0 :     errno = save_errno;
     117           0 : }
     118             : 
     119             : /* SIGHUP: set flag to re-read config file at next convenient time */
     120             : static void
     121           0 : StartupProcSigHupHandler(SIGNAL_ARGS)
     122             : {
     123           0 :     int         save_errno = errno;
     124             : 
     125           0 :     got_SIGHUP = true;
     126           0 :     WakeupRecovery();
     127             : 
     128           0 :     errno = save_errno;
     129           0 : }
     130             : 
     131             : /* SIGTERM: set flag to abort redo and exit */
     132             : static void
     133           0 : StartupProcShutdownHandler(SIGNAL_ARGS)
     134             : {
     135           0 :     int         save_errno = errno;
     136             : 
     137           0 :     if (in_restore_command)
     138           0 :         proc_exit(1);
     139             :     else
     140           0 :         shutdown_requested = true;
     141           0 :     WakeupRecovery();
     142             : 
     143           0 :     errno = save_errno;
     144           0 : }
     145             : 
     146             : /* Handle SIGHUP and SIGTERM signals of startup process */
     147             : void
     148           0 : HandleStartupProcInterrupts(void)
     149             : {
     150             :     /*
     151             :      * Check if we were requested to re-read config file.
     152             :      */
     153           0 :     if (got_SIGHUP)
     154             :     {
     155           0 :         got_SIGHUP = false;
     156           0 :         ProcessConfigFile(PGC_SIGHUP);
     157             :     }
     158             : 
     159             :     /*
     160             :      * Check if we were requested to exit without finishing recovery.
     161             :      */
     162           0 :     if (shutdown_requested)
     163           0 :         proc_exit(1);
     164             : 
     165             :     /*
     166             :      * Emergency bailout if postmaster has died.  This is to avoid the
     167             :      * necessity for manual cleanup of all postmaster children.
     168             :      */
     169           0 :     if (IsUnderPostmaster && !PostmasterIsAlive())
     170           0 :         exit(1);
     171           0 : }
     172             : 
     173             : 
     174             : /* ----------------------------------
     175             :  *  Startup Process main entry point
     176             :  * ----------------------------------
     177             :  */
     178             : void
     179           1 : StartupProcessMain(void)
     180             : {
     181             :     /*
     182             :      * Properly accept or ignore signals the postmaster might send us.
     183             :      */
     184           1 :     pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
     185           1 :     pqsignal(SIGINT, SIG_IGN);  /* ignore query cancel */
     186           1 :     pqsignal(SIGTERM, StartupProcShutdownHandler);  /* request shutdown */
     187           1 :     pqsignal(SIGQUIT, startupproc_quickdie);    /* hard crash time */
     188           1 :     InitializeTimeouts();       /* establishes SIGALRM handler */
     189           1 :     pqsignal(SIGPIPE, SIG_IGN);
     190           1 :     pqsignal(SIGUSR1, StartupProcSigUsr1Handler);
     191           1 :     pqsignal(SIGUSR2, StartupProcTriggerHandler);
     192             : 
     193             :     /*
     194             :      * Reset some signals that are accepted by postmaster but not here
     195             :      */
     196           1 :     pqsignal(SIGCHLD, SIG_DFL);
     197           1 :     pqsignal(SIGTTIN, SIG_DFL);
     198           1 :     pqsignal(SIGTTOU, SIG_DFL);
     199           1 :     pqsignal(SIGCONT, SIG_DFL);
     200           1 :     pqsignal(SIGWINCH, SIG_DFL);
     201             : 
     202             :     /*
     203             :      * Register timeouts needed for standby mode
     204             :      */
     205           1 :     RegisterTimeout(STANDBY_DEADLOCK_TIMEOUT, StandbyDeadLockHandler);
     206           1 :     RegisterTimeout(STANDBY_TIMEOUT, StandbyTimeoutHandler);
     207           1 :     RegisterTimeout(STANDBY_LOCK_TIMEOUT, StandbyLockTimeoutHandler);
     208             : 
     209             :     /*
     210             :      * Unblock signals (they were blocked when the postmaster forked us)
     211             :      */
     212           1 :     PG_SETMASK(&UnBlockSig);
     213             : 
     214             :     /*
     215             :      * Do what we came for.
     216             :      */
     217           1 :     StartupXLOG();
     218             : 
     219             :     /*
     220             :      * Exit normally. Exit code 0 tells postmaster that we completed recovery
     221             :      * successfully.
     222             :      */
     223           1 :     proc_exit(0);
     224             : }
     225             : 
     226             : void
     227           0 : PreRestoreCommand(void)
     228             : {
     229             :     /*
     230             :      * Set in_restore_command to tell the signal handler that we should exit
     231             :      * right away on SIGTERM. We know that we're at a safe point to do that.
     232             :      * Check if we had already received the signal, so that we don't miss a
     233             :      * shutdown request received just before this.
     234             :      */
     235           0 :     in_restore_command = true;
     236           0 :     if (shutdown_requested)
     237           0 :         proc_exit(1);
     238           0 : }
     239             : 
     240             : void
     241           0 : PostRestoreCommand(void)
     242             : {
     243           0 :     in_restore_command = false;
     244           0 : }
     245             : 
     246             : bool
     247           0 : IsPromoteTriggered(void)
     248             : {
     249           0 :     return promote_triggered;
     250             : }
     251             : 
     252             : void
     253           0 : ResetPromoteTriggered(void)
     254             : {
     255           0 :     promote_triggered = false;
     256           0 : }

Generated by: LCOV version 1.11