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
 
int huge_page_size
 
unsigned long UsedShmemSegID
 
void * UsedShmemSegAddr
 

Macro Definition Documentation

◆ DEFAULT_SHARED_MEMORY_TYPE

#define DEFAULT_SHARED_MEMORY_TYPE   SHMEM_TYPE_MMAP

Definition at line 74 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 50 of file pg_shmem.h.

◆ PGShmemType

Enumerator
SHMEM_TYPE_WINDOWS 
SHMEM_TYPE_SYSV 
SHMEM_TYPE_MMAP 

Definition at line 58 of file pg_shmem.h.

Function Documentation

◆ PGSharedMemoryCreate()

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

Definition at line 651 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, UsedShmemSegAddr, UsedShmemSegID, and UsedShmemSegSize.

Referenced by CreateSharedMemoryAndSemaphores().

653 {
654  IpcMemoryKey NextShmemSegID;
655  void *memAddress;
656  PGShmemHeader *hdr;
657  struct stat statbuf;
658  Size sysvsize;
659 
660  /*
661  * We use the data directory's ID info (inode and device numbers) to
662  * positively identify shmem segments associated with this data dir, and
663  * also as seeds for searching for a free shmem key.
664  */
665  if (stat(DataDir, &statbuf) < 0)
666  ereport(FATAL,
668  errmsg("could not stat data directory \"%s\": %m",
669  DataDir)));
670 
671  /* Complain if hugepages demanded but we can't possibly support them */
672 #if !defined(MAP_HUGETLB)
673  if (huge_pages == HUGE_PAGES_ON)
674  ereport(ERROR,
675  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
676  errmsg("huge pages not supported on this platform")));
677 #endif
678 
679  /* Room for a header? */
680  Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
681 
683  {
685  AnonymousShmemSize = size;
686 
687  /* Register on-exit routine to unmap the anonymous segment */
689 
690  /* Now we need only allocate a minimal-sized SysV shmem block. */
691  sysvsize = sizeof(PGShmemHeader);
692  }
693  else
694  sysvsize = size;
695 
696  /*
697  * Loop till we find a free IPC key. Trust CreateDataDirLockFile() to
698  * ensure no more than one postmaster per data directory can enter this
699  * loop simultaneously. (CreateDataDirLockFile() does not entirely ensure
700  * that, but prefer fixing it over coping here.)
701  */
702  NextShmemSegID = statbuf.st_ino;
703 
704  for (;;)
705  {
706  IpcMemoryId shmid;
707  PGShmemHeader *oldhdr;
709 
710  /* Try to create new segment */
711  memAddress = InternalIpcMemoryCreate(NextShmemSegID, sysvsize);
712  if (memAddress)
713  break; /* successful create and attach */
714 
715  /* Check shared memory and possibly remove and recreate */
716 
717  /*
718  * shmget() failure is typically EACCES, hence SHMSTATE_FOREIGN.
719  * ENOENT, a narrow possibility, implies SHMSTATE_ENOENT, but one can
720  * safely treat SHMSTATE_ENOENT like SHMSTATE_FOREIGN.
721  */
722  shmid = shmget(NextShmemSegID, sizeof(PGShmemHeader), 0);
723  if (shmid < 0)
724  {
725  oldhdr = NULL;
726  state = SHMSTATE_FOREIGN;
727  }
728  else
729  state = PGSharedMemoryAttach(shmid, NULL, &oldhdr);
730 
731  switch (state)
732  {
734  case SHMSTATE_ATTACHED:
735  ereport(FATAL,
736  (errcode(ERRCODE_LOCK_FILE_EXISTS),
737  errmsg("pre-existing shared memory block (key %lu, ID %lu) is still in use",
738  (unsigned long) NextShmemSegID,
739  (unsigned long) shmid),
740  errhint("Terminate any old server processes associated with data directory \"%s\".",
741  DataDir)));
742  break;
743  case SHMSTATE_ENOENT:
744 
745  /*
746  * To our surprise, some other process deleted since our last
747  * InternalIpcMemoryCreate(). Moments earlier, we would have
748  * seen SHMSTATE_FOREIGN. Try that same ID again.
749  */
750  elog(LOG,
751  "shared memory block (key %lu, ID %lu) deleted during startup",
752  (unsigned long) NextShmemSegID,
753  (unsigned long) shmid);
754  break;
755  case SHMSTATE_FOREIGN:
756  NextShmemSegID++;
757  break;
758  case SHMSTATE_UNATTACHED:
759 
760  /*
761  * The segment pertains to DataDir, and every process that had
762  * used it has died or detached. Zap it, if possible, and any
763  * associated dynamic shared memory segments, as well. This
764  * shouldn't fail, but if it does, assume the segment belongs
765  * to someone else after all, and try the next candidate.
766  * Otherwise, try again to create the segment. That may fail
767  * if some other process creates the same shmem key before we
768  * do, in which case we'll try the next key.
769  */
770  if (oldhdr->dsm_control != 0)
772  if (shmctl(shmid, IPC_RMID, NULL) < 0)
773  NextShmemSegID++;
774  break;
775  }
776 
777  if (oldhdr && shmdt(oldhdr) < 0)
778  elog(LOG, "shmdt(%p) failed: %m", oldhdr);
779  }
780 
781  /* Initialize new segment. */
782  hdr = (PGShmemHeader *) memAddress;
783  hdr->creatorPID = getpid();
784  hdr->magic = PGShmemMagic;
785  hdr->dsm_control = 0;
786 
787  /* Fill in the data directory ID info, too */
788  hdr->device = statbuf.st_dev;
789  hdr->inode = statbuf.st_ino;
790 
791  /*
792  * Initialize space allocation status for segment.
793  */
794  hdr->totalsize = size;
795  hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
796  *shim = hdr;
797 
798  /* Save info for possible future use */
799  UsedShmemSegAddr = memAddress;
800  UsedShmemSegID = (unsigned long) NextShmemSegID;
801 
802  /*
803  * If AnonymousShmem is NULL here, then we're not using anonymous shared
804  * memory, and should return a pointer to the System V shared memory
805  * block. Otherwise, the System V shared memory block is only a shim, and
806  * we must return a pointer to the real block.
807  */
808  if (AnonymousShmem == NULL)
809  return hdr;
810  memcpy(AnonymousShmem, hdr, sizeof(PGShmemHeader));
811  return (PGShmemHeader *) AnonymousShmem;
812 }
IpcMemoryState
Definition: sysv_shmem.c:87
pid_t creatorPID
Definition: pg_shmem.h:33
int errhint(const char *fmt,...)
Definition: elog.c:1071
void dsm_cleanup_using_control_segment(dsm_handle old_control_handle)
Definition: dsm.c:210
dsm_handle dsm_control
Definition: pg_shmem.h:36
struct PGShmemHeader PGShmemHeader
int shared_memory_type
Definition: ipci.c:51
static Size AnonymousShmemSize
Definition: sysv_shmem.c:100
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
static void * InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
Definition: sysv_shmem.c:124
#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:73
static IpcMemoryState PGSharedMemoryAttach(IpcMemoryId shmId, void *attachAt, PGShmemHeader **addr)
Definition: sysv_shmem.c:340
int errcode_for_file_access(void)
Definition: elog.c:633
void * UsedShmemSegAddr
Definition: sysv_shmem.c:98
static void AnonymousShmemDetach(int status, Datum arg)
Definition: sysv_shmem.c:626
int32 magic
Definition: pg_shmem.h:31
static void * CreateAnonymousSegment(Size *size)
Definition: sysv_shmem.c:558
#define stat(a, b)
Definition: win32_port.h:255
Size totalsize
Definition: pg_shmem.h:34
uintptr_t Datum
Definition: postgres.h:367
unsigned long UsedShmemSegID
Definition: sysv_shmem.c:97
#define IPC_RMID
Definition: win32_port.h:80
static void * AnonymousShmem
Definition: sysv_shmem.c:101
ino_t inode
Definition: pg_shmem.h:40
#define ereport(elevel,...)
Definition: elog.h:144
dev_t device
Definition: pg_shmem.h:39
#define Assert(condition)
Definition: c.h:745
Definition: regguts.h:298
#define PGShmemMagic
Definition: pg_shmem.h:32
Size freeoffset
Definition: pg_shmem.h:35
size_t Size
Definition: c.h:473
int IpcMemoryId
Definition: sysv_shmem.c:74
#define MAXALIGN(LEN)
Definition: c.h:698
int huge_pages
Definition: guc.c:582
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
char * DataDir
Definition: globals.c:62

