PostgreSQL Source Code git master
Loading...
Searching...
No Matches
signalfuncs.c File Reference
#include "postgres.h"
#include <signal.h>
#include "catalog/pg_authid.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/syslogger.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/acl.h"
#include "utils/fmgrprotos.h"
#include "utils/wait_event.h"
Include dependency graph for signalfuncs.c:

Go to the source code of this file.

Macros

#define SIGNAL_BACKEND_SUCCESS   0
 
#define SIGNAL_BACKEND_ERROR   1
 
#define SIGNAL_BACKEND_NOPERMISSION   2
 
#define SIGNAL_BACKEND_NOSUPERUSER   3
 
#define SIGNAL_BACKEND_NOAUTOVAC   4
 

Functions

static int pg_signal_backend (int pid, int sig)
 
Datum pg_cancel_backend (PG_FUNCTION_ARGS)
 
static bool pg_wait_until_termination (int pid, int64 timeout)
 
Datum pg_terminate_backend (PG_FUNCTION_ARGS)
 
Datum pg_reload_conf (PG_FUNCTION_ARGS)
 
Datum pg_rotate_logfile (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ SIGNAL_BACKEND_ERROR

#define SIGNAL_BACKEND_ERROR   1

Definition at line 47 of file signalfuncs.c.

◆ SIGNAL_BACKEND_NOAUTOVAC

#define SIGNAL_BACKEND_NOAUTOVAC   4

Definition at line 50 of file signalfuncs.c.

◆ SIGNAL_BACKEND_NOPERMISSION

#define SIGNAL_BACKEND_NOPERMISSION   2

Definition at line 48 of file signalfuncs.c.

◆ SIGNAL_BACKEND_NOSUPERUSER

#define SIGNAL_BACKEND_NOSUPERUSER   3

Definition at line 49 of file signalfuncs.c.

◆ SIGNAL_BACKEND_SUCCESS

#define SIGNAL_BACKEND_SUCCESS   0

Definition at line 46 of file signalfuncs.c.

Function Documentation

◆ pg_cancel_backend()

Datum pg_cancel_backend ( PG_FUNCTION_ARGS  )

Definition at line 134 of file signalfuncs.c.

135{
137
141 errmsg("permission denied to cancel query"),
142 errdetail("Only roles with the %s attribute may cancel queries of roles with the %s attribute.",
143 "SUPERUSER", "SUPERUSER")));
144
148 errmsg("permission denied to cancel query"),
149 errdetail("Only roles with privileges of the \"%s\" role may cancel autovacuum workers.",
150 "pg_signal_autovacuum_worker")));
151
155 errmsg("permission denied to cancel query"),
156 errdetail("Only roles with privileges of the role whose query is being canceled or with privileges of the \"%s\" role may cancel this query.",
157 "pg_signal_backend")));
158
160}
int errcode(int sqlerrcode)
Definition elog.c:874
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
static char * errmsg
static int fb(int x)
static int pg_signal_backend(int pid, int sig)
Definition signalfuncs.c:52
#define SIGNAL_BACKEND_SUCCESS
Definition signalfuncs.c:46
#define SIGNAL_BACKEND_NOPERMISSION
Definition signalfuncs.c:48
#define SIGNAL_BACKEND_NOSUPERUSER
Definition signalfuncs.c:49
#define SIGNAL_BACKEND_NOAUTOVAC
Definition signalfuncs.c:50

References ereport, errcode(), errdetail(), errmsg, ERROR, fb(), PG_GETARG_INT32, PG_RETURN_BOOL, pg_signal_backend(), SIGNAL_BACKEND_NOAUTOVAC, SIGNAL_BACKEND_NOPERMISSION, SIGNAL_BACKEND_NOSUPERUSER, and SIGNAL_BACKEND_SUCCESS.

◆ pg_reload_conf()

Datum pg_reload_conf ( PG_FUNCTION_ARGS  )

Definition at line 286 of file signalfuncs.c.

