• Tom Lane's avatar
    Cope with EINVAL and EIDRM shmat() failures in PGSharedMemoryAttach. · 610747d8
    Tom Lane authored
    There's a very old race condition in our code to see whether a pre-existing
    shared memory segment is still in use by a conflicting postmaster: it's
    possible for the other postmaster to remove the segment in between our
    shmctl() and shmat() calls.  It's a narrow window, and there's no risk
    unless both postmasters are using the same port number, but that's possible
    during parallelized "make check" tests.  (Note that while the TAP tests
    take some pains to choose a randomized port number, pg_regress doesn't.)
    If it does happen, we treated that as an unexpected case and errored out.
    
    To fix, allow EINVAL to be treated as segment-not-present, and the same
    for EIDRM on Linux.  AFAICS, the considerations here are basically
    identical to the checks for acceptable shmctl() failures, so I documented
    and coded it that way.
    
    While at it, adjust PGSharedMemoryAttach's API to remove its undocumented
    dependency on UsedShmemSegAddr in favor of passing the attach address
    explicitly.  This makes it easier to be sure we're using a null shmaddr
    when probing for segment conflicts (thus avoiding questions about what
    EINVAL means).  I don't think there was a bug there, but it required
    fragile assumptions about the state of UsedShmemSegAddr during
    PGSharedMemoryIsInUse.
    
    Commit c0985099 may have made this failure more probable by applying
    the conflicting-segment tests more often.  Hence, back-patch to all
    supported branches, as that was.
    
    Discussion: https://postgr.es/m/22224.1557340366@sss.pgh.pa.us
    610747d8
sysv_shmem.c 28.9 KB