0001-Fix-thinko-in-handling-of-corrupted-DSM-control-a-v2.patch

application/octet-stream

Filename: 0001-Fix-thinko-in-handling-of-corrupted-DSM-control-a-v2.patch
Type: application/octet-stream
Part: 0
Message: Re: DSM robustness failure (was Re: Peripatus/failures)

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v2-0001
Subject: Fix thinko in handling of corrupted DSM control area.
File+
src/backend/storage/ipc/dsm.c 16 5
From ead7cba6708502d79c559c67fd204e8df5b3ee99 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
Date: Thu, 18 Oct 2018 10:48:18 +1300
Subject: [PATCH] Fix thinko in handling of corrupted DSM control area.

If dsm_postmaster_shutdown() determines that the DSM control segment
is corrupted, it should still destroy it, otherwise it is leaked.
Leaving it mapped in was causing an assertion failure in
dsm_postmaster_startup() during crash restart.

Reported by build-farm animal peripatus.  The root cause of the
corrupted segment in that case is not yet known, but that's a
separate problem to investigate.

Author: Thomas Munro
Reviewed-by: Amit Kapila
Diagnosed-by: Tom Lane
Discussion: https://postgr.es/m/6153.1539806400%40sss.pgh.pa.us
---
 src/backend/storage/ipc/dsm.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 9629f22f7af..3521a00798e 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -138,8 +138,7 @@ static void *dsm_control_impl_private = NULL;
 /*
  * Start up the dynamic shared memory system.
  *
- * This is called just once during each cluster lifetime, at postmaster
- * startup time.
+ * This is called at postmaster startup time, and again during crash restarts.
  */
 void
 dsm_postmaster_startup(PGShmemHeader *shim)
@@ -334,15 +333,17 @@ dsm_postmaster_shutdown(int code, Datum arg)
 	 * control segment while it was dying.  In that case, we warn and ignore
 	 * the contents of the control segment.  This may end up leaving behind
 	 * stray shared memory segments, but there's not much we can do about that
-	 * if the metadata is gone.
+	 * if the metadata is gone.  We'll still attempt to destroy the segment
+	 * itself.
 	 */
-	nitems = dsm_control->nitems;
 	if (!dsm_control_segment_sane(dsm_control, dsm_control_mapped_size))
 	{
 		ereport(LOG,
 				(errmsg("dynamic shared memory control segment is corrupt")));
-		return;
+		nitems = 0;
 	}
+	else
+		nitems = dsm_control->nitems;
 
 	/* Remove any remaining segments. */
 	for (i = 0; i < nitems; ++i)
@@ -371,6 +372,16 @@ dsm_postmaster_shutdown(int code, Datum arg)
 	dsm_impl_op(DSM_OP_DESTROY, dsm_control_handle, 0,
 				&dsm_control_impl_private, &dsm_control_address,
 				&dsm_control_mapped_size, LOG);
+
+	/*
+	 * In the unlikely event that we failed to unmap the segment, we'll just
+	 * forget that we have it mapped so that we can proceed without an
+	 * assertion failure, in case of crash restart.
+	 */
+	dsm_control_address = NULL;
+	dsm_control_mapped_size = 0;
+	dsm_control_impl_private = NULL;
+
 	dsm_control = dsm_control_address;
 	shim->dsm_control = 0;
 }
-- 
2.19.1