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 661 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(), errmsg_internal(), 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::st_dev, stat::st_ino, stat, PGShmemHeader::totalsize, UsedShmemSegAddr, UsedShmemSegID, and UsedShmemSegSize.

Referenced by CreateSharedMemoryAndSemaphores().

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

◆ PGSharedMemoryDetach()

void PGSharedMemoryDetach ( void  )

Definition at line 919 of file sysv_shmem.c.

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

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

920 {
921  if (UsedShmemSegAddr != NULL)
922  {
923  if ((shmdt(UsedShmemSegAddr) < 0)
924 #if defined(EXEC_BACKEND) && defined(__CYGWIN__)
925  /* Work-around for cygipc exec bug */
926  && shmdt(NULL) < 0
927 #endif
928  )
929  elog(LOG, "shmdt(%p) failed: %m", UsedShmemSegAddr);
930  UsedShmemSegAddr = NULL;
931  }
932 
933  if (AnonymousShmem != NULL)
934  {
935  if (munmap(AnonymousShmem, AnonymousShmemSize) < 0)
936  elog(LOG, "munmap(%p, %zu) failed: %m",
938  AnonymousShmem = NULL;
939  }
940 }
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:232

◆ PGSharedMemoryIsInUse()

bool PGSharedMemoryIsInUse ( unsigned long  id1,
unsigned long  id2 
)

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

321 {
322  PGShmemHeader *memAddress;
324 
325  state = PGSharedMemoryAttach((IpcMemoryId) id2, NULL, &memAddress);
326  if (memAddress && shmdt(memAddress) < 0)
327  elog(LOG, "shmdt(%p) failed: %m", memAddress);
328  switch (state)
329  {
330  case SHMSTATE_ENOENT:
331  case SHMSTATE_FOREIGN:
332  case SHMSTATE_UNATTACHED:
333  return false;
335  case SHMSTATE_ATTACHED:
336  return true;
337  }
338  return true;
339 }
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:350
Definition: regguts.h:317
int IpcMemoryId
Definition: sysv_shmem.c:74
#define elog(elevel,...)
Definition: elog.h:232

Variable Documentation

◆ huge_page_size

int huge_page_size

Definition at line 641 of file guc.c.

Referenced by PGSharedMemoryAttach().

◆ huge_pages

int huge_pages

Definition at line 640 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