// See comments above for open_ckpt_to_read() int dmtcp::CkptSerializer::openDmtcpCheckpointFile(const dmtcp::string& path, int *offset, int skipBytes) { char buf[1024]; // 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."); 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 */ JASSERT(fd >= 0) (path) .Text("Failed to open file."); } if (offset != NULL) { *offset = strlen(DMTCP_FILE_HEADER); } skipBytes -= strlen(DMTCP_FILE_HEADER); if (skipBytes > 0) { JASSERT(dmtcp::Util::skipBytes(fd, skipBytes) == skipBytes) (skipBytes); } return fd; }
char dmtcp::Util::readChar (int fd) { char c; int rc; do { rc = _real_read (fd, &c, 1); } while ( rc == -1 && errno == EINTR ); if (rc <= 0) return (0); return (c); }
int dmtcp::CkptSerializer::openDmtcpCheckpointFile(const dmtcp::string& path){ int fd = open( path.c_str(), O_RDONLY); 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); return fd; }else{ close(fd); dmtcp::string cmd = dmtcp::string()+"exec gzip -d - < '"+path+"'"; FILE* t = _real_popen(cmd.c_str(),"r"); JASSERT(t!=NULL)(path)(cmd).Text("Failed to launch gzip."); JTRACE ( "created gzip child process to uncompress checkpoint file"); fd = fileno(t); JASSERT(_real_read(fd, buf, len)==len)(cmd)(path).Text("Invalid checkpoint file"); JASSERT(strncmp(buf, DMTCP_FILE_HEADER, len)==0)(path).Text("Invalid checkpoint file"); JTRACE("opened checkpoint file [compressed]")(path); return fd; } }
static char first_char(const char *filename) { int fd, rc; char c; fd = open(filename, O_RDONLY); JASSERT(fd >= 0)(filename).Text("ERROR: Cannot open filename"); rc = _real_read(fd, &c, 1); JASSERT(rc == 1)(filename).Text("ERROR: Error reading from filename"); close(fd); return c; }
// Reads from fd until count bytes are read, or newline encountered. // Returns NULL at EOF. // FIXME: count is unused. Buffer-overrun possible int dmtcp::Util::readLine(int fd, char *buf, int count) { int i = 0; char c; while (i < count) { if (_real_read(fd, &c, 1) == 0) { buf[i] = '\0'; return '\0'; } buf[i++] = c; if (c == '\n') break; } buf[i++] = '\0'; return i; }
// Fails, succeeds, or partial read due to EOF (returns num read) // return value: // -1: unrecoverable error // <n>: number of bytes read ssize_t dmtcp::Util::readAll(int fd, void *buf, size_t count) { ssize_t rc; char *ptr = (char *) buf; size_t num_read = 0; for (num_read = 0; num_read < count;) { rc = _real_read (fd, ptr + num_read, count - num_read); if (rc == -1) { if (errno == EINTR || errno == EAGAIN) continue; else return -1; } else if (rc == 0) break; else // else rc > 0 num_read += rc; } return num_read; }
// 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; }