1 /*-------------------------------------------------------------------------
2  *
3  * pmsignal.h
4  *	  routines for signaling between the postmaster and its child processes
5  *
6  *
7  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/storage/pmsignal.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef PMSIGNAL_H
15 #define PMSIGNAL_H
16 
17 #include <signal.h>
18 
19 #ifdef HAVE_SYS_PRCTL_H
20 #include "sys/prctl.h"
21 #endif
22 
23 #ifdef HAVE_SYS_PROCCTL_H
24 #include "sys/procctl.h"
25 #endif
26 
27 /*
28  * Reasons for signaling the postmaster.  We can cope with simultaneous
29  * signals for different reasons.  If the same reason is signaled multiple
30  * times in quick succession, however, the postmaster is likely to observe
31  * only one notification of it.  This is okay for the present uses.
32  */
33 typedef enum
34 {
35 	PMSIGNAL_RECOVERY_STARTED,	/* recovery has started */
36 	PMSIGNAL_BEGIN_HOT_STANDBY, /* begin Hot Standby */
37 	PMSIGNAL_ROTATE_LOGFILE,	/* send SIGUSR1 to syslogger to rotate logfile */
38 	PMSIGNAL_START_AUTOVAC_LAUNCHER,	/* start an autovacuum launcher */
39 	PMSIGNAL_START_AUTOVAC_WORKER,	/* start an autovacuum worker */
40 	PMSIGNAL_BACKGROUND_WORKER_CHANGE,	/* background worker state change */
41 	PMSIGNAL_START_WALRECEIVER, /* start a walreceiver */
42 	PMSIGNAL_ADVANCE_STATE_MACHINE, /* advance postmaster's state machine */
43 
44 	NUM_PMSIGNALS				/* Must be last value of enum! */
45 } PMSignalReason;
46 
47 /*
48  * Reasons why the postmaster would send SIGQUIT to its children.
49  */
50 typedef enum
51 {
52 	PMQUIT_NOT_SENT = 0,		/* postmaster hasn't sent SIGQUIT */
53 	PMQUIT_FOR_CRASH,			/* some other backend bought the farm */
54 	PMQUIT_FOR_STOP				/* immediate stop was commanded */
55 } QuitSignalReason;
56 
57 /* PMSignalData is an opaque struct, details known only within pmsignal.c */
58 typedef struct PMSignalData PMSignalData;
59 
60 /*
61  * prototypes for functions in pmsignal.c
62  */
63 extern Size PMSignalShmemSize(void);
64 extern void PMSignalShmemInit(void);
65 extern void SendPostmasterSignal(PMSignalReason reason);
66 extern bool CheckPostmasterSignal(PMSignalReason reason);
67 extern void SetQuitSignalReason(QuitSignalReason reason);
68 extern QuitSignalReason GetQuitSignalReason(void);
69 extern int	AssignPostmasterChildSlot(void);
70 extern bool ReleasePostmasterChildSlot(int slot);
71 extern bool IsPostmasterChildWalSender(int slot);
72 extern void MarkPostmasterChildActive(void);
73 extern void MarkPostmasterChildInactive(void);
74 extern void MarkPostmasterChildWalSender(void);
75 extern bool PostmasterIsAliveInternal(void);
76 extern void PostmasterDeathSignalInit(void);
77 
78 
79 /*
80  * Do we have a way to ask for a signal on parent death?
81  *
82  * If we do, pmsignal.c will set up a signal handler, that sets a flag when
83  * the parent dies.  Checking the flag first makes PostmasterIsAlive() a lot
84  * cheaper in usual case that the postmaster is alive.
85  */
86 #if (defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_PDEATHSIG)) || \
87 	(defined(HAVE_SYS_PROCCTL_H) && defined(PROC_PDEATHSIG_CTL))
88 #define USE_POSTMASTER_DEATH_SIGNAL
89 #endif
90 
91 #ifdef USE_POSTMASTER_DEATH_SIGNAL
92 extern volatile sig_atomic_t postmaster_possibly_dead;
93 
94 static inline bool
PostmasterIsAlive(void)95 PostmasterIsAlive(void)
96 {
97 	if (likely(!postmaster_possibly_dead))
98 		return true;
99 	return PostmasterIsAliveInternal();
100 }
101 #else
102 #define PostmasterIsAlive() PostmasterIsAliveInternal()
103 #endif
104 
105 #endif							/* PMSIGNAL_H */
106