示例#1
0
extern "C" pid_t fork()
{
  /* Acquire the wrapperExeution lock to prevent checkpoint to happen while
   * processing this system call.
   */
  WRAPPER_EXECUTION_GET_EXCL_LOCK();
  dmtcp::KernelDeviceToConnection::instance().prepareForFork();

  /* Little bit cheating here: child_time should be same for both parent and
   * child, thus we compute it before forking the child. */
  child_time = time(NULL);
  long host = dmtcp::UniquePid::ThisProcess().hostid();
  dmtcp::UniquePid parent = dmtcp::UniquePid::ThisProcess();
  dmtcp::string child_name = jalib::Filesystem::GetProgramName() + "_(forked)";

  //Unset this environment variable so that we can get a new virtualPid from
  //the coordinator.
  _dmtcp_unsetenv(ENV_VAR_VIRTUAL_PID);
  coordinatorAPI.createNewConnectionBeforeFork(child_name);
  pid_t virtualPid = coordinatorAPI.virtualPid();
  dmtcp::Util::setVirtualPidEnvVar(virtualPid, getpid());

  //Enable the pthread_atfork child call
  pthread_atfork_enabled = true;
  pid_t childPid = _real_fork();

  if (childPid == -1) {
  } else if (childPid == 0) { /* child process */
    /* NOTE: Any work that needs to be done for the newly created child
     * should be put into pthread_atfork_child() function. That function is
     * hooked to the libc:fork() and will be called right after the new
     * process is created and before the fork() returns.
     *
     * pthread_atfork_child is registered by calling pthread_atfork() from
     * within the DmtcpWorker constructor to make sure that this is the first
     * registered handle.
     */
    dmtcp::UniquePid child = dmtcp::UniquePid(host, getpid(), child_time);
    JTRACE("fork() done [CHILD]") (child) (parent);
  } else if (childPid > 0) { /* Parent Process */
    dmtcp::UniquePid child = dmtcp::UniquePid(host, childPid, child_time);
    dmtcp::ProcessInfo::instance().insertChild(childPid, child);
    JTRACE("fork()ed [PARENT] done") (child);;
  }

  pthread_atfork_enabled = false;

  if (childPid != 0) {
    dmtcp::Util::setVirtualPidEnvVar(getpid(), getppid());
    coordinatorAPI.closeConnection();
    WRAPPER_EXECUTION_RELEASE_EXCL_LOCK();
  }
  return childPid;
}
static void restoreSockets(dmtcp::DmtcpCoordinatorAPI& coordinatorAPI,
                           dmtcp::ConnectionState& ckptCoord)
{
  JTRACE("restoreSockets begin");
  jalib::JSocket& restoreSocket = coordinatorAPI.openRestoreSocket();

  //reconnect to our coordinator
  coordinatorAPI.connectToCoordinator();
  coordinatorAPI.sendCoordinatorHandshake(jalib::Filesystem::GetProgramName(),
                                          compGroup, numPeers,
                                          DMT_RESTART_PROCESS);
  coordinatorAPI.recvCoordinatorHandshake(&coordTstamp);
  JTRACE("Connected to coordinator") (coordTstamp);

  jalib::JSocket& coordinatorSocket = coordinatorAPI.coordinatorSocket();
  // finish sockets restoration
  ckptCoord.doReconnect(coordinatorSocket, restoreSocket);

  JTRACE ("sockets restored!");
}
示例#3
0
LIB_PRIVATE void pthread_atfork_child()
{
  if (!pthread_atfork_enabled) {
    return;
  }
  pthread_atfork_enabled = false;

  long host = dmtcp::UniquePid::ThisProcess().hostid();
  dmtcp::UniquePid parent = dmtcp::UniquePid::ThisProcess();
  dmtcp::UniquePid child = dmtcp::UniquePid(host, getpid(), child_time);
  dmtcp::string child_name = jalib::Filesystem::GetProgramName() + "_(forked)";
  JALIB_RESET_ON_FORK();
  _dmtcp_remutex_on_fork();
  dmtcp::SyslogCheckpointer::resetOnFork();
  dmtcp::ThreadSync::resetLocks();

  dmtcp::UniquePid::resetOnFork(child);
  dmtcp::Util::initializeLogFile(child_name);

  dmtcp::ProcessInfo::instance().resetOnFork();

  JTRACE("fork()ed [CHILD]") (child) (parent);
  dmtcp::DmtcpWorker::resetOnFork(coordinatorAPI.coordinatorSocket());
}