PostgreSQL Source Code  git master
signalfuncs.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * signalfuncs.c
4  * Functions for signaling backends
5  *
6  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/storage/ipc/signalfuncs.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include <signal.h>
18 
19 #include "catalog/pg_authid.h"
20 #include "miscadmin.h"
21 #include "pgstat.h"
22 #include "postmaster/syslogger.h"
23 #include "storage/pmsignal.h"
24 #include "storage/proc.h"
25 #include "storage/procarray.h"
26 #include "utils/acl.h"
27 #include "utils/builtins.h"
28 
29 
30 /*
31  * Send a signal to another backend.
32  *
33  * The signal is delivered if the user is either a superuser or the same
34  * role as the backend being signaled. For "dangerous" signals, an explicit
35  * check for superuser needs to be done prior to calling this function.
36  *
37  * Returns 0 on success, 1 on general failure, 2 on normal permission error
38  * and 3 if the caller needs to be a superuser.
39  *
40  * In the event of a general failure (return code 1), a warning message will
41  * be emitted. For permission errors, doing that is the responsibility of
42  * the caller.
43  */
44 #define SIGNAL_BACKEND_SUCCESS 0
45 #define SIGNAL_BACKEND_ERROR 1
46 #define SIGNAL_BACKEND_NOPERMISSION 2
47 #define SIGNAL_BACKEND_NOSUPERUSER 3
48 static int
49 pg_signal_backend(int pid, int sig)
50 {
51  PGPROC *proc = BackendPidGetProc(pid);
52 
53  /*
54  * BackendPidGetProc returns NULL if the pid isn't valid; but by the time
55  * we reach kill(), a process for which we get a valid proc here might
56  * have terminated on its own. There's no way to acquire a lock on an
57  * arbitrary process to prevent that. But since so far all the callers of
58  * this mechanism involve some request for ending the process anyway, that
59  * it might end on its own first is not a problem.
60  */
61  if (proc == NULL)
62  {
63  /*
64  * This is just a warning so a loop-through-resultset will not abort
65  * if one backend terminated on its own during the run.
66  */
68  (errmsg("PID %d is not a PostgreSQL server process", pid)));
69  return SIGNAL_BACKEND_ERROR;
70  }
71 
72  /* Only allow superusers to signal superuser-owned backends. */
73  if (superuser_arg(proc->roleId) && !superuser())
75 
76  /* Users can signal backends they have role membership in. */
77  if (!has_privs_of_role(GetUserId(), proc->roleId) &&
78  !has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
80 
81  /*
82  * Can the process we just validated above end, followed by the pid being
83  * recycled for a new process, before reaching here? Then we'd be trying
84  * to kill the wrong thing. Seems near impossible when sequential pid
85  * assignment and wraparound is used. Perhaps it could happen on a system
86  * where pid re-use is randomized. That race condition possibility seems
87  * too unlikely to worry about.
88  */
89 
90  /* If we have setsid(), signal the backend's whole process group */
91 #ifdef HAVE_SETSID
92  if (kill(-pid, sig))
93 #else
94  if (kill(pid, sig))
95 #endif
96  {
97  /* Again, just a warning to allow loops */
99  (errmsg("could not send signal to process %d: %m", pid)));
100  return SIGNAL_BACKEND_ERROR;
101  }
102  return SIGNAL_BACKEND_SUCCESS;
103 }
104 
105 /*
106  * Signal to cancel a backend process. This is allowed if you are a member of
107  * the role whose process is being canceled.
108  *
109  * Note that only superusers can signal superuser-owned processes.
110  */
111 Datum
113 {
114  int r = pg_signal_backend(PG_GETARG_INT32(0), SIGINT);
115 
117  ereport(ERROR,
118  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
119  errmsg("must be a superuser to cancel superuser query")));
120 
122  ereport(ERROR,
123  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
124  errmsg("must be a member of the role whose query is being canceled or member of pg_signal_backend")));
125 
127 }
128 
129 /*
130  * Wait until there is no backend process with the given PID and return true.
131  * On timeout, a warning is emitted and false is returned.
132  */
133 static bool
134 pg_wait_until_termination(int pid, int64 timeout)
135 {
136  /*
137  * Wait in steps of waittime milliseconds until this function exits or
138  * timeout.
139  */
140  int64 waittime = 100;
141  /*
142  * Initially remaining time is the entire timeout specified by the user.
143  */
144  int64 remainingtime = timeout;
145 
146  /*
147  * Check existence of the backend. If the backend still exists, then wait
148  * for waittime milliseconds, again check for the existence. Repeat this
149  * until timeout or an error occurs or a pending interrupt such as query
150  * cancel gets processed.
151  */
152  do
153  {
154  if (remainingtime < waittime)
155  waittime = remainingtime;
156 
157  if (kill(pid, 0) == -1)
158  {
159  if (errno == ESRCH)
160  return true;
161  else
162  ereport(ERROR,
163  (errcode(ERRCODE_INTERNAL_ERROR),
164  errmsg("could not check the existence of the backend with PID %d: %m",
165  pid)));
166  }
167 
168  /* Process interrupts, if any, before waiting */
170 
171  (void) WaitLatch(MyLatch,
173  waittime,
175 
177 
178  remainingtime -= waittime;
179  } while (remainingtime > 0);
180 
182  (errmsg("backend with PID %d did not terminate within %lld milliseconds",
183  pid, (long long int) timeout)));
184 
185  return false;
186 }
187 
188 /*
189  * Signal to terminate a backend process. This is allowed if you are a member
190  * of the role whose process is being terminated. If timeout input argument is
191  * 0 (which is default), then this function just signals the backend and
192  * doesn't wait. Otherwise it waits until given the timeout milliseconds or no
193  * process has the given PID and returns true. On timeout, a warning is emitted
194  * and false is returned.
195  *
196  * Note that only superusers can signal superuser-owned processes.
197  */
198 Datum
200 {
201  int pid;
202  int r;
203  int timeout;
204 
205  pid = PG_GETARG_INT32(0);
206  timeout = PG_GETARG_INT64(1);
207 
208  if (timeout < 0)
209  ereport(ERROR,
210  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
211  errmsg("\"timeout\" must not be negative")));
212 
213  r = pg_signal_backend(pid, SIGTERM);
214 
216  ereport(ERROR,
217  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
218  errmsg("must be a superuser to terminate superuser process")));
219 
221  ereport(ERROR,
222  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
223  errmsg("must be a member of the role whose process is being terminated or member of pg_signal_backend")));
224 
225  /* Wait only on success and if actually requested */
226  if (r == SIGNAL_BACKEND_SUCCESS && timeout > 0)
228  else
230 }
231 
232 /*
233  * Wait for a backend process with the given PID to exit or until the given
234  * timeout milliseconds occurs. Returns true if the backend has exited. On
235  * timeout a warning is emitted and false is returned.
236  *
237  * We allow any user to call this function, consistent with any user being
238  * able to view the pid of the process in pg_stat_activity etc.
239  */
240 Datum
242 {
243  int pid;
244  int64 timeout;
245  PGPROC *proc = NULL;
246 
247  pid = PG_GETARG_INT32(0);
248  timeout = PG_GETARG_INT64(1);
249 
250  if (timeout <= 0)
251  ereport(ERROR,
252  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
253  errmsg("\"timeout\" must not be negative or zero")));
254 
255  proc = BackendPidGetProc(pid);
256 
257  if (proc == NULL)
258  {
260  (errmsg("PID %d is not a PostgreSQL server process", pid)));
261 
262  PG_RETURN_BOOL(false);
263  }
264 
266 }
267 
268 /*
269  * Signal to reload the database configuration
270  *
271  * Permission checking for this function is managed through the normal
272  * GRANT system.
273  */
274 Datum
276 {
277  if (kill(PostmasterPid, SIGHUP))
278  {
280  (errmsg("failed to send signal to postmaster: %m")));
281  PG_RETURN_BOOL(false);
282  }
283 
284  PG_RETURN_BOOL(true);
285 }
286 
287 
288 /*
289  * Rotate log file
290  *
291  * This function is kept to support adminpack 1.0.
292  */
293 Datum
295 {
296  if (!superuser())
297  ereport(ERROR,
298  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
299  errmsg("must be superuser to rotate log files with adminpack 1.0"),
300  /* translator: %s is a SQL function name */
301  errhint("Consider using %s, which is part of core, instead.",
302  "pg_logfile_rotate()")));
303 
304  if (!Logging_collector)
305  {
307  (errmsg("rotation not possible because log collection not active")));
308  PG_RETURN_BOOL(false);
309  }
310 
312  PG_RETURN_BOOL(true);
313 }
314 
315 /*
316  * Rotate log file
317  *
318  * Permission checking for this function is managed through the normal
319  * GRANT system.
320  */
321 Datum
323 {
324  if (!Logging_collector)
325  {
327  (errmsg("rotation not possible because log collection not active")));
328  PG_RETURN_BOOL(false);
329  }
330 
332  PG_RETURN_BOOL(true);
333 }
Datum pg_rotate_logfile(PG_FUNCTION_ARGS)
Definition: signalfuncs.c:294
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int errhint(const char *fmt,...)
Definition: elog.c:1156
Datum pg_rotate_logfile_v2(PG_FUNCTION_ARGS)
Definition: signalfuncs.c:322
#define WL_TIMEOUT
Definition: latch.h:128
Oid GetUserId(void)
Definition: miscinit.c:478
PGPROC * BackendPidGetProc(int pid)
Definition: procarray.c:3067
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4843
Oid roleId
Definition: proc.h:155
int errcode(int sqlerrcode)
Definition: elog.c:698
bool superuser(void)
Definition: superuser.c:46
#define kill(pid, sig)
Definition: win32_port.h:454
Datum pg_cancel_backend(PG_FUNCTION_ARGS)
Definition: signalfuncs.c:112
#define SIGNAL_BACKEND_SUCCESS
Definition: signalfuncs.c:44
void ResetLatch(Latch *latch)
Definition: latch.c:660
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:452
static int pg_signal_backend(int pid, int sig)
Definition: signalfuncs.c:49
bool Logging_collector
Definition: syslogger.c:70
#define SIGNAL_BACKEND_NOSUPERUSER
Definition: signalfuncs.c:47
#define ERROR
Definition: elog.h:46
#define SIGHUP
Definition: win32_port.h:159
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
#define SIGNAL_BACKEND_NOPERMISSION
Definition: signalfuncs.c:46
Datum pg_reload_conf(PG_FUNCTION_ARGS)
Definition: signalfuncs.c:275
pid_t PostmasterPid
Definition: globals.c:98
#define WARNING
Definition: elog.h:40
static bool pg_wait_until_termination(int pid, int64 timeout)
Definition: signalfuncs.c:134
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:411
#define SIGNAL_BACKEND_ERROR
Definition: signalfuncs.c:45
Datum pg_wait_for_backend_termination(PG_FUNCTION_ARGS)
Definition: signalfuncs.c:241
static int sig
Definition: pg_ctl.c:84
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
Datum pg_terminate_backend(PG_FUNCTION_ARGS)
Definition: signalfuncs.c:199
struct Latch * MyLatch
Definition: globals.c:57
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:102
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:153
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
Definition: proc.h:121
#define WL_LATCH_SET
Definition: latch.h:125
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:130