Example #1
0
void RestoreTarget::CreateProcess(CoordinatorAPI& coordinatorAPI,
                                  SlidingFdTable& slidingFd)
{
  //change UniquePid
  UniquePid::resetOnFork(upid());
  //UniquePid::ThisProcess(true) = _conToFd.upid();

  Util::initializeLogFile(procname());
  JTRACE("Creating process during restart") (upid()) (procname());

  JTRACE("")(getpid())(getppid())(getsid(0));
  ProcessInfo &pInfo = _processInfo;
  pid_t psid = pInfo.sid();

  JTRACE("Restore /proc/self/* fds");
  ConnectionList& connections = ConnectionList::instance();
  ConnectionList::iterator it;
  for (it = connections.begin(); it != connections.end(); ++it) {
    dmtcp::Connection *con = it->second;
    if (con->subType() == FileConnection::FILE_PROCFS) {
      dmtcp::FileConnection *filecon = (dmtcp::FileConnection*) con;
      char buf[32];
      dmtcp::vector<int> fds;
      fds.push_back(slidingFd.getFdFor(con->id()));
      sprintf(buf, "/proc/%d/", pInfo.pid());
      if (dmtcp::Util::strStartsWith(filecon->filePath(), buf)) {
        filecon->restore(fds);
      }
    }
  }


  if (!isSessionLeader()) {

    // Restore Group information
    restoreGroup(slidingFd);

    // If process is not session leader, restore it and all children.
    t_iterator it = _children.begin();
    for (; it != _children.end(); it++) {
      JTRACE ("Forking Child Process") ((*it)->upid());
      pid_t cid = fork();

      if (cid == 0) {
        (*it)->CreateProcess (coordinatorAPI, slidingFd);
        JASSERT (false) . Text ("Unreachable");
      }
      JASSERT (cid > 0);
    }
  } else {
    // Process is session leader.
    // There may be not setsid-ed children.
    for (t_iterator it = _children.begin(); it != _children.end(); it++) {
      s_iterator sit = (*it)->getSmap().find(psid);
      JTRACE("Restore processes that were created before their parent called setsid()");
      if (sit == (*it)->getSmap().end()) {
        JTRACE ("Forking Child Process") ((*it)->upid());
        pid_t cid = fork();
        if (cid == 0) {
          (*it)->CreateProcess (coordinatorAPI, slidingFd);
          JASSERT (false) . Text ("Unreachable");
        }
        JASSERT (cid > 0);
      }
    }

    pid_t nsid = setsid();
    JTRACE("change SID")(nsid);

    // Restore Group information
    restoreGroup(slidingFd);

    for (t_iterator it = _children.begin(); it != _children.end(); it++) {
      JTRACE("Restore processes that was created after their parent called setsid()");
      s_iterator sit = (*it)->getSmap().find(psid);
      if (sit != (*it)->getSmap().end()) {
        JTRACE ("Forking Child Process") ((*it)->upid());
        pid_t cid = fork();
        if (cid == 0) {
          (*it)->CreateProcess (coordinatorAPI, slidingFd);
          JASSERT (false) . Text ("Unreachable");
        }
        JASSERT (cid> 0);
      }
    }

    for (t_iterator it = _roots.begin() ; it != _roots.end(); it++) {
      JTRACE ("Forking Dependent Root Process") ((*it)->upid());
      pid_t cid;
      if ((cid = fork())) {
        waitpid(cid, NULL, 0);
      } else {
        if (fork())
          exit(0);
        (*it)->CreateProcess(coordinatorAPI, slidingFd);
        JASSERT (false) . Text("Unreachable");
      }
    }
  }

  bool isTheGroupLeader = isGroupLeader(); // Calls JTRACE;avoid recursion
  JTRACE("Child and dependent root processes forked, restoring process")
    (upid())(getpid())(isTheGroupLeader);

  //Reconnect to dmtcp_coordinator
  WorkerState::setCurrentState (WorkerState::RESTARTING);

  coordinatorAPI.connectToCoordinator();
  coordinatorAPI.sendCoordinatorHandshake(procname(), _processInfo.compGroup());
  coordinatorAPI.recvCoordinatorHandshake();

  //restart targets[i]
  dupAllSockets (slidingFd);

  mtcpRestart();

  JASSERT (false).Text ("unreachable");
}