int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "USAGE: %s /path/to/sync-log\n", argv[0]); return 1; } initializeJalib(); rewriteLog(argv[1]); return 0; }
int main ( int argc, char** argv ) { initializeJalib(); if (! getenv(ENV_VAR_QUIET)) setenv(ENV_VAR_QUIET, "0", 0); processArgs(&argc, &argv); // If --ssh-slave and --prefix both are present, verify that the prefix-dir // of this binary (dmtcp_checkpoint) is same as the one provided with // --prefix if (isSSHSlave && getenv(ENV_VAR_PREFIX_PATH) != NULL) { const char *str = getenv(ENV_VAR_PREFIX_PATH); dmtcp::string prefixDir = jalib::Filesystem::ResolveSymlink(str); dmtcp::string programPrefixDir = jalib::Filesystem::DirName(jalib::Filesystem::GetProgramDir()); JASSERT(prefixDir == programPrefixDir) (prefixDir) (programPrefixDir); } dmtcp::UniquePid::setTmpDir(getenv(ENV_VAR_TMPDIR)); dmtcp::UniquePid::ThisProcess(true); dmtcp::Util::initializeLogFile(); #ifdef FORKED_CHECKPOINTING /* When this is robust, add --forked-checkpointing option on command-line, * with #ifdef FORKED_CHECKPOINTING around the option, change default of * configure.ac, dmtcp/configure.ac, to enable, and change them * from enable-forked... to disable-... */ setenv(ENV_VAR_FORKED_CKPT, "1", 1); #endif if (jassert_quiet == 0) JASSERT_STDERR << DMTCP_BANNER; // This code will go away when zero-mapped pages are implemented in MTCP. struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); if (rlim.rlim_cur > 256*1024*1024 && rlim.rlim_cur != RLIM_INFINITY) JASSERT_STDERR << "*** WARNING: RLIMIT_STACK > 1/4 GB. This causes each thread to" "\n*** receive a 1/4 GB stack segment. Checkpoint/restart will be slow," "\n*** and will potentially break if many threads are created." "\n*** Suggest setting (sh/bash): ulimit -s 10000" "\n*** (csh/tcsh): limit stacksize 10000" "\n*** prior to using DMTCP. (This will be fixed in the future, when" "\n*** DMTCP supports restoring zero-mapped pages.)\n\n\n" ; // Remove this when zero-mapped pages are supported. For segments with // no file backing: Start with 4096 (page) offset and keep doubling offset // until finding region of memory segment with many zeroes. // Then mark as CS_ZERO_PAGES in MTCP instead of CS_RESTORE (or mark // entire segment as CS_ZERO_PAGES and then overwrite with CS_RESTORE // region for portion to be read back from checkpoint image. // For CS_ZERO_PAGES region, mmap // on restart, but don't write in zeroes. // Also, after checkpointing segment, munmap zero pages, and mmap them again. // Don't try to find all pages. The above strategy may increase // the non-zero-mapped mapped pages to no more than double the actual // non-zero region (assuming that the zero-mapped pages are contiguous). // - Gene testMatlab(argv[0]); testJava(argv); // Warn that -Xmx flag needed to limit virtual memory size // If dmtcphijack.so is in standard search path and _also_ has setgid access, // then LD_PRELOAD will work. // Otherwise, it will only work if the application does not use setuid and // setgid access. So, we test // if the application does not use // setuid/setgid. (See 'man ld.so') // FIXME: ALSO DO THIS FOR execwrappers.cpp:dmtcpPrepareForExec() // Should pass dmtcphijack.so path, and let testSetuid determine // if setgid is set for it. If so, no problem: continue. // If not, call testScreen() and adapt 'screen' to run using // Util::patchArgvIfSetuid(argv[0], argv, &newArgv) (which shouldn't // will just modify argv[0] to point to /tmp/dmtcp-USER@HOST/screen // and other modifications: doesn't need newArgv). // If it's not 'screen' and if no setgid for dmtcphijack.so, then testSetuid // should issue the warning, unset our LD_PRELOAD, and hope for the best. // A program like /usr/libexec/utempter/utempter (Fedora path) // is short-lived and can be safely run. Ideally, we should // disable checkpoints while utempter is running, and enable checkpoints // when utempter finishes. See possible model at // execwrappers.cpp:execLibProcessAndExit(), since the same applies // to running /lib/libXXX.so for running libraries as executables. if (testSetuid(argv[0])) { char **newArgv; // THIS NEXT LINE IS DANGEROUS. MOST setuid PROGRAMS CAN'T RUN UNPRIVILEGED dmtcp::Util::patchArgvIfSetuid(argv[0], argv, &newArgv); argv = newArgv; }; if (argc > 0) { JTRACE("dmtcp_checkpoint starting new program:")(argv[0]); } //set up CHECKPOINT_DIR if(getenv(ENV_VAR_CHECKPOINT_DIR) == NULL){ const char* ckptDir = get_current_dir_name(); if(ckptDir != NULL ){ //copy to private buffer static dmtcp::string _buf = ckptDir; ckptDir = _buf.c_str(); }else{ ckptDir="."; } setenv ( ENV_VAR_CHECKPOINT_DIR, ckptDir, 0 ); JTRACE("setting " ENV_VAR_CHECKPOINT_DIR)(ckptDir); } dmtcp::string stderrDevice = jalib::Filesystem::ResolveSymlink ( _stderrProcPath() ); //TODO: // When stderr is a pseudo terminal for IPC between parent/child processes, // this logic fails and JASSERT may write data to FD 2 (stderr). // This will cause problems in programs that use FD 2 (stderr) for // algorithmic things ... if ( stderrDevice.length() > 0 && jalib::Filesystem::FileExists ( stderrDevice ) ) setenv ( ENV_VAR_STDERR_PATH,stderrDevice.c_str(), 0 ); else// if( isSSHSlave ) setenv ( ENV_VAR_STDERR_PATH, "/dev/null", 0 ); if ( getenv(ENV_VAR_SIGCKPT) != NULL ) setenv ( "MTCP_SIGCKPT", getenv(ENV_VAR_SIGCKPT), 1); else unsetenv("MTCP_SIGCKPT"); if ( checkpointOpenFiles ) setenv( ENV_VAR_CKPT_OPEN_FILES, "1", 0 ); else unsetenv( ENV_VAR_CKPT_OPEN_FILES); #ifdef PID_VIRTUALIZATION setenv( ENV_VAR_ROOT_PROCESS, "1", 1 ); #endif bool isElf, is32bitElf; if (dmtcp::Util::elfType(argv[0], &isElf, &is32bitElf) == -1) { // Couldn't read argv_buf // FIXME: This could have been a symbolic link. Don't issue an error, // unless we're sure that the executable is not readable. JASSERT_STDERR << "*** ERROR: Executable to run w/ DMTCP appears not to be readable,\n" "*** or no such executable in path.\n\n" << argv[0] << "\n"; exit(DMTCP_FAIL_RC); } else { #if defined(__x86_64__) && !defined(CONFIG_M32) if (is32bitElf) JASSERT_STDERR << "*** ERROR: You appear to be checkpointing " << "a 32-bit target under 64-bit Linux.\n" << "*** If this fails, then please try re-configuring DMTCP:\n" << "*** configure --enable-m32 ; make clean ; make\n\n"; #endif testStaticallyLinked(argv[0]); } // UNSET DISPLAY environment variable. unsetenv("DISPLAY"); // FIXME: Unify this code with code prior to execvp in execwrappers.cpp // Can use argument to dmtcpPrepareForExec() or getenv("DMTCP_...") // from DmtcpWorker constructor, to distinguish the two cases. dmtcp::Util::adjustRlimitStack(); // FIXME: This call should be moved closer to call to execvp(). dmtcp::Util::prepareDlsymWrapper(); if (autoStartCoordinator) dmtcp::DmtcpCoordinatorAPI::startCoordinatorIfNeeded(allowedModes); dmtcp::DmtcpCoordinatorAPI coordinatorAPI; pid_t virtualPid = coordinatorAPI.getVirtualPidFromCoordinator(); if (virtualPid != -1) { JTRACE("Got virtual pid from coordinator") (virtualPid); dmtcp::Util::setVirtualPidEnvVar(virtualPid, getppid()); } // preloadLibs are to set LD_PRELOAD: // LD_PRELOAD=PLUGIN_LIBS:UTILITY_DIR/dmtcphijack.so:R_LIBSR_UTILITY_DIR/ dmtcp::string preloadLibs = ""; // FIXME: If the colon-separated elements of ENV_VAR_PLUGIN are not // absolute pathnames, then they must be expanded to absolute pathnames. // Warn user if an absolute pathname is not valid. if ( getenv(ENV_VAR_PLUGIN) != NULL ) { preloadLibs += getenv(ENV_VAR_PLUGIN); preloadLibs += ":"; } // FindHelperUtiltiy requires ENV_VAR_UTILITY_DIR to be set dmtcp::string searchDir = jalib::Filesystem::GetProgramDir(); setenv ( ENV_VAR_UTILITY_DIR, searchDir.c_str(), 0 ); #ifdef PTRACE preloadLibs += jalib::Filesystem::FindHelperUtility ( "ptracehijack.so" ); preloadLibs += ":"; #endif preloadLibs += jalib::Filesystem::FindHelperUtility ( "dmtcphijack.so" ); #ifdef PID_VIRTUALIZATION preloadLibs += ":"; preloadLibs += jalib::Filesystem::FindHelperUtility ( "pidvirt.so" ); #endif setenv(ENV_VAR_HIJACK_LIBS, preloadLibs.c_str(), 1); // If dmtcp_checkpoint was called with user LD_PRELOAD, and if // if dmtcp_checkpoint survived the experience, then pass it back to user. if (getenv("LD_PRELOAD")) preloadLibs = preloadLibs + ":" + getenv("LD_PRELOAD"); setenv ( "LD_PRELOAD", preloadLibs.c_str(), 1 ); JTRACE("getting value of LD_PRELOAD")(getenv("LD_PRELOAD")); //run the user program char **newArgv = NULL; if (testScreen(argv, &newArgv)) execvp ( newArgv[0], newArgv ); else execvp ( argv[0], argv ); //should be unreachable JASSERT_STDERR << "ERROR: Failed to exec(\"" << argv[0] << "\"): " << JASSERT_ERRNO << "\n" << "Perhaps it is not in your $PATH?\n" << "See `dmtcp_checkpoint --help` for usage.\n"; //fprintf(stderr, theExecFailedMsg, argv[0], JASSERT_ERRNO); return -1; }