1 /*-------------------------------------------------------------------------
4 * Functions for signaling backends
6 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/storage/ipc/signalfuncs.c
13 *-------------------------------------------------------------------------
19 #include "catalog/pg_authid.h"
20 #include "miscadmin.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/fmgrprotos.h"
31 * Send a signal to another backend.
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.
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.
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
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
51 pg_signal_backend(int pid
, int sig
)
53 PGPROC
*proc
= BackendPidGetProc(pid
);
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.
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()).
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.
74 (errmsg("PID %d is not a PostgreSQL backend process", pid
)));
76 return SIGNAL_BACKEND_ERROR
;
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).
86 * Otherwise, users can signal backends for roles they have privileges of.
88 if (!OidIsValid(proc
->roleId
) || superuser_arg(proc
->roleId
))
90 ProcNumber procNumber
= GetNumberFromPGProc(proc
);
91 PgBackendStatus
*procStatus
= pgstat_get_beentry_by_proc_number(procNumber
);
93 if (procStatus
&& procStatus
->st_backendType
== B_AUTOVAC_WORKER
)
95 if (!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_AUTOVACUUM_WORKER
))
96 return SIGNAL_BACKEND_NOAUTOVAC
;
98 else if (!superuser())
99 return SIGNAL_BACKEND_NOSUPERUSER
;
101 else if (!has_privs_of_role(GetUserId(), proc
->roleId
) &&
102 !has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND
))
103 return SIGNAL_BACKEND_NOPERMISSION
;
106 * Can the process we just validated above end, followed by the pid being
107 * recycled for a new process, before reaching here? Then we'd be trying
108 * to kill the wrong thing. Seems near impossible when sequential pid
109 * assignment and wraparound is used. Perhaps it could happen on a system
110 * where pid re-use is randomized. That race condition possibility seems
111 * too unlikely to worry about.
114 /* If we have setsid(), signal the backend's whole process group */
121 /* Again, just a warning to allow loops */
123 (errmsg("could not send signal to process %d: %m", pid
)));
124 return SIGNAL_BACKEND_ERROR
;
126 return SIGNAL_BACKEND_SUCCESS
;
130 * Signal to cancel a backend process. This is allowed if you are a member of
131 * the role whose process is being canceled.
133 * Note that only superusers can signal superuser-owned processes.
136 pg_cancel_backend(PG_FUNCTION_ARGS
)
138 int r
= pg_signal_backend(PG_GETARG_INT32(0), SIGINT
);
140 if (r
== SIGNAL_BACKEND_NOSUPERUSER
)
142 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
143 errmsg("permission denied to cancel query"),
144 errdetail("Only roles with the %s attribute may cancel queries of roles with the %s attribute.",
145 "SUPERUSER", "SUPERUSER")));
147 if (r
== SIGNAL_BACKEND_NOAUTOVAC
)
149 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
150 errmsg("permission denied to cancel query"),
151 errdetail("Only roles with privileges of the \"%s\" role may cancel autovacuum workers.",
152 "pg_signal_autovacuum_worker")));
154 if (r
== SIGNAL_BACKEND_NOPERMISSION
)
156 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
157 errmsg("permission denied to cancel query"),
158 errdetail("Only roles with privileges of the role whose query is being canceled or with privileges of the \"%s\" role may cancel this query.",
159 "pg_signal_backend")));
161 PG_RETURN_BOOL(r
== SIGNAL_BACKEND_SUCCESS
);
165 * Wait until there is no backend process with the given PID and return true.
166 * On timeout, a warning is emitted and false is returned.
169 pg_wait_until_termination(int pid
, int64 timeout
)
172 * Wait in steps of waittime milliseconds until this function exits or
175 int64 waittime
= 100;
178 * Initially remaining time is the entire timeout specified by the user.
180 int64 remainingtime
= timeout
;
183 * Check existence of the backend. If the backend still exists, then wait
184 * for waittime milliseconds, again check for the existence. Repeat this
185 * until timeout or an error occurs or a pending interrupt such as query
186 * cancel gets processed.
190 if (remainingtime
< waittime
)
191 waittime
= remainingtime
;
193 if (kill(pid
, 0) == -1)
199 (errcode(ERRCODE_INTERNAL_ERROR
),
200 errmsg("could not check the existence of the backend with PID %d: %m",
204 /* Process interrupts, if any, before waiting */
205 CHECK_FOR_INTERRUPTS();
207 (void) WaitLatch(MyLatch
,
208 WL_LATCH_SET
| WL_TIMEOUT
| WL_EXIT_ON_PM_DEATH
,
210 WAIT_EVENT_BACKEND_TERMINATION
);
214 remainingtime
-= waittime
;
215 } while (remainingtime
> 0);
218 (errmsg_plural("backend with PID %d did not terminate within %lld millisecond",
219 "backend with PID %d did not terminate within %lld milliseconds",
221 pid
, (long long int) timeout
)));
227 * Send a signal to terminate a backend process. This is allowed if you are a
228 * member of the role whose process is being terminated. If the timeout input
229 * argument is 0, then this function just signals the backend and returns
230 * true. If timeout is nonzero, then it waits until no process has the given
231 * PID; if the process ends within the timeout, true is returned, and if the
232 * timeout is exceeded, a warning is emitted and false is returned.
234 * Note that only superusers can signal superuser-owned processes.
237 pg_terminate_backend(PG_FUNCTION_ARGS
)
241 int timeout
; /* milliseconds */
243 pid
= PG_GETARG_INT32(0);
244 timeout
= PG_GETARG_INT64(1);
248 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE
),
249 errmsg("\"timeout\" must not be negative")));
251 r
= pg_signal_backend(pid
, SIGTERM
);
253 if (r
== SIGNAL_BACKEND_NOSUPERUSER
)
255 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
256 errmsg("permission denied to terminate process"),
257 errdetail("Only roles with the %s attribute may terminate processes of roles with the %s attribute.",
258 "SUPERUSER", "SUPERUSER")));
260 if (r
== SIGNAL_BACKEND_NOAUTOVAC
)
262 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
263 errmsg("permission denied to terminate process"),
264 errdetail("Only roles with privileges of the \"%s\" role may terminate autovacuum workers.",
265 "pg_signal_autovacuum_worker")));
267 if (r
== SIGNAL_BACKEND_NOPERMISSION
)
269 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
270 errmsg("permission denied to terminate process"),
271 errdetail("Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process.",
272 "pg_signal_backend")));
274 /* Wait only on success and if actually requested */
275 if (r
== SIGNAL_BACKEND_SUCCESS
&& timeout
> 0)
276 PG_RETURN_BOOL(pg_wait_until_termination(pid
, timeout
));
278 PG_RETURN_BOOL(r
== SIGNAL_BACKEND_SUCCESS
);
282 * Signal to reload the database configuration
284 * Permission checking for this function is managed through the normal
288 pg_reload_conf(PG_FUNCTION_ARGS
)
290 if (kill(PostmasterPid
, SIGHUP
))
293 (errmsg("failed to send signal to postmaster: %m")));
294 PG_RETURN_BOOL(false);
297 PG_RETURN_BOOL(true);
304 * Permission checking for this function is managed through the normal
308 pg_rotate_logfile(PG_FUNCTION_ARGS
)
310 if (!Logging_collector
)
313 (errmsg("rotation not possible because log collection not active")));
314 PG_RETURN_BOOL(false);
317 SendPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE
);
318 PG_RETURN_BOOL(true);