🌐 AI搜索 & 代理 主页
Skip to content

Commit 1165a93

Browse files
Teach DSM registry to ERROR if attaching to an uninitialized entry.
If DSM entry initialization fails, backends could try to use an uninitialized DSM segment, DSA, or dshash table (since the entry is still added to the registry). To fix, keep track of whether initialization completed, and ERROR if a backend tries to attach to an uninitialized entry. We could instead retry initialization as needed, but that seemed complicated, error prone, and unlikely to help most cases. Furthermore, such problems probably indicate a coding error. Reported-by: Alexander Lakhin <exclusion@gmail.com> Reviewed-by: Sami Imseih <samimseih@gmail.com> Discussion: https://postgr.es/m/dd36d384-55df-4fc2-825c-5bc56c950fa9%40gmail.com Backpatch-through: 17
1 parent 0bdc777 commit 1165a93

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

src/backend/storage/ipc/dsm_registry.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ typedef struct DSMRegistryEntry
9393
{
9494
char name[NAMEDATALEN];
9595
DSMREntryType type;
96+
bool initialized;
9697
union
9798
{
9899
NamedDSMState dsm;
@@ -216,6 +217,7 @@ GetNamedDSMSegment(const char *name, size_t size,
216217
dsm_segment *seg;
217218

218219
entry->type = DSMR_ENTRY_TYPE_DSM;
220+
entry->initialized = false;
219221

220222
/* Initialize the segment. */
221223
seg = dsm_create(size, 0);
@@ -228,13 +230,21 @@ GetNamedDSMSegment(const char *name, size_t size,
228230

229231
if (init_callback)
230232
(*init_callback) (ret);
233+
234+
entry->initialized = true;
231235
}
232236
else if (entry->type != DSMR_ENTRY_TYPE_DSM)
233237
ereport(ERROR,
234-
(errmsg("requested DSM segment does not match type of existing entry")));
238+
(errmsg("requested DSM segment \"%s\" does not match type of existing entry",
239+
name)));
240+
else if (!entry->initialized)
241+
ereport(ERROR,
242+
(errmsg("requested DSM segment \"%s\" failed initialization",
243+
name)));
235244
else if (entry->dsm.size != size)
236245
ereport(ERROR,
237-
(errmsg("requested DSM segment size does not match size of existing segment")));
246+
(errmsg("requested DSM segment \"%s\" does not match size of existing entry",
247+
name)));
238248
else
239249
{
240250
NamedDSMState *state = &entry->dsm;
@@ -297,6 +307,7 @@ GetNamedDSA(const char *name, bool *found)
297307
NamedDSAState *state = &entry->dsa;
298308

299309
entry->type = DSMR_ENTRY_TYPE_DSA;
310+
entry->initialized = false;
300311

301312
/* Initialize the LWLock tranche for the DSA. */
302313
state->tranche = LWLockNewTrancheId(name);
@@ -308,10 +319,17 @@ GetNamedDSA(const char *name, bool *found)
308319

309320
/* Store handle for other backends to use. */
310321
state->handle = dsa_get_handle(ret);
322+
323+
entry->initialized = true;
311324
}
312325
else if (entry->type != DSMR_ENTRY_TYPE_DSA)
313326
ereport(ERROR,
314-
(errmsg("requested DSA does not match type of existing entry")));
327+
(errmsg("requested DSA \"%s\" does not match type of existing entry",
328+
name)));
329+
else if (!entry->initialized)
330+
ereport(ERROR,
331+
(errmsg("requested DSA \"%s\" failed initialization",
332+
name)));
315333
else
316334
{
317335
NamedDSAState *state = &entry->dsa;
@@ -372,6 +390,7 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
372390
dsa_area *dsa;
373391

374392
entry->type = DSMR_ENTRY_TYPE_DSH;
393+
entry->initialized = false;
375394

376395
/* Initialize the LWLock tranche for the hash table. */
377396
dsh_state->tranche = LWLockNewTrancheId(name);
@@ -389,10 +408,17 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
389408
/* Store handles for other backends to use. */
390409
dsh_state->dsa_handle = dsa_get_handle(dsa);
391410
dsh_state->dsh_handle = dshash_get_hash_table_handle(ret);
411+
412+
entry->initialized = true;
392413
}
393414
else if (entry->type != DSMR_ENTRY_TYPE_DSH)
394415
ereport(ERROR,
395-
(errmsg("requested DSHash does not match type of existing entry")));
416+
(errmsg("requested DSHash \"%s\" does not match type of existing entry",
417+
name)));
418+
else if (!entry->initialized)
419+
ereport(ERROR,
420+
(errmsg("requested DSHash \"%s\" failed initialization",
421+
name)));
396422
else
397423
{
398424
NamedDSHState *dsh_state = &entry->dsh;

0 commit comments

Comments
 (0)