Example #1
0
static int queryPbsConfig(dmtcp::string option, dmtcp::string &pbs_config)
{
  int fds[2];
  const char *pbs_config_path = "pbs-config";
  static const char *pbs_config_args[] = { "pbs-config", option.c_str(), NULL };
  int cpid;

  if( pipe(fds) == -1){
    // just go away - we cannot serve this request
    JTRACE("Cannot create pipe to execute pbs-config to find Torque/PBS library!");
    return -1;
  }

  cpid = _real_fork();

  if( cpid < 0 ){
    JTRACE( "ERROR: cannot execute pbs-config. Will not run tm_spawn!");
    return -1;
  }
  if( cpid == 0 ){
    JTRACE ( "child process, will exec into external de-compressor");
    fds[1] = dup(dup(dup(fds[1])));
    close(fds[0]);
    JASSERT(dup2(fds[1], STDOUT_FILENO) == STDOUT_FILENO);
    close(fds[1]);
    _real_execvp(pbs_config_path, (char **)pbs_config_args);
    /* should not get here */
    JASSERT(false)("ERROR: Failed to exec pbs-config. tm_spawn will fail with TM_BADINIT")(strerror(errno));
    exit(0);
  }

  /* parent process */
  JTRACE ( "created child process for pbs-config")(cpid);
  int status;
  if( waitpid(cpid,&status,0) < 0 ){
    return -1;
  }
  if( !( WIFEXITED(status) && WEXITSTATUS(status) == 0 ) ){
    return -1;
  }

  // set descriptor as non-blocking
  // JTRACE ( "Set pipe fds[0] as non-blocking");
  int flags = fcntl(fds[0], F_GETFL);
  fcntl(fds[0], F_SETFL, flags | O_NONBLOCK);

  //JTRACE ( "Read pbs-config output from pipe");
  pbs_config = "";
  char buf[256];
  int count = 0;
  while( (count = read(fds[0], buf, 255)) > 0 ){
    buf[count] = '\0';
    pbs_config += dmtcp::string() + buf;
  }

  JTRACE ( "pbs-config output:")(pbs_config);
  return 0;
}
Example #2
0
extern "C" pid_t fork()
{
  if (isPerformingCkptRestart()) {
    return _real_syscall(SYS_fork);
  }

  /* Acquire the wrapperExeution lock to prevent checkpoint to happen while
   * processing this system call.
   */
  WRAPPER_EXECUTION_GET_EXCL_LOCK();
  dmtcp::DmtcpWorker::processEvent(DMTCP_EVENT_PRE_FORK, NULL);

  /* 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)";

  coordinatorAPI.createNewConnectionBeforeFork(child_name);
  dmtcp::Util::setVirtualPidEnvVar(coordinatorAPI.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);

    dmtcp::initializeMtcpEngine();
  } 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;
}
Example #3
0
pid_t fork()
{
  WRAPPER_HEADER(pid_t, fork, _real_fork);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_TYPED(pid_t, fork);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_fork();
    if (retval != 0) {
      dmtcp::ThreadInfo::unsetOptionalEvent();
      WRAPPER_LOG_WRITE_ENTRY(fork);
    }
  }
  return retval;
}
extern "C" pid_t fork()
{
  pid_t retval = 0;
  pid_t virtualPid = getPidFromEnvVar();

  dmtcp::VirtualPidTable::instance().writeVirtualTidToFileForPtrace(virtualPid);

  pid_t realPid = _real_fork();

  if (realPid > 0) { /* Parent Process */
    retval = virtualPid;
    dmtcp::VirtualPidTable::instance().updateMapping(virtualPid, realPid);
  } else {
    retval = realPid;
    dmtcp::VirtualPidTable::instance().readVirtualTidFromFileForPtrace();
  }

  return retval;
}
// Copied from mtcp/mtcp_restart.c.
// Let's keep this code close to MTCP code to avoid maintenance problems.
// MTCP code in:  mtcp/mtcp_restart.c:open_ckpt_to_read()
// A previous version tried to replace this with popen, causing a regression:
//   (no call to pclose, and possibility of using a wrong fd).
// Returns fd; sets ext_decomp_pid, if checkpoint was compressed.
static int open_ckpt_to_read(const char *filename)
{
    int fd;
    int fds[2];
    char fc;
    const char *decomp_path;
    const char **decomp_args;
    const char *gzip_path = "gzip";
    static const char * gzip_args[] = { "gzip", "-d", "-", NULL };
#ifdef HBICT_DELTACOMP
    const char *hbict_path = "hbict";
    static const char *hbict_args[] = { "hbict", "-r", NULL };
#endif
    pid_t cpid;

    fc = first_char(filename);
    fd = open(filename, O_RDONLY);
    JASSERT(fd>=0)(filename).Text("Failed to open file.");

    if(fc == DMTCP_MAGIC_FIRST) /* no compression */
        return fd;
#ifdef HBICT_DELTACOMP
    else if (fc == GZIP_FIRST || fc == HBICT_FIRST){ /* External compression */
#else
    else if(fc == GZIP_FIRST){ /* gzip */
#endif
        if( fc == GZIP_FIRST ){
          decomp_path = gzip_path;
          decomp_args = gzip_args;
        }
#ifdef HBICT_DELTACOMP
        else{
          decomp_path = hbict_path;
          decomp_args = hbict_args;
        }
#endif

        JASSERT(pipe(fds) != -1)(filename).Text("Cannot create pipe to execute gunzip to decompress checkpoint file!");

        cpid = _real_fork();

        JASSERT(cpid != -1).Text("ERROR: Cannot fork to execute gunzip to decompress checkpoint file!");
        if(cpid > 0) /* parent process */
        {
           JTRACE ( "created child process to uncompress checkpoint file")(cpid);
            ext_decomp_pid = cpid;
            close(fd);
            close(fds[1]);
            return fds[0];
        }
        else /* child process */
        {
           JTRACE ( "child process, will exec into external de-compressor");
            fd = dup(dup(dup(fd)));
            fds[1] = dup(fds[1]);
            close(fds[0]);
            JASSERT(fd != -1);
            JASSERT(dup2(fd, STDIN_FILENO) == STDIN_FILENO);
            close(fd);
            JASSERT(dup2(fds[1], STDOUT_FILENO) == STDOUT_FILENO);
            close(fds[1]);
            _real_execvp(decomp_path, (char **)decomp_args);
            JASSERT(decomp_path!=NULL)(decomp_path).Text("Failed to launch gzip.");
            /* should not get here */
            JASSERT(false)("ERROR: Decompression failed!  No restoration will be performed!  Cancelling now!");
            abort();
        }
    } else /* invalid magic number */
        JASSERT(false).Text("ERROR: Invalid magic number in this checkpoint file!");
    // NOT_REACHED
    return -1;
}

// See comments above for open_ckpt_to_read()
int dmtcp::CkptSerializer::openDmtcpCheckpointFile(const dmtcp::string& path){
  // Function also sets dmtcp::ext_decomp_pid::ConnectionToFds
  int fd = open_ckpt_to_read( path.c_str() );
  // The rest of this function is for compatibility with original definition.
  JASSERT(fd>=0)(path).Text("Failed to open file.");
  char buf[512];
  const int len = strlen(DMTCP_FILE_HEADER);
  JASSERT(_real_read(fd, buf, len)==len)(path).Text("_real_read() failed");
  if(strncmp(buf, DMTCP_FILE_HEADER, len)==0){
    JTRACE("opened checkpoint file [uncompressed]")(path);
  }else{
    close_ckpt_to_read(fd);
    fd = open_ckpt_to_read( path.c_str() ); /* Re-open from beginning */
  }
  return fd;
}
Example #6
0
// Copied from mtcp/mtcp_restart.c.
// Let's keep this code close to MTCP code to avoid maintenance problems.
// MTCP code in:  mtcp/mtcp_restart.c:open_ckpt_to_read()
// A previous version tried to replace this with popen, causing a regression:
//   (no call to pclose, and possibility of using a wrong fd).
// Returns fd; sets ext_decomp_pid, if checkpoint was compressed.
static int open_ckpt_to_read(const char *filename)
{
  int fd;
  int fds[2];
  char fc;
  const char *decomp_path;
  const char **decomp_args;
  const char *gzip_path = "gzip";
  static const char * gzip_args[] = { "gzip", "-d", "-", NULL };
#ifdef HBICT_DELTACOMP
  const char *hbict_path = "hbict";
  static const char *hbict_args[] = { "hbict", "-r", NULL };
#endif
  pid_t cpid;

  fc = first_char(filename);
  fd = open(filename, O_RDONLY);
  JASSERT(fd>=0)(filename).Text("Failed to open file.");

  if (fc == DMTCP_MAGIC_FIRST) { /* no compression */
    return fd;
  }
  else if (fc == GZIP_FIRST
#ifdef HBICT_DELTACOMP
           || fc == HBICT_FIRST
#endif
          ) {
    if (fc == GZIP_FIRST) {
      decomp_path = gzip_path;
      decomp_args = gzip_args;
    }
#ifdef HBICT_DELTACOMP
    else {
      decomp_path = hbict_path;
      decomp_args = hbict_args;
    }
#endif

    JASSERT(pipe(fds) != -1) (filename)
      .Text("Cannot create pipe to execute gunzip to decompress ckpt file!");

    cpid = _real_fork();

    JASSERT(cpid != -1)
      .Text("ERROR: Cannot fork to execute gunzip to decompress ckpt file!");
    if (cpid > 0) { /* parent process */
      JTRACE("created child process to uncompress checkpoint file") (cpid);
      ext_decomp_pid = cpid;
      close(fd);
      close(fds[1]);
      return fds[0];
    } else { /* child process */
      JTRACE ( "child process, will exec into external de-compressor");
      fd = dup(dup(dup(fd)));
      fds[1] = dup(fds[1]);
      close(fds[0]);
      JASSERT(fd != -1);
      JASSERT(dup2(fd, STDIN_FILENO) == STDIN_FILENO);
      close(fd);
      JASSERT(dup2(fds[1], STDOUT_FILENO) == STDOUT_FILENO);
      close(fds[1]);
      _real_execvp(decomp_path, (char **)decomp_args);
      JASSERT(decomp_path!=NULL) (decomp_path)
        .Text("Failed to launch gzip.");
      /* should not get here */
      JASSERT(false)
        .Text("Decompression failed!  No restoration will be performed!");
    }
  } else { /* invalid magic number */
    JASSERT(false)
      .Text("ERROR: Invalid magic number in this checkpoint file!");
  }
  return -1;
}