◆ PGSharedMemoryDetach()

void PGSharedMemoryDetach ( void  )

Definition at line 909 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().

910 {
911  if (UsedShmemSegAddr != NULL)
912  {
913  if ((shmdt(UsedShmemSegAddr) < 0)
914 #if defined(EXEC_BACKEND) && defined(__CYGWIN__)
915  /* Work-around for cygipc exec bug */
916  && shmdt(NULL) < 0
917 #endif
918  )
919  elog(LOG, "shmdt(%p) failed: %m", UsedShmemSegAddr);
920  UsedShmemSegAddr = NULL;
921  }
922 
923  if (AnonymousShmem != NULL)
924  {
925  if (munmap(AnonymousShmem, AnonymousShmemSize) < 0)
926  elog(LOG, "munmap(%p, %zu) failed: %m",
928  AnonymousShmem = NULL;
929  }
930 }
static Size AnonymousShmemSize
Definition: sysv_shmem.c:100
#define LOG
Definition: elog.h:26
void * UsedShmemSegAddr
Definition: sysv_shmem.c:98
static void * AnonymousShmem
Definition: sysv_shmem.c:101
#define elog(elevel,...)
Definition: elog.h:214

◆ PGSharedMemoryIsInUse()

bool PGSharedMemoryIsInUse ( unsigned long  id1,
unsigned long  id2 
)

Definition at line 310 of file sysv_shmem.c.

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

Referenced by CreateLockFile().

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

Variable Documentation

◆ huge_page_size

int huge_page_size

Definition at line 583 of file guc.c.

Referenced by PGSharedMemoryAttach().

◆ huge_pages

int huge_pages

Definition at line 582 of file guc.c.

Referenced by CreateAnonymousSegment(), and PGSharedMemoryCreate().

◆ shared_memory_type

int shared_memory_type

Definition at line 51 of file ipci.c.

Referenced by PGSharedMemoryCreate().

◆ UsedShmemSegAddr

◆ UsedShmemSegID