예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
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();
}
예제 #5
0
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;
}
예제 #6
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();
}
예제 #7
0
//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);
    }
  }
}