Go to the documentation of this file.
   42     assert(!chunkSize || 
static_cast<off_t
>(chunkSize) > 0);
 
   62     theFD(-1), theName(GenerateName(id)), theMem(nullptr),
 
   63     theSize(0), theReserved(0), doUnlink(false)
 
   73             debugs(54, 5, 
"close " << theName << 
": " << 
xstrerr(xerrno));
 
   99     if (!createFresh(xerrno) && xerrno == EEXIST) {
 
  105         debugs(54, 5, 
"shm_open " << theName << 
": " << 
xstrerr(xerrno));
 
  106         fatalf(
"Ipc::Mem::Segment::create failed to shm_open(%s): %s\n",
 
  107                theName.termedBuf(), 
xstrerr(xerrno));
 
  110     if (ftruncate(theFD, aSize)) {
 
  113         debugs(54, 5, 
"ftruncate " << theName << 
": " << 
xstrerr(xerrno));
 
  114         fatalf(
"Ipc::Mem::Segment::create failed to ftruncate(%s): %s\n",
 
  115                theName.termedBuf(), 
xstrerr(xerrno));
 
  119     theSize = statSize(
"Ipc::Mem::Segment::create");
 
  127     debugs(54, 3, 
"created " << theName << 
" segment: " << theSize);
 
  136     theFD = 
shm_open(theName.termedBuf(), O_RDWR, 0);
 
  139         debugs(54, 5, 
"shm_open " << theName << 
": " << 
xstrerr(xerrno));
 
  140         fatalf(
"Ipc::Mem::Segment::open failed to shm_open(%s): %s\n",
 
  141                theName.termedBuf(), 
xstrerr(xerrno));
 
  144     theSize = statSize(
"Ipc::Mem::Segment::open");
 
  145     doUnlink = unlinkWhenDone;
 
  147     debugs(54, 3, 
"opened " << theName << 
" segment: " << theSize);
 
  155 Ipc::Mem::Segment::createFresh(
int &xerrno)
 
  157     theFD = 
shm_open(theName.termedBuf(),
 
  158                      O_EXCL | O_CREAT | O_RDWR,
 
  166 Ipc::Mem::Segment::attach()
 
  173     assert(theSize == 
static_cast<off_t
>(
static_cast<size_t>(theSize)));
 
  176         mmap(
nullptr, theSize, PROT_READ | PROT_WRITE, MAP_SHARED, theFD, 0);
 
  177     if (p == MAP_FAILED) {
 
  179         debugs(54, 5, 
"mmap " << theName << 
": " << 
xstrerr(xerrno));
 
  180         fatalf(
"Ipc::Mem::Segment::attach failed to mmap(%s): %s\n",
 
  181                theName.termedBuf(), 
xstrerr(xerrno));
 
  190 Ipc::Mem::Segment::detach()
 
  195     if (munmap(theMem, theSize)) {
 
  197         debugs(54, 5, 
"munmap " << theName << 
": " << 
xstrerr(xerrno));
 
  198         fatalf(
"Ipc::Mem::Segment::detach failed to munmap(%s): %s\n",
 
  199                theName.termedBuf(), 
xstrerr(xerrno));
 
  207 Ipc::Mem::Segment::lock()
 
  210         debugs(54, 5, 
"mlock(2)-ing disabled");
 
  214 #if defined(_POSIX_MEMLOCK_RANGE) 
  215     debugs(54, 7, 
"mlock(" << theName << 
',' << theSize << 
") starts");
 
  216     if (mlock(theMem, theSize) != 0) {
 
  217         const int savedError = errno;
 
  218         fatalf(
"shared_memory_locking on but failed to mlock(%s, %" PRId64 "): %s\n",
 
  219                theName.termedBuf(),
static_cast<int64_t
>(theSize), 
xstrerr(savedError));
 
  222     debugs(54, 7, 
"mlock(" << theName << 
',' << theSize << 
") OK");
 
  224     debugs(54, 5, 
"insufficient mlock(2) support");
 
  226         static bool warnedOnce = 
false;
 
  229                    "honoring `shared_memory_locking on`. " <<
 
  230                    "If you lack RAM, kernel will kill Squid later.");
 
  238 Ipc::Mem::Segment::unlink()
 
  242         debugs(54, 5, 
"shm_unlink(" << theName << 
"): " << 
xstrerr(xerrno));
 
  244         debugs(54, 3, 
"unlinked " << theName << 
" segment");
 
  249 Ipc::Mem::Segment::statSize(
const char *context)
 const 
  254     memset(&s, 0, 
sizeof(s));
 
  256     if (fstat(theFD, &s) != 0) {
 
  258         debugs(54, 5, context << 
" fstat " << theName << 
": " << 
xstrerr(xerrno));
 
  259         fatalf(
"Ipc::Mem::Segment::statSize: %s failed to fstat(%s): %s\n",
 
  260                context, theName.termedBuf(), 
xstrerr(xerrno));
 
  269 Ipc::Mem::Segment::GenerateName(
const char *
id)
 
  271     assert(BasePath && *BasePath);
 
  276         if (name[name.
size()-1] != 
'/')
 
  284     for (
const char *slash = strchr(
id, 
'/'); slash; slash = strchr(
id, 
'/')) {
 
  286             name.
append(
id, slash - 
id);
 
  305     theName(id), theMem(
NULL), theSize(0), theReserved(0), doUnlink(false)
 
  312         delete [] 
static_cast<char *
>(theMem);
 
  315         debugs(54, 3, 
"unlinked " << theName << 
" fake segment");
 
  330     checkSupport(
"Fake segment creation");
 
  332     const bool inserted = 
Segments.insert(std::make_pair(theName, 
this)).second;
 
  334         fatalf(
"Duplicate fake segment creation: %s", theName.termedBuf());
 
  336     theMem = 
new char[aSize];
 
  340     debugs(54, 3, 
"created " << theName << 
" fake segment: " << theSize);
 
  347     checkSupport(
"Fake segment open");
 
  349     const SegmentMap::const_iterator i = 
Segments.find(theName);
 
  351         fatalf(
"Fake segment not found: %s", theName.termedBuf());
 
  353     const Segment &segment = *i->second;
 
  357     debugs(54, 3, 
"opened " << theName << 
" fake segment: " << theSize);
 
  365                ": True shared memory segments are not supported. " 
  366                "Cannot fake shared segments in SMP config.");
 
  367         fatalf(
"Ipc::Mem::Segment: Cannot fake shared segments in SMP config (%s)\n",
 
  
const char * xstrerr(int error)
bool shm_portable_segment_name_is_path()
Determines whether segment names are interpreted as full file paths.
Segment(const char *const id)
Create a shared memory segment.
int shm_unlink(const char *)
void * theMem
pointer to mmapped shared memory segment
void * reserve(size_t chunkSize)
reserve and return the next chunk
static const char * BasePath
common path of all segment names in path-based environments
void append(char const *buf, int len)
off_t theSize
shared memory segment size
SBuf NamePrefix(const char *head, const char *tail=nullptr)
void fatalf(const char *fmt,...)
void useConfig() override
POSIX shared memory segment.
void checkSupport(const char *const context)
SBuf & append(const SBuf &S)
static SBuf Name(const SBuf &prefix, const char *suffix)
concatenates parts of a name to form a complete name (or its prefix)
static bool Enabled()
Whether shared memory support is available.
off_t theReserved
the total number of reserve()d bytes
YesNoNone shmLocking
shared_memory_locking
void open(const bool unlinkWhenDone)
void create(const off_t aSize)
Create a new shared memory segment. Unlinks the segment on destruction.
std::map< String, Ipc::Mem::Segment * > SegmentMap
int xclose(int fd)
POSIX close(2) equivalent.
static SegmentMap Segments
#define debugs(SECTION, LEVEL, CONTENT)
int shm_open(const char *, int, mode_t)