diff options
author | Bruce Momjian <bruce@momjian.us> | 2008-04-15 13:55:12 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2008-04-15 13:55:12 +0000 |
commit | 18b286f3e3317c26f27ead1dea8be23c63a7ef2a (patch) | |
tree | 380518a08736536d69901e2e9c0a13594a101d63 /src/backend/utils/adt/misc.c | |
parent | fcf053d7829f2d83829256153e856f9a36c83ffd (diff) | |
download | postgresql-18b286f3e3317c26f27ead1dea8be23c63a7ef2a.tar.gz postgresql-18b286f3e3317c26f27ead1dea8be23c63a7ef2a.zip |
Add pg_terminate_backend() to allow terminating only a single session.
Diffstat (limited to 'src/backend/utils/adt/misc.c')
-rw-r--r-- | src/backend/utils/adt/misc.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index f7aaec12f0e..d5e794abee2 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.59 2008/04/04 16:57:21 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.60 2008/04/15 13:55:11 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ #include "postmaster/syslogger.h" #include "storage/fd.h" #include "storage/pmsignal.h" +#include "storage/proc.h" #include "storage/procarray.h" #include "utils/builtins.h" #include "tcop/tcopprot.h" @@ -89,7 +90,7 @@ current_query(PG_FUNCTION_ARGS) * Functions to send signals to other backends. */ static bool -pg_signal_backend(int pid, int sig) +pg_signal_check(int pid) { if (!superuser()) ereport(ERROR, @@ -106,7 +107,16 @@ pg_signal_backend(int pid, int sig) (errmsg("PID %d is not a PostgreSQL server process", pid))); return false; } + else + return true; +} +/* + * Functions to send signals to other backends. + */ +static bool +pg_signal_backend(int pid, int sig) +{ /* If we have setsid(), signal the backend's whole process group */ #ifdef HAVE_SETSID if (kill(-pid, sig)) @@ -125,7 +135,43 @@ pg_signal_backend(int pid, int sig) Datum pg_cancel_backend(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGINT)); + int pid = PG_GETARG_INT32(0); + + if (pg_signal_check(pid)) + PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT)); + else + PG_RETURN_BOOL(false); +} + +/* + * To cleanly terminate a backend, we set PGPROC(pid)->terminate + * then send a cancel signal. We get ProcArrayLock only when + * setting PGPROC->terminate so the function might fail in + * several places, but that is fine because in those cases the + * backend is already gone. + */ +Datum +pg_terminate_backend(PG_FUNCTION_ARGS) +{ + int pid = PG_GETARG_INT32(0); + volatile PGPROC *term_proc; + + /* Is this the super-user, and can we find the PGPROC entry for the pid? */ + if (pg_signal_check(pid) && (term_proc = BackendPidGetProc(pid)) != NULL) + { + LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); + /* Recheck now that we have the ProcArray lock. */ + if (term_proc->pid == pid) + { + term_proc->terminate = true; + LWLockRelease(ProcArrayLock); + PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT)); + } + else + LWLockRelease(ProcArrayLock); + } + + PG_RETURN_BOOL(false); } Datum @@ -169,17 +215,6 @@ pg_rotate_logfile(PG_FUNCTION_ARGS) PG_RETURN_BOOL(true); } -#ifdef NOT_USED - -/* Disabled in 8.0 due to reliability concerns; FIXME someday */ -Datum -pg_terminate_backend(PG_FUNCTION_ARGS) -{ - PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM)); -} -#endif - - /* Function to find out which databases make use of a tablespace */ typedef struct |