LCOV - code coverage report
Current view: top level - src/backend/postmaster - startup.c (source / functions) Hit Total Coverage
Test: PostgreSQL 12beta2 Lines: 60 65 92.3 %
Date: 2019-06-19 14:06:47 Functions: 10 11 90.9 %
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-2019, 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             :     /*
      73             :      * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here
      74             :      * because shared memory may be corrupted, so we don't want to try to
      75             :      * clean up our transaction.  Just nail the windows shut and get out of
      76             :      * town.  The callbacks wouldn't be safe to run from a signal handler,
      77             :      * anyway.
      78             :      *
      79             :      * Note we do _exit(2) not _exit(0).  This is to force the postmaster into
      80             :      * a system reset cycle if someone sends a manual SIGQUIT to a random
      81             :      * backend.  This is necessary precisely because we don't clean up our
      82             :      * shared memory state.  (The "dead man switch" mechanism in pmsignal.c
      83             :      * should ensure the postmaster sees this as a crash, too, but no harm in
      84             :      * being doubly sure.)
      85             :      */
      86           0 :     _exit(2);
      87             : }
      88             : 
      89             : 
      90             : /* SIGUSR1: let latch facility handle the signal */
      91             : static void
      92         472 : StartupProcSigUsr1Handler(SIGNAL_ARGS)
      93             : {
      94         472 :     int         save_errno = errno;
      95             : 
      96         472 :     latch_sigusr1_handler();
      97             : 
      98         472 :     errno = save_errno;
      99         472 : }
     100             : 
     101             : /* SIGUSR2: set flag to finish recovery */
     102             : static void
     103          42 : StartupProcTriggerHandler(SIGNAL_ARGS)
     104             : {
     105          42 :     int         save_errno = errno;
     106             : 
     107          42 :     promote_triggered = true;
     108          42 :     WakeupRecovery();
     109             : 
     110          42 :     errno = save_errno;
     111          42 : }
     112             : 
     113             : /* SIGHUP: set flag to re-read config file at next convenient time */
     114             : static void
     115           2 : StartupProcSigHupHandler(SIGNAL_ARGS)
     116             : {
     117           2 :     int         save_errno = errno;
     118             : 
     119           2 :     got_SIGHUP = true;
     120           2 :     WakeupRecovery();
     121             : 
     122           2 :     errno = save_errno;
     123           2 : }
     124             : 
     125             : /* SIGTERM: set flag to abort redo and exit */
     126             : static void
     127          22 : StartupProcShutdownHandler(SIGNAL_ARGS)
     128             : {
     129          22 :     int         save_errno = errno;
     130             : 
     131          22 :     if (in_restore_command)
     132           0 :         proc_exit(1);
     133             :     else
     134          22 :         shutdown_requested = true;
     135          22 :     WakeupRecovery();
     136             : 
     137          22 :     errno = save_errno;
     138          22 : }
     139             : 
     140             : /* Handle SIGHUP and SIGTERM signals of startup process */
     141             : void
     142      196210 : HandleStartupProcInterrupts(void)
     143             : {
     144             :     /*
     145             :      * Check if we were requested to re-read config file.
     146             :      */
     147      196210 :     if (got_SIGHUP)
     148             :     {
     149           2 :         got_SIGHUP = false;
     150           2 :         ProcessConfigFile(PGC_SIGHUP);
     151             :     }
     152             : 
     153             :     /*
     154             :      * Check if we were requested to exit without finishing recovery.
     155             :      */
     156      196210 :     if (shutdown_requested)
     157          22 :         proc_exit(1);
     158             : 
     159             :     /*
     160             :      * Emergency bailout if postmaster has died.  This is to avoid the
     161             :      * necessity for manual cleanup of all postmaster children.
     162             :      */
     163      196188 :     if (IsUnderPostmaster && !PostmasterIsAlive())
     164           0 :         exit(1);
     165      196188 : }
     166             : 
     167             : 
     168             : /* ----------------------------------
     169             :  *  Startup Process main entry point
     170             :  * ----------------------------------
     171             :  */
     172             : void
     173         522 : StartupProcessMain(void)
     174             : {
     175             :     /*
     176             :      * Properly accept or ignore signals the postmaster might send us.
     177             :      */
     178         522 :     pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
     179         522 :     pqsignal(SIGINT, SIG_IGN);  /* ignore query cancel */
     180         522 :     pqsignal(SIGTERM, StartupProcShutdownHandler);  /* request shutdown */
     181         522 :     pqsignal(SIGQUIT, startupproc_quickdie);    /* hard crash time */
     182         522 :     InitializeTimeouts();       /* establishes SIGALRM handler */
     183         522 :     pqsignal(SIGPIPE, SIG_IGN);
     184         522 :     pqsignal(SIGUSR1, StartupProcSigUsr1Handler);
     185         522 :     pqsignal(SIGUSR2, StartupProcTriggerHandler);
     186             : 
     187             :     /*
     188             :      * Reset some signals that are accepted by postmaster but not here
     189             :      */
     190         522 :     pqsignal(SIGCHLD, SIG_DFL);
     191             : 
     192             :     /*
     193             :      * Register timeouts needed for standby mode
     194             :      */
     195         522 :     RegisterTimeout(STANDBY_DEADLOCK_TIMEOUT, StandbyDeadLockHandler);
     196         522 :     RegisterTimeout(STANDBY_TIMEOUT, StandbyTimeoutHandler);
     197         522 :     RegisterTimeout(STANDBY_LOCK_TIMEOUT, StandbyLockTimeoutHandler);
     198             : 
     199             :     /*
     200             :      * Unblock signals (they were blocked when the postmaster forked us)
     201             :      */
     202         522 :     PG_SETMASK(&UnBlockSig);
     203             : 
     204             :     /*
     205             :      * Do what we came for.
     206             :      */
     207         522 :     StartupXLOG();
     208             : 
     209             :     /*
     210             :      * Exit normally. Exit code 0 tells postmaster that we completed recovery
     211             :      * successfully.
     212             :      */
     213         498 :     proc_exit(0);
     214             : }
     215             : 
     216             : void
     217          82 : PreRestoreCommand(void)
     218             : {
     219             :     /*
     220             :      * Set in_restore_command to tell the signal handler that we should exit
     221             :      * right away on SIGTERM. We know that we're at a safe point to do that.
     222             :      * Check if we had already received the signal, so that we don't miss a
     223             :      * shutdown request received just before this.
     224             :      */
     225          82 :     in_restore_command = true;
     226          82 :     if (shutdown_requested)
     227           0 :         proc_exit(1);
     228          82 : }
     229             : 
     230             : void
     231          82 : PostRestoreCommand(void)
     232             : {
     233          82 :     in_restore_command = false;
     234          82 : }
     235             : 
     236             : bool
     237         784 : IsPromoteTriggered(void)
     238             : {
     239         784 :     return promote_triggered;
     240             : }
     241             : 
     242             : void
     243          42 : ResetPromoteTriggered(void)
     244             : {
     245          42 :     promote_triggered = false;
     246          42 : }

Generated by: LCOV version 1.13