1 /*-------------------------------------------------------------------------
2  *
3  * interrupt.c
4  *	  Interrupt handling routines.
5  *
6  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *	  src/backend/postmaster/interrupt.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 
15 #include "postgres.h"
16 
17 #include <unistd.h>
18 
19 #include "miscadmin.h"
20 #include "postmaster/interrupt.h"
21 #include "storage/ipc.h"
22 #include "storage/latch.h"
23 #include "storage/procsignal.h"
24 #include "utils/guc.h"
25 
26 volatile sig_atomic_t ConfigReloadPending = false;
27 volatile sig_atomic_t ShutdownRequestPending = false;
28 
29 /*
30  * Simple interrupt handler for main loops of background processes.
31  */
32 void
HandleMainLoopInterrupts(void)33 HandleMainLoopInterrupts(void)
34 {
35 	if (ProcSignalBarrierPending)
36 		ProcessProcSignalBarrier();
37 
38 	if (ConfigReloadPending)
39 	{
40 		ConfigReloadPending = false;
41 		ProcessConfigFile(PGC_SIGHUP);
42 	}
43 
44 	if (ShutdownRequestPending)
45 		proc_exit(0);
46 }
47 
48 /*
49  * Simple signal handler for triggering a configuration reload.
50  *
51  * Normally, this handler would be used for SIGHUP. The idea is that code
52  * which uses it would arrange to check the ConfigReloadPending flag at
53  * convenient places inside main loops, or else call HandleMainLoopInterrupts.
54  */
55 void
SignalHandlerForConfigReload(SIGNAL_ARGS)56 SignalHandlerForConfigReload(SIGNAL_ARGS)
57 {
58 	int			save_errno = errno;
59 
60 	ConfigReloadPending = true;
61 	SetLatch(MyLatch);
62 
63 	errno = save_errno;
64 }
65 
66 /*
67  * Simple signal handler for exiting quickly as if due to a crash.
68  *
69  * Normally, this would be used for handling SIGQUIT.
70  */
71 void
SignalHandlerForCrashExit(SIGNAL_ARGS)72 SignalHandlerForCrashExit(SIGNAL_ARGS)
73 {
74 	/*
75 	 * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here
76 	 * because shared memory may be corrupted, so we don't want to try to
77 	 * clean up our transaction.  Just nail the windows shut and get out of
78 	 * town.  The callbacks wouldn't be safe to run from a signal handler,
79 	 * anyway.
80 	 *
81 	 * Note we do _exit(2) not _exit(0).  This is to force the postmaster into
82 	 * a system reset cycle if someone sends a manual SIGQUIT to a random
83 	 * backend.  This is necessary precisely because we don't clean up our
84 	 * shared memory state.  (The "dead man switch" mechanism in pmsignal.c
85 	 * should ensure the postmaster sees this as a crash, too, but no harm in
86 	 * being doubly sure.)
87 	 */
88 	_exit(2);
89 }
90 
91 /*
92  * Simple signal handler for triggering a long-running background process to
93  * shut down and exit.
94  *
95  * Typically, this handler would be used for SIGTERM, but some procesess use
96  * other signals. In particular, the checkpointer exits on SIGUSR2, the
97  * stats collector on SIGQUIT, and the WAL writer exits on either SIGINT
98  * or SIGTERM.
99  *
100  * ShutdownRequestPending should be checked at a convenient place within the
101  * main loop, or else the main loop should call HandleMainLoopInterrupts.
102  */
103 void
SignalHandlerForShutdownRequest(SIGNAL_ARGS)104 SignalHandlerForShutdownRequest(SIGNAL_ARGS)
105 {
106 	int			save_errno = errno;
107 
108 	ShutdownRequestPending = true;
109 	SetLatch(MyLatch);
110 
111 	errno = save_errno;
112 }
113