diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c index 173b982..060d0cb 100644 --- a/src/backend/storage/ipc/dsm_impl.c +++ b/src/backend/storage/ipc/dsm_impl.c @@ -62,6 +62,7 @@ #include #endif +#include "miscadmin.h" #include "portability/mem.h" #include "storage/dsm_impl.h" #include "storage/fd.h" @@ -80,6 +81,7 @@ static bool dsm_impl_sysv(dsm_op op, dsm_handle handle, Size request_size, Size *mapped_size, int elevel); #endif #ifdef USE_DSM_WINDOWS +static char *get_segment_name(dsm_handle handle); static bool dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel); @@ -590,6 +592,36 @@ dsm_impl_sysv(dsm_op op, dsm_handle handle, Size request_size, #ifdef USE_DSM_WINDOWS /* + * Generate shared memory segment name, using the data directory to generate + * a unique identifier. This segment is stored in Global\ namespace to allow + * any other process to have an access to it. + */ +static char * +get_segment_name(dsm_handle handle) +{ + char *res; + + /* let enough place for prefix and handle */ + res = palloc_extended(strlen(DataDir) + 64, MCXT_ALLOC_NO_OOM); + + if (res == NULL) + return NULL; + + /* + * Storing the shared memory segment in the Global\ namespace, can allow + * any process running in any session to access that file mapping object + * provided that the caller has the required access rights. But to avoid + * issues faced in main shared memory, we are using the naming convention + * similar to main shared memory. We can change here once issue mentioned + * in GetSharedMemName is resolved. + */ + snprintf(res, strlen(DataDir) + 64, "%s.%s.%u", + SEGMENT_NAME_PREFIX, DataDir, handle); + + return res; +} + +/* * Operating system primitives to support Windows shared memory. * * Windows shared memory implementation is done using file mapping @@ -609,7 +641,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, { char *address; HANDLE hmap; - char name[64]; + char *name; MEMORY_BASIC_INFORMATION info; /* Resize is not supported for Windows shared memory. */ @@ -623,15 +655,13 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, if (op == DSM_OP_ATTACH && *mapped_address != NULL) return true; - /* - * Storing the shared memory segment in the Global\ namespace, can allow - * any process running in any session to access that file mapping object - * provided that the caller has the required access rights. But to avoid - * issues faced in main shared memory, we are using the naming convention - * similar to main shared memory. We can change here once issue mentioned - * in GetSharedMemName is resolved. - */ - snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle); + name = get_segment_name(handle); + + if (name == NULL) + { + elog(elevel, "could not allocate memory for shared memory segment name"); + return false; + } /* * Handle teardown cases. Since Windows automatically destroys the object @@ -647,6 +677,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, (errcode_for_dynamic_shared_memory(), errmsg("could not unmap shared memory segment \"%s\": %m", name))); + pfree(name); return false; } if (*impl_private != NULL @@ -657,12 +688,14 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, (errcode_for_dynamic_shared_memory(), errmsg("could not remove shared memory segment \"%s\": %m", name))); + pfree(name); return false; } *impl_private = NULL; *mapped_address = NULL; *mapped_size = 0; + pfree(name); return true; } @@ -693,6 +726,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, (errcode_for_dynamic_shared_memory(), errmsg("could not create shared memory segment \"%s\": %m", name))); + pfree(name); return false; } _dosmaperr(GetLastError()); @@ -705,6 +739,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, * modified. */ CloseHandle(hmap); + pfree(name); return false; } } @@ -720,6 +755,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, (errcode_for_dynamic_shared_memory(), errmsg("could not open shared memory segment \"%s\": %m", name))); + pfree(name); return false; } } @@ -741,6 +777,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, (errcode_for_dynamic_shared_memory(), errmsg("could not map shared memory segment \"%s\": %m", name))); + pfree(name); return false; } @@ -765,6 +802,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, (errcode_for_dynamic_shared_memory(), errmsg("could not stat shared memory segment \"%s\": %m", name))); + pfree(name); return false; } @@ -772,6 +810,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, *mapped_size = info.RegionSize; *impl_private = hmap; + pfree(name); return true; } #endif @@ -1009,14 +1048,15 @@ dsm_impl_pin_segment(dsm_handle handle, void *impl_private) PostmasterHandle, &hmap, 0, FALSE, DUPLICATE_SAME_ACCESS)) { - char name[64]; + char *name; - snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle); _dosmaperr(GetLastError()); + name = get_segment_name(handle); ereport(ERROR, (errcode_for_dynamic_shared_memory(), errmsg("could not duplicate handle for \"%s\": %m", - name))); + name ? name : "undefined"))); + pfree(name); } break; }