PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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"
23#include "storage/pmsignal.h"
24#include "storage/proc.h"
25#include "storage/procarray.h"
26#include "utils/acl.h"
27#include "utils/fmgrprotos.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 * 3 if the caller needs to be a superuser, and 4 if the caller needs to have
39 * privileges of pg_signal_autovacuum_worker.
40 *
41 * In the event of a general failure (return code 1), a warning message will
42 * be emitted. For permission errors, doing that is the responsibility of
43 * the caller.
44 */
45#define SIGNAL_BACKEND_SUCCESS 0
46#define SIGNAL_BACKEND_ERROR 1
47#define SIGNAL_BACKEND_NOPERMISSION 2
48#define SIGNAL_BACKEND_NOSUPERUSER 3
49#define SIGNAL_BACKEND_NOAUTOVAC 4
50static int
52{
53 PGPROC *proc = BackendPidGetProc(pid);
54
55 /*
56 * BackendPidGetProc returns NULL if the pid isn't valid; but by the time
57 * we reach kill(), a process for which we get a valid proc here might
58 * have terminated on its own. There's no way to acquire a lock on an
59 * arbitrary process to prevent that. But since so far all the callers of
60 * this mechanism involve some request for ending the process anyway, that
61 * it might end on its own first is not a problem.
62 *
63 * Note that proc will also be NULL if the pid refers to an auxiliary
64 * process or the postmaster (neither of which can be signaled via
65 * pg_signal_backend()).
66 */
67 if (proc == NULL)
68 {
69 /*
70 * This is just a warning so a loop-through-resultset will not abort
71 * if one backend terminated on its own during the run.
72 */
74 (errmsg("PID %d is not a PostgreSQL backend process", pid)));
75
77 }
78
79 /*
80 * Only allow superusers to signal superuser-owned backends. Any process
81 * not advertising a role might have the importance of a superuser-owned
82 * backend, so treat it that way. As an exception, we allow roles with
83 * privileges of pg_signal_autovacuum_worker to signal autovacuum workers
84 * (which do not advertise a role).
85 *
86 * Otherwise, users can signal backends for roles they have privileges of.
87 */
88 if (!OidIsValid(proc->roleId) || superuser_arg(proc->roleId))
89 {
90 if (proc->backendType == B_AUTOVAC_WORKER)
91 {
94 }
95 else if (!superuser())
97 }
98 else if (!has_privs_of_role(GetUserId(), proc->roleId) &&
101
102 /*
103 * Can the process we just validated above end, followed by the pid being
104 * recycled for a new process, before reaching here? Then we'd be trying
105 * to kill the wrong thing. Seems near impossible when sequential pid
106 * assignment and wraparound is used. Perhaps it could happen on a system
107 * where pid re-use is randomized. That race condition possibility seems
108 * too unlikely to worry about.
109 */
110
111 /* If we have setsid(), signal the backend's whole process group */
112#ifdef HAVE_SETSID
113 if (kill(-pid, sig))
114#else
115 if (kill(pid, sig))
116#endif
117 {
118 /* Again, just a warning to allow loops */
120 (errmsg("could not send signal to process %d: %m", pid)));
122 }
124}
125
126/*
127 * Signal to cancel a backend process. This is allowed if you are a member of
128 * the role whose process is being canceled.
129 *
130 * Note that only superusers can signal superuser-owned processes.
131 */
132Datum
134{
136
140 errmsg("permission denied to cancel query"),
141 errdetail("Only roles with the %s attribute may cancel queries of roles with the %s attribute.",
142 "SUPERUSER", "SUPERUSER")));
143
147 errmsg("permission denied to cancel query"),
148 errdetail("Only roles with privileges of the \"%s\" role may cancel autovacuum workers.",
149 "pg_signal_autovacuum_worker")));
150
154 errmsg("permission denied to cancel query"),
155 errdetail("Only roles with privileges of the role whose query is being canceled or with privileges of the \"%s\" role may cancel this query.",
156 "pg_signal_backend")));
157
159}
160
161/*
162 * Wait until there is no backend process with the given PID and return true.
163 * On timeout, a warning is emitted and false is returned.
164 */
165static bool
167{
168 /*
169 * Wait in steps of waittime milliseconds until this function exits or
170 * timeout.
171 */
172 int64 waittime = 100;
173
174 /*
175 * Initially remaining time is the entire timeout specified by the user.
176 */
178
179 /*
180 * Check existence of the backend. If the backend still exists, then wait
181 * for waittime milliseconds, again check for the existence. Repeat this
182 * until timeout or an error occurs or a pending interrupt such as query
183 * cancel gets processed.
184 */
185 do
186 {
189
190 if (kill(pid, 0) == -1)
191 {
192 if (errno == ESRCH)
193 return true;
194 else
197 errmsg("could not check the existence of the backend with PID %d: %m",
198 pid)));
199 }
200
201 /* Process interrupts, if any, before waiting */
203
206 waittime,
208
210
212 } while (remainingtime > 0);
213
215 (errmsg_plural("backend with PID %d did not terminate within %" PRId64 " millisecond",
216 "backend with PID %d did not terminate within %" PRId64 " milliseconds",
217 timeout,
218 pid, timeout)));
219
220 return false;
221}
222
223/*
224 * Send a signal to terminate a backend process. This is allowed if you are a
225 * member of the role whose process is being terminated. If the timeout input
226 * argument is 0, then this function just signals the backend and returns
227 * true. If timeout is nonzero, then it waits until no process has the given
228 * PID; if the process ends within the timeout, true is returned, and if the
229 * timeout is exceeded, a warning is emitted and false is returned.
230 *
231 * Note that only superusers can signal superuser-owned processes.
232 */
233Datum
235{
236 int pid;
237 int r;
238 int timeout; /* milliseconds */
239
240 pid = PG_GETARG_INT32(0);
242
243 if (timeout < 0)
246 errmsg("\"timeout\" must not be negative")));
247
248 r = pg_signal_backend(pid, SIGTERM);
249
253 errmsg("permission denied to terminate process"),
254 errdetail("Only roles with the %s attribute may terminate processes of roles with the %s attribute.",
255 "SUPERUSER", "SUPERUSER")));
256
260 errmsg("permission denied to terminate process"),
261 errdetail("Only roles with privileges of the \"%s\" role may terminate autovacuum workers.",
262 "pg_signal_autovacuum_worker")));
263
267 errmsg("permission denied to terminate process"),
268 errdetail("Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process.",
269 "pg_signal_backend")));
270
271 /* Wait only on success and if actually requested */
272 if (r == SIGNAL_BACKEND_SUCCESS && timeout > 0)
274 else
276}
277
278/*
279 * Signal to reload the database configuration
280 *
281 * Permission checking for this function is managed through the normal
282 * GRANT system.
283 */
284Datum
286{
288 {
290 (errmsg("failed to send signal to postmaster: %m")));
291 PG_RETURN_BOOL(false);
292 }
293
294 PG_RETURN_BOOL(true);
295}
296
297
298/*
299 * Rotate log file
300 *
301 * Permission checking for this function is managed through the normal
302 * GRANT system.
303 */
304Datum
306{
308 {
310 (errmsg("rotation not possible because log collection not active")));
311 PG_RETURN_BOOL(false);
312 }
313
315 PG_RETURN_BOOL(true);
316}
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5284
int64_t int64
Definition c.h:543
#define OidIsValid(objectId)
Definition c.h:788
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition elog.c:1193
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
pid_t PostmasterPid
Definition globals.c:106
struct Latch * MyLatch
Definition globals.c:63
void ResetLatch(Latch *latch)
Definition latch.c:374
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition latch.c:172
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
@ B_AUTOVAC_WORKER
Definition miscadmin.h:345
Oid GetUserId(void)
Definition miscinit.c:469
static int sig
Definition pg_ctl.c:81
void SendPostmasterSignal(PMSignalReason reason)
Definition pmsignal.c:165
@ PMSIGNAL_ROTATE_LOGFILE
Definition pmsignal.h:38
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
PGPROC * BackendPidGetProc(int pid)
Definition procarray.c:3154
static int pg_signal_backend(int pid, int sig)
Definition signalfuncs.c:51
Datum pg_cancel_backend(PG_FUNCTION_ARGS)
#define SIGNAL_BACKEND_SUCCESS
Definition signalfuncs.c:45
#define SIGNAL_BACKEND_NOPERMISSION
Definition signalfuncs.c:47
Datum pg_rotate_logfile(PG_FUNCTION_ARGS)
#define SIGNAL_BACKEND_NOSUPERUSER
Definition signalfuncs.c:48
#define SIGNAL_BACKEND_NOAUTOVAC
Definition signalfuncs.c:49
Datum pg_reload_conf(PG_FUNCTION_ARGS)
Datum pg_terminate_backend(PG_FUNCTION_ARGS)
#define SIGNAL_BACKEND_ERROR
Definition signalfuncs.c:46
static bool pg_wait_until_termination(int pid, int64 timeout)
Definition proc.h:180
BackendType backendType
Definition proc.h:231
Oid roleId
Definition proc.h:226
bool superuser_arg(Oid roleid)
Definition superuser.c:56
bool superuser(void)
Definition superuser.c:46
bool Logging_collector
Definition syslogger.c:70
#define WL_TIMEOUT
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET
#define SIGHUP
Definition win32_port.h:158
#define kill(pid, sig)
Definition win32_port.h:490