287{
289 {
291 (errmsg("failed to send signal to postmaster: %m")));
292 PG_RETURN_BOOL(false);
293 }
294
295 PG_RETURN_BOOL(true);
296}
#define WARNING
Definition elog.h:36
pid_t PostmasterPid
Definition globals.c:106
#define SIGHUP
Definition win32_port.h:158
#define kill(pid, sig)
Definition win32_port.h:490

References ereport, errmsg, kill, PG_RETURN_BOOL, PostmasterPid, SIGHUP, and WARNING.

◆ pg_rotate_logfile()

Datum pg_rotate_logfile ( PG_FUNCTION_ARGS  )

Definition at line 306 of file signalfuncs.c.

307{
309 {
311 (errmsg("rotation not possible because log collection not active")));
312 PG_RETURN_BOOL(false);
313 }
314
316 PG_RETURN_BOOL(true);
317}
void SendPostmasterSignal(PMSignalReason reason)
Definition pmsignal.c:165
@ PMSIGNAL_ROTATE_LOGFILE
Definition pmsignal.h:38
bool Logging_collector
Definition syslogger.c:71

References ereport, errmsg, Logging_collector, PG_RETURN_BOOL, PMSIGNAL_ROTATE_LOGFILE, SendPostmasterSignal(), and WARNING.

◆ pg_signal_backend()

static int pg_signal_backend ( int  pid,
int  sig 
)
static

Definition at line 52 of file signalfuncs.c.

53{
54 PGPROC *proc = BackendPidGetProc(pid);
55
56 /*
57 * BackendPidGetProc returns NULL if the pid isn't valid; but by the time
58 * we reach kill(), a process for which we get a valid proc here might
59 * have terminated on its own. There's no way to acquire a lock on an
60 * arbitrary process to prevent that. But since so far all the callers of
61 * this mechanism involve some request for ending the process anyway, that
62 * it might end on its own first is not a problem.
63 *
64 * Note that proc will also be NULL if the pid refers to an auxiliary
65 * process or the postmaster (neither of which can be signaled via
66 * pg_signal_backend()).
67 */
68 if (proc == NULL)
69 {
70 /*
71 * This is just a warning so a loop-through-resultset will not abort
72 * if one backend terminated on its own during the run.
73 */
75 (errmsg("PID %d is not a PostgreSQL backend process", pid)));
76
78 }
79
80 /*
81 * Only allow superusers to signal superuser-owned backends. Any process
82 * not advertising a role might have the importance of a superuser-owned
83 * backend, so treat it that way. As an exception, we allow roles with
84 * privileges of pg_signal_autovacuum_worker to signal autovacuum workers
85 * (which do not advertise a role).
86 *
87 * Otherwise, users can signal backends for roles they have privileges of.
88 */
89 if (!OidIsValid(proc->roleId) || superuser_arg(proc->roleId))
90 {
91 if (proc->backendType == B_AUTOVAC_WORKER)
92 {
95 }
96 else if (!superuser())
98 }
99 else if (!has_privs_of_role(GetUserId(), proc->roleId) &&
102
103 /*
104 * Can the process we just validated above end, followed by the pid being
105 * recycled for a new process, before reaching here? Then we'd be trying
106 * to kill the wrong thing. Seems near impossible when sequential pid
107 * assignment and wraparound is used. Perhaps it could happen on a system
108 * where pid re-use is randomized. That race condition possibility seems
109 * too unlikely to worry about.
110 */
111
112 /* If we have setsid(), signal the backend's whole process group */
113#ifdef HAVE_SETSID
114 if (kill(-pid, sig))
115#else
116 if (kill(pid, sig))
117#endif
118 {
119 /* Again, just a warning to allow loops */
121 (errmsg("could not send signal to process %d: %m", pid)));
123 }
125}
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
#define OidIsValid(objectId)
Definition c.h:860
@ B_AUTOVAC_WORKER
Definition miscadmin.h:345
Oid GetUserId(void)
Definition miscinit.c:470
static int sig
Definition pg_ctl.c:81
PGPROC * BackendPidGetProc(int pid)
Definition procarray.c:3156
#define SIGNAL_BACKEND_ERROR
Definition signalfuncs.c:47
Definition proc.h:176
BackendType backendType
Definition proc.h:195
Oid roleId
Definition proc.h:199
bool superuser_arg(Oid roleid)
Definition superuser.c:57
bool superuser(void)
Definition superuser.c:47

