diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 9fe3ea251bc..ca3b31d9b9c 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -336,6 +336,8 @@ ShmemRequestStructWithOpts(const ShmemStructOpts *options) /* * Internal workhorse of ShmemRequestStruct() and ShmemRequestHash(). * + * Validates the shared memory request options and registers the request. + * * Note: Unlike in the public ShmemRequestStruct() and ShmemRequestHash() * functions, 'options' is *not* copied. It must be allocated in * TopMemoryContext by the caller, and will be freed after the init/attach @@ -356,6 +358,10 @@ ShmemRequestInternal(ShmemStructOpts *options, ShmemRequestKind kind) if (options->name == NULL) elog(ERROR, "shared memory request is missing 'name' option"); + /* + * A request with SHMEM_ATTACH_UNKNOWN_SIZE is valid after startup. Accept it + * here. + */ if (options->size <= 0 && options->size != SHMEM_ATTACH_UNKNOWN_SIZE) elog(ERROR, "invalid size %zd for shared memory request for \"%s\"", options->size, options->name); @@ -387,8 +393,8 @@ ShmemRequestInternal(ShmemStructOpts *options, ShmemRequestKind kind) * ShmemGetRequestedSize() --- estimate the total size of all registered shared * memory structures. * - * This is called when sizing a new segment at postmaster or standalone - * startup, including a postmaster crash restart. + * This is called before creating the main shared memory segment at postmaster or + * standalone startup, and a postmaster crash restart. */ size_t ShmemGetRequestedSize(void) @@ -405,6 +411,7 @@ ShmemGetRequestedSize(void) { size_t alignment = request->options->alignment; + /* We can't estimate the total size when the size is unknown. */ if (request->options->size == SHMEM_ATTACH_UNKNOWN_SIZE) elog(ERROR, "SHMEM_ATTACH_UNKNOWN_SIZE cannot be used during startup"); diff --git a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl index 18e4b2f33bd..06796a7934c 100644 --- a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl +++ b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl @@ -21,29 +21,24 @@ $node->stop; ### $node->start; -# This first call to the function after startup loads the library -# and initializes the shmem area. +# Check that the attach counter is incremented on a new connection my $attach_count1 = $node->safe_psql("postgres", "SELECT get_test_shmem_attach_count();"); - -# Check that the attach counter is incremented on a new connection my $attach_count2 = $node->safe_psql("postgres", "SELECT get_test_shmem_attach_count();"); cmp_ok($attach_count2, '>', $attach_count1, "attach callback is called in each backend"); -# Allocate another shmem area, after the library is loaded. -my $stderr; +# Allocate and attach to a new shared memory area after startup my $res = $node->safe_psql("postgres", "SELECT test_shmem_register('test_shmem after startup', 20, 1);"); is($res, 0, 'allocate after startup'); - -# Test attaching to it again $res = $node->safe_psql("postgres", "SELECT test_shmem_register('test_shmem after startup', 20, 2);"); is($res, 1, 'attach after startup'); # If the size doesn't match when attaching, you get an error +my $stderr; (undef, undef, $stderr) = $node->psql("postgres", "SELECT test_shmem_register('test_shmem after startup', 25, 3);"); like( @@ -70,7 +65,7 @@ like($stderr, qr/shared memory size must be at least \d+ bytes/, $node->stop; ### -# Test that loading via shared_preload_libraries works +# Test that loading via shared_preload_libraries also works ### $node->append_conf('postgresql.conf', "shared_preload_libraries = 'test_shmem'"); @@ -99,7 +94,7 @@ else } $node->stop; -$node->adjust_conf('postgresql.conf', 'shared_preload_libraries', undef); +$node->adjust_conf('postgresql.conf', "shared_preload_libraries", undef); ### # Test a failure in initializing the shared memory area @@ -175,6 +170,7 @@ SKIP: skip 'single-user test is not supported by this platform', 5 if $windows_os; + # Common part of single-user mode command my @command = ( 'postgres', '--single', '-F', '-D' => $node->data_dir); @@ -221,8 +217,4 @@ SELECT test_shmem_register('test_shmem after error', -1, 8); "unknown-size requests are rejected during single-user startup"); } -# clean up -$node->stop; -$node->adjust_conf('postgresql.conf', "shared_preload_libraries", undef); - done_testing();