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; }
extern "C" int execvp (const char *filename, char *const argv[]) { if (isPerformingCkptRestart()) { return _real_execvp(filename, argv); } JTRACE("execvp() wrapper") (filename); /* Acquire the wrapperExeution lock to prevent checkpoint to happen while * processing this system call. */ WRAPPER_EXECUTION_GET_EXCL_LOCK(); char *newFilename; char **newArgv; dmtcpPrepareForExec(filename, argv, &newFilename, &newArgv); setenv("LD_PRELOAD", getUpdatedLdPreload().c_str(), 1); int retVal = _real_execvp (newFilename, newArgv); dmtcpProcessFailedExec(filename, newArgv); WRAPPER_EXECUTION_RELEASE_EXCL_LOCK(); 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; }
// 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; }