From b5f7903b97ab9d0539630bab8805fcbcdcef793d Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Thu, 18 Oct 2018 10:48:18 +1300 Subject: [PATCH] Fix thinko in handling of corrupted DSM control area. If dsm_cleanup_using_control_segment() or dsm_postmaster_shutdown() determine that the DSM control segment is corrupted, they should still destroy it, otherwise it is leaked. This fixes an assertion failure in dsm_postmaster_startup(). Reported by build-farm animal peripatus. The root cause of the corrupted segment in that case is not yet known, but that's another matter. Author: Thomas Munro Diagnosed-by: Tom Lane Discussion: https://postgr.es/m/6153.1539806400%40sss.pgh.pa.us --- src/backend/storage/ipc/dsm.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index 9629f22f7af..f24bf2e74a1 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) @@ -227,21 +226,19 @@ dsm_cleanup_using_control_segment(dsm_handle old_control_handle) /* * We've managed to reattach it, but the contents might not be sane. If - * they aren't, we disregard the segment after all. + * they aren't, we disregard the contents of the segment after all. */ old_control = (dsm_control_header *) mapped_address; if (!dsm_control_segment_sane(old_control, mapped_size)) { dsm_impl_op(DSM_OP_DETACH, old_control_handle, 0, &impl_private, &mapped_address, &mapped_size, LOG); - return; + nitems = 0; } + else + nitems = old_control->nitems; - /* - * OK, the control segment looks basically valid, so we can use it to get - * a list of segments that need to be removed. - */ - nitems = old_control->nitems; + /* Get a list of segments that need to be removed. */ for (i = 0; i < nitems; ++i) { dsm_handle handle; @@ -336,13 +333,14 @@ dsm_postmaster_shutdown(int code, Datum arg) * stray shared memory segments, but there's not much we can do about that * if the metadata is gone. */ - 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) -- 2.17.1 (Apple Git-112)