void email_asciifile_tail( FILE* output, const char* file, int lines ) { FILE *input; int ch, last_ch; long loc; int first_line = TRUE; TAIL_QUEUE queue, *q = &queue; if( !file ) { return; } if( (input=safe_fopen_wrapper_follow(file,"r",0644)) == NULL ) { // try the .old file in the off shoot case we hit this during the transition. std::string szTmp = file; szTmp += ".old"; if( (input=safe_fopen_wrapper_follow(szTmp.c_str(),"r",0644)) == NULL ) { dprintf( D_FULLDEBUG, "Failed to email %s: cannot open file\n", file ); return; } } init_queue( q, lines ); last_ch = '\n'; while( (ch=getc(input)) != EOF ) { if( last_ch == '\n' && ch != '\n' ) { insert_queue( q, ftell(input) - 1 ); } last_ch = ch; } while( !empty_queue( q ) ) { loc = delete_queue( q ); /* If this is the first line, print header */ if ( first_line ) { first_line = FALSE; fprintf(output,"\n*** Last %d line(s) of file %s:\n", lines, file); } /* Now print the line */ display_line( loc, input, output ); } (void)fclose( input ); /* if we printed any of the file, print a footer */ if ( first_line == FALSE ) { fprintf(output,"*** End of file %s\n\n", condor_basename(file)); } }
bool JobInfoCommunicator::writeOutputAdFile( ClassAd* ad ) { if( ! job_output_ad_file ) { return false; } FILE* fp; if( job_output_ad_is_stdout ) { dprintf( D_ALWAYS, "Will write job output ClassAd to STDOUT\n" ); fp = stdout; } else { fp = safe_fopen_wrapper_follow( job_output_ad_file, "a" ); if( ! fp ) { dprintf( D_ALWAYS, "Failed to open job output ClassAd " "\"%s\": %s (errno %d)\n", job_output_ad_file, strerror(errno), errno ); return false; } else { dprintf( D_ALWAYS, "Writing job output ClassAd to \"%s\"\n", job_output_ad_file ); } } // append a delimiter? ad->fPrint( fp ); if( job_output_ad_is_stdout ) { fflush( fp ); } else { fclose( fp ); } return true; }
void Defrag::loadState() { FILE *fp; if( !(fp = safe_fopen_wrapper_follow(m_state_file.c_str(), "r")) ) { if( errno == ENOENT ) { dprintf(D_ALWAYS,"State file %s does not yet exist.\n",m_state_file.c_str()); } else { EXCEPT("failed to load state from %s\n",m_state_file.c_str()); } } else { int isEOF=0, errorReadingAd=0, adEmpty=0; ClassAd *ad = new ClassAd(fp, "...", isEOF, errorReadingAd, adEmpty); fclose( fp ); if( errorReadingAd ) { dprintf(D_ALWAYS,"WARNING: failed to parse state from %s\n",m_state_file.c_str()); } int timestamp = (int)m_last_poll; ad->LookupInteger(ATTR_LAST_POLL,timestamp); m_last_poll = (time_t)timestamp; dprintf(D_ALWAYS,"Last poll: %d\n",(int)m_last_poll); delete ad; } }
void AvailStats::checkpoint() { // Checkpoint our state to disk by serializing to a string // and writing the string to disk. It's not very efficient // to create this string each time, but it shouldn't be too big // (under 1KB), so I don't think it's worth worrying too much // about efficiency. if( ckpt_filename.Length() ) { FILE *fp = safe_fopen_wrapper_follow(tmp_ckpt_filename.Value(), "w"); if( fp ) { MyString state = serialize(); if( (int)fwrite(state.Value(), sizeof(char), state.Length(), fp) == state.Length() ) { fclose(fp); if ( rotate_file(tmp_ckpt_filename.Value(), ckpt_filename.Value()) < 0 ) { dprintf( D_ALWAYS, "AvailStats::checkpoint() failed to rotate " "%s to %s\n", tmp_ckpt_filename.Value(), ckpt_filename.Value() ); } } else { fclose(fp); } } } }
MyString MultiLogFiles::readFileToString(const MyString &strFilename) { dprintf( D_FULLDEBUG, "MultiLogFiles::readFileToString(%s)\n", strFilename.Value() ); FILE *pFile = safe_fopen_wrapper_follow(strFilename.Value(), "r"); if (!pFile) { dprintf( D_ALWAYS, "MultiLogFiles::readFileToString: " "safe_fopen_wrapper_follow(%s) failed with errno %d (%s)\n", strFilename.Value(), errno, strerror(errno) ); return ""; } if ( fseek(pFile, 0, SEEK_END) != 0 ) { dprintf( D_ALWAYS, "MultiLogFiles::readFileToString: " "fseek(%s) failed with errno %d (%s)\n", strFilename.Value(), errno, strerror(errno) ); fclose(pFile); return ""; } int iLength = ftell(pFile); if ( iLength == -1 ) { dprintf( D_ALWAYS, "MultiLogFiles::readFileToString: " "ftell(%s) failed with errno %d (%s)\n", strFilename.Value(), errno, strerror(errno) ); fclose(pFile); return ""; } MyString strToReturn; strToReturn.reserve_at_least(iLength); fseek(pFile, 0, SEEK_SET); char *psBuf = new char[iLength+1]; /* We now clear the buffer to ensure there will be a NULL at the end of our buffer after the fread(). Why no just do psBuf[iLength] = 0 ? Because on Win32, iLength may not point to the end of the buffer because \r\n are converted into \n because the file is opened in text mode. */ memset(psBuf,0,iLength+1); int ret = fread(psBuf, 1, iLength, pFile); if (ret == 0) { dprintf( D_ALWAYS, "MultiLogFiles::readFileToString: " "fread failed with errno %d (%s)\n", errno, strerror(errno) ); fclose(pFile); delete [] psBuf; return ""; } fclose(pFile); strToReturn = psBuf; delete [] psBuf; return strToReturn; }
static int set_print_mask_from_stream( AttrListPrintMask & print_mask, std::string & constraint, const char * streamid, bool is_filename) { StringList attrs; // used for projection, which we don't currently do. std::string messages; printmask_aggregation_t aggregation; printmask_headerfooter_t headFoot = STD_HEADFOOT; std::vector<GroupByKeyInfo> group_by_keys; SimpleInputStream * pstream = NULL; FILE *file = NULL; if (MATCH == strcmp("-", streamid)) { pstream = new SimpleFileInputStream(stdin, false); } else if (is_filename) { file = safe_fopen_wrapper_follow(streamid, "r"); if (file == NULL) { fprintf(stderr, "Can't open select file: %s\n", streamid); return -1; } pstream = new SimpleFileInputStream(file, true); } else { pstream = new StringLiteralInputStream(streamid); } ASSERT(pstream); int err = SetAttrListPrintMaskFromStream( *pstream, LocalPrintFormatsTable, print_mask, headFoot, aggregation, group_by_keys, constraint, attrs, messages); delete pstream; pstream = NULL; if ( ! err) { customFormat = true; if ( ! constraint.empty()) { ExprTree *constraintExpr=NULL; if ( ! ParseClassAdRvalExpr(constraint.c_str(), constraintExpr)) { formatstr_cat(messages, "WHERE expression is not valid: %s\n", constraint.c_str()); err = -1; } else { delete constraintExpr; } } if (aggregation) { formatstr_cat(messages, "AUTOCLUSTER or UNIQUE aggregation is not supported.\n"); err = -1; } } if ( ! messages.empty()) { fprintf(stderr, "%s", messages.c_str()); } return err; }
void email_corefile_tail( FILE* output, const char * subsystem_name ) { #ifdef WIN32 char *ptmp; FILE *input; int ch; long loc = -1; ptmp = param("LOG"); if ( ptmp ) { char file[MAX_PATH]; sprintf(file,"%s\\core.%s.WIN32",ptmp, subsystem_name); free(ptmp); if( (input=safe_fopen_wrapper_follow(file,"r",0644)) == NULL ) { dprintf( D_FULLDEBUG, "Failed to email %s: cannot open file\n", file ); return; } /* This is slow, but who cares. Basically, each "core" entry ** begins with a '=' character. So we scan through the file and ** find the location of the last '=' ; this is the offset where ** we will start to email. Thus we send only the most recent core. */ while( (ch=getc(input)) != EOF ) { if( ch == '=' ) { loc = ftell(input); } } /* Now send it */ if ( loc != -1 ) { fprintf(output,"*** Last entry in core file %s\n\n", condor_basename(file)); (void)fseek( input, loc, 0 ); while( (ch=getc(input)) != EOF ) { (void)putc( ch, output ); } fprintf(output,"*** End of file %s\n\n", condor_basename(file)); } (void)fclose(input); } #else // Shut the compiler up output = output; subsystem_name = subsystem_name; #endif // of ifdef WIN32 }
/* Returns a new compat_classad::ClassAd from a file */ compat_classad::ClassAd* get_classad_from_file(){ FILE* classad_file; ClassAd* classad_from_file; const char* classad_string = "A = 0.7\n B=2\n C = 3\n D = \"alain\"\n " "MyType=\"foo\"\n TargetType=\"blah\""; compat_classad::ClassAd classad; classad.initFromString(classad_string, NULL); classad_file = safe_fopen_wrapper_follow("classad_file", "w"); classad.fPrint(classad_file); fprintf(classad_file, "***\n"); fclose(classad_file); int iseof, error, empty; classad_file = safe_fopen_wrapper_follow("classad_file", "r"); classad_from_file = new ClassAd(classad_file, "***", iseof, error, empty); fclose(classad_file); return classad_from_file; }
//--------------------------------------------------------------------------- void JobstateLog::Write( const time_t *eventTimeP, const MyString &info ) { // // Here for "fake" events like JOB_SUCCESS, the event will get // the timestamp of the last "real" event from the job; this is // so that we can correctly avoid re-writing the "fake" events // in recovery mode. // time_t eventTime; if ( eventTimeP != NULL && *eventTimeP != 0 ) { eventTime = *eventTimeP; } else { eventTime = time( NULL ); } // Avoid "re-writing" events in recovery mode: // If the event time is *after* _lastTimestampWritten, we // write the event. If the event time is *before* // _lastTimestampWritten, we don't write the event. If // the times are equal, we have to do a further test down // below. if ( eventTime < _lastTimestampWritten ) { return; } MyString outline; outline.formatstr( "%lu %s", (unsigned long)eventTime, info.Value() ); // // If this event's time matches the time of the last "real" // event in the pre-recovery part of the file, we check whether // this line is already in the pre-recovery part of the file, // and if it is we don't write it again. // if ( (eventTime == _lastTimestampWritten) && (_lastTimestampLines.count( outline ) > 0) ) { return; } if ( !_outfile ) { _outfile = safe_fopen_wrapper_follow( _jobstateLogFile, "a" ); if ( !_outfile ) { debug_printf( DEBUG_QUIET, "Could not open jobstate log file %s for writing.\n", _jobstateLogFile ); main_shutdown_graceful(); return; } } fprintf( _outfile, "%s\n", outline.Value() ); }
FileOpErrCode ClassAdLogParser::openFile() { // open a job_queue.log file #ifdef _NO_CONDOR_ log_fp = fopen(job_queue_name, "r"); #else log_fp = safe_fopen_wrapper_follow(job_queue_name, "r"); #endif if (log_fp == NULL) { return FILE_OPEN_ERROR; } return FILE_OP_SUCCESS; }
float sysapi_load_avg_raw(void) { FILE *proc; struct utsname buf; int major, minor, patch; float short_avg, medium_avg, long_avg; sysapi_internal_reconfig(); // Obtain the kernel version so that we know what /proc looks like.. if( uname(&buf) < 0 ) return -1; sscanf(buf.release, "%d.%d.%d", &major, &minor, &patch); // /proc/loadavg looks like: // Kernel Version 2.0.0: // 0.03 0.03 0.09 2/42 15582 proc=safe_fopen_wrapper_follow("/proc/loadavg","r",0644); if(!proc) return -1; switch(major) { case 1: case 2: case 3: if (fscanf(proc, "%f %f %f", &short_avg, &medium_avg, &long_avg) != 3) { dprintf(D_ALWAYS, "Failed to fscanf 3 floats from /proc/loadavg\n"); fclose(proc); return -1; } break; default: dprintf(D_ALWAYS, "/proc format unknown for kernel version %d.%d.%d\n", major, minor, patch); fclose(proc); return -1; break; } fclose(proc); if( IsDebugVerbose( D_LOAD ) ) { dprintf( D_LOAD, "Load avg: %.2f %.2f %.2f\n", short_avg, medium_avg, long_avg ); } return short_avg; }
// Linux methods const char * sysapi_get_linux_info(void) { char* info_str; FILE *my_fp; const char * etc_issue_path = "/etc/issue"; // read the first line only my_fp = safe_fopen_wrapper_follow(etc_issue_path, "r"); if ( my_fp != NULL ) { char tmp_str[200] = {0}; char *ret = fgets(tmp_str, sizeof(tmp_str), my_fp); if (ret == 0) { dprintf(D_FULLDEBUG, "Result of reading /etc/issue: %s \n", ret); strcpy( tmp_str, "Unknown" ); } fclose(my_fp); // trim trailing spaces and other cruft int len = strlen(tmp_str); while (len > 0) { while (len > 0 && (isspace((int)(tmp_str[len-1])) || tmp_str[len-1] == '\n') ) { tmp_str[--len] = 0; } // Ubuntu and Debian have \n \l at the end of the issue string // this looks like a bug, in any case, we want to strip it if (len > 2 && tmp_str[len-2] == '\\' && (tmp_str[len-1] == 'n' || tmp_str[len-1] == 'l')) { tmp_str[--len] = 0; tmp_str[--len] = 0; } else { break; } } info_str = strdup( tmp_str ); } else { info_str = strdup( "Unknown" ); } if( !info_str ) { EXCEPT( "Out of memory!" ); } return info_str; }
bool write_local_settings_from_file(FILE* out_fp, const char* param_name, const char* start_mark, const char* end_mark) { char* tmp = param(param_name); if (tmp == NULL) { return true; } MyString local_settings_file = tmp; free(tmp); if (start_mark != NULL) { if (fprintf(out_fp, "%s\n", start_mark) < 0) { vmprintf(D_ALWAYS, "fprintf error writing start marker: %s\n", strerror(errno)); return false; } } FILE* in_fp = safe_fopen_wrapper_follow(local_settings_file.Value(), "r"); if (in_fp == NULL) { vmprintf(D_ALWAYS, "fopen error on %s: %s\n", local_settings_file.Value(), strerror(errno)); return false; } MyString line; while (line.readLine(in_fp)) { if (fputs(line.Value(), out_fp) == EOF) { vmprintf(D_ALWAYS, "fputs error copying local settings: %s\n", strerror(errno)); fclose(in_fp); return false; } } fclose(in_fp); if (end_mark != NULL) { if (fprintf(out_fp, "%s\n", end_mark) == EOF) { vmprintf(D_ALWAYS, "fputs error writing end marker: %s\n", strerror(errno)); return false; } } return true; }
void CheckSpoolVersion(char const *spool, int spool_min_version_i_support, int spool_cur_version_i_support, int &spool_min_version,int &spool_cur_version) { spool_min_version = 0; // before 7.5.5 there was no version stamp spool_cur_version = 0; std::string vers_fname; formatstr(vers_fname,"%s%cspool_version",spool,DIR_DELIM_CHAR); FILE *vers_file = safe_fopen_wrapper_follow(vers_fname.c_str(),"r"); if( vers_file ) { if( 1 != fscanf(vers_file, "minimum compatible spool version %d\n", &spool_min_version) ) { EXCEPT("Failed to find minimum compatible spool version in %s\n", vers_fname.c_str()); } if( 1 != fscanf(vers_file, "current spool version %d\n", &spool_cur_version) ) { EXCEPT("Failed to find current spool version in %s\n", vers_fname.c_str()); } fclose(vers_file); } dprintf(D_FULLDEBUG,"Spool format version requires >= %d (I support version %d)\n", spool_min_version, spool_cur_version_i_support); dprintf(D_FULLDEBUG,"Spool format version is %d (I require version >= %d)\n", spool_min_version, spool_min_version_i_support); if( spool_min_version > spool_cur_version_i_support ) { EXCEPT("According to %s, the SPOOL directory requires that I support spool version %d, but I only support %d.\n", vers_fname.c_str(), spool_min_version, spool_cur_version_i_support); } if( spool_cur_version < spool_min_version_i_support ) { EXCEPT("According to %s, the SPOOL directory is written in spool version %d, but I only support versions back to %d.\n", vers_fname.c_str(), spool_cur_version, spool_min_version_i_support); } }
int Condor_Diffie_Hellman :: initialize() { // First, check the config file to find out where is the file // with all the parameters config(); char * dh_config = param(DH_CONFIG_FILE); FILE * fp = 0; if ( dh_config ) { if ( (fp = safe_fopen_wrapper_follow(dh_config, "r")) == NULL) { dprintf(D_ALWAYS, "Unable to open condor_dh_config file %s\n", dh_config); goto error; } dh_ = PEM_read_DHparams(fp, NULL, NULL, NULL); if (dh_ == NULL) { dprintf(D_ALWAYS, "Unable to read DH structure from the configuration file.\n"); goto error; } // Now generate private key if (DH_generate_key(dh_) == 0) { dprintf(D_ALWAYS, "Unable to generate a private key \n"); goto error; } } else { dprintf(D_ALWAYS, "The required configuration parameter CONDOR_DH_CONFIG is not specified in the condor configuration file!\n"); goto error; } fclose(fp); free(dh_config); return 1; error: if (dh_) { DH_free(dh_); dh_ = 0; } if (dh_config) { free(dh_config); } if (fp) { fclose(fp); } return 0; }
struct chirp_client * chirp_client_connect_starter() { FILE *file; int fields; struct chirp_client *client; char *default_filename; char host[CONDOR_HOSTNAME_MAX]; char cookie[CHIRP_LINE_MAX]; MyString path; int port; int result; const char *dir; if ((default_filename = getenv("_CONDOR_CHIRP_CONFIG"))) { path.formatstr( "%s", default_filename ); } else { if (NULL == (dir = getenv("_CONDOR_SCRATCH_DIR"))) { dir = "."; } path.formatstr( "%s%c%s",dir,DIR_DELIM_CHAR,".chirp.config"); } file = safe_fopen_wrapper_follow(path.Value(),"r"); if(!file) { fprintf(stderr, "Can't open %s file\n",path.Value()); return 0; } fields = fscanf(file,"%s %d %s",host,&port,cookie); fclose(file); if(fields!=3) { errno = EINVAL; return 0; } client = chirp_client_connect(host,port); if(!client) return 0; result = chirp_client_cookie(client,cookie); if(result!=0) { DISCONNECT_AND_RETURN(client, 0); } return client; }
void AvailStats::checkpoint_filename( MyString filename ) { ckpt_filename = filename; tmp_ckpt_filename = ckpt_filename + "tmp"; FILE *fp = safe_fopen_wrapper_follow(ckpt_filename.Value(), "r"); if( fp ) { MyString state; char buf[1025]; memset(buf, 0, 1025); while( fread(buf, sizeof(char), 1024, fp) ) { state += buf; } fclose(fp); serialize(state); } }
void Defrag::saveState() { ClassAd ad; ad.Assign(ATTR_LAST_POLL,(int)m_last_poll); std::string new_state_file; sprintf(new_state_file,"%s.new",m_state_file.c_str()); FILE *fp; if( !(fp = safe_fopen_wrapper_follow(new_state_file.c_str(), "w")) ) { EXCEPT("failed to save state to %s\n",new_state_file.c_str()); } else { ad.fPrint(fp); fclose( fp ); if( rotate_file(new_state_file.c_str(),m_state_file.c_str())!=0 ) { EXCEPT("failed to save state to %s\n",m_state_file.c_str()); } } }
int VanillaProc::pidNameSpaceReaper( int status ) { TemporaryPrivSentry sentry(PRIV_ROOT); FILE *f = safe_fopen_wrapper_follow(m_pid_ns_status_filename.c_str(), "r"); if (f == NULL) { // Probably couldn't exec the wrapper. Badness dprintf(D_ALWAYS, "JobReaper: condor_pid_ns_init didn't drop filename %s (%d)\n", m_pid_ns_status_filename.c_str(), errno); EXCEPT("Starter configured to use PID NAMESPACES, but libexec/condor_pid_ns_init did not run properly"); } if (fscanf(f, "ExecFailed") > 0) { EXCEPT("Starter configured to use PID NAMESPACES, but execing the job failed"); } fseek(f, 0, SEEK_SET); if (fscanf(f, "Exited: %d", &status) > 0) { dprintf(D_FULLDEBUG, "Real job exit code of %d read from wrapper output file\n", status); } fclose(f); return status; }
int GlobusResource::ReadMonitorLogFile() { // return 0 on nothing of interest, 1 on normal exit, 2 on error exit int retval = 0; FILE *fp; char buff[1024]; if( monitorLogFile == NULL) { EXCEPT("Consistency problem for GlobusResource::ReadMonitorLogFile %s, null monitor log file name", resourceName); } fp = safe_fopen_wrapper_follow( monitorLogFile, "r" ); if ( fp == NULL ) { dprintf( D_ALWAYS, "Failed to open grid_monitor log file %s\n", monitorLogFile ); return 2; } while ( fgets( buff, sizeof(buff), fp ) != NULL ) { int error_code; if ( sscanf( buff, "%*d-%*d-%*d %*d:%*d:%*d ERROR: %d", &error_code ) == 1 ) { if ( error_code == 0 ) { retval = 1; } else { dprintf(D_ALWAYS, "grid_monitor log file for %s has error code %d\n", resourceName, error_code); retval = 2; } } } fclose( fp ); return retval; }
//--------------------------------------------------------------------------- // Here we re-read the jobstate.log file to find out what sequence number // we should start with when running a rescue DAG. void JobstateLog::InitializeRescue() { debug_printf( DEBUG_DEBUG_2, "JobstateLog::InitializeRescue()\n" ); if ( !_jobstateLogFile ) { return; } FILE *infile = safe_fopen_wrapper_follow( _jobstateLogFile, "r" ); if ( !infile ) { // This is a fatal error, because by the time we get here, // we should, at the very least, have written the // DAGMAN_STARTED "event". debug_printf( DEBUG_QUIET, "Could not open jobstate log file %s for reading.\n", _jobstateLogFile ); main_shutdown_graceful(); return; } int maxSeqNum = 0; MyString line; while ( line.readLine( infile ) ) { time_t newTimestamp; MyString nodeName; int seqNum; if ( ParseLine( line, newTimestamp, nodeName, seqNum ) ) { maxSeqNum = MAX( maxSeqNum, seqNum ); } } fclose( infile ); debug_printf( DEBUG_DEBUG_2, "Max sequence num in jobstate.log file: %d\n", maxSeqNum ); Job::SetJobstateNextSequenceNum( maxSeqNum + 1 ); }
bool UserProc::JobReaper(int pid, int status) { MyString line; MyString error_txt; MyString filename; const char* dir = Starter->GetWorkingDir(); FILE* fp; dprintf( D_FULLDEBUG, "Inside UserProc::JobReaper()\n" ); filename.sprintf("%s%c%s", dir, DIR_DELIM_CHAR, JOB_WRAPPER_FAILURE_FILE); if (0 == access(filename.Value(), F_OK)) { // The job wrapper failed, so read the contents of the file // and EXCEPT, just as is done when an executable is unable // to be run. Ideally, both failure cases would propagate // into the job ad fp = safe_fopen_wrapper_follow(filename.Value(), "r"); if (!fp) { dprintf(D_ALWAYS, "Unable to open \"%s\" for reading: " "%s (errno %d)\n", filename.Value(), strerror(errno), errno); } else { while (line.readLine(fp)) { error_txt += line; } fclose(fp); } error_txt.trim(); EXCEPT("The job wrapper failed to execute the job: %s", error_txt.Value()); } if (JobPid == pid) { m_proc_exited = true; exit_status = status; job_exit_time.getTime(); } return m_proc_exited; }
extern "C" FILE * open_debug_file(const char flags[]) { FILE *fp; int save_errno; /* Note: The log file shouldn't need to be group writeable anymore, since PRIV_CONDOR changes euid now. */ errno = 0; if( (fp=safe_fopen_wrapper_follow(debug_fn,flags,0644)) == NULL ) { save_errno = errno; if (debug_fp == 0) { debug_fp = stderr; } fprintf( debug_fp, "Can't open \"%s\" (error code: %i)\n",debug_fn, save_errno); return NULL; } return fp; }
void parseArgv( int /*argc*/, char* argv[] ) { char** tmp = argv; for( tmp++; *tmp; tmp++ ) { if( (*tmp)[0] != '-' ) { // If it doesn't start with '-', skip it continue; } switch( (*tmp)[1] ) { // // // // // // // // // // // // // // // // // Shared options that make sense to all cmds // // // // // // // // // // // // // // // // case 'v': if( strncmp("-version", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } version(); break; case 'h': if( strncmp("-help", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } usage( my_name, 0); break; case 'd': if( strncmp("-debug", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } dprintf_set_tool_debug("TOOL", 0); break; case 'a': if( cmd != CA_REQUEST_CLAIM ) { invalid( *tmp ); } if( strncmp("-address", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-address" ); } if( ! is_valid_sinful(*tmp) ) { fprintf( stderr, "%s: '%s' is not a valid address\n", my_name, *tmp ); exit( 1 ); } if (addr) { free(addr); } addr = strdup( *tmp ); break; case 'n': if( cmd != CA_REQUEST_CLAIM ) { invalid( *tmp ); } if( strncmp("-name", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-name" ); } if (name) { free(name); } name = get_daemon_name( *tmp ); if( ! name ) { fprintf( stderr, "%s: unknown host %s\n", my_name, get_host_part(*tmp) ); exit( 1 ); } break; // // // // // // // // // // // // // // // // // Switches that only make sense to some cmds // // // // // // // // // // // // // // // // case 'f': if( !((cmd == CA_RELEASE_CLAIM) || (cmd == CA_DEACTIVATE_CLAIM)) ) { invalid( *tmp ); } if( strncmp("-fast", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } vacate_type = VACATE_FAST; break; case 'r': if( !((cmd == CA_REQUEST_CLAIM) || (cmd == CA_ACTIVATE_CLAIM)) ) { invalid( *tmp ); } if( strncmp("-requirements", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-requirements" ); } if (requirements) { free(requirements); } requirements = strdup( *tmp ); break; case 'i': if( cmd == CA_REQUEST_CLAIM ) { invalid( *tmp ); } if( strncmp("-id", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-id" ); } if (claim_id) { free(claim_id); } claim_id = strdup( *tmp ); break; case 'j': if( cmd != CA_ACTIVATE_CLAIM ) { invalid( *tmp ); } if( strncmp("-jobad", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-jobad" ); } if (jobad_path) { free(jobad_path); } jobad_path = strdup( *tmp ); break; case 'k': if( cmd != CA_ACTIVATE_CLAIM ) { invalid( *tmp ); } if( strncmp("-keyword", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-keyword" ); } if (job_keyword) { free(job_keyword); } job_keyword = strdup( *tmp ); break; // // // // // // // // // // // // // // // // // // // P and C are complicated, since they are ambiguous // in the case of activate, but not others. so, they // have their own methods to make it easier to // understand what the hell's going on. :) // // // // // // // // // // // // // // // // // // case 'l': if( strncmp("-lease", *tmp, strlen(*tmp)) == 0 ) { if( cmd != CA_REQUEST_CLAIM ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-lease" ); } lease_time = atoi( *tmp ); } else { invalid( *tmp ); } break; case 't': if( strncmp("-timeout", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-timeout" ); } timeout = atoi( *tmp ); break; case 'x': if( strncmp("-x509proxy", *tmp, strlen(*tmp)) ) { invalid( *tmp ); } tmp++; if( ! (tmp && *tmp) ) { another( "-x509proxy" ); } proxy_file = *tmp; break; case 'p': parsePOpt( tmp[0], tmp[1] ); tmp++; break; case 'c': parseCOpt( tmp[0], tmp[1] ); tmp++; break; default: invalid( *tmp ); } } // Now that we're done parsing, make sure it all makes sense if( needs_id && ! claim_id ) { fprintf( stderr, "ERROR: You must specify a ClaimID with " "-id for %s\n", my_name ); usage( my_name ); } if( addr && name ) { fprintf( stderr, "ERROR: You cannot specify both -name and -address\n" ); usage( my_name ); } if( addr ) { target = addr; } else if( name ) { target = name; } else if( claim_id ) { // This is the last resort, because claim ids are // no longer considered to be the correct place to // get the startd's address. target = getAddrFromClaimId( claim_id ); } else { // local startd target = NULL; } if( cmd == CA_ACTIVATE_CLAIM && ! (job_keyword || jobad_path) ) { fprintf( stderr, "ERROR: You must specify -keyword or -jobad for %s\n", my_name ); usage( my_name ); } if (cmd == DELEGATE_GSI_CRED_STARTD && !proxy_file) { proxy_file = get_x509_proxy_filename(); if (!proxy_file) { fprintf( stderr, "\nERROR: can't determine proxy filename to delegate\n" ); exit(1); } } if( jobad_path ) { if( ! strcmp(jobad_path, "-") ) { JOBAD_PATH = stdin; } else { JOBAD_PATH = safe_fopen_wrapper_follow( jobad_path, "r" ); if( !JOBAD_PATH ) { fprintf( stderr, "ERROR: failed to open '%s': errno %d (%s)\n", jobad_path, errno, strerror(errno) ); exit( 1 ); } } } if( classad_path ) { CA_PATH = safe_fopen_wrapper_follow( classad_path, "w" ); if( !CA_PATH ) { fprintf( stderr, "ERROR: failed to open '%s': errno %d (%s)\n", classad_path, errno, strerror(errno) ); exit( 1 ); } } }
GlobusResource::ReadFileStatus GlobusResource::ReadMonitorJobStatusFile() { // return true if file successfully processed and jobs notified, // else return false. // TODO should distinguish between temporary and permanent problems. // e.g. if file is incomplete, retry after short delay FILE *fp; char buff[1024]; char contact[1024]; int status; int scan_start = 0; int scan_finish = 0; int job_count = 0; if(monitorJobStatusFile == NULL) { EXCEPT("Consistency problem for GlobusResource::ReadMonitorJobStatusFile %s, null job status file name", resourceName); } fp = safe_fopen_wrapper_follow( monitorJobStatusFile, "r" ); if ( fp == NULL ) { dprintf( D_ALWAYS, "Failed to open grid_monitor job status file %s\n", monitorJobStatusFile ); return RFS_ERROR; } if ( fgets( buff, sizeof(buff), fp ) == NULL ) { if( feof(fp) ) { dprintf( D_FULLDEBUG, "grid_monitor job status file empty (%s), treating as partial.\n", monitorJobStatusFile ); fclose( fp ); return RFS_PARTIAL; } dprintf( D_ALWAYS, "Can't read grid_monitor job status file %s\n", monitorJobStatusFile ); fclose( fp ); return RFS_ERROR; } if ( sscanf( buff, "%d %d", &scan_start, &scan_finish ) != 2 ) { dprintf( D_ALWAYS, "Failed to read scan times from grid_monitor " "status file %s\n", monitorJobStatusFile ); fclose( fp ); return RFS_ERROR; } bool found_eof = false; while ( fgets( buff, sizeof(buff), fp ) != NULL ) { contact[0] = '\0'; status = 0; const char * MAGIC_EOF = "GRIDMONEOF"; if(strncmp(buff, MAGIC_EOF, strlen(MAGIC_EOF)) == 0) { found_eof = true; break; } if ( sscanf( buff, "%s %d", contact, &status ) == 2 && *contact != '\0' && status > 0 ) { int rc; GlobusJob *job = NULL; job_count++; rc = JobsByContact.lookup( HashKey( globusJobId(contact) ), job ); if ( rc == 0 && job != NULL ) { if ( status == GLOBUS_GRAM_PROTOCOL_JOB_STATE_DONE ) { status=GLOBUS_GRAM_PROTOCOL_JOB_STATE_STAGE_OUT; } // Don't flood the log file // with a long stream of identical job status updates. // We do need to send identical job status updates to // the job so that it can track the last time we // received an update on its status. if ( status != job->globusState ) { dprintf(D_FULLDEBUG,"Sending callback of %d to %d.%d (%s)\n",status,job->procID.cluster,job->procID.proc, resourceName); } job->GramCallback( status, 0 ); } } } fclose( fp ); int limit = param_integer( "GRID_MONITOR_NO_STATUS_TIMEOUT", 15*60 ); int now = time(NULL); GlobusJob *next_job; registeredJobs.Rewind(); while ( (next_job = (GlobusJob *)registeredJobs.Next()) != NULL ) { if ( next_job->jobContact && now > next_job->lastRemoteStatusUpdate + limit ) { next_job->SetEvaluateState(); } } dprintf( D_FULLDEBUG, "Read %s grid_monitor status file for %s: " "scan start=%d, scan finish=%d, job count=%d\n", found_eof ? "full" : "partial", resourceName, scan_start, scan_finish, job_count ); if(found_eof) return RFS_OK; return RFS_PARTIAL; }
ClassAd* readJobAd( void ) { ClassAd* ad = NULL; bool is_stdin = false; bool read_something = false; ASSERT( job_ad_file ); if( job_ad_file[0] == '-' && job_ad_file[1] == '\0' ) { fp = stdin; is_stdin = true; } else { if (fp == NULL) { fp = safe_fopen_wrapper_follow( job_ad_file, "r" ); if( ! fp ) { EXCEPT( "Failed to open ClassAd file (%s): %s (errno %d)", job_ad_file, strerror(errno), errno ); } } } dprintf( D_FULLDEBUG, "Reading job ClassAd from %s\n", is_stdin ? "STDIN" : job_ad_file ); ad = new ClassAd; MyString line; while( line.readLine(fp) ) { read_something = true; line.chomp(); if( line[0] == '#' ) { dprintf( D_JOB, "IGNORING COMMENT: %s\n", line.Value() ); continue; } if( line == "***" ) { dprintf( D_JOB, "Saw ClassAd delimitor, stopping\n" ); break; } if( ! ad->Insert(line.Value()) ) { EXCEPT( "Failed to insert \"%s\" into ClassAd!", line.Value() ); } } if( ! read_something ) { EXCEPT( "reading ClassAd from (%s): file is empty", is_stdin ? "STDIN" : job_ad_file ); } if( IsDebugVerbose(D_JOB) ) { ad->dPrint( D_JOB ); } // For debugging, see if there's a special attribute in the // job ad that sends us into an infinite loop, waiting for // someone to attach with a debugger int shadow_should_wait = 0; ad->LookupInteger( ATTR_SHADOW_WAIT_FOR_DEBUG, shadow_should_wait ); if( shadow_should_wait ) { dprintf( D_ALWAYS, "Job requested shadow should wait for " "debugger with %s=%d, going into infinite loop\n", ATTR_SHADOW_WAIT_FOR_DEBUG, shadow_should_wait ); while( shadow_should_wait ) { } } return ad; }
void check_recovery_file( const char *execute_dir ) { MyString recovery_file; FILE *recovery_fp = NULL; ClassAd *recovery_ad = NULL; if ( execute_dir == NULL ) { return; } recovery_file.formatstr( "%s.recover", execute_dir ); StatInfo si( recovery_file.Value() ); if ( si.Error() ) { if ( si.Error() != SINoFile ) { if (unlink(recovery_file.Value()) < 0) { dprintf( D_FULLDEBUG, "check_recovery_file: Failed to remove file '%s'\n", recovery_file.Value() ); } } return; } // TODO: check file ownership? recovery_fp = safe_fopen_wrapper_follow( recovery_file.Value(), "r" ); if ( recovery_fp == NULL ) { if (unlink(recovery_file.Value()) < 0) { dprintf( D_FULLDEBUG, "check_recovery_file: Failed to remove file '%s'\n", recovery_file.Value() ); } return; } int eof = 0; int error = 0; int empty = 0; recovery_ad = new ClassAd( recovery_fp, "***", eof, error, empty ); if ( error || empty ) { fclose( recovery_fp ); if (unlink(recovery_file.Value()) < 0) { dprintf( D_FULLDEBUG, "check_recovery_file: Failed to remove file '%s'\n", recovery_file.Value() ); } return; } int universe = 0; recovery_ad->LookupInteger( ATTR_JOB_UNIVERSE, universe ); if ( universe == CONDOR_UNIVERSE_VM ) { MyString vm_id; recovery_ad->LookupString( "JobVMId", vm_id ); if ( !vm_id.IsEmpty() ) { resmgr->m_vmuniverse_mgr.killVM( vm_id.Value() ); } } delete recovery_ad; fclose( recovery_fp ); if (unlink(recovery_file.Value()) < 0) { dprintf( D_FULLDEBUG, "check_recovery_file: Failed to remove file '%s'\n", recovery_file.Value() ); } }
int main( int argc, char *argv[] ) { int i; char *log_file_name = 0; char *job_name = 0; time_t waittime=0, stoptime=0; int minjobs = 0; int print_status = false; int echo_events = false; int debug_print_rescue = false; myDistro->Init( argc, argv ); config(); for( i=1; i<argc; i++ ) { if(!strcmp(argv[i],"-help")) { usage(argv[0]); EXIT_SUCCESS; } else if(!strcmp(argv[i],"-version")) { version(); EXIT_FAILURE; } else if(!strcmp(argv[i],"-debug")) { // dprintf to console dprintf_set_tool_debug("TOOL", 0); print_status = false; } else if(!strcmp(argv[i],"-status")) { if (dprintf_to_term_check()) { fprintf(stderr,"-status is implied by -debug\n"); } else { print_status = true; } } else if(!strcmp(argv[i],"-echo")) { echo_events = true; } else if(!strcmp(argv[i],"-wait")) { i++; if(i>=argc) { fprintf(stderr,"-wait requires an argument\n"); usage(argv[0]); EXIT_FAILURE; } waittime = atoi(argv[i]); stoptime = time(0) + waittime; dprintf(D_FULLDEBUG,"Will wait until %s\n",ctime(&stoptime)); } else if( !strcmp( argv[i], "-num" ) ) { i++; if( i >= argc ) { fprintf( stderr, "-num requires an argument\n" ); usage( argv[0] ); EXIT_FAILURE; } minjobs = atoi( argv[i] ); if( minjobs < 1 ) { fprintf( stderr, "-num must be greater than zero\n" ); usage( argv[0] ); EXIT_FAILURE; } dprintf( D_FULLDEBUG, "Will wait until %d jobs end\n", minjobs ); } else if(argv[i][0]!='-') { if(!log_file_name) { log_file_name = argv[i]; } else if(!job_name) { job_name = argv[i]; } else { fprintf(stderr,"Extra argument: %s\n\n",argv[i]); usage(argv[0]); EXIT_FAILURE; } } else { usage(argv[0]); EXIT_FAILURE; } } if( !log_file_name ) { usage(argv[0]); EXIT_FAILURE; } int cluster=ANY_NUMBER; int process=ANY_NUMBER; int subproc=ANY_NUMBER; if( job_name ) { int fields = sscanf(job_name,"%d.%d.%d",&cluster,&process,&subproc); if(fields>=1 && fields<=3) { /* number is fine */ } else { fprintf(stderr,"Couldn't understand job number: %s\n",job_name); EXIT_FAILURE; } } dprintf(D_FULLDEBUG,"Reading log file %s\n",log_file_name); int submitted, aborted, completed, flagged; FILE *sec_fp = NULL; int pos, nPos; rescue : submitted=0; aborted=0; completed=0; flagged = 0; ReadUserLog log ; HashTable<MyString,MyString> table(127,MyStringHash); if(log.initialize(log_file_name,false,false,true)) { sec_fp = safe_fopen_wrapper_follow(log_file_name, "r", 0644); fseek (sec_fp, 0, SEEK_END); pos = ftell(sec_fp); nPos = pos; if (debug_print_rescue) printf("begin:%d ", nPos); while(1) { fseek(sec_fp, 0, SEEK_END); int tmp_pos = ftell(sec_fp); ULogEventOutcome outcome; ULogEvent *event; outcome = log.readEvent(event); if(outcome==ULOG_OK) { flagged = 0; pos = nPos = tmp_pos; if (debug_print_rescue) printf("top:%d ", nPos); char key[1024]; sprintf(key,"%d.%d.%d",event->cluster,event->proc,event->subproc); MyString str(key); if( jobnum_matches( event, cluster, process, subproc ) ) { if (echo_events) { event->putEvent(stdout); printf("...\n"); } if(event->eventNumber==ULOG_SUBMIT) { dprintf(D_FULLDEBUG,"%s submitted\n",key); if (print_status) printf("%s submitted\n", key); table.insert(str,str); submitted++; } else if(event->eventNumber==ULOG_JOB_TERMINATED) { dprintf(D_FULLDEBUG,"%s completed\n",key); if (print_status) printf("%s completed\n", key); table.remove(str); completed++; } else if(event->eventNumber==ULOG_JOB_ABORTED) { dprintf(D_FULLDEBUG,"%s aborted\n",key); if (print_status) printf("%s aborted\n", key); table.remove(str); aborted++; } else if (event->eventNumber==ULOG_EXECUTE) { if (print_status) { printf("%s executing on host %s\n", key, ((ExecuteEvent*)event)->getExecuteHost()); } } else { /* nothing to do */ } } if (event != NULL) delete event; if( minjobs && (completed + aborted >= minjobs ) ) { printf( "Specifed number of jobs (%d) done.\n", minjobs ); EXIT_SUCCESS; } } else { // did something change in the file since our last visit? fseek(sec_fp, 0, SEEK_END); nPos = ftell(sec_fp); if (flagged == 1) { fclose(sec_fp); dprintf(D_FULLDEBUG, "INFO: File %s changed but userLog reader could not read another event. We are reinitializing userLog reader. \n", log_file_name); if (debug_print_rescue) printf("rescue:%d ", nPos); if (print_status) printf("<reinitializing userLog reader>\n"); // reinitialize the user log, we ended up here a second time goto rescue; } if ( nPos != pos ){ if (debug_print_rescue) printf("lagging:%d!=%d ", nPos, pos); pos = nPos; // we do not want to retry every time we are in a waiting sleep cycle, therefore flag a change flagged = 1; } dprintf(D_FULLDEBUG,"%d submitted %d completed %d aborted %d remaining\n",submitted,completed,aborted,submitted-completed-aborted); if(table.getNumElements()==0) { if(submitted>0) { if( !minjobs ) { printf("All jobs done.\n"); EXIT_SUCCESS; } } else { if(cluster==ANY_NUMBER) { fprintf(stderr,"This log does not mention any jobs!\n"); } else { fprintf(stderr,"This log does not mention that job!\n"); } EXIT_FAILURE; } } else if(stoptime && time(0)>stoptime) { printf("Time expired.\n"); EXIT_FAILURE; } else { time_t sleeptime; if(stoptime) { sleeptime = stoptime-time(0); } else { sleeptime = 5; } if(sleeptime>5) { sleeptime = 5; } else if(sleeptime<1) { sleeptime = 1; } log.synchronize(); dprintf(D_FULLDEBUG,"No more events, sleeping for %ld seconds\n", (long)sleeptime); sleep(sleeptime); } } } fclose(sec_fp); } else { fprintf(stderr,"Couldn't open %s: %s\n",log_file_name,strerror(errno)); } EXIT_FAILURE; return 1; /* meaningless, but it makes Windows happy */ }
/* Safely creates an empty file */ void create_empty_file(const char *file) { FILE *f = NULL; cut_assert_not_null( f = safe_fopen_wrapper_follow(file, "w+") ); cut_assert_z( fclose(f) ); }
int check_sub_file(void* /*pv*/, SubmitHash * sub, _submit_file_role role, const char * pathname, int flags) { if (role == SFR_LOG) { if ( !DumpClassAdToFile && !DashDryRun ) { // check that the log is a valid path if ( !DisableFileChecks ) { FILE* test = safe_fopen_wrapper_follow(pathname, "a+", 0664); if (!test) { fprintf(stderr, "\nERROR: Invalid log file: \"%s\" (%s)\n", pathname, strerror(errno)); return 1; } else { fclose(test); } } // Check that the log file isn't on NFS bool nfs_is_error = param_boolean("LOG_ON_NFS_IS_ERROR", false); bool nfs = false; if ( nfs_is_error ) { if ( fs_detect_nfs( pathname, &nfs ) != 0 ) { fprintf(stderr, "\nWARNING: Can't determine whether log file %s is on NFS\n", pathname ); } else if ( nfs ) { fprintf(stderr, "\nERROR: Log file %s is on NFS.\nThis could cause" " log file corruption. Condor has been configured to" " prohibit log files on NFS.\n", pathname ); return 1; } } } return 0; } else if (role == SFR_EXECUTABLE || role == SFR_PSEUDO_EXECUTABLE) { const char * ename = pathname; bool transfer_it = (flags & 1) != 0; LastExecutable = ename; SpoolLastExecutable = false; // ensure the executables exist and spool them only if no // $$(arch).$$(opsys) are specified (note that if we are simply // dumping the class-ad to a file, we won't actually transfer // or do anything [nothing that follows will affect the ad]) if ( transfer_it && !DumpClassAdToFile && !strstr(ename,"$$") ) { StatInfo si(ename); if ( SINoFile == si.Error () ) { fprintf ( stderr, "\nERROR: Executable file %s does not exist\n", ename ); return 1; // abort } if (!si.Error() && (si.GetFileSize() == 0)) { fprintf( stderr, "\nERROR: Executable file %s has zero length\n", ename ); return 1; // abort } if (role == SFR_EXECUTABLE) { bool param_exists; SpoolLastExecutable = sub->submit_param_bool( SUBMIT_KEY_CopyToSpool, "CopyToSpool", false, ¶m_exists ); if ( ! param_exists) { if ( submit_hash.getUniverse() == CONDOR_UNIVERSE_STANDARD ) { // Standard universe jobs can't restore from a checkpoint // if the executable changes. Therefore, it is deemed // too risky to have copy_to_spool=false by default // for standard universe. SpoolLastExecutable = true; } else { // In so many cases, copy_to_spool=true would just add // needless overhead. Therefore, (as of 6.9.3), the // default is false. SpoolLastExecutable = false; } } } } return 0; } // Queue files for testing access if not already queued int junk; if( flags & O_WRONLY ) { if ( CheckFilesWrite.lookup(pathname,junk) < 0 ) { // this file not found in our list; add it CheckFilesWrite.insert(pathname,junk); } } else { if ( CheckFilesRead.lookup(pathname,junk) < 0 ) { // this file not found in our list; add it CheckFilesRead.insert(pathname,junk); } } return 0; // of the check is ok, nonzero to abort }