]> granicus.if.org Git - postgresql/commitdiff
Per previous discussions, here are two functions to send INT and TERM
authorBruce Momjian <bruce@momjian.us>
Wed, 2 Jun 2004 21:29:29 +0000 (21:29 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 2 Jun 2004 21:29:29 +0000 (21:29 +0000)
(cancel and terminate) signals to other backends.   They permit only INT
and TERM, and permits sending only to postgresql backends.

Magnus Hagander

src/backend/storage/ipc/sinval.c
src/backend/utils/adt/misc.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/storage/sinval.h
src/include/utils/builtins.h

index 570feab25e6e6cb7008926ea69eb63b64f836830..856d0f0a73f2b65218a69212d33e945b79f079f9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.63 2004/05/23 03:50:45 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.64 2004/06/02 21:29:28 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -463,6 +463,40 @@ TransactionIdIsInProgress(TransactionId xid)
        return result;
 }
 
+/*
+ * IsBackendPid -- is a given pid a running backend
+ */
+bool
+IsBackendPid(int pid)
+{
+       bool            result = false;
+       SISeg      *segP = shmInvalBuffer;
+       ProcState  *stateP = segP->procState;
+       int                     index;
+
+       LWLockAcquire(SInvalLock, LW_SHARED);
+
+       for (index = 0; index < segP->lastBackend; index++)
+       {
+               SHMEM_OFFSET pOffset = stateP[index].procStruct;
+
+               if (pOffset != INVALID_OFFSET)
+               {
+                       PGPROC     *proc = (PGPROC *) MAKE_PTR(pOffset);
+
+                       if (proc->pid == pid)
+                       {
+                               result = true;
+                               break;
+                       }
+               }
+       }
+
+       LWLockRelease(SInvalLock);
+
+       return result;
+}
+
 /*
  * GetOldestXmin -- returns oldest transaction that was running
  *                                     when any current transaction was started.
index 673b175bbc042c4a3fed81304b381d13563a3db8..8ab6953cb02c151148a9fabc449b0b9c157128b9 100644 (file)
@@ -8,16 +8,18 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.33 2004/05/21 05:08:02 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.34 2004/06/02 21:29:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
 #include <sys/file.h>
+#include <signal.h>
 
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "storage/sinval.h"
 #include "utils/builtins.h"
 
 
@@ -57,3 +59,47 @@ current_database(PG_FUNCTION_ARGS)
        namestrcpy(db, get_database_name(MyDatabaseId));
        PG_RETURN_NAME(db);
 }
+
+
+/*
+ * Functions to terminate a backend or cancel a query running on
+ * a different backend.
+ */
+
+static int pg_signal_backend(int pid, int sig) 
+{
+       if (!superuser()) 
+               ereport(ERROR,
+                               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                (errmsg("only superuser can signal other backends"))));
+       
+       if (!IsBackendPid(pid))
+       {
+               /* This is just a warning so a loop-through-resultset will not abort
+                * if one backend terminated on it's own during the run */
+               ereport(WARNING,
+                               (errmsg("pid %i is not a postgresql backend",pid)));
+               return 0;
+       }
+
+       if (kill(pid, sig)) 
+       {
+               /* Again, just a warning to allow loops */
+               ereport(WARNING,
+                               (errmsg("failed to send signal to backend %i: %m",pid)));
+               return 0;
+       }
+       return 1;
+}
+
+Datum
+pg_terminate_backend(PG_FUNCTION_ARGS)
+{
+       PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGTERM));
+}
+
+Datum
+pg_cancel_backend(PG_FUNCTION_ARGS)
+{
+       PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGINT));
+}
index f0c2f8269197ce965166dbd1daeb64b7275d7da3..bf6ded488cad8cfc5a0564dd794bdeb951f61d7e 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.232 2004/05/26 18:37:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.233 2004/06/02 21:29:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200405262
+#define CATALOG_VERSION_NO     200406021
 
 #endif
index c87eb2155658212cc0ea0e9b4b992d474f3bd9f4..cb3279747b03a934c4d0ef4cdd96850540ca3b61 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.333 2004/05/26 18:37:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.334 2004/06/02 21:29:29 momjian Exp $
  *
  * NOTES
  *       The script catalog/genbki.sh reads this file and generates .bki
@@ -2808,6 +2808,11 @@ DESCR("Statistics: Blocks fetched for database");
 DATA(insert OID = 1945 (  pg_stat_get_db_blocks_hit            PGNSP PGUID 12 f f t f s 1 20 "26" _null_       pg_stat_get_db_blocks_hit - _null_ ));
 DESCR("Statistics: Blocks found in cache for database");
 
+DATA(insert OID = 2171 ( pg_terminate_backend           PGNSP PGUID 12 f f t f s 1 23 "23" _null_ pg_terminate_backend - _null_ ));
+DESCR("Terminate a backend process");
+DATA(insert OID = 2172 ( pg_cancel_backend              PGNSP PGUID 12 f f t f s 1 23 "23" _null_ pg_cancel_backend - _null_ ));
+DESCR("Cancel running query on a backend process");
+
 DATA(insert OID = 1946 (  encode                                               PGNSP PGUID 12 f f t f i 2 25 "17 25" _null_  binary_encode - _null_ ));
 DESCR("Convert bytea value into some ascii-only text string");
 DATA(insert OID = 1947 (  decode                                               PGNSP PGUID 12 f f t f i 2 17 "25 25" _null_  binary_decode - _null_ ));
index a1c731024cf8c4d51550af8dca33e475f010384b..84769200504450f8c5089c028465e8429c9592ba 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.34 2004/05/23 03:50:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.35 2004/06/02 21:29:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,6 +97,7 @@ extern void ReceiveSharedInvalidMessages(
 
 extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
 extern bool TransactionIdIsInProgress(TransactionId xid);
+extern bool IsBackendPid(int pid);
 extern TransactionId GetOldestXmin(bool allDbs);
 extern int     CountActiveBackends(void);
 extern int     CountEmptyBackendSlots(void);
index 267ededb1303af7684e6ecbdce148946dc1f2744..1fc26e69a1f5d59f3dce1950f2121bbd443d34b1 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.240 2004/05/26 18:35:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.241 2004/06/02 21:29:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -354,6 +354,8 @@ extern Datum float84ge(PG_FUNCTION_ARGS);
 extern Datum nullvalue(PG_FUNCTION_ARGS);
 extern Datum nonnullvalue(PG_FUNCTION_ARGS);
 extern Datum current_database(PG_FUNCTION_ARGS);
+extern Datum pg_terminate_backend(PG_FUNCTION_ARGS);
+extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
 
 /* not_in.c */
 extern Datum int4notin(PG_FUNCTION_ARGS);