Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vNbqE-008NBC-1l for pgsql-hackers@arkaria.postgresql.org; Mon, 24 Nov 2025 19:03:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vNbqD-003KT2-0Y for pgsql-hackers@arkaria.postgresql.org; Mon, 24 Nov 2025 19:03:13 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vNbqC-003KSu-2k for pgsql-hackers@lists.postgresql.org; Mon, 24 Nov 2025 19:03:13 +0000 Received: from mail-il1-x134.google.com ([2607:f8b0:4864:20::134]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vNbqB-001HOi-0w for pgsql-hackers@lists.postgresql.org; Mon, 24 Nov 2025 19:03:12 +0000 Received: by mail-il1-x134.google.com with SMTP id e9e14a558f8ab-431d65ad973so17946265ab.3 for ; Mon, 24 Nov 2025 11:03:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1764010989; x=1764615789; darn=lists.postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=hKIddfOPn0dEcpjUmabsOVbGyvT3H/ZpWW/TcCAk+fQ=; b=BARnmucWJIxg05pi5UkMRXtgir3rcOIxgbDC7kbKJTPzt2CnEuiP9+U3r1tOTZ5tIg 1ESfutn/vXMOTW9UVc2uGoOk3UYEiywZHT+q7QPxkATPdZAKsDVxZK12H4OUn4rPw0wK KTZWjabJeVudAooIUSd6p1yQzs1/4z5J7yXYhxUACv+Z2Di1nq1Qo5WWkmK4776tbrys xCh4HAQ9qMRAbsSWP5OdUKmTOf1xXDNDGHdKg0h37vZvdS6DiAcm1EDarNyRdqsJqp9Z DxdqyF5X6bdnxXhdwwY07fB/QGlnuMewIjzkgGyA78RWJKU4gxODe095//pdqAtX4mZP bjLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764010989; x=1764615789; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hKIddfOPn0dEcpjUmabsOVbGyvT3H/ZpWW/TcCAk+fQ=; b=jg2p+g2KfXoLQ9qrR1qL9v0vXP4DW13jKwFFuCvf4YgRnPVKru8KZ0NAG0WTifygou yIq7VhUvImy/F3eXaoFl2OKcY8qv8lG5JJtyXzyS5V/nDDXBSYTd19WkeiRp3TZ2kkV3 4uaUleng0DeSbFQ2pNLSMkqcfoQQg8tDj1d+hJZt9BkxgFmDbvY0E4w478sJBvC3rKCd TqOwUFx0xeaoYzcUvfOeaD2ffmn5tGuqc/7Z9aDaYy01JaElDX5v8LkzgevxNj9m6FIo bxO+iB3lW5x7ISFEceHhGvD1DaYVnvd3QDEdwS3V1cH8Y6AM+V2BmPqE9YFl6EsDQ4rZ G+bg== X-Gm-Message-State: AOJu0Yy69bKsften3eGMPzep/4rFBd8RIL7fHEsUbXuRxWiBeqqPj7wo +PuqLBNhCATKeY0GgpNd5Pi3+cbh9/rACOwbbqfdUrOYYpZCvnwM+pfo X-Gm-Gg: ASbGncuxqhXY3QkM4n15qkRiQnQclGmQyi2V+mQGoR8QdjSpKZx+hBgPaEpSNSdJORc mxj44/diVv/TZ+POxFh5N62M1HIwCdlIoozpmHYJ+DxcsXkl3cmpcgMlZ/5zKsYy6V/WPXQZJin XIso25LMOZmgN8tvvHmgvhyJUBhz3AWxsxhGpZAh+A3ovzeOt31pCy9a356UTYFIrGhGDCZffT5 t28Mx3RTXFnwLFODv88WL6nDSJv+UfKyNwLDWijxdY4Bchc8aO7VxUGZ7AW77CYnOSSVA85C35m oCuauAwZGkZ/YlBko+aQBKdOE1RXBqgpN4EkPLTK0sySC+BMhFgKA6mBfX3/1f4ca8PPmYK70H2 XuPZVm+SVY9etks/l/qbbWpThPCApmJocGFd20rhusnQhiWpjv1O23V1dfj+EGL2RB7X6tCsfza 8If6xENNqq+rbETivjAHbCvFbS9EUom6FIc5sLuIv5O371IykzcFS1ocsRElbERhCfi3CUG+ywL VZc X-Google-Smtp-Source: AGHT+IHMZjwjvvQ8/UaqL4F7YqjYrKLLpw0uZFhoPeMGci7wJK/tAiAnXgcJ/gwvvKhL82JSaJHBCQ== X-Received: by 2002:a05:6e02:18c5:b0:435:a148:3940 with SMTP id e9e14a558f8ab-435b8efdc35mr110116625ab.42.1764010989162; Mon, 24 Nov 2025 11:03:09 -0800 (PST) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id e9e14a558f8ab-435a90e75d7sm62390295ab.32.2025.11.24.11.03.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Nov 2025 11:03:08 -0800 (PST) Date: Mon, 24 Nov 2025 13:03:06 -0600 From: Nathan Bossart To: Robert Haas Cc: PostgreSQL Hackers Subject: Re: pgsql: Teach DSM registry to ERROR if attaching to an uninitialized ent Message-ID: References: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="POf/bFZrFFck8lM9" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --POf/bFZrFFck8lM9 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Nov 24, 2025 at 12:36:25PM -0600, Nathan Bossart wrote: > On Sat, Nov 22, 2025 at 01:41:21PM -0600, Nathan Bossart wrote: >> I'll give what you suggested a try. It seems reasonable enough. > > Here is a mostly-untested first try. I think 0002 was more complicated than necessary. Here's a second try. -- nathan --POf/bFZrFFck8lM9 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0001-Revert-Teach-DSM-registry-to-ERROR-if-attaching-t.patch From 55956903a8339c754ba96ff0f52ddb38f7ae184b Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 24 Nov 2025 11:03:52 -0600 Subject: [PATCH v2 1/2] Revert "Teach DSM registry to ERROR if attaching to an uninitialized entry." This reverts commit 1165a933aab1355757a43cfd9193b6cce06f573b. --- src/backend/storage/ipc/dsm_registry.c | 34 +++----------------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c index 7eba8a8cffb..a926b9c3f32 100644 --- a/src/backend/storage/ipc/dsm_registry.c +++ b/src/backend/storage/ipc/dsm_registry.c @@ -93,7 +93,6 @@ typedef struct DSMRegistryEntry { char name[NAMEDATALEN]; DSMREntryType type; - bool initialized; union { NamedDSMState dsm; @@ -217,7 +216,6 @@ GetNamedDSMSegment(const char *name, size_t size, dsm_segment *seg; entry->type = DSMR_ENTRY_TYPE_DSM; - entry->initialized = false; /* Initialize the segment. */ seg = dsm_create(size, 0); @@ -230,21 +228,13 @@ GetNamedDSMSegment(const char *name, size_t size, if (init_callback) (*init_callback) (ret); - - entry->initialized = true; } else if (entry->type != DSMR_ENTRY_TYPE_DSM) ereport(ERROR, - (errmsg("requested DSM segment \"%s\" does not match type of existing entry", - name))); - else if (!entry->initialized) - ereport(ERROR, - (errmsg("requested DSM segment \"%s\" failed initialization", - name))); + (errmsg("requested DSM segment does not match type of existing entry"))); else if (entry->dsm.size != size) ereport(ERROR, - (errmsg("requested DSM segment \"%s\" does not match size of existing entry", - name))); + (errmsg("requested DSM segment size does not match size of existing segment"))); else { NamedDSMState *state = &entry->dsm; @@ -307,7 +297,6 @@ GetNamedDSA(const char *name, bool *found) NamedDSAState *state = &entry->dsa; entry->type = DSMR_ENTRY_TYPE_DSA; - entry->initialized = false; /* Initialize the LWLock tranche for the DSA. */ state->tranche = LWLockNewTrancheId(name); @@ -319,17 +308,10 @@ GetNamedDSA(const char *name, bool *found) /* Store handle for other backends to use. */ state->handle = dsa_get_handle(ret); - - entry->initialized = true; } else if (entry->type != DSMR_ENTRY_TYPE_DSA) ereport(ERROR, - (errmsg("requested DSA \"%s\" does not match type of existing entry", - name))); - else if (!entry->initialized) - ereport(ERROR, - (errmsg("requested DSA \"%s\" failed initialization", - name))); + (errmsg("requested DSA does not match type of existing entry"))); else { NamedDSAState *state = &entry->dsa; @@ -390,7 +372,6 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) dsa_area *dsa; entry->type = DSMR_ENTRY_TYPE_DSH; - entry->initialized = false; /* Initialize the LWLock tranche for the hash table. */ dsh_state->tranche = LWLockNewTrancheId(name); @@ -408,17 +389,10 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) /* Store handles for other backends to use. */ dsh_state->dsa_handle = dsa_get_handle(dsa); dsh_state->dsh_handle = dshash_get_hash_table_handle(ret); - - entry->initialized = true; } else if (entry->type != DSMR_ENTRY_TYPE_DSH) ereport(ERROR, - (errmsg("requested DSHash \"%s\" does not match type of existing entry", - name))); - else if (!entry->initialized) - ereport(ERROR, - (errmsg("requested DSHash \"%s\" failed initialization", - name))); + (errmsg("requested DSHash does not match type of existing entry"))); else { NamedDSHState *dsh_state = &entry->dsh; -- 2.39.5 (Apple Git-154) --POf/bFZrFFck8lM9 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-handle-ERRORs-in-DSM-registry-functions.patch From 3529f2e17b85537198d8a6fa783ca9c0b0522547 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 24 Nov 2025 12:28:23 -0600 Subject: [PATCH v2 2/2] handle ERRORs in DSM registry functions --- src/backend/storage/ipc/dsm_registry.c | 85 +++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c index a926b9c3f32..bae67d15add 100644 --- a/src/backend/storage/ipc/dsm_registry.c +++ b/src/backend/storage/ipc/dsm_registry.c @@ -155,9 +155,10 @@ init_dsm_registry(void) { /* Initialize dynamic shared hash table for registry. */ dsm_registry_dsa = dsa_create(LWTRANCHE_DSM_REGISTRY_DSA); + dsm_registry_table = dshash_create(dsm_registry_dsa, &dsh_params, NULL); + dsa_pin(dsm_registry_dsa); dsa_pin_mapping(dsm_registry_dsa); - dsm_registry_table = dshash_create(dsm_registry_dsa, &dsh_params, NULL); /* Store handles in shared memory for other backends to use. */ DSMRegistryCtx->dsah = dsa_get_handle(dsm_registry_dsa); @@ -218,16 +219,24 @@ GetNamedDSMSegment(const char *name, size_t size, entry->type = DSMR_ENTRY_TYPE_DSM; /* Initialize the segment. */ - seg = dsm_create(size, 0); + PG_TRY(); + { + seg = dsm_create(size, 0); + ret = dsm_segment_address(seg); + if (init_callback) + (*init_callback) (ret); + } + PG_CATCH(); + { + dshash_delete_entry(dsm_registry_table, entry); + PG_RE_THROW(); + } + PG_END_TRY(); dsm_pin_segment(seg); dsm_pin_mapping(seg); state->handle = dsm_segment_handle(seg); state->size = size; - ret = dsm_segment_address(seg); - - if (init_callback) - (*init_callback) (ret); } else if (entry->type != DSMR_ENTRY_TYPE_DSM) ereport(ERROR, @@ -297,12 +306,23 @@ GetNamedDSA(const char *name, bool *found) NamedDSAState *state = &entry->dsa; entry->type = DSMR_ENTRY_TYPE_DSA; + state->handle = DSA_HANDLE_INVALID; /* Initialize the LWLock tranche for the DSA. */ - state->tranche = LWLockNewTrancheId(name); + PG_TRY(); + { + state->tranche = LWLockNewTrancheId(name); + } + PG_CATCH(); + { + dshash_delete_entry(dsm_registry_table, entry); + PG_RE_THROW(); + } + PG_END_TRY(); /* Initialize the DSA. */ ret = dsa_create(state->tranche); + dsa_pin(ret); dsa_pin_mapping(ret); @@ -312,6 +332,19 @@ GetNamedDSA(const char *name, bool *found) else if (entry->type != DSMR_ENTRY_TYPE_DSA) ereport(ERROR, (errmsg("requested DSA does not match type of existing entry"))); + else if (entry->dsa.handle == DSA_HANDLE_INVALID) + { + NamedDSAState *state = &entry->dsa; + + /* Initialize the DSA. */ + ret = dsa_create(state->tranche); + + dsa_pin(ret); + dsa_pin_mapping(ret); + + /* Store handle for other backends to use. */ + state->handle = dsa_get_handle(ret); + } else { NamedDSAState *state = &entry->dsa; @@ -372,20 +405,31 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) dsa_area *dsa; entry->type = DSMR_ENTRY_TYPE_DSH; + dsh_state->dsa_handle = DSA_HANDLE_INVALID; /* Initialize the LWLock tranche for the hash table. */ - dsh_state->tranche = LWLockNewTrancheId(name); + PG_TRY(); + { + dsh_state->tranche = LWLockNewTrancheId(name); + } + PG_CATCH(); + { + dshash_delete_entry(dsm_registry_table, entry); + PG_RE_THROW(); + } + PG_END_TRY(); /* Initialize the DSA for the hash table. */ dsa = dsa_create(dsh_state->tranche); - dsa_pin(dsa); - dsa_pin_mapping(dsa); /* Initialize the dshash table. */ memcpy(¶ms_copy, params, sizeof(dshash_parameters)); params_copy.tranche_id = dsh_state->tranche; ret = dshash_create(dsa, ¶ms_copy, NULL); + dsa_pin(dsa); + dsa_pin_mapping(dsa); + /* Store handles for other backends to use. */ dsh_state->dsa_handle = dsa_get_handle(dsa); dsh_state->dsh_handle = dshash_get_hash_table_handle(ret); @@ -393,6 +437,27 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) else if (entry->type != DSMR_ENTRY_TYPE_DSH) ereport(ERROR, (errmsg("requested DSHash does not match type of existing entry"))); + else if (entry->dsh.dsa_handle == DSA_HANDLE_INVALID) + { + NamedDSHState *dsh_state = &entry->dsh; + dshash_parameters params_copy; + dsa_area *dsa; + + /* Initialize the DSA for the hash table. */ + dsa = dsa_create(dsh_state->tranche); + + /* Initialize the dshash table. */ + memcpy(¶ms_copy, params, sizeof(dshash_parameters)); + params_copy.tranche_id = dsh_state->tranche; + ret = dshash_create(dsa, ¶ms_copy, NULL); + + dsa_pin(dsa); + dsa_pin_mapping(dsa); + + /* Store handles for other backends to use. */ + dsh_state->dsa_handle = dsa_get_handle(dsa); + dsh_state->dsh_handle = dshash_get_hash_table_handle(ret); + } else { NamedDSHState *dsh_state = &entry->dsh; -- 2.39.5 (Apple Git-154) --POf/bFZrFFck8lM9--