extern "C" int ttyname_r(int fd, char *buf, size_t buflen) { char tmpbuf[64]; DMTCP_PLUGIN_DISABLE_CKPT(); int ret = _real_ttyname_r(fd, tmpbuf, sizeof(tmpbuf)); if (ret == 0 && strcmp(tmpbuf, "/dev/tty") != 0) { Connection* c = FileConnList::instance().getConnection(fd); JASSERT(c != NULL) (fd) (tmpbuf); PtyConnection* ptyCon =(PtyConnection*) c; string virtPtsName = ptyCon->virtPtsName(); if (virtPtsName.length() >= buflen) { JWARNING(false) (virtPtsName) (virtPtsName.length()) (buflen) .Text("fake ptsname() too long for user buffer"); errno = ERANGE; ret = -1; } else { strncpy(buf, virtPtsName.c_str(), buflen); } } DMTCP_PLUGIN_ENABLE_CKPT(); return ret; }
void dmtcp::FileConnList::refill(bool isRestart) { // Check comments in PtyConnection::preRefill()/refill() for (iterator i = begin(); i != end(); ++i) { Connection* con = i->second; if (con->hasLock() && con->conType() == Connection::PTY) { PtyConnection *pcon = (PtyConnection*) con; pcon->preRefill(isRestart); } } ConnectionList::refill(isRestart); }
void FileConnList::refill(bool isRestart) { // Check comments in PtyConnection::preRefill()/refill() for (iterator i = begin(); i != end(); ++i) { Connection* con = i->second; if (con->hasLock() && con->conType() == Connection::PTY) { PtyConnection *pcon = (PtyConnection*) con; pcon->preRefill(isRestart); } } if (isRestart) { // The backing file will be created as a result of restoreShmArea. We need // to unlink all such files in the resume() call below. for (size_t i = 0; i < missingUnlinkedShmFiles.size(); i++) { recreateShmFileAndMap(missingUnlinkedShmFiles[i]); } } ConnectionList::refill(isRestart); }
void FileConnList::postRestart() { /* It is possible to have two different connection-ids for a pre-existing * CTTY in two or more different process trees. In this case, only one of the * several process trees would be able to acquire a lock on the underlying * fd. The send-receive fd logic fails in this case due to different * connection-ids. Therefore, we let every process do a postRestart to * reopen the CTTY. * * TODO: A better fix would be to have a unique connection-id for each * pre-existing CTTY that is then used by all process trees. It can be * implemented by using the SharedData area. */ for (iterator i = begin(); i != end(); ++i) { Connection* con = i->second; if (!con->hasLock() && con->conType() == Connection::PTY && con->isPreExistingCTTY()) { PtyConnection *pcon = (PtyConnection*) con; pcon->postRestart(); } } /* Try to map the file as is, if it already exists on the disk. */ for (size_t i = 0; i < unlinkedShmAreas.size(); i++) { if (jalib::Filesystem::FileExists(unlinkedShmAreas[i].name)) { // TODO(kapil): Verify the file contents. JWARNING(false) (unlinkedShmAreas[i].name) .Text("File was unlinked at ckpt but is currently present on disk; " "remove it and try again."); restoreShmArea(unlinkedShmAreas[i]); } else { missingUnlinkedShmFiles.push_back(unlinkedShmAreas[i]); } } ConnectionList::postRestart(); }
static int ptsname_r_work(int fd, char * buf, size_t buflen) { JTRACE("Calling ptsname_r"); Connection* c = FileConnList::instance().getConnection(fd); PtyConnection* ptyCon =(PtyConnection*) c; string virtPtsName = ptyCon->virtPtsName(); JTRACE("ptsname_r") (virtPtsName); if (virtPtsName.length() >= buflen) { JWARNING(false) (virtPtsName) (virtPtsName.length()) (buflen) .Text("fake ptsname() too long for user buffer"); errno = ERANGE; return -1; } strcpy(buf, virtPtsName.c_str()); return 0; }
void dmtcp::FileConnList::postRestart() { /* It is possible to have two different connection-ids for a pre-existing * CTTY in two or more different process trees. In this case, only one of the * several process trees would be able to acquire a lock on the underlying * fd. The send-receive fd logic fails in this case due to different * connection-ids. Therefore, we let every process do a postRestart to * reopen the CTTY. * * TODO: A better fix would be to have a unique connection-id for each * pre-existing CTTY that is then used by all process trees. It can be * implemented by using the SharedData area. */ for (iterator i = begin(); i != end(); ++i) { Connection* con = i->second; if (!con->hasLock() && con->conType() == Connection::PTY && con->isPreExistingCTTY()) { PtyConnection *pcon = (PtyConnection*) con; pcon->postRestart(); } } ConnectionList::postRestart(); }
//examine /proc/self/fd for unknown connections void dmtcp::FileConnList::scanForPreExisting() { // FIXME: Detect stdin/out/err fds to detect duplicates. dmtcp::vector<int> fds = jalib::Filesystem::ListOpenFds(); dmtcp::string ctty = jalib::Filesystem::GetControllingTerm(); dmtcp::string parentCtty = jalib::Filesystem::GetControllingTerm(getppid()); for (size_t i = 0; i < fds.size(); ++i) { int fd = fds[i]; if (!Util::isValidFd(fd)) continue; if (dmtcp_is_protected_fd(fd)) continue; struct stat statbuf; JASSERT(fstat(fd, &statbuf) == 0); bool isRegularFile = (S_ISREG(statbuf.st_mode) || S_ISCHR(statbuf.st_mode) || S_ISDIR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)); dmtcp::string device = _resolveSymlink(_procFDPath(fd)); JTRACE("scanning pre-existing device") (fd) (device); if (device == ctty || device == parentCtty) { // Search if this is duplicate connection iterator conit; int cttyType = (device == ctty) ? PtyConnection::PTY_CTTY : PtyConnection::PTY_PARENT_CTTY; for (conit = begin(); conit != end(); conit++) { Connection *c = conit->second; if (c->subType() == cttyType && ((PtyConnection*)c)->ptsName() == device) { processDup(c->getFds()[0], fd); break; } } if (conit == end()) { // FIXME: Merge this code with the code in processFileConnection PtyConnection *con = new PtyConnection(fd, (const char*) device.c_str(), -1, -1, cttyType); // Check comments in FileConnList::postRestart() for the explanation // about isPreExistingCTTY. con->markPreExistingCTTY(); add(fd, (Connection*)con); } } else if(dmtcp_is_bq_file && dmtcp_is_bq_file(device.c_str())) { if (isRegularFile) { Connection *c = findDuplication(fd, device.c_str()); if (c != NULL) { c->addFd(fd); continue; } } processFileConnection(fd, device.c_str(), -1, -1); } else if( fd <= 2 ){ add(fd, new StdioConnection(fd)); } else if (Util::strStartsWith(device, "/")) { if (isRegularFile) { Connection *c = findDuplication(fd, device.c_str()); if (c != NULL) { c->addFd(fd); continue; } } processFileConnection(fd, device.c_str(), -1, -1); } } }