mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Retry DSM control segment creation if Windows indicates access denied.
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>
This commit is contained in:
parent
45310221a9
commit
419113dfdc
@ -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,25 +687,29 @@ 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);
|
||||
if (!hmap)
|
||||
{
|
||||
_dosmaperr(GetLastError());
|
||||
ereport(elevel,
|
||||
(errcode_for_dynamic_shared_memory(),
|
||||
errmsg("could not create shared memory segment \"%s\": %m",
|
||||
name)));
|
||||
return false;
|
||||
}
|
||||
_dosmaperr(GetLastError());
|
||||
if (errno == EEXIST)
|
||||
|
||||
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. We don't do _dosmaperr here, so errno won't be
|
||||
* modified.
|
||||
* 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.
|
||||
*/
|
||||
CloseHandle(hmap);
|
||||
if (hmap)
|
||||
CloseHandle(hmap);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hmap)
|
||||
{
|
||||
_dosmaperr(errcode);
|
||||
ereport(elevel,
|
||||
(errcode_for_dynamic_shared_memory(),
|
||||
errmsg("could not create shared memory segment \"%s\": %m",
|
||||
name)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user