mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03: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_high;
|
||||||
DWORD size_low;
|
DWORD size_low;
|
||||||
|
DWORD errcode;
|
||||||
|
|
||||||
/* Shifts >= the width of the type are undefined. */
|
/* Shifts >= the width of the type are undefined. */
|
||||||
#ifdef _WIN64
|
#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_high, /* Upper 32 bits of size */
|
||||||
size_low, /* Lower 32 bits of size */
|
size_low, /* Lower 32 bits of size */
|
||||||
name);
|
name);
|
||||||
if (!hmap)
|
|
||||||
{
|
errcode = GetLastError();
|
||||||
_dosmaperr(GetLastError());
|
if (errcode == ERROR_ALREADY_EXISTS || errcode == ERROR_ACCESS_DENIED)
|
||||||
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
|
* On Windows, when the segment already exists, a handle for the
|
||||||
* existing segment is returned. We must close it before
|
* existing segment is returned. We must close it before
|
||||||
* returning. We don't do _dosmaperr here, so errno won't be
|
* returning. However, if the existing segment is created by a
|
||||||
* modified.
|
* service, then it returns ERROR_ACCESS_DENIED. We don't do
|
||||||
|
* _dosmaperr here, so errno won't be modified.
|
||||||
*/
|
*/
|
||||||
|
if (hmap)
|
||||||
CloseHandle(hmap);
|
CloseHandle(hmap);
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user