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!"); }
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()); }