git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4531022)
Retry DSM control segment creation if Windows indicates access denied.
2016年9月20日 16:04:41 +0000 (12:04 -0400)
2016年9月20日 16:04:41 +0000 (12:04 -0400)
Otherwise, attempts to run multiple postmasters running on the same
machine may fail, because Windows sometimes returns ERROR_ACCESS_DENIED
rather than ERROR_ALREADY_EXISTS when there is an existing segment.

Hitting this bug is much more likely because of another defect not
fixed by this patch, namely that dsm_postmaster_startup() uses
random() which returns the same value every time. But that's not
a reason not to fix this.

Kyotaro Horiguchi and Amit Kapila, reviewed by Michael Paquier

Discussion: <CAA4eK1JyNdMeF-dgrpHozDecpDfsRZUtpCi+1AbtuEkfG3YooQ@mail.gmail.com>


diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index 99051f02c8c7c4dc6162bfff2ea1a54978e834ed..7122c4abe000368b7827c2fa963d068eba9f4db0 100644 (file)
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -671,6 +671,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size,
{
DWORD size_high;
DWORD size_low;
+ DWORD errcode;
/* Shifts >= the width of the type are undefined. */
#ifdef _WIN64
@@ -686,27 +687,31 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size,
size_high, /* Upper 32 bits of size */
size_low, /* Lower 32 bits of size */
name);
+
+ errcode = GetLastError();
+ if (errcode == ERROR_ALREADY_EXISTS || errcode == ERROR_ACCESS_DENIED)
+ {
+ /*
+ * On Windows, when the segment already exists, a handle for the
+ * existing segment is returned. We must close it before
+ * returning. However, if the existing segment is created by a
+ * service, then it returns ERROR_ACCESS_DENIED. We don't do
+ * _dosmaperr here, so errno won't be modified.
+ */
+ if (hmap)
+ CloseHandle(hmap);
+ return false;
+ }
+
if (!hmap)
{
- _dosmaperr(GetLastError());
+ _dosmaperr(errcode);
ereport(elevel,
(errcode_for_dynamic_shared_memory(),
errmsg("could not create shared memory segment \"%s\": %m",
name)));
return false;
}
- _dosmaperr(GetLastError());
- if (errno == EEXIST)
- {
- /*
- * On Windows, when the segment already exists, a handle for the
- * existing segment is returned. We must close it before
- * returning. We don't do _dosmaperr here, so errno won't be
- * modified.
- */
- CloseHandle(hmap);
- return false;
- }
}
else
{
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /