PostgreSQL Source Code  git master
pg_shmem.h File Reference
#include "storage/dsm_impl.h"
Include dependency graph for pg_shmem.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PGShmemHeader
 

Macros

#define PGShmemMagic   679834894
 
#define DEFAULT_SHARED_MEMORY_TYPE   SHMEM_TYPE_MMAP
 

Typedefs

typedef struct PGShmemHeader PGShmemHeader
 

Enumerations

enum  HugePagesType { HUGE_PAGES_OFF, HUGE_PAGES_ON, HUGE_PAGES_TRY }
 
enum  PGShmemType { SHMEM_TYPE_WINDOWS, SHMEM_TYPE_SYSV, SHMEM_TYPE_MMAP }
 

Functions

PGShmemHeaderPGSharedMemoryCreate (Size size, PGShmemHeader **shim)
 
bool PGSharedMemoryIsInUse (unsigned long id1, unsigned long id2)
 
void PGSharedMemoryDetach (void)
 

Variables

int shared_memory_type
 
int huge_pages
 
unsigned long UsedShmemSegID
 
void * UsedShmemSegAddr
 

Macro Definition Documentation

◆ DEFAULT_SHARED_MEMORY_TYPE

#define DEFAULT_SHARED_MEMORY_TYPE   SHMEM_TYPE_MMAP

Definition at line 73 of file pg_shmem.h.

◆ PGShmemMagic

#define PGShmemMagic   679834894

Definition at line 32 of file pg_shmem.h.

Referenced by PGSharedMemoryAttach(), PGSharedMemoryCreate(), and PGSharedMemoryReAttach().

Typedef Documentation

◆ PGShmemHeader

typedef struct PGShmemHeader PGShmemHeader

Enumeration Type Documentation

◆ HugePagesType

Enumerator
HUGE_PAGES_OFF 
HUGE_PAGES_ON 
HUGE_PAGES_TRY 

Definition at line 49 of file pg_shmem.h.

◆ PGShmemType

Enumerator
SHMEM_TYPE_WINDOWS 
SHMEM_TYPE_SYSV 
SHMEM_TYPE_MMAP 

Definition at line 57 of file pg_shmem.h.

Function Documentation

◆ PGSharedMemoryCreate()

PGShmemHeader* PGSharedMemoryCreate ( Size  size,
PGShmemHeader **  shim 
)

Definition at line 623 of file sysv_shmem.c.

References AnonymousShmem, AnonymousShmemDetach(), AnonymousShmemSize, Assert, CreateAnonymousSegment(), PGShmemHeader::creatorPID, DataDir, DEBUG1, DEBUG3, PGShmemHeader::device, dsm_cleanup_using_control_segment(), PGShmemHeader::dsm_control, elog, EnableLockPagesPrivilege(), ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), ERROR, FATAL, free, PGShmemHeader::freeoffset, GetSharedMemName(), huge_pages, HUGE_PAGES_ON, HUGE_PAGES_TRY, i, PGShmemHeader::inode, InternalIpcMemoryCreate(), IPC_RMID, IsUnderPostmaster, LOG, PGShmemHeader::magic, MAXALIGN, on_shmem_exit(), PGSharedMemoryAttach(), PGSharedMemoryDetach(), PGSharedMemoryNoReAttach(), PGSharedMemoryReAttach(), PGShmemMagic, pgwin32_SharedMemoryDelete(), PointerGetDatum, PROTECTIVE_REGION_SIZE, shared_memory_type, SHMEM_TYPE_MMAP, ShmemProtectiveRegion, SHMSTATE_ANALYSIS_FAILURE, SHMSTATE_ATTACHED, SHMSTATE_ENOENT, SHMSTATE_FOREIGN, SHMSTATE_UNATTACHED, stat, PGShmemHeader::totalsize, TRUE, UsedShmemSegAddr, UsedShmemSegID, and UsedShmemSegSize.

Referenced by CreateSharedMemoryAndSemaphores().

625 {
626  IpcMemoryKey NextShmemSegID;
627  void *memAddress;
628  PGShmemHeader *hdr;
629  struct stat statbuf;
630  Size sysvsize;
631 
632  /*
633  * We use the data directory's ID info (inode and device numbers) to
634  * positively identify shmem segments associated with this data dir, and
635  * also as seeds for searching for a free shmem key.
636  */
637  if (stat(DataDir, &statbuf) < 0)
638  ereport(FATAL,
640  errmsg("could not stat data directory \"%s\": %m",
641  DataDir)));
642 
643  /* Complain if hugepages demanded but we can't possibly support them */
644 #if !defined(MAP_HUGETLB)
645  if (huge_pages == HUGE_PAGES_ON)
646  ereport(ERROR,
647  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
648  errmsg("huge pages not supported on this platform")));
649 #endif
650 
651  /* Room for a header? */
652  Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
653 
655  {
657  AnonymousShmemSize = size;
658 
659  /* Register on-exit routine to unmap the anonymous segment */
661 
662  /* Now we need only allocate a minimal-sized SysV shmem block. */
663  sysvsize = sizeof(PGShmemHeader);
664  }
665  else
666  sysvsize = size;
667 
668  /*
669  * Loop till we find a free IPC key. Trust CreateDataDirLockFile() to
670  * ensure no more than one postmaster per data directory can enter this
671  * loop simultaneously. (CreateDataDirLockFile() does not entirely ensure
672  * that, but prefer fixing it over coping here.)
673  */
674  NextShmemSegID = statbuf.st_ino;
675 
676  for (;;)
677  {
678  IpcMemoryId shmid;
679  PGShmemHeader *oldhdr;
681 
682  /* Try to create new segment */
683  memAddress = InternalIpcMemoryCreate(NextShmemSegID, sysvsize);
684  if (memAddress)
685  break; /* successful create and attach */
686 
687  /* Check shared memory and possibly remove and recreate */
688 
689  /*
690  * shmget() failure is typically EACCES, hence SHMSTATE_FOREIGN.
691  * ENOENT, a narrow possibility, implies SHMSTATE_ENOENT, but one can
692  * safely treat SHMSTATE_ENOENT like SHMSTATE_FOREIGN.
693  */
694  shmid = shmget(NextShmemSegID, sizeof(PGShmemHeader), 0);
695  if (shmid < 0)
696  {
697  oldhdr = NULL;
698  state = SHMSTATE_FOREIGN;
699  }
700  else
701  state = PGSharedMemoryAttach(shmid, NULL, &oldhdr);
702 
703  switch (state)
704  {
706  case SHMSTATE_ATTACHED:
707  ereport(FATAL,
708  (errcode(ERRCODE_LOCK_FILE_EXISTS),
709  errmsg("pre-existing shared memory block (key %lu, ID %lu) is still in use",
710  (unsigned long) NextShmemSegID,
711  (unsigned long) shmid),
712  errhint("Terminate any old server processes associated with data directory \"%s\".",
713  DataDir)));
714  break;
715  case SHMSTATE_ENOENT:
716 
717  /*
718  * To our surprise, some other process deleted since our last
719  * InternalIpcMemoryCreate(). Moments earlier, we would have
720  * seen SHMSTATE_FOREIGN. Try that same ID again.
721  */
722  elog(LOG,
723  "shared memory block (key %lu, ID %lu) deleted during startup",
724  (unsigned long) NextShmemSegID,
725  (unsigned long) shmid);
726  break;
727  case SHMSTATE_FOREIGN:
728  NextShmemSegID++;
729  break;
730  case SHMSTATE_UNATTACHED:
731 
732  /*
733  * The segment pertains to DataDir, and every process that had
734  * used it has died or detached. Zap it, if possible, and any
735  * associated dynamic shared memory segments, as well. This
736  * shouldn't fail, but if it does, assume the segment belongs
737  * to someone else after all, and try the next candidate.
738  * Otherwise, try again to create the segment. That may fail
739  * if some other process creates the same shmem key before we
740  * do, in which case we'll try the next key.
741  */
742  if (oldhdr->dsm_control != 0)
744  if (shmctl(shmid, IPC_RMID, NULL) < 0)
745  NextShmemSegID++;
746  break;
747  }
748 
749  if (oldhdr && shmdt(oldhdr) < 0)
750  elog(LOG, "shmdt(%p) failed: %m", oldhdr);
751  }
752 
753  /* Initialize new segment. */
754  hdr = (PGShmemHeader *) memAddress;
755  hdr->creatorPID = getpid();
756  hdr->magic = PGShmemMagic;
757  hdr->dsm_control = 0;
758 
759  /* Fill in the data directory ID info, too */
760  hdr->device = statbuf.st_dev;
761  hdr->inode = statbuf.st_ino;
762 
763  /*
764  * Initialize space allocation status for segment.
765  */
766  hdr->totalsize = size;
767  hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
768  *shim = hdr;
769 
770  /* Save info for possible future use */
771  UsedShmemSegAddr = memAddress;
772  UsedShmemSegID = (unsigned long) NextShmemSegID;
773 
774  /*
775  * If AnonymousShmem is NULL here, then we're not using anonymous shared
776  * memory, and should return a pointer to the System V shared memory
777  * block. Otherwise, the System V shared memory block is only a shim, and
778  * we must return a pointer to the real block.
779  */
780  if (AnonymousShmem == NULL)
781  return hdr;
782  memcpy(AnonymousShmem, hdr, sizeof(PGShmemHeader));
783  return (PGShmemHeader *) AnonymousShmem;
784 }
IpcMemoryState
Definition: sysv_shmem.c:86
pid_t creatorPID
Definition: pg_shmem.h:33
int errhint(const char *fmt,...)
Definition: elog.c:974
void dsm_cleanup_using_control_segment(dsm_handle old_control_handle)
Definition: dsm.c:206
dsm_handle dsm_control
Definition: pg_shmem.h:36
struct PGShmemHeader PGShmemHeader
int shared_memory_type
Definition: ipci.c:50
static Size AnonymousShmemSize
Definition: sysv_shmem.c:99
int errcode(int sqlerrcode)
Definition: elog.c:570
#define LOG
Definition: elog.h:26
static void * InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
Definition: sysv_shmem.c:123
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
key_t IpcMemoryKey
Definition: sysv_shmem.c:72
static IpcMemoryState PGSharedMemoryAttach(IpcMemoryId shmId, void *attachAt, PGShmemHeader **addr)
Definition: sysv_shmem.c:339
int errcode_for_file_access(void)
Definition: elog.c:593
void * UsedShmemSegAddr
Definition: sysv_shmem.c:97
static void AnonymousShmemDetach(int status, Datum arg)
Definition: sysv_shmem.c:598
#define ereport(elevel, rest)
Definition: elog.h:141
int32 magic
Definition: pg_shmem.h:31
static void * CreateAnonymousSegment(Size *size)
Definition: sysv_shmem.c:530
#define stat(a, b)
Definition: win32_port.h:264
Size totalsize
Definition: pg_shmem.h:34
uintptr_t Datum
Definition: postgres.h:367
unsigned long UsedShmemSegID
Definition: sysv_shmem.c:96
#define IPC_RMID
Definition: win32_port.h:81
static void * AnonymousShmem
Definition: sysv_shmem.c:100
ino_t inode
Definition: pg_shmem.h:40
dev_t device
Definition: pg_shmem.h:39
#define Assert(condition)
Definition: c.h:732
Definition: regguts.h:298
#define PGShmemMagic
Definition: pg_shmem.h:32
Size freeoffset
Definition: pg_shmem.h:35
size_t Size
Definition: c.h:466
int IpcMemoryId
Definition: sysv_shmem.c:73
#define MAXALIGN(LEN)
Definition: c.h:685
int huge_pages
Definition: guc.c:548
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
char * DataDir
Definition: globals.c:62

◆ PGSharedMemoryDetach()

void PGSharedMemoryDetach ( void  )

Definition at line 881 of file sysv_shmem.c.

References AnonymousShmem, AnonymousShmemSize, elog, LOG, ShmemProtectiveRegion, UsedShmemSegAddr, and UsedShmemSegID.

Referenced by pgarch_start(), PGSharedMemoryCreate(), PGSharedMemoryNoReAttach(), pgstat_start(), pgwin32_SharedMemoryDelete(), StartBackgroundWorker(), and SysLogger_Start().

882 {
883  if (UsedShmemSegAddr != NULL)
884  {
885  if ((shmdt(UsedShmemSegAddr) < 0)
886 #if defined(EXEC_BACKEND) && defined(__CYGWIN__)
887  /* Work-around for cygipc exec bug */
888  && shmdt(NULL) < 0
889 #endif
890  )
891  elog(LOG, "shmdt(%p) failed: %m", UsedShmemSegAddr);
892  UsedShmemSegAddr = NULL;
893  }
894 
895  if (AnonymousShmem != NULL)
896  {
897  if (munmap(AnonymousShmem, AnonymousShmemSize) < 0)
898  elog(LOG, "munmap(%p, %zu) failed: %m",
900  AnonymousShmem = NULL;
901  }
902 }
static Size AnonymousShmemSize
Definition: sysv_shmem.c:99
#define LOG
Definition: elog.h:26
void * UsedShmemSegAddr
Definition: sysv_shmem.c:97
static void * AnonymousShmem
Definition: sysv_shmem.c:100
#define elog(elevel,...)
Definition: elog.h:226

◆ PGSharedMemoryIsInUse()

bool PGSharedMemoryIsInUse ( unsigned long  id1,
unsigned long  id2 
)

Definition at line 309 of file sysv_shmem.c.

References elog, FALSE, free, GetSharedMemName(), LOG, PGSharedMemoryAttach(), SHMSTATE_ANALYSIS_FAILURE, SHMSTATE_ATTACHED, SHMSTATE_ENOENT, SHMSTATE_FOREIGN, and SHMSTATE_UNATTACHED.

Referenced by CreateLockFile().

310 {
311  PGShmemHeader *memAddress;
313 
314  state = PGSharedMemoryAttach((IpcMemoryId) id2, NULL, &memAddress);
315  if (memAddress && shmdt(memAddress) < 0)
316  elog(LOG, "shmdt(%p) failed: %m", memAddress);
317  switch (state)
318  {
319  case SHMSTATE_ENOENT:
320  case SHMSTATE_FOREIGN:
321  case SHMSTATE_UNATTACHED:
322  return false;
324  case SHMSTATE_ATTACHED:
325  return true;
326  }
327  return true;
328 }
IpcMemoryState
Definition: sysv_shmem.c:86
#define LOG
Definition: elog.h:26
static IpcMemoryState PGSharedMemoryAttach(IpcMemoryId shmId, void *attachAt, PGShmemHeader **addr)
Definition: sysv_shmem.c:339
Definition: regguts.h:298
int IpcMemoryId
Definition: sysv_shmem.c:73
#define elog(elevel,...)
Definition: elog.h:226

Variable Documentation

◆ huge_pages

int huge_pages

Definition at line 548 of file guc.c.

Referenced by CreateAnonymousSegment(), and PGSharedMemoryCreate().

◆ shared_memory_type

int shared_memory_type

Definition at line 50 of file ipci.c.

Referenced by PGSharedMemoryCreate().

◆ UsedShmemSegAddr

◆ UsedShmemSegID