Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * signalfuncs.c
4 : * Functions for signaling backends
5 : *
6 : * Portions Copyright (c) 1996-2023, 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
1648 michael 49 CBC 35 : pg_signal_backend(int pid, int sig)
50 : {
51 35 : 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 : * Note that proc will also be NULL if the pid refers to an auxiliary
62 : * process or the postmaster (neither of which can be signaled via
63 : * pg_signal_backend()).
64 : */
65 35 : if (proc == NULL)
66 : {
67 : /*
68 : * This is just a warning so a loop-through-resultset will not abort
69 : * if one backend terminated on its own during the run.
70 : */
1648 michael 71 UBC 0 : ereport(WARNING,
72 : (errmsg("PID %d is not a PostgreSQL backend process", pid)));
73 :
74 0 : return SIGNAL_BACKEND_ERROR;
75 : }
76 :
77 : /* Only allow superusers to signal superuser-owned backends. */
1648 michael 78 CBC 35 : if (superuser_arg(proc->roleId) && !superuser())
1648 michael 79 UBC 0 : return SIGNAL_BACKEND_NOSUPERUSER;
80 :
81 : /* Users can signal backends they have role membership in. */
1648 michael 82 CBC 35 : if (!has_privs_of_role(GetUserId(), proc->roleId) &&
738 sfrost 83 UBC 0 : !has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
1648 michael 84 0 : return SIGNAL_BACKEND_NOPERMISSION;
85 :
86 : /*
87 : * Can the process we just validated above end, followed by the pid being
88 : * recycled for a new process, before reaching here? Then we'd be trying
89 : * to kill the wrong thing. Seems near impossible when sequential pid
90 : * assignment and wraparound is used. Perhaps it could happen on a system
91 : * where pid re-use is randomized. That race condition possibility seems
92 : * too unlikely to worry about.
93 : */
94 :
95 : /* If we have setsid(), signal the backend's whole process group */
96 : #ifdef HAVE_SETSID
1648 michael 97 CBC 35 : if (kill(-pid, sig))
98 : #else
99 : if (kill(pid, sig))
100 : #endif
101 : {
102 : /* Again, just a warning to allow loops */
1648 michael 103 UBC 0 : ereport(WARNING,
104 : (errmsg("could not send signal to process %d: %m", pid)));
105 0 : return SIGNAL_BACKEND_ERROR;
106 : }
1648 michael 107 CBC 35 : return SIGNAL_BACKEND_SUCCESS;
108 : }
109 :
110 : /*
111 : * Signal to cancel a backend process. This is allowed if you are a member of
112 : * the role whose process is being canceled.
113 : *
114 : * Note that only superusers can signal superuser-owned processes.
115 : */
116 : Datum
117 29 : pg_cancel_backend(PG_FUNCTION_ARGS)
118 : {
119 29 : int r = pg_signal_backend(PG_GETARG_INT32(0), SIGINT);
120 :
121 29 : if (r == SIGNAL_BACKEND_NOSUPERUSER)
1648 michael 122 UBC 0 : ereport(ERROR,
123 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
124 : errmsg("permission denied to cancel query"),
125 : errdetail("Only roles with the %s attribute may cancel queries of roles with %s.",
126 : "SUPERUSER", "SUPERUSER")));
127 :
1648 michael 128 GIC 29 : if (r == SIGNAL_BACKEND_NOPERMISSION)
1648 michael 129 UIC 0 : ereport(ERROR,
1648 michael 130 ECB : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
131 : errmsg("permission denied to cancel query"),
132 : errdetail("Only roles with privileges of the role whose query is being canceled or with privileges of the \"%s\" role may cancel this query.",
133 : "pg_signal_backend")));
134 :
1648 michael 135 GIC 29 : PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
136 : }
137 :
138 : /*
731 magnus 139 ECB : * Wait until there is no backend process with the given PID and return true.
140 : * On timeout, a warning is emitted and false is returned.
141 : */
142 : static bool
731 magnus 143 GIC 2 : pg_wait_until_termination(int pid, int64 timeout)
144 : {
145 : /*
146 : * Wait in steps of waittime milliseconds until this function exits or
731 magnus 147 ECB : * timeout.
148 : */
697 tgl 149 GIC 2 : int64 waittime = 100;
150 :
151 : /*
152 : * Initially remaining time is the entire timeout specified by the user.
731 magnus 153 ECB : */
697 tgl 154 GIC 2 : int64 remainingtime = timeout;
155 :
156 : /*
157 : * Check existence of the backend. If the backend still exists, then wait
731 magnus 158 ECB : * for waittime milliseconds, again check for the existence. Repeat this
159 : * until timeout or an error occurs or a pending interrupt such as query
160 : * cancel gets processed.
161 : */
162 : do
163 : {
731 magnus 164 GIC 6 : if (remainingtime < waittime)
731 magnus 165 UIC 0 : waittime = remainingtime;
166 :
731 magnus 167 GIC 6 : if (kill(pid, 0) == -1)
731 magnus 168 ECB : {
731 magnus 169 GBC 2 : if (errno == ESRCH)
731 magnus 170 GIC 2 : return true;
731 magnus 171 ECB : else
731 magnus 172 UIC 0 : ereport(ERROR,
731 magnus 173 ECB : (errcode(ERRCODE_INTERNAL_ERROR),
174 : errmsg("could not check the existence of the backend with PID %d: %m",
175 : pid)));
731 magnus 176 EUB : }
177 :
178 : /* Process interrupts, if any, before waiting */
731 magnus 179 GIC 4 : CHECK_FOR_INTERRUPTS();
180 :
181 4 : (void) WaitLatch(MyLatch,
182 : WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
731 magnus 183 ECB : waittime,
184 : WAIT_EVENT_BACKEND_TERMINATION);
185 :
731 magnus 186 GIC 4 : ResetLatch(MyLatch);
187 :
188 4 : remainingtime -= waittime;
189 4 : } while (remainingtime > 0);
731 magnus 190 ECB :
731 magnus 191 UIC 0 : ereport(WARNING,
634 peter 192 ECB : (errmsg_plural("backend with PID %d did not terminate within %lld millisecond",
193 : "backend with PID %d did not terminate within %lld milliseconds",
194 : timeout,
634 peter 195 EUB : pid, (long long int) timeout)));
196 :
731 magnus 197 UIC 0 : return false;
198 : }
199 :
200 : /*
664 noah 201 EUB : * Send a signal to terminate a backend process. This is allowed if you are a
202 : * member of the role whose process is being terminated. If the timeout input
203 : * argument is 0, then this function just signals the backend and returns
204 : * true. If timeout is nonzero, then it waits until no process has the given
205 : * PID; if the process ends within the timeout, true is returned, and if the
206 : * timeout is exceeded, a warning is emitted and false is returned.
207 : *
208 : * Note that only superusers can signal superuser-owned processes.
209 : */
210 : Datum
1648 michael 211 GIC 6 : pg_terminate_backend(PG_FUNCTION_ARGS)
212 : {
213 : int pid;
214 : int r;
664 noah 215 ECB : int timeout; /* milliseconds */
216 :
731 magnus 217 GIC 6 : pid = PG_GETARG_INT32(0);
218 6 : timeout = PG_GETARG_INT64(1);
219 :
220 6 : if (timeout < 0)
731 magnus 221 LBC 0 : ereport(ERROR,
731 magnus 222 ECB : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
223 : errmsg("\"timeout\" must not be negative")));
224 :
731 magnus 225 GBC 6 : r = pg_signal_backend(pid, SIGTERM);
226 :
1648 michael 227 GIC 6 : if (r == SIGNAL_BACKEND_NOSUPERUSER)
1648 michael 228 UIC 0 : ereport(ERROR,
1648 michael 229 ECB : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
230 : errmsg("permission denied to terminate process"),
231 : errdetail("Only roles with the %s attribute may terminate processes of roles with %s.",
232 : "SUPERUSER", "SUPERUSER")));
233 :
1648 michael 234 GBC 6 : if (r == SIGNAL_BACKEND_NOPERMISSION)
1648 michael 235 UIC 0 : ereport(ERROR,
236 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
237 : errmsg("permission denied to terminate process"),
238 : errdetail("Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process.",
239 : "pg_signal_backend")));
240 :
241 : /* Wait only on success and if actually requested */
731 magnus 242 CBC 6 : if (r == SIGNAL_BACKEND_SUCCESS && timeout > 0)
731 magnus 243 GBC 2 : PG_RETURN_BOOL(pg_wait_until_termination(pid, timeout));
244 : else
731 magnus 245 GIC 4 : PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
246 : }
247 :
248 : /*
249 : * Signal to reload the database configuration
1648 michael 250 ECB : *
251 : * Permission checking for this function is managed through the normal
252 : * GRANT system.
253 : */
254 : Datum
1648 michael 255 GIC 16 : pg_reload_conf(PG_FUNCTION_ARGS)
256 : {
257 16 : if (kill(PostmasterPid, SIGHUP))
258 : {
1648 michael 259 UIC 0 : ereport(WARNING,
260 : (errmsg("failed to send signal to postmaster: %m")));
261 0 : PG_RETURN_BOOL(false);
262 : }
1648 michael 263 ECB :
1648 michael 264 GIC 16 : PG_RETURN_BOOL(true);
1648 michael 265 ECB : }
266 :
1648 michael 267 EUB :
268 : /*
269 : * Rotate log file
270 : *
271 : * This function is kept to support adminpack 1.0.
1648 michael 272 ECB : */
273 : Datum
1648 michael 274 UIC 0 : pg_rotate_logfile(PG_FUNCTION_ARGS)
275 : {
276 0 : if (!superuser())
277 0 : ereport(ERROR,
278 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
279 : errmsg("must be superuser to rotate log files with adminpack 1.0"),
280 : /* translator: %s is a SQL function name */
281 : errhint("Consider using %s, which is part of core, instead.",
1165 alvherre 282 EUB : "pg_logfile_rotate()")));
283 :
1648 michael 284 UBC 0 : if (!Logging_collector)
1648 michael 285 EUB : {
1648 michael 286 UIC 0 : ereport(WARNING,
287 : (errmsg("rotation not possible because log collection not active")));
288 0 : PG_RETURN_BOOL(false);
289 : }
290 :
291 0 : SendPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE);
1648 michael 292 UBC 0 : PG_RETURN_BOOL(true);
293 : }
1648 michael 294 EUB :
295 : /*
296 : * Rotate log file
297 : *
298 : * Permission checking for this function is managed through the normal
299 : * GRANT system.
300 : */
301 : Datum
1648 michael 302 UIC 0 : pg_rotate_logfile_v2(PG_FUNCTION_ARGS)
303 : {
304 0 : if (!Logging_collector)
305 : {
306 0 : ereport(WARNING,
307 : (errmsg("rotation not possible because log collection not active")));
308 0 : PG_RETURN_BOOL(false);
309 : }
1648 michael 310 EUB :
1648 michael 311 UIC 0 : SendPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE);
1648 michael 312 UBC 0 : PG_RETURN_BOOL(true);
313 : }
|