References B_AUTOVAC_WORKER, BackendPidGetProc(), PGPROC::backendType, ereport, errmsg, fb(), GetUserId(), has_privs_of_role(), kill, OidIsValid, PGPROC::roleId, sig, SIGNAL_BACKEND_ERROR, SIGNAL_BACKEND_NOAUTOVAC, SIGNAL_BACKEND_NOPERMISSION, SIGNAL_BACKEND_NOSUPERUSER, SIGNAL_BACKEND_SUCCESS, superuser(), superuser_arg(), and WARNING.

Referenced by pg_cancel_backend(), and pg_terminate_backend().

◆ pg_terminate_backend()

Datum pg_terminate_backend ( PG_FUNCTION_ARGS  )

Definition at line 235 of file signalfuncs.c.

236{
237 int pid;
238 int r;
239 int timeout; /* milliseconds */
240
241 pid = PG_GETARG_INT32(0);
243
244 if (timeout < 0)
247 errmsg("\"timeout\" must not be negative")));
248
249 r = pg_signal_backend(pid, SIGTERM);
250
254 errmsg("permission denied to terminate process"),
255 errdetail("Only roles with the %s attribute may terminate processes of roles with the %s attribute.",
256 "SUPERUSER", "SUPERUSER")));
257
261 errmsg("permission denied to terminate process"),
262 errdetail("Only roles with privileges of the \"%s\" role may terminate autovacuum workers.",
263 "pg_signal_autovacuum_worker")));
264
268 errmsg("permission denied to terminate process"),
269 errdetail("Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process.",
270 "pg_signal_backend")));
271
272 /* Wait only on success and if actually requested */
273 if (r == SIGNAL_BACKEND_SUCCESS && timeout > 0)
275 else
277}
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
static bool pg_wait_until_termination(int pid, int64 timeout)

References ereport, errcode(), errdetail(), errmsg, ERROR, fb(), PG_GETARG_INT32, PG_GETARG_INT64, PG_RETURN_BOOL, pg_signal_backend(), pg_wait_until_termination(), SIGNAL_BACKEND_NOAUTOVAC, SIGNAL_BACKEND_NOPERMISSION, SIGNAL_BACKEND_NOSUPERUSER, and SIGNAL_BACKEND_SUCCESS.

◆ pg_wait_until_termination()

static bool pg_wait_until_termination ( int  pid,
int64  timeout 
)
static

Definition at line 167 of file signalfuncs.c.

168{
169 /*
170 * Wait in steps of waittime milliseconds until this function exits or
171 * timeout.
172 */
173 int64 waittime = 100;
174
175 /*
176 * Initially remaining time is the entire timeout specified by the user.
177 */
179
180 /*
181 * Check existence of the backend. If the backend still exists, then wait
182 * for waittime milliseconds, again check for the existence. Repeat this
183 * until timeout or an error occurs or a pending interrupt such as query
184 * cancel gets processed.
185 */
186 do
187 {
190
191 if (kill(pid, 0) == -1)
192 {
193 if (errno == ESRCH)
194 return true;
195 else
198 errmsg("could not check the existence of the backend with PID %d: %m",
199 pid)));
200 }
201
202 /* Process interrupts, if any, before waiting */
204
207 waittime,
209
211
213 } while (remainingtime > 0);
214
216 (errmsg_plural("backend with PID %d did not terminate within %" PRId64 " millisecond",
217 "backend with PID %d did not terminate within %" PRId64 " milliseconds",
218 timeout,
219 pid, timeout)));
220
221 return false;
222}
int64_t int64
Definition c.h:615
int int int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
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
#define WL_TIMEOUT
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET

References CHECK_FOR_INTERRUPTS, ereport, errcode(), errmsg, errmsg_plural(), ERROR, fb(), kill, MyLatch, ResetLatch(), WaitLatch(), WARNING, WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, and WL_TIMEOUT.

Referenced by pg_terminate_backend().