root/shareddata.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- dmtcp_SharedData_EventHook
- initializeHeader
- initialized
- initialize
- suspended
- preCkpt
- refill
- coordHost
- coordPort
- getTmpDir
- getTmpDir
- getInstallDir
- getCkptInterval
- updateGeneration
- getCompId
- getCoordId
- getCoordTimeStamp
- getCoordAddr
- setCoordHost
- getLocalIPAddr
- updateDlsymOffset
- getDlsymOffset
- getDlsymOffset_m32
- getRealPid
- setPidMap
- getRealIPCId
- setIPCIdMap
- getPtraceVirtualId
- setPtraceVirtualId
- createVirtualPtyName
- getRealPtyName
- getVirtPtyName
- insertPtyNameMap
- registerIncomingCons
- getMissingConMaps
- insertInodeConnIdMaps
- getCkptLeaderForFile
1 /****************************************************************************
2 * Copyright (C) 2006-2013 by Jason Ansel, Kapil Arya, and Gene Cooperman *
3 * jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu *
4 * *
5 * This file is part of DMTCP. *
6 * *
7 * DMTCP is free software: you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public License as *
9 * published by the Free Software Foundation, either version 3 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * DMTCP is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with DMTCP:dmtcp/src. If not, see *
19 * <http://www.gnu.org/licenses/>. *
20 ****************************************************************************/
21
22 #include <stdlib.h>
23 #include <fcntl.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/ipc.h>
27
28 #include "constants.h"
29 #include "protectedfds.h"
30 #include "dmtcpalloc.h"
31 #include "uniquepid.h"
32 #include "syscallwrappers.h"
33 #include "util.h"
34 #include "membarrier.h"
35 #include "coordinatorapi.h"
36 #include "shareddata.h"
37 #include "../jalib/jassert.h"
38 #include "../jalib/jconvert.h"
39
40 #define SHM_MAX_SIZE (sizeof(SharedData::Header))
41
42 using namespace dmtcp;
43 static struct SharedData::Header *sharedDataHeader = NULL;
44 static void *prevSharedDataHeaderAddr = NULL;
45 static uint32_t nextVirtualPtyId = (uint32_t)-1;
46
47 void dmtcp_SharedData_EventHook(DmtcpEvent_t event, DmtcpEventData_t *data)
48 {
49 switch (event) {
50 case DMTCP_EVENT_INIT:
51 break;
52
53 case DMTCP_EVENT_THREADS_SUSPEND:
54 SharedData::suspended();
55 break;
56
57 case DMTCP_EVENT_REGISTER_NAME_SERVICE_DATA:
58 case DMTCP_EVENT_REFILL:
59 SharedData::refill();
60 break;
61
62 default:
63 break;
64 }
65 }
66
67 void SharedData::initializeHeader(const char *tmpDir,
68 const char *installDir,
69 DmtcpUniqueProcessId *compId,
70 CoordinatorInfo *coordInfo,
71 struct in_addr *localIPAddr)
72 {
73 JASSERT(tmpDir && installDir && compId && coordInfo && localIPAddr);
74
75 off_t size = CEIL(SHM_MAX_SIZE , Util::pageSize());
76 JASSERT(lseek(PROTECTED_SHM_FD, size, SEEK_SET) == size)
77 (JASSERT_ERRNO);
78 Util::writeAll(PROTECTED_SHM_FD, "", 1);
79 memset(sharedDataHeader, 0, size);
80
81 strcpy(sharedDataHeader->versionStr, SHM_VERSION_STR);
82 #if 0
83 sharedDataHeader->coordHost[0] = '\0';
84 sharedDataHeader->coordPort = -1;
85 sharedDataHeader->ckptInterval = -1;
86 #endif
87 sharedDataHeader->dlsymOffset = 0;
88 sharedDataHeader->dlsymOffset_m32 = 0;
89 sharedDataHeader->numSysVShmIdMaps = 0;
90 sharedDataHeader->numSysVSemIdMaps = 0;
91 sharedDataHeader->numSysVMsqIdMaps = 0;
92 sharedDataHeader->numPtraceIdMaps = 0;
93 sharedDataHeader->numPtyNameMaps = 0;
94 sharedDataHeader->initialized = true;
95 sharedDataHeader->numIncomingConMaps = 0;
96 memcpy(&sharedDataHeader->compId, compId, sizeof(*compId));
97 memcpy(&sharedDataHeader->coordInfo, coordInfo, sizeof (*coordInfo));
98 memcpy(&sharedDataHeader->localIPAddr, localIPAddr, sizeof (*localIPAddr));
99 // The current implementation simply increments the last count and returns it.
100 // Although highly unlikely, this can cause a problem if the counter resets to
101 // zero. In that case we should have some more sophisticated code which checks
102 // to see if the value pointed by counter is in use or not.
103 if (nextVirtualPtyId != (uint32_t)-1) {
104 sharedDataHeader->nextVirtualPtyId = nextVirtualPtyId;
105 } else {
106 sharedDataHeader->nextVirtualPtyId = 0;
107 }
108 JASSERT(strlen(tmpDir) < sizeof(sharedDataHeader->tmpDir) - 1) (tmpDir);
109 strcpy(sharedDataHeader->tmpDir, tmpDir);
110
111 JASSERT(strlen(installDir) < sizeof(sharedDataHeader->installDir) - 1)
112 (installDir);
113 strcpy(sharedDataHeader->installDir, installDir);
114 }
115
116 bool SharedData::initialized()
117 {
118 return sharedDataHeader != NULL;
119 }
120
121 void SharedData::initialize(const char *tmpDir = NULL,
122 const char *installDir = NULL,
123 DmtcpUniqueProcessId *compId = NULL,
124 CoordinatorInfo *coordInfo = NULL,
125 struct in_addr *localIPAddr = NULL)
126 {
127 /* FIXME: If the coordinator timestamp resolution is 1 second, during
128 * subsequent restart, the coordinator timestamp may have the same value
129 * causing conflict with SharedData file. In future, a better fix would be to
130 * delete the file associated with SharedData in preCkpt phase and recreate
131 * it in postCkpt/postRestart phase.
132 */
133 bool needToInitialize = false;
134 JASSERT((coordInfo != NULL && localIPAddr != NULL) ||
135 Util::isValidFd(PROTECTED_SHM_FD));
136 if (!Util::isValidFd(PROTECTED_SHM_FD)) {
137 JASSERT(tmpDir != NULL);
138 ostringstream o;
139 o << tmpDir << "/dmtcpSharedArea."
140 << *compId << "." << std::hex << coordInfo->timeStamp;
141
142 int fd = _real_open(o.str().c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
143 if (fd == -1 && errno == EEXIST) {
144 fd = _real_open(o.str().c_str(), O_RDWR, 0600);
145 } else {
146 needToInitialize = true;
147 }
148 JASSERT(fd != -1) (JASSERT_ERRNO);
149 JASSERT(_real_dup2(fd, PROTECTED_SHM_FD) == PROTECTED_SHM_FD)
150 (JASSERT_ERRNO);
151 _real_close(fd);
152 }
153
154 size_t size = CEIL(SHM_MAX_SIZE , Util::pageSize());
155 void *addr = _real_mmap(prevSharedDataHeaderAddr, size,
156 PROT_READ | PROT_WRITE, MAP_SHARED,
157 PROTECTED_SHM_FD, 0);
158 JASSERT(addr != MAP_FAILED) (JASSERT_ERRNO)
159 .Text("Unable to find shared area.");
160
161 #if __arm__
162 WMB; // Ensure store to memory by kernel mmap call has completed
163 #endif
164
165 sharedDataHeader = (struct Header*) addr;
166 prevSharedDataHeaderAddr = addr;
167
168 if (needToInitialize) {
169 Util::lockFile(PROTECTED_SHM_FD);
170 initializeHeader(tmpDir, installDir, compId, coordInfo, localIPAddr);
171 Util::unlockFile(PROTECTED_SHM_FD);
172 } else {
173 struct stat statbuf;
174 while (1) {
175 Util::lockFile(PROTECTED_SHM_FD);
176 JASSERT(fstat(PROTECTED_SHM_FD, &statbuf) != -1) (JASSERT_ERRNO);
177 Util::unlockFile(PROTECTED_SHM_FD);
178 if (statbuf.st_size > 0) {
179 break;
180 }
181 struct timespec sleepTime = {0, 100*1000*1000};
182 nanosleep(&sleepTime, NULL);
183 }
184
185 Util::lockFile(PROTECTED_SHM_FD);
186 if (!Util::strStartsWith(sharedDataHeader->versionStr,
187 SHM_VERSION_STR)) {
188 JASSERT(false) (sharedDataHeader->versionStr) (SHM_VERSION_STR)
189 .Text("Wrong signature");
190 }
191 Util::unlockFile(PROTECTED_SHM_FD);
192 }
193 JTRACE("Shared area mapped") (sharedDataHeader);
194 }
195
196 void SharedData::suspended()
197 {
198 if (sharedDataHeader == NULL) initialize();
199 sharedDataHeader->numInodeConnIdMaps = 0;
200 }
201
202 void SharedData::preCkpt()
203 {
204 if (sharedDataHeader != NULL) {
205 nextVirtualPtyId = sharedDataHeader->nextVirtualPtyId;
206 // Need to reset these counters before next post-restart/post-ckpt routines
207 sharedDataHeader->numIncomingConMaps = 0;
208 WMB;
209 size_t size = CEIL(SHM_MAX_SIZE, Util::pageSize());
210 JASSERT(_real_munmap(sharedDataHeader, size) == 0) (JASSERT_ERRNO);
211 sharedDataHeader = NULL;
212 }
213 }
214
215 void SharedData::refill()
216 {
217 if (sharedDataHeader == NULL) initialize();
218 }
219
220 string SharedData::coordHost()
221 {
222 if (sharedDataHeader == NULL) initialize();
223 const struct sockaddr_in *sin =
224 (const struct sockaddr_in*) &sharedDataHeader->coordInfo.addr;
225 string remoteIP = inet_ntoa(sin->sin_addr);
226 return remoteIP;
227 }
228
229 uint32_t SharedData::coordPort()
230 {
231 if (sharedDataHeader == NULL) initialize();
232 const struct sockaddr_in *sin =
233 (const struct sockaddr_in*) &sharedDataHeader->coordInfo.addr;
234 return ntohs(sin->sin_port);
235 }
236
237 string SharedData::getTmpDir()
238 {
239 if (sharedDataHeader == NULL) initialize();
240 JASSERT(sharedDataHeader->tmpDir[0] != '\0');
241 return string(sharedDataHeader->tmpDir);
242 }
243
244 char *SharedData::getTmpDir(char *buf, uint32_t len)
245 {
246 if (sharedDataHeader == NULL) initialize();
247 JASSERT(sharedDataHeader->tmpDir[0] != '\0');
248 if (len <= strlen(sharedDataHeader->tmpDir)) {
249 return NULL;
250 }
251 strcpy(buf, sharedDataHeader->tmpDir);
252 return buf;
253 }
254
255 string SharedData::getInstallDir()
256 {
257 if (sharedDataHeader == NULL) initialize();
258 return sharedDataHeader->installDir;
259 }
260
261 uint32_t SharedData::getCkptInterval()
262 {
263 if (sharedDataHeader == NULL) initialize();
264 return sharedDataHeader->coordInfo.interval;
265 }
266
267 void SharedData::updateGeneration(uint32_t generation)
268 {
269 if (sharedDataHeader == NULL) initialize();
270 sharedDataHeader->compId._computation_generation = generation;
271 }
272 DmtcpUniqueProcessId SharedData::getCompId()
273 {
274 if (sharedDataHeader == NULL) initialize();
275 return sharedDataHeader->compId;
276 }
277
278 DmtcpUniqueProcessId SharedData::getCoordId()
279 {
280 if (sharedDataHeader == NULL) initialize();
281 return sharedDataHeader->coordInfo.id;
282 }
283
284 uint64_t SharedData::getCoordTimeStamp()
285 {
286 if (sharedDataHeader == NULL) initialize();
287 return sharedDataHeader->coordInfo.timeStamp;
288 }
289
290 void SharedData::getCoordAddr(struct sockaddr *addr, uint32_t *len)
291 {
292 if (sharedDataHeader == NULL) initialize();
293 JASSERT(addr != NULL);
294 *len = sharedDataHeader->coordInfo.addrLen;
295 memcpy(addr, &sharedDataHeader->coordInfo.addr, *len);
296 }
297
298 void SharedData::setCoordHost(struct in_addr *in)
299 {
300 if (sharedDataHeader == NULL) initialize();
301 JASSERT(in != NULL);
302 struct sockaddr_in *sin =
303 (struct sockaddr_in*) &sharedDataHeader->coordInfo.addr;
304 memcpy(&sin->sin_addr, in, sizeof sin->sin_addr);
305 }
306
307 void SharedData::getLocalIPAddr(struct in_addr *in)
308 {
309 if (sharedDataHeader == NULL) initialize();
310 JASSERT(in != NULL);
311 memcpy(in, &sharedDataHeader->localIPAddr, sizeof *in);
312 }
313
314 void SharedData::updateDlsymOffset(int32_t dlsymOffset,
315 int32_t dlsymOffset_m32)
316 {
317 if (sharedDataHeader == NULL) initialize();
318 JASSERT(sharedDataHeader->dlsymOffset == 0 ||
319 sharedDataHeader->dlsymOffset == dlsymOffset)
320 (dlsymOffset) (sharedDataHeader->dlsymOffset);
321
322 JASSERT(sharedDataHeader->dlsymOffset_m32 == 0 ||
323 sharedDataHeader->dlsymOffset_m32 == dlsymOffset_m32)
324 (dlsymOffset_m32) (sharedDataHeader->dlsymOffset_m32);
325 sharedDataHeader->dlsymOffset = dlsymOffset;
326 sharedDataHeader->dlsymOffset_m32 = dlsymOffset_m32;
327 }
328
329 int32_t SharedData::getDlsymOffset(void)
330 {
331 if (sharedDataHeader == NULL) initialize();
332 return sharedDataHeader->dlsymOffset;
333 }
334
335 int32_t SharedData::getDlsymOffset_m32(void)
336 {
337 if (sharedDataHeader == NULL) initialize();
338 return sharedDataHeader->dlsymOffset_m32;
339 }
340
341 pid_t SharedData::getRealPid(pid_t virt)
342 {
343 pid_t res = -1;
344 if (sharedDataHeader == NULL) initialize();
345 Util::lockFile(PROTECTED_SHM_FD);
346 for (size_t i = 0; i < sharedDataHeader->numPidMaps; i++) {
347 if (sharedDataHeader->pidMap[i].virt == virt) {
348 res = sharedDataHeader->pidMap[i].real;
349 }
350 }
351 Util::unlockFile(PROTECTED_SHM_FD);
352 return res;
353 }
354
355 void SharedData::setPidMap(pid_t virt, pid_t real)
356 {
357 size_t i;
358 if (sharedDataHeader == NULL) initialize();
359 Util::lockFile(PROTECTED_SHM_FD);
360 for (i = 0; i < sharedDataHeader->numPidMaps; i++) {
361 if (sharedDataHeader->pidMap[i].virt == virt) {
362 sharedDataHeader->pidMap[i].real = real;
363 break;
364 }
365 }
366 if (i == sharedDataHeader->numPidMaps) {
367 JASSERT(sharedDataHeader->numPidMaps < MAX_PID_MAPS);
368 sharedDataHeader->pidMap[i].virt = virt;
369 sharedDataHeader->pidMap[i].real = real;
370 sharedDataHeader->numPidMaps++;
371 }
372 Util::unlockFile(PROTECTED_SHM_FD);
373 }
374
375 int32_t SharedData::getRealIPCId(int type, int32_t virt)
376 {
377 int32_t res = -1;
378 uint32_t nmaps = 0;
379 IPCIdMap *map = NULL;
380 if (sharedDataHeader == NULL) initialize();
381 Util::lockFile(PROTECTED_SHM_FD);
382 switch (type) {
383 case SYSV_SHM_ID:
384 nmaps = sharedDataHeader->numSysVShmIdMaps;
385 map = sharedDataHeader->sysvShmIdMap;
386 break;
387
388 case SYSV_SEM_ID:
389 nmaps = sharedDataHeader->numSysVSemIdMaps;
390 map = sharedDataHeader->sysvSemIdMap;
391 break;
392
393 case SYSV_MSQ_ID:
394 nmaps = sharedDataHeader->numSysVMsqIdMaps;
395 map = sharedDataHeader->sysvMsqIdMap;
396 break;
397
398 default:
399 JASSERT(false) (type) .Text("Unknown IPC-Id type.");
400 break;
401 }
402 for (size_t i = 0; i < nmaps; i++) {
403 if (map[i].virt == virt) {
404 res = map[i].real;
405 }
406 }
407 Util::unlockFile(PROTECTED_SHM_FD);
408 return res;
409 }
410
411 void SharedData::setIPCIdMap(int type, int32_t virt, int32_t real)
412 {
413 size_t i;
414 uint32_t *nmaps = NULL;
415 IPCIdMap *map = NULL;
416 if (sharedDataHeader == NULL) initialize();
417 Util::lockFile(PROTECTED_SHM_FD);
418 switch (type) {
419 case SYSV_SHM_ID:
420 nmaps = &sharedDataHeader->numSysVShmIdMaps;
421 map = sharedDataHeader->sysvShmIdMap;
422 break;
423
424 case SYSV_SEM_ID:
425 nmaps = &sharedDataHeader->numSysVSemIdMaps;
426 map = sharedDataHeader->sysvSemIdMap;
427 break;
428
429 case SYSV_MSQ_ID:
430 nmaps = &sharedDataHeader->numSysVMsqIdMaps;
431 map = sharedDataHeader->sysvMsqIdMap;
432 break;
433
434 default:
435 JASSERT(false) (type) .Text("Unknown IPC-Id type.");
436 break;
437 }
438 for (i = 0; i < *nmaps; i++) {
439 if (map[i].virt == virt) {
440 map[i].real = real;
441 break;
442 }
443 }
444 if (i == *nmaps) {
445 JASSERT(*nmaps < MAX_IPC_ID_MAPS);
446 map[i].virt = virt;
447 map[i].real = real;
448 *nmaps += 1;
449 }
450 Util::unlockFile(PROTECTED_SHM_FD);
451 }
452
453 pid_t SharedData::getPtraceVirtualId(pid_t tracerId)
454 {
455 pid_t childId = -1;
456 if (sharedDataHeader == NULL) initialize();
457 Util::lockFile(PROTECTED_SHM_FD);
458 for (size_t i = 0; i < sharedDataHeader->numPtraceIdMaps; i++) {
459 if (sharedDataHeader->ptraceIdMap[i].tracerId == tracerId) {
460 childId = sharedDataHeader->ptraceIdMap[i].childId;
461 sharedDataHeader->ptraceIdMap[i] =
462 sharedDataHeader->ptraceIdMap[sharedDataHeader->numPtraceIdMaps];
463 sharedDataHeader->numPtraceIdMaps--;
464 }
465 }
466 Util::unlockFile(PROTECTED_SHM_FD);
467 return childId;
468 }
469
470 void SharedData::setPtraceVirtualId(pid_t tracerId, pid_t childId)
471 {
472 size_t i;
473 if (sharedDataHeader == NULL) initialize();
474 Util::lockFile(PROTECTED_SHM_FD);
475 for (i = 0; i < sharedDataHeader->numPtraceIdMaps; i++) {
476 if (sharedDataHeader->ptraceIdMap[i].tracerId == tracerId) {
477 break;
478 }
479 }
480
481 if (i == sharedDataHeader->numPtraceIdMaps) {
482 JASSERT(sharedDataHeader->numPtraceIdMaps < MAX_PTRACE_ID_MAPS);
483 sharedDataHeader->numPtraceIdMaps++;
484 }
485 sharedDataHeader->ptraceIdMap[i].tracerId = tracerId;
486 sharedDataHeader->ptraceIdMap[i].childId = childId;
487 Util::unlockFile(PROTECTED_SHM_FD);
488 }
489
490 void SharedData::createVirtualPtyName(const char* real, char *out, uint32_t len)
491 {
492 if (sharedDataHeader == NULL) initialize();
493 JASSERT(sharedDataHeader->nextVirtualPtyId != (unsigned) -1);
494
495 Util::lockFile(PROTECTED_SHM_FD);
496 string virt = VIRT_PTS_PREFIX_STR +
497 jalib::XToString(sharedDataHeader->nextVirtualPtyId++);
498 // FIXME: We should be removing ptys once they are gone.
499 JASSERT(sharedDataHeader->numPtyNameMaps < MAX_PTY_NAME_MAPS);
500 size_t n = sharedDataHeader->numPtyNameMaps++;
501 JASSERT(strlen(real) < PTS_PATH_MAX);
502 JASSERT(virt.length() < PTS_PATH_MAX);
503 strcpy(sharedDataHeader->ptyNameMap[n].real, real);
504 strcpy(sharedDataHeader->ptyNameMap[n].virt, virt.c_str());
505 JASSERT(len > virt.length());
506 strcpy(out, virt.c_str());
507 Util::unlockFile(PROTECTED_SHM_FD);
508 }
509
510 void SharedData::getRealPtyName(const char* virt, char *out, uint32_t len)
511 {
512 if (sharedDataHeader == NULL) initialize();
513 *out = '\0';
514 Util::lockFile(PROTECTED_SHM_FD);
515 for (size_t i = 0; i < sharedDataHeader->numPtyNameMaps; i++) {
516 if (strcmp(virt, sharedDataHeader->ptyNameMap[i].virt) == 0) {
517 JASSERT(strlen(sharedDataHeader->ptyNameMap[i].real) < len);
518 strcpy(out, sharedDataHeader->ptyNameMap[i].real);
519 break;
520 }
521 }
522 Util::unlockFile(PROTECTED_SHM_FD);
523 }
524
525 void SharedData::getVirtPtyName(const char* real, char *out, uint32_t len)
526 {
527 if (sharedDataHeader == NULL) initialize();
528 *out = '\0';
529 Util::lockFile(PROTECTED_SHM_FD);
530 for (size_t i = 0; i < sharedDataHeader->numPtyNameMaps; i++) {
531 if (strcmp(real, sharedDataHeader->ptyNameMap[i].real) == 0) {
532 JASSERT(strlen(sharedDataHeader->ptyNameMap[i].virt) < len);
533 strcpy(out, sharedDataHeader->ptyNameMap[i].virt);
534 break;
535 }
536 }
537 Util::unlockFile(PROTECTED_SHM_FD);
538 }
539
540 void SharedData::insertPtyNameMap(const char* virt, const char* real)
541 {
542 if (sharedDataHeader == NULL) initialize();
543 Util::lockFile(PROTECTED_SHM_FD);
544 size_t n = sharedDataHeader->numPtyNameMaps++;
545 JASSERT(strlen(virt) < PTS_PATH_MAX);
546 JASSERT(strlen(real) < PTS_PATH_MAX);
547 strcpy(sharedDataHeader->ptyNameMap[n].real, real);
548 strcpy(sharedDataHeader->ptyNameMap[n].virt, virt);
549 Util::unlockFile(PROTECTED_SHM_FD);
550 }
551
552 void SharedData::registerIncomingCons(vector<const char*>& ids,
553 struct sockaddr_un receiverAddr,
554 socklen_t len)
555 {
556 if (sharedDataHeader == NULL) initialize();
557 Util::lockFile(PROTECTED_SHM_FD);
558 for (size_t i = 0; i < ids.size(); i++) {
559 size_t n = sharedDataHeader->numIncomingConMaps++;
560 memcpy(sharedDataHeader->incomingConMap[n].id, ids[i], CON_ID_LEN);
561 memcpy(&sharedDataHeader->incomingConMap[n].addr, &receiverAddr, len);
562 sharedDataHeader->incomingConMap[n].len = len;
563 }
564 Util::unlockFile(PROTECTED_SHM_FD);
565 }
566
567 void SharedData::getMissingConMaps(IncomingConMap **map, uint32_t *nmaps)
568 {
569 if (sharedDataHeader == NULL) initialize();
570 *map = sharedDataHeader->incomingConMap;
571 *nmaps = sharedDataHeader->numIncomingConMaps;
572 }
573
574 void SharedData::insertInodeConnIdMaps(vector<InodeConnIdMap>& maps)
575 {
576 if (sharedDataHeader == NULL) initialize();
577 Util::lockFile(PROTECTED_SHM_FD);
578 size_t startIdx = sharedDataHeader->numInodeConnIdMaps;
579 sharedDataHeader->numInodeConnIdMaps += maps.size();
580 Util::unlockFile(PROTECTED_SHM_FD);
581
582 for (size_t i = 0; i < maps.size(); i++) {
583 sharedDataHeader->inodeConnIdMap[startIdx + i] = maps[i];
584 }
585 }
586
587 bool SharedData::getCkptLeaderForFile(dev_t devnum, ino_t inode, void *id)
588 {
589 if (sharedDataHeader == NULL) initialize();
590 JASSERT(id != NULL);
591 if (sharedDataHeader->numInodeConnIdMaps > 0) {
592 for (int i = sharedDataHeader->numInodeConnIdMaps - 1; i >= 0; i--) {
593 InodeConnIdMap& map = sharedDataHeader->inodeConnIdMap[i];
594 if (map.devnum == devnum && map.inode== inode) {
595 memcpy(id, map.id, sizeof(map.id));
596 return true;
597 }
598 }
599 }
600 return false;
601 }