aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2014-05-07 14:54:43 -0400
committerRobert Haas <rhaas@postgresql.org>2014-05-07 14:56:49 -0400
commit4d155d8b08fe08c1a1649fdbad61c6dcf4a8671f (patch)
treea71336ebdeb02017f00918030c7275d63a54ac48 /src
parent04e5025be8bbe572e12b19c4ba9e2a8360b8ffe5 (diff)
downloadpostgresql-4d155d8b08fe08c1a1649fdbad61c6dcf4a8671f.tar.gz
postgresql-4d155d8b08fe08c1a1649fdbad61c6dcf4a8671f.zip
Detach shared memory from bgworkers without shmem access.
Since the postmaster won't perform a crash-and-restart sequence for background workers which don't request shared memory access, we'd better make sure that they can't corrupt shared memory. Patch by me, review by Tom Lane.
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/bgworker.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index a6b25d8494a..8078a38ed72 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -20,9 +20,11 @@
#include "postmaster/bgworker_internals.h"
#include "postmaster/postmaster.h"
#include "storage/barrier.h"
+#include "storage/dsm.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/lwlock.h"
+#include "storage/pg_shmem.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procsignal.h"
@@ -400,12 +402,16 @@ BackgroundWorkerStopNotifications(pid_t pid)
BackgroundWorker *
BackgroundWorkerEntry(int slotno)
{
+ static BackgroundWorker myEntry;
BackgroundWorkerSlot *slot;
Assert(slotno < BackgroundWorkerData->total_slots);
slot = &BackgroundWorkerData->slot[slotno];
Assert(slot->in_use);
- return &slot->worker; /* can't become free while we're still here */
+
+ /* must copy this in case we don't intend to retain shmem access */
+ memcpy(&myEntry, &slot->worker, sizeof myEntry);
+ return &myEntry;
}
#endif
@@ -542,6 +548,20 @@ StartBackgroundWorker(void)
snprintf(buf, MAXPGPATH, "bgworker: %s", worker->bgw_name);
init_ps_display(buf, "", "", "");
+ /*
+ * If we're not supposed to have shared memory access, then detach from
+ * shared memory. If we didn't request shared memory access, the
+ * postmaster won't force a cluster-wide restart if we exit unexpectedly,
+ * so we'd better make sure that we don't mess anything up that would
+ * require that sort of cleanup.
+ */
+ if ((worker->bgw_flags & BGWORKER_SHMEM_ACCESS) == 0)
+ {
+ on_exit_reset();
+ dsm_detach_all();
+ PGSharedMemoryDetach();
+ }
+
SetProcessingMode(InitProcessing);
/* Apply PostAuthDelay */
@@ -616,19 +636,29 @@ StartBackgroundWorker(void)
/* We can now handle ereport(ERROR) */
PG_exception_stack = &local_sigjmp_buf;
- /* Early initialization */
- BaseInit();
-
/*
- * If necessary, create a per-backend PGPROC struct in shared memory,
- * except in the EXEC_BACKEND case where this was done in
- * SubPostmasterMain. We must do this before we can use LWLocks (and in
- * the EXEC_BACKEND case we already had to do some stuff with LWLocks).
+ * If the background worker request shared memory access, set that up now;
+ * else, detach all shared memory segments.
*/
-#ifndef EXEC_BACKEND
if (worker->bgw_flags & BGWORKER_SHMEM_ACCESS)
+ {
+ /*
+ * Early initialization. Some of this could be useful even for
+ * background workers that aren't using shared memory, but they can
+ * call the individual startup routines for those subsystems if needed.
+ */
+ BaseInit();
+
+ /*
+ * Create a per-backend PGPROC struct in shared memory, except in the
+ * EXEC_BACKEND case where this was done in SubPostmasterMain. We must
+ * do this before we can use LWLocks (and in the EXEC_BACKEND case we
+ * already had to do some stuff with LWLocks).
+ */
+#ifndef EXEC_BACKEND
InitProcess();
#endif
+ }
/*
* If bgw_main is set, we use that value as the initial entrypoint.