Esempio n. 1
0
    void createProcess(bool createIndependentRootProcesses = false)
    {
      UniquePid::ThisProcess() = _pInfo.upid();
      UniquePid::ParentProcess() = _pInfo.uppid();
      Util::initializeLogFile(_pInfo.procname());

      if (createIndependentRootProcesses) {
        DmtcpUniqueProcessId compId = _pInfo.compGroup().upid();
        CoordinatorInfo coordInfo;
        struct in_addr localIPAddr;
        if (_pInfo.noCoordinator()) {
          allowedModes = COORD_NONE;
        }

        // dmtcp_restart sets ENV_VAR_NAME_HOST/PORT, even if cmd line flag used
        const char *host = NULL;
        int port = UNINITIALIZED_PORT;
        CoordinatorAPI::getCoordHostAndPort(allowedModes, &host, &port);
        // FIXME:  We will use the new HOST and PORT here, but after restart,,
        //           we will use the old HOST and PORT from the ckpt image.
        CoordinatorAPI::instance().connectToCoordOnRestart(allowedModes,
                                                           _pInfo.procname(),
                                                           _pInfo.compGroup(),
                                                           _pInfo.numPeers(),
                                                           &coordInfo,
                                                           host,
                                                           port,
                                                           &localIPAddr);
        // If port was 0, we'll get new random port when coordinator starts up.
        CoordinatorAPI::getCoordHostAndPort(allowedModes, &host, &port);
        Util::writeCoordPortToFile(port, thePortFile.c_str());

        string installDir =
          jalib::Filesystem::DirName(jalib::Filesystem::GetProgramDir());

#if defined(__i386__) || defined(__arm__)
        if (Util::strEndsWith(installDir, "/lib/dmtcp/32")) {
          // If dmtcp_launch was compiled for 32 bits in 64-bit O/S, then note:
          // DMTCP_ROOT/bin/dmtcp_launch is a symbolic link to:
          //    DMTCP_ROOT/bin/dmtcp_launch/lib/dmtcp/32/bin
          // GetProgramDir() followed the link.  So, need to remove the suffix.
          char *str = const_cast<char*>(installDir.c_str());
          str[strlen(str) - strlen("/lib/dmtcp/32")] = '\0';
          installDir = str;
        }
#endif

        /* We need to initialize SharedData here to make sure that it is
         * initialized with the correct coordinator timestamp.  The coordinator
         * timestamp is updated only during postCkpt callback. However, the
         * SharedData area may be initialized earlier (for example, while
         * recreating threads), causing it to use *older* timestamp.
         */
        SharedData::initialize(tmpDir.c_str(),
                               installDir.c_str(),
                               &compId,
                               &coordInfo,
                               &localIPAddr);

        Util::prepareDlsymWrapper();
      }

      JTRACE("Creating process during restart") (upid()) (_pInfo.procname());

      RestoreTargetMap::iterator it;
      for (it = targets.begin(); it != targets.end(); it++) {
        RestoreTarget *t = it->second;
        if (_pInfo.upid() == t->_pInfo.upid()) {
          continue;
        } else if (_pInfo.isChild(t->upid()) &&
                   t->_pInfo.sid() != _pInfo.pid()) {
          t->createDependentChildProcess();
        }
      }

      if (createIndependentRootProcesses) {
        RestoreTargetMap::iterator it;
        for (it = independentProcessTreeRoots.begin();
             it != independentProcessTreeRoots.end();
             it++) {
          RestoreTarget *t = it->second;
          if (t != this) {
            t->createDependentNonChildProcess();
          }
        }
      }

      // If we were the session leader, become one now.
      if (_pInfo.sid() == _pInfo.pid()) {
        if (getsid(0) != _pInfo.pid()) {
          JWARNING(setsid() != -1) (getsid(0)) (JASSERT_ERRNO)
            .Text("Failed to restore this process as session leader.");
        }
      }

      // Now recreate processes with sid == _pid
      for (it = targets.begin(); it != targets.end(); it++) {
        RestoreTarget *t = it->second;
        if (_pInfo.upid() == t->_pInfo.upid()) {
          continue;
        } else if (t->_pInfo.sid() == _pInfo.pid()) {
          if (_pInfo.isChild(t->upid())) {
            t->createDependentChildProcess();
          } else if (t->isRootOfProcessTree()) {
            t->createDependentNonChildProcess();
          }
        }
      }

      // Now close all open fds except _fd;
      for (it = targets.begin(); it != targets.end(); it++) {
        RestoreTarget *t = it->second;
        if (t != this) {
          close(t->fd());
        }
      }

      string ckptDir = jalib::Filesystem::GetDeviceName(PROTECTED_CKPT_DIR_FD);
      if (ckptDir.length() == 0) {
        // Create the ckpt-dir fd so that the restarted process can know about
        // the abs-path of ckpt-image.
        string dirName = jalib::Filesystem::DirName(_path);
        int dirfd = open(dirName.c_str(), O_RDONLY);
        JASSERT(dirfd != -1) (JASSERT_ERRNO);
        if (dirfd != PROTECTED_CKPT_DIR_FD) {
          JASSERT(dup2(dirfd, PROTECTED_CKPT_DIR_FD) == PROTECTED_CKPT_DIR_FD);
          close(dirfd);
        }
      }

      if (!createIndependentRootProcesses) {
        // dmtcp_restart sets ENV_VAR_NAME_HOST/PORT, even if cmd line flag used
        const char *host = NULL;
        int port = UNINITIALIZED_PORT;
        int *port_p = &port;
        CoordinatorAPI::getCoordHostAndPort(allowedModes, &host, port_p);
        CoordinatorAPI::instance().connectToCoordOnRestart(allowedModes,
                                                           _pInfo.procname(),
                                                           _pInfo.compGroup(),
                                                           _pInfo.numPeers(),
                                                           NULL,
                                                           host,
                                                           port,
                                                           NULL);
      }

      setEnvironFd();
      int is32bitElf = 0;

#if defined(__x86_64__) || defined(__aarch64__)
      is32bitElf = (_pInfo.elfType() == ProcessInfo::Elf_32);
#elif defined(__i386__) || defined(__arm__)
      is32bitElf = true;
#endif


      runMtcpRestart(is32bitElf, _fd, &_pInfo);

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