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)