/* some pretty lame, but useful test code */ int main(int argc, char **argv) { WindowsFirewallHelper wfh; int result; bool isOn; const char* app; result = 0; dprintf_set_tool_debug("TOOL", 0); isOn = wfh.firewallIsOn(); printf("firewall is %s.\n", (isOn) ? "On" : "Off"); if ( argc <= 1 ) { app = "C:\\Condor\\bin\\condor_master.exe"; } else { app = argv[1]; } isOn = wfh.applicationIsTrusted(app); printf("%s is %s by the firewall.\n", app, (isOn) ? "Trusted" : "Not Trusted"); wfh.removeTrusted(app); // wfh.addTrusted(app); if ( ! SUCCEEDED(wfh.addTrusted("C:\\Condor\\bin\\condor_master.exe")) ) { printf("first addTrusted() failed\n"); result = 1; } if ( ! SUCCEEDED(wfh.addTrusted("C:\\Condor\\condor_master.exe")) ) { printf("second addTrusted() failed\n"); result = 1; } HRESULT hr = wfh.removeTrusted("C:\\Condor\\bin\\condor_master.exe"); if (FAILED(hr)) { printf("first removeTrusted() failed 0x%08x\n", hr); result = 1; } hr = wfh.removeTrusted("C:\\Condor\\bin\\condor_master.exe"); if (FAILED(hr)) { printf("second removeTrusted() failed 0x%08x\n", hr); result = 1; } printf("tests are done!\n"); return result; }
int main() { dprintf_set_tool_debug("TOOL", 0); LocalClient* client = new LocalClient; ASSERT(client != NULL); if (!client->initialize(PIPE_ADDR)) { EXCEPT("unable to initialize LocalClient"); } while (true) { char c1, c2; cin >> c1; if (!cin) { if (!cin.eof()) { cout << "error in input stream" << endl; } break; } if (!client->start_connection(&c1, sizeof(char))) { EXCEPT("error in LocalClient::start_connection"); } if (!client->read_data(&c2, sizeof(char))) { EXCEPT("error in LocalClient::read_data"); } client->end_connection(); cout << "received " << c2 << endl; if (c2 == 'q') { break; } } return 0; }
/*ARGSUSED*/ int main(int argc, char *argv[] ) { char *tmp = NULL; int reserved_swap, free_swap; char *host = NULL, *cluster = NULL, *proc = NULL; char *bogus_capability; int i; set_mySubSystem( "SHADOW", SUBSYSTEM_TYPE_SHADOW ); myDistro->Init( argc, argv ); if( argc == 2 && strncasecmp(argv[1], "-cl", 3) == MATCH ) { printClassAd(); exit( 0 ); } #if defined(SYSCALL_DEBUG) SyscallLabel = argv[0] + 7; #endif #if !defined(WIN32) install_sig_handler(SIGPIPE, (SIG_HANDLER)SIG_IGN ); #endif if( argc > 1 ) { if( strcmp("-t",argv[1]) == MATCH ) { Termlog = 1; argv++; argc--; } } ShadowBDate = LastRestartTime = time(0); _EXCEPT_Cleanup = ExceptCleanup; MyPid = getpid(); config(); /* Start up with condor.condor privileges. */ /* we need to do this AFTER we call config() so that if CONDOR_IDS is being defined in the config file, we'll get the right value */ set_condor_priv(); if(Termlog) dprintf_set_tool_debug(get_mySubSystem()->getName(), 0); else dprintf_config( get_mySubSystem()->getName() ); DebugId = whoami; // create a database connection object dprintf( D_ALWAYS, "******* Standard Shadow starting up *******\n" ); dprintf( D_ALWAYS, "** %s\n", CondorVersion() ); dprintf( D_ALWAYS, "** %s\n", CondorPlatform() ); dprintf( D_ALWAYS, "*******************************************\n" ); reserved_swap = param_integer("RESERVED_SWAP", 0); reserved_swap *= 1024; /* megabytes -> kb */ bool use_sql_log = param_boolean("QUILL_USE_SQL_LOG", false); FILEObj = FILESQL::createInstance(use_sql_log); free_swap = sysapi_swap_space(); dprintf( D_FULLDEBUG, "*** Reserved Swap = %d\n", reserved_swap ); dprintf( D_FULLDEBUG, "*** Free Swap = %d\n", free_swap ); if( reserved_swap && free_swap < reserved_swap ) { dprintf( D_ALWAYS, "Not enough reserved swap space\n" ); if(FILEObj) { delete FILEObj; } exit( JOB_NO_MEM ); } dprintf(D_ALWAYS, "uid=%d, euid=%d, gid=%d, egid=%d\n", getuid(), geteuid(), getgid(), getegid()); dprintf(D_FULLDEBUG, "argc = %d\n", argc); for(i = 0; i < argc; i++) { dprintf(D_FULLDEBUG, "argv[%d] = %s\n", i, argv[i]); } if( argc < 6 ) { usage(); } if (param_boolean("SHADOW_DEBUG_WAIT", false, false)) { int debug_wait = 1; dprintf(D_ALWAYS, "SHADOW_DEBUG_WAIT is TRUE, waiting for debugger to attach to pid %d.\n", (int)::getpid()); while (debug_wait) { sleep(1); } } CheckSpoolVersion(SPOOL_MIN_VERSION_SHADOW_SUPPORTS,SPOOL_CUR_VERSION_SHADOW_SUPPORTS); if( strcmp("-pipe",argv[1]) == 0 ) { bogus_capability = argv[2]; cluster = argv[3]; proc = argv[4]; // read the big comment in the function for why this is here. RemoveNewShadowDroppings(cluster, proc); pipe_setup( cluster, proc, bogus_capability ); } else { schedd = argv[1]; host = argv[2]; bogus_capability = argv[3]; cluster = argv[4]; proc = argv[5]; if ( argc > 6 ) { IpcFile = argv[6]; dprintf(D_FULLDEBUG,"Setting IpcFile to %s\n",IpcFile); } else { IpcFile = NULL; } // read the big comment in the function for why this is here. RemoveNewShadowDroppings(cluster, proc); regular_setup( host, cluster, proc ); } scheddName = getenv( EnvGetName( ENV_SCHEDD_NAME ) ); #if 0 /* Don't want to share log file lock between child and pnarent */ (void)close( LockFd ); LockFd = -1; #endif // initialize the user log initializeUserLog(); My_Filesystem_Domain = param( "FILESYSTEM_DOMAIN" ); dprintf( D_ALWAYS, "My_Filesystem_Domain = \"%s\"\n", My_Filesystem_Domain ); My_UID_Domain = param( "UID_DOMAIN" ); dprintf( D_ALWAYS, "My_UID_Domain = \"%s\"\n", My_UID_Domain ); UseAFS = param_boolean_crufty( "USE_AFS", false ) ? TRUE : FALSE; UseNFS = param_boolean_crufty( "USE_NFS", false ) ? TRUE : FALSE; // if job specifies a checkpoint server host, this overrides // the config file parameters tmp = NULL; if (JobAd->LookupString(ATTR_CKPT_SERVER, &tmp) == 1) { if (CkptServerHost) free(CkptServerHost); UseCkptServer = TRUE; CkptServerHost = strdup(tmp); StarterChoosesCkptServer = FALSE; free(tmp); } else { free(tmp); if (CkptServerHost) { free(CkptServerHost); } CkptServerHost = param( "CKPT_SERVER_HOST" ); UseCkptServer = FALSE; if( CkptServerHost && param_boolean_crufty( "USE_CKPT_SERVER", true ) ) { UseCkptServer = TRUE; } StarterChoosesCkptServer = param_boolean_crufty("STARTER_CHOOSES_CKPT_SERVER", true) ? TRUE : FALSE; } // Initialize location of our checkpoint file. If we stored it // on a checkpoint server then set LastCkptServer. Otherwise, // LastCkptServer should be NULL to indicate that we should // look on the local disk for our checkpoint file. LastCkptServer = NULL; if (JobAd->LookupString(ATTR_LAST_CKPT_SERVER, &LastCkptServer) == 0) { free(LastCkptServer); LastCkptServer = NULL; } // LIGO if (param_boolean("ALWAYS_USE_LOCAL_CKPT_SERVER", false)) { if (LastCkptServer) { char *remoteHost = NULL; JobAd->LookupString(ATTR_REMOTE_HOST, &remoteHost); char *machineName = strrchr(remoteHost, '@'); if (machineName == NULL) { machineName = remoteHost; } else { machineName++; } LastCkptServer = strdup(machineName); CkptServerHost = strdup(machineName); dprintf(D_ALWAYS, "ALWAYS_USE_LOCAL_CKPT_SERVER is true, forcing LastCkptServer to %s\n", LastCkptServer); } else { dprintf(D_ALWAYS, "ALWAYS_USE_LOCAL_CKPT_SERVER is true, but checkpoint is not on server, restoring file local file\n"); } } MaxDiscardedRunTime = param_integer( "MAX_DISCARDED_RUN_TIME", 3600 ); CompressPeriodicCkpt = param_boolean( "COMPRESS_PERIODIC_CKPT", false ); PeriodicSync = param_boolean( "PERIODIC_MEMORY_SYNC", false ); CompressVacateCkpt = param_boolean( "COMPRESS_VACATE_CKPT", false ); SlowCkptSpeed = param_integer( "SLOW_CKPT_SPEED", 0 ); // Install signal handlers such that all signals are blocked when inside // the handler. sigset_t fullset; sigfillset(&fullset); install_sig_handler_with_mask( SIGCHLD,&fullset, reaper ); // SIGUSR1 is sent by the schedd when a job is removed with // condor_rm. install_sig_handler_with_mask( SIGUSR1, &fullset, handle_sigusr1 ); // SIGQUIT is sent for a fast shutdow. install_sig_handler_with_mask( SIGQUIT, &fullset, handle_sigquit ); // SIGTERM is sent for a graceful shutdow. install_sig_handler_with_mask( SIGTERM, &fullset, handle_sigterm ); /* Here we block the async signals. We do this mainly because on HPUX, * XDR wigs out if it is interrupted by a signal. We do it on all * platforms because it seems like a safe idea. We unblock the signals * during before select(), which is where we spend most of our time. */ block_signal(SIGCHLD); block_signal(SIGUSR1); /* If the completed job had been committed to the job queue, but for some reason the shadow exited wierdly and the schedd is trying to run it again, then simply write the job termination events and send the email as if the job had just ended. */ if (terminate_is_pending() == TRUE) { /* This function will exit()! */ handle_terminate_pending(); } HandleSyscalls(); Wrapup(); /* HACK! WHOOO!!!!! Throw the old shadow away already! */ /* This will figure out whether or not the job should go on hold AFTER the job has exited for whatever reason, or if the job should be allowed to exit. It modifies ExitReason approriately for job holding, or, get this, just EXCEPTs if the jobs is supposed to go into idle state and not leave. :) */ /* Small change by Todd : only check the static policy if the job really exited of its own accord -- we don't want to even evaluate the static policy if the job exited because it was preempted, for instance */ if (check_static_policy && (ExitReason == JOB_EXITED || ExitReason == JOB_KILLED || ExitReason == JOB_COREDUMPED)) { static_policy(); } if( My_UID_Domain ) { free( My_UID_Domain ); } if( My_Filesystem_Domain ) { free( My_Filesystem_Domain ); } if(FILEObj) { delete FILEObj; } dprintf( D_ALWAYS, "********** Shadow Exiting(%d) **********\n", ExitReason ); exit( ExitReason ); }
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 */ }
int main(int argc, char *argv[]) { has_proc = false; MyString constraint; Qmgr_connection *q; int nextarg = 1, cluster=0, proc=0; bool UseConstraint = false; MyString schedd_name; MyString pool_name; ExprTree* value_expr; myDistro->Init( argc, argv ); config(); #if !defined(WIN32) install_sig_handler(SIGPIPE, SIG_IGN ); #endif if (argc < 2) { usage(argv[0]); } // if -debug is present, it must be first. sigh. if (argv[nextarg][0] == '-' && argv[nextarg][1] == 'd') { // output dprintf messages to stderror at TOOL_DEBUG level dprintf_set_tool_debug("TOOL", 0); nextarg++; } // if it is present, it must be first after debug. if (argv[nextarg][0] == '-' && argv[nextarg][1] == 'n') { nextarg++; // use the given name as the schedd name to connect to if (argc <= nextarg) { fprintf(stderr, "%s: -n requires another argument\n", argv[0]); exit(1); } schedd_name = argv[nextarg]; nextarg++; } if (argc <= nextarg) { usage(argv[0]); } // if it is present, it must be just after -n flag if (argv[nextarg][0] == '-' && argv[nextarg][1] == 'p') { nextarg++; if (argc <= nextarg) { fprintf(stderr, "%s: -pool requires another argument\n", argv[0]); exit(1); } pool_name = argv[nextarg]; nextarg++; } DCSchedd schedd((schedd_name.Length() == 0) ? NULL : schedd_name.Value(), (pool_name.Length() == 0) ? NULL : pool_name.Value()); if ( schedd.locate() == false ) { if (schedd_name == "") { fprintf( stderr, "%s: ERROR: Can't find address of local schedd\n", argv[0] ); exit(1); } if (pool_name == "") { fprintf( stderr, "%s: No such schedd named %s in local pool\n", argv[0], schedd_name.Value() ); } else { fprintf( stderr, "%s: No such schedd named %s in " "pool %s\n", argv[0], schedd_name.Value(), pool_name.Value() ); } exit(1); } // Open job queue q = ConnectQ( schedd.addr(), 0, false, NULL, NULL, schedd.version() ); if( !q ) { fprintf( stderr, "Failed to connect to queue manager %s\n", schedd.addr() ); exit(1); } if (argc <= nextarg) { usage(argv[0]); } if (isdigit(argv[nextarg][0])) { char *tmp; cluster = strtol(argv[nextarg], &tmp, 10); if (cluster <= 0) { fprintf( stderr, "Invalid cluster # from %s.\n", argv[nextarg]); exit(1); } if (*tmp == '.') { proc = strtol(tmp + 1, &tmp, 10); if (cluster <= 0) { fprintf( stderr, "Invalid proc # from %s.\n", argv[nextarg]); exit(1); } UseConstraint = false; has_proc = true; } else { constraint.formatstr("(%s == %d)", ATTR_CLUSTER_ID, cluster); UseConstraint = true; } nextarg++; } else if (!match_prefix(argv[nextarg], "-constraint")) { constraint.formatstr("(%s == \"%s\")", ATTR_OWNER, argv[nextarg]); nextarg++; UseConstraint = true; } if (argc <= nextarg) { usage(argv[0]); } while (match_prefix(argv[nextarg], "-constraint")) { if ( has_proc ){ fprintf(stderr, "condor_qedit: proc_id specified. Ignoring constraint option\n"); nextarg+=2; continue; } nextarg++; if (argc <= nextarg) { usage(argv[0]); } if ( !UseConstraint ){ constraint = argv[nextarg]; } else{ constraint = "( " + constraint + " ) && " + argv[nextarg]; } nextarg++; UseConstraint = true; } if (argc <= nextarg) { usage(argv[0]); } for (; nextarg < argc; nextarg += 2) { if (argc <= nextarg+1) { usage(argv[0]); } if (ProtectedAttribute(argv[nextarg])) { fprintf(stderr, "Update of attribute \"%s\" is not allowed.\n", argv[nextarg]); fprintf(stderr, "Transaction failed. No attributes were set.\n"); exit(1); } // Check validity of attribute-name if ( blankline(argv[nextarg]) || !IsValidAttrName(argv[nextarg]) ) { fprintf(stderr, "Update aborted, illegal attribute-name specified for attribute \"%s\".\n", argv[nextarg]); fprintf(stderr, "Transaction failed. No attributes were set.\n"); exit(1); } // Check validity of attribute-value value_expr = NULL; if ( blankline(argv[nextarg+1]) || !IsValidAttrValue(argv[nextarg+1]) || ParseClassAdRvalExpr(argv[nextarg+1], value_expr) ) { fprintf(stderr, "Update aborted, illegal attribute-value specified for attribute \"%s\".\n", argv[nextarg]); fprintf(stderr, "Transaction failed. No attributes were set.\n"); exit(1); } if (value_expr) delete value_expr; if (UseConstraint) { // Try to communicate with the newer protocol first if (SetAttributeByConstraint(constraint.Value(), argv[nextarg], argv[nextarg+1], SETDIRTY) < 0) { if (SetAttributeByConstraint(constraint.Value(), argv[nextarg], argv[nextarg+1]) < 0) { fprintf(stderr, "Failed to set attribute \"%s\" by constraint: %s\n", argv[nextarg], constraint.Value()); fprintf(stderr, "Transaction failed. No attributes were set.\n"); exit(1); } } } else { if (SetAttribute(cluster, proc, argv[nextarg], argv[nextarg+1], SETDIRTY) < 0) { fprintf(stderr, "Failed to set attribute \"%s\" for job %d.%d.\n", argv[nextarg], cluster, proc); fprintf(stderr, "Transaction failed. No attributes were set.\n"); exit(1); } } printf("Set attribute \"%s\".\n", argv[nextarg]); } if (!DisconnectQ(q)) { fprintf(stderr, "Queue transaction failed. No attributes were set.\n"); exit(1); } return 0; }
int main(int argc, char **argv) { int result = 0; if ( argc <= 1 || (argc >= 2 && !strcmp("-usage", argv[1])) ) { printf("Usage: condor_check_userlogs <log file 1> " "[log file 2] ... [log file n]\n"); exit(0); } // Set up dprintf. dprintf_set_tool_debug("condor_check_userlogs", 0); set_debug_flags(NULL, D_ALWAYS); StringList logFiles; for ( int argnum = 1; argnum < argc; ++argnum ) { logFiles.append(argv[argnum]); } logFiles.rewind(); ReadMultipleUserLogs ru; char *filename; while ( (filename = logFiles.next()) ) { MyString filestring( filename ); CondorError errstack; if ( !ru.monitorLogFile( filestring, false, errstack ) ) { fprintf( stderr, "Error monitoring log file %s: %s\n", filename, errstack.getFullText().c_str() ); result = 1; } } bool logsMissing = false; CheckEvents ce; int totalSubmitted = 0; int netSubmitted = 0; bool done = false; while( !done ) { ULogEvent* e = NULL; MyString errorMsg; ULogEventOutcome outcome = ru.readEvent( e ); switch (outcome) { case ULOG_RD_ERROR: case ULOG_UNK_ERROR: logsMissing = true; case ULOG_NO_EVENT: printf( "Log outcome: %s\n", ULogEventOutcomeNames[outcome] ); done = true; break; case ULOG_OK: printf( "Log event: %s (%d.%d.%d)", ULogEventNumberNames[e->eventNumber], e->cluster, e->proc, e->subproc ); if ( ce.CheckAnEvent(e, errorMsg) != CheckEvents::EVENT_OKAY ) { fprintf(stderr, "%s\n", errorMsg.Value()); result = 1; } if( e->eventNumber == ULOG_SUBMIT ) { SubmitEvent* ee = (SubmitEvent*) e; printf( " (\"%s\")", ee->submitEventLogNotes ); ++totalSubmitted; ++netSubmitted; printf( "\n Total submitted: %d; net submitted: %d\n", totalSubmitted, netSubmitted ); } if( e->eventNumber == ULOG_JOB_HELD ) { JobHeldEvent* ee = (JobHeldEvent*) e; printf( " (code=%d subcode=%d)", ee->getReasonCode(), ee->getReasonSubCode()); } if( e->eventNumber == ULOG_JOB_TERMINATED ) { --netSubmitted; printf( "\n Total submitted: %d; net submitted: %d\n", totalSubmitted, netSubmitted ); } if( e->eventNumber == ULOG_JOB_ABORTED ) { --netSubmitted; printf( "\n Total submitted: %d; net submitted: %d\n", totalSubmitted, netSubmitted ); } if( e->eventNumber == ULOG_EXECUTABLE_ERROR ) { --netSubmitted; printf( "\n Total submitted: %d; net submitted: %d\n", totalSubmitted, netSubmitted ); } printf( "\n" ); break; default: fprintf(stderr, "Unexpected read event outcome!\n"); result = 1; break; } } logFiles.rewind(); while ( (filename = logFiles.next()) ) { MyString filestring( filename ); CondorError errstack; if ( !ru.unmonitorLogFile( filestring, errstack ) ) { fprintf( stderr, "Error unmonitoring log file %s: %s\n", filename, errstack.getFullText().c_str() ); result = 1; } } MyString errorMsg; CheckEvents::check_event_result_t checkAllResult = ce.CheckAllJobs(errorMsg); if ( checkAllResult != CheckEvents::EVENT_OKAY ) { fprintf(stderr, "%s\n", errorMsg.Value()); fprintf(stderr, "CheckAllJobs() result: %s\n", CheckEvents::ResultToString(checkAllResult)); result = 1; } if ( result == 0 ) { if ( !logsMissing ) { printf("Log(s) are okay\n"); } else { printf("Log(s) may be okay\n"); printf( "Some logs cannot be read\n"); } } else { printf("Log(s) have error(s)\n"); } return result; }
int main( int argc, char *argv[] ) { char *arg; char **args = (char **)malloc(sizeof(char *)*(argc - 1)); // args int nArgs = 0; // number of args int i; char* cmd_str; DCCollector* pool = NULL; char* scheddName = NULL; char* scheddAddr = NULL; // Initialize our global variables has_constraint = false; myDistro->Init( argc, argv ); MyName = strrchr( argv[0], DIR_DELIM_CHAR ); if( !MyName ) { MyName = argv[0]; } else { MyName++; } cmd_str = strchr( MyName, '_'); // we match modes based on characters after the '_'. This means // 'condor_hold.exe' or 'condor_hold_wrapped' are all legal argv[0]'s // for condor_hold. if (cmd_str && strncasecmp( cmd_str, "_hold", strlen("_hold") ) == MATCH) { mode = JA_HOLD_JOBS; } else if ( cmd_str && strncasecmp( cmd_str, "_release", strlen("_release") ) == MATCH ) { mode = JA_RELEASE_JOBS; } else if ( cmd_str && strncasecmp( cmd_str, "_suspend", strlen("_suspend") ) == MATCH ) { mode = JA_SUSPEND_JOBS; } else if ( cmd_str && strncasecmp( cmd_str, "_continue", strlen("_continue") ) == MATCH ) { mode = JA_CONTINUE_JOBS; }else if ( cmd_str && strncasecmp( cmd_str, "_rm", strlen("_rm") ) == MATCH ) { mode = JA_REMOVE_JOBS; } else if( cmd_str && ! strncasecmp(cmd_str, "_vacate_job", strlen("_vacate_job")) ) { mode = JA_VACATE_JOBS; } else { // don't know what mode we're using, so bail. fprintf( stderr, "Unrecognized command name, \"%s\"\n", MyName ); usage(); } config(); if( argc < 2 ) { // We got no indication of what to act on fprintf( stderr, "You did not specify any jobs\n" ); usage(); } #if !defined(WIN32) install_sig_handler(SIGPIPE, SIG_IGN ); #endif for( argv++; (arg = *argv); argv++ ) { if( arg[0] == '-' ) { if (match_prefix(arg, "-debug")) { // dprintf to console dprintf_set_tool_debug("TOOL", 0); } else if (match_prefix(arg, "-constraint")) { args[nArgs] = arg; nArgs++; argv++; if( ! *argv ) { fprintf( stderr, "%s: -constraint requires another argument\n", MyName); exit(1); } args[nArgs] = *argv; nArgs++; ConstraintArg = true; } else if (match_prefix(arg, "-all")) { All = true; } else if (match_prefix(arg, "-addr")) { argv++; if( ! *argv ) { fprintf( stderr, "%s: -addr requires another argument\n", MyName); exit(1); } if( is_valid_sinful(*argv) ) { scheddAddr = strdup(*argv); if( ! scheddAddr ) { fprintf( stderr, "Out of memory!\n" ); exit(1); } } else { fprintf( stderr, "%s: \"%s\" is not a valid address\n", MyName, *argv ); fprintf( stderr, "Should be of the form " "<ip.address.here:port>\n" ); fprintf( stderr, "For example: <123.456.789.123:6789>\n" ); exit( 1 ); } } else if (match_prefix(arg, "-reason")) { argv++; if( ! *argv ) { fprintf( stderr, "%s: -reason requires another argument\n", MyName); exit(1); } actionReason = strdup(*argv); if( ! actionReason ) { fprintf( stderr, "Out of memory!\n" ); exit(1); } } else if (match_prefix(arg, "-subcode")) { argv++; if( ! *argv ) { fprintf( stderr, "%s: -subcode requires another argument\n", MyName); exit(1); } char *end = NULL; long code = strtol(*argv,&end,10); if( code == LONG_MIN || !end || *end || end==*argv ) { fprintf( stderr, "Invalid -subcode %s!\n", *argv ); exit(1); } holdReasonSubCode = strdup(*argv); ASSERT( holdReasonSubCode ); } else if (match_prefix(arg, "-forcex")) { if( mode == JA_REMOVE_JOBS ) { mode = JA_REMOVE_X_JOBS; } else { fprintf( stderr, "-forcex is only valid with condor_rm\n" ); usage(); } } else if (match_prefix(arg, "-fast")) { if( mode == JA_VACATE_JOBS ) { mode = JA_VACATE_FAST_JOBS; } else { fprintf( stderr, "-fast is only valid with condor_vacate_job\n" ); usage(); } } else if (match_prefix(arg, "-name")) { // use the given name as the schedd name to connect to argv++; if( ! *argv ) { fprintf( stderr, "%s: -name requires another argument\n", MyName); exit(1); } if( !(scheddName = get_daemon_name(*argv)) ) { fprintf( stderr, "%s: unknown host %s\n", MyName, get_host_part(*argv) ); exit(1); } } else if (match_prefix(arg, "-pool")) { // use the given name as the central manager to query argv++; if( ! *argv ) { fprintf( stderr, "%s: -pool requires another argument\n", MyName); exit(1); } if( pool ) { delete pool; } pool = new DCCollector( *argv ); if( ! pool->addr() ) { fprintf( stderr, "%s: %s\n", MyName, pool->error() ); exit(1); } } else if (match_prefix(arg, "-version")) { version(); } else if (match_prefix(arg, "-help")) { usage(0); } else { fprintf( stderr, "Unrecognized option: %s\n", arg ); usage(); } } else { if( All ) { // If -all is set, there should be no other // constraint arguments. usage(); } args[nArgs] = arg; nArgs++; UserJobIdArg = true; } } if( ! (All || nArgs) ) { // We got no indication of what to act on fprintf( stderr, "You did not specify any jobs\n" ); usage(); } if ( ConstraintArg && UserJobIdArg ) { fprintf( stderr, "You can't use both -constraint and usernames or job ids\n" ); usage(); } // Pick the default reason if the user didn't specify one if( actionReason == NULL ) { switch( mode ) { case JA_RELEASE_JOBS: actionReason = strdup("via condor_release"); break; case JA_REMOVE_X_JOBS: actionReason = strdup("via condor_rm -forcex"); break; case JA_REMOVE_JOBS: actionReason = strdup("via condor_rm"); break; case JA_HOLD_JOBS: actionReason = strdup("via condor_hold"); break; case JA_SUSPEND_JOBS: actionReason = strdup("via condor_suspend"); break; case JA_CONTINUE_JOBS: actionReason = strdup("via condor_continue"); break; default: actionReason = NULL; } } // We're done parsing args, now make sure we know how to // contact the schedd. if( ! scheddAddr ) { // This will always do the right thing, even if either or // both of scheddName or pool are NULL. schedd = new DCSchedd( scheddName, pool ? pool->addr() : NULL ); } else { schedd = new DCSchedd( scheddAddr ); } if( ! schedd->locate() ) { fprintf( stderr, "%s: %s\n", MyName, schedd->error() ); exit( 1 ); } // Special case for condor_rm -forcex: a configuration // setting can disable this functionality. The real // validation is done in the schedd, but we can catch // the most common cases here and give a useful error // message. if(mode == JA_REMOVE_X_JOBS) { if( mayUserForceRm() == false) { fprintf( stderr, "Remove aborted. condor_rm -forcex has been disabled by the administrator.\n" ); exit( 1 ); } } // Process the args so we do the work. if( All ) { handleAll(); } else { for(i = 0; i < nArgs; i++) { if( match_prefix( args[i], "-constraint" ) ) { i++; addConstraint( args[i] ); } else { procArg(args[i]); } } } // Deal with all the -constraint constraints handleConstraints(); // Finally, do the actual work for all our args which weren't // constraints... if( job_ids ) { CondorError errstack; ClassAd* result_ad = doWorkByList( job_ids, &errstack ); if (had_error) { fprintf( stderr, "%s\n", errstack.getFullText(true).c_str() ); } printNewMessages( result_ad, job_ids ); delete( result_ad ); } // If releasing jobs, and no errors happened, do a // reschedule command now. if ( mode == JA_RELEASE_JOBS && had_error == false ) { Daemon my_schedd(DT_SCHEDD, NULL, NULL); CondorError errstack; if (!my_schedd.sendCommand(RESCHEDULE, Stream::safe_sock, 0, &errstack)) { fprintf( stderr, "%s\n", errstack.getFullText(true).c_str() ); } } return had_error; }
int main(int argc, char **argv) { // Set up the dprintf stuff... dprintf_set_tool_debug("test_check_events", 0); set_debug_flags(NULL, D_ALWAYS); bool result = true; Status tmpStatus = CheckArgs(argc, argv); if ( tmpStatus == STATUS_CANCEL ) { return 0; } else if ( tmpStatus == STATUS_ERROR ) { return 1; } //------------------------------------------------------------------------- printf("\n### Testing various error conditions (multiple " "submits, etc.)\n\n"); CheckEvents ce1; MyString errorMsg; // Test a submit event. SubmitEvent se1; se1.cluster = 1234; se1.proc = 0; se1.subproc = 0; CheckThisEvent(__LINE__, ce1, &se1, CheckEvents::EVENT_OKAY, result); // Re-do the same submit event -- this should generate an error. CheckThisEvent(__LINE__, ce1, &se1, CheckEvents::EVENT_ERROR, result); // Test a submit event for a new job. SubmitEvent se2; se2.cluster = 1234; se2.proc = 1; se2.subproc = 0; CheckThisEvent(__LINE__, ce1, &se2, CheckEvents::EVENT_OKAY, result); // Test a terminate event. This should no longer fail because // of better support for "write at least once" semantics. JobTerminatedEvent te1; te1.cluster = 1234; te1.proc = 0; te1.subproc = 0; CheckThisEvent(__LINE__, ce1, &te1, CheckEvents::EVENT_OKAY, result); // Test a job aborted event. JobAbortedEvent ae2; ae2.cluster = 1234; ae2.proc = 1; ae2.subproc = 0; CheckThisEvent(__LINE__, ce1, &ae2, CheckEvents::EVENT_OKAY, result); // Test an execute event. This should fail because we already // got an aborted event for this job. ExecuteEvent exec; exec.cluster = 1234; exec.proc = 1; exec.subproc = 0; CheckThisEvent(__LINE__, ce1, &exec, CheckEvents::EVENT_ERROR, result); // Test an execute event. This should fail because we haven't // gotten a submit event for this job. exec.cluster = 1234; exec.proc = 5; exec.subproc = 0; CheckThisEvent(__LINE__, ce1, &exec, CheckEvents::EVENT_ERROR, result); // Test a terminate event. This should fail because we already // got an aborted event for this job. JobTerminatedEvent te2; te2.cluster = 1234; te2.proc = 1; te2.subproc = 0; CheckThisEvent(__LINE__, ce1, &te2, CheckEvents::EVENT_ERROR, result); // Test a job aborted event. This should fail because we // don't have a submit event for this job yet. JobAbortedEvent ae3; ae3.cluster = 1236; ae3.proc = 0; ae3.subproc = 0; CheckThisEvent(__LINE__, ce1, &ae3, CheckEvents::EVENT_ERROR, result); // Test a submit event for the job that just aborted. This // should fail because we got the abort before the submit. SubmitEvent se3; se3.cluster = 1236; se3.proc = 0; se3.subproc = 0; CheckThisEvent(__LINE__, ce1, &se3, CheckEvents::EVENT_ERROR, result); printf("\nTesting CheckAllJobs()... "); CheckEvents::check_event_result_t tmpResult = ce1.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_ERROR, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing good events\n\n"); // Make a new CheckEvents object where we only insert "correct" // events... CheckEvents ce2; CheckThisEvent(__LINE__, ce2, &se1, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce2, &se2, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce2, &te1, CheckEvents::EVENT_OKAY, result); // This should fail because the second job doesn't have a terminate // or abort event. printf("Testing CheckAllJobs()... "); tmpResult = ce2.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_ERROR, tmpResult, errorMsg, result); ExecutableErrorEvent ee2; ee2.cluster = 1234; ee2.proc = 1; ee2.subproc = 0; CheckThisEvent(__LINE__, ce2, &ee2, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce2, &ae2, CheckEvents::EVENT_OKAY, result); PostScriptTerminatedEvent pt1; // Note: special "no submit" ID. pt1.cluster = -1; pt1.proc = 0; pt1.subproc = 0; CheckThisEvent(__LINE__, ce2, &pt1, CheckEvents::EVENT_OKAY, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce2.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_OKAY, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing allowing \"extra\" abort events\n\n"); // Make a new CheckEvents object that allows extra abort events // (apparently Condor sometimes generates a terminate and an abort // event). CheckEvents ce3(CheckEvents::ALLOW_TERM_ABORT); SubmitEvent se4; se4.cluster = 9876; se4.proc = 5; se4.subproc = 0; CheckThisEvent(__LINE__, ce3, &se4, CheckEvents::EVENT_OKAY, result); ExecuteEvent exec2; exec2.cluster = 9876; exec2.proc = 5; exec2.subproc = 0; CheckThisEvent(__LINE__, ce3, &exec2, CheckEvents::EVENT_OKAY, result); JobTerminatedEvent te3; te3.cluster = 9876; te3.proc = 5; te3.subproc = 0; CheckThisEvent(__LINE__, ce3, &te3, CheckEvents::EVENT_OKAY, result); JobAbortedEvent ae4; ae4.cluster = 9876; ae4.proc = 5; ae4.subproc = 0; CheckThisEvent(__LINE__, ce3, &ae4, CheckEvents::EVENT_BAD_EVENT, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce3.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_BAD_EVENT, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing that we catch \"extra\" abort events if we don't " "explicitly allow them\n\n"); CheckEvents ce4; CheckThisEvent(__LINE__, ce4, &se4, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce4, &exec2, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce4, &te3, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce4, &ae4, CheckEvents::EVENT_ERROR, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce4.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_ERROR, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing allowing multiple runs\n\n"); CheckEvents ce5(CheckEvents::ALLOW_RUN_AFTER_TERM); CheckThisEvent(__LINE__, ce5, &se4, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce5, &exec2, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce5, &te3, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce5, &exec2, CheckEvents::EVENT_BAD_EVENT, result); CheckThisEvent(__LINE__, ce5, &te3, CheckEvents::EVENT_BAD_EVENT, result); printf("\nTesting CheckAllJobs()... "); // Note that here we're no longer explicitly allowing "run after // terminate", but this check doesn't fail because we don't know // whether any of the terminates came before the executes. ce5.SetAllowEvents(CheckEvents::ALLOW_DOUBLE_TERMINATE); tmpResult = ce5.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_BAD_EVENT, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing that we catch multiple runs if we don't " "explicitly allow them\n\n"); CheckEvents ce6; CheckThisEvent(__LINE__, ce6, &se4, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce6, &exec2, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce6, &te3, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce6, &exec2, CheckEvents::EVENT_ERROR, result); CheckThisEvent(__LINE__, ce6, &te3, CheckEvents::EVENT_ERROR, result); CheckThisEvent(__LINE__, ce6, &pt1, CheckEvents::EVENT_OKAY, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce6.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_ERROR, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing allowing garbage\n\n"); CheckEvents ce7(CheckEvents::ALLOW_GARBAGE); SubmitEvent se5; se4.cluster = 1000; se4.proc = 0; se4.subproc = 0; CheckThisEvent(__LINE__, ce7, &se5, CheckEvents::EVENT_OKAY, result); ExecuteEvent exec3; exec3.cluster = 2000; // Note different from submit event! exec3.proc = 0; exec3.subproc = 0; CheckThisEvent(__LINE__, ce7, &exec3, CheckEvents::EVENT_WARNING, result); JobTerminatedEvent te4; te4.cluster = 3000; te4.proc = 0; te4.subproc = 0; CheckThisEvent(__LINE__, ce7, &te4, CheckEvents::EVENT_WARNING, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce7.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_BAD_EVENT, tmpResult, errorMsg, result); CheckThisEvent(__LINE__, ce7, &te4, CheckEvents::EVENT_ERROR, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce7.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_ERROR, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing allowing almost all bad events\n\n"); CheckEvents ce8(CheckEvents::ALLOW_ALMOST_ALL); ExecuteEvent exec8; exec8.cluster = 1234; exec8.proc = 0; exec8.subproc = 0; CheckThisEvent(__LINE__, ce8, &exec8, CheckEvents::EVENT_WARNING, result); CheckThisEvent(__LINE__, ce8, &se1, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce8, &te1, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce8, &se1, CheckEvents::EVENT_BAD_EVENT, result); // ALLOW_ALMOST_ALL should *not* allow execute after terminate. CheckThisEvent(__LINE__, ce8, &exec8, CheckEvents::EVENT_ERROR, result); CheckThisEvent(__LINE__, ce8, &te1, CheckEvents::EVENT_BAD_EVENT, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce8.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_BAD_EVENT, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing allowing execute before submit\n\n"); CheckEvents ce9(CheckEvents::ALLOW_EXEC_BEFORE_SUBMIT); ExecuteEvent exec9; exec9.cluster = 1234; exec9.proc = 0; exec9.subproc = 0; CheckThisEvent(__LINE__, ce9, &exec9, CheckEvents::EVENT_WARNING, result); CheckThisEvent(__LINE__, ce9, &se1, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce9, &te1, CheckEvents::EVENT_OKAY, result); // This should return OKAY because at this point we don't // remember that the execute came before the submit. printf("\nTesting CheckAllJobs()... "); tmpResult = ce9.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_OKAY, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing allowing double-terminate\n\n"); CheckEvents ce10(CheckEvents::ALLOW_DOUBLE_TERMINATE); CheckThisEvent(__LINE__, ce10, &se1, CheckEvents::EVENT_OKAY, result); ExecuteEvent exec10; exec10.cluster = 1234; exec10.proc = 0; exec10.subproc = 0; CheckThisEvent(__LINE__, ce10, &exec10, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce10, &te1, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce10, &te1, CheckEvents::EVENT_BAD_EVENT, result); PostScriptTerminatedEvent pt10; pt10.cluster = 1234; pt10.proc = 0; pt10.subproc = 0; CheckThisEvent(__LINE__, ce10, &pt10, CheckEvents::EVENT_OKAY, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce10.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_BAD_EVENT, tmpResult, errorMsg, result); CheckThisEvent(__LINE__, ce10, &se2, CheckEvents::EVENT_OKAY, result); exec10.proc = 1; CheckThisEvent(__LINE__, ce10, &exec10, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce10, &te2, CheckEvents::EVENT_OKAY, result); // Terminate then execute should still be an error. CheckThisEvent(__LINE__, ce10, &exec10, CheckEvents::EVENT_ERROR, result); CheckThisEvent(__LINE__, ce10, &te2, CheckEvents::EVENT_BAD_EVENT, result); // We get bad event here instead of error because we don't // "remember" that an execute event came after a terminated event. printf("\nTesting CheckAllJobs()... "); tmpResult = ce10.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_BAD_EVENT, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing running POST scripts after submit failures\n\n"); CheckEvents ce11; PostScriptTerminatedEvent pt2; // ID of POST script terminated event is -1.0.0 if all submit // attempts of the node job failed. pt2.cluster = -1; pt2.proc = 0; pt2.subproc = 0; CheckThisEvent(__LINE__, ce11, &pt2, CheckEvents::EVENT_OKAY, result); // This is okay because we specifically allow duplicates with the // special "submit attempts failed" ID. CheckThisEvent(__LINE__, ce11, &pt2, CheckEvents::EVENT_OKAY, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce11.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_OKAY, tmpResult, errorMsg, result); // Make sure we flag multiple post script terminates for a *real* // job as errors... SubmitEvent se11; se11.cluster = 1234; se11.proc = 0; se11.subproc = 0; CheckThisEvent(__LINE__, ce11, &se11, CheckEvents::EVENT_OKAY, result); JobTerminatedEvent te11; te11.cluster = 1234; te11.proc = 0; te11.subproc = 0; CheckThisEvent(__LINE__, ce11, &te11, CheckEvents::EVENT_OKAY, result); pt2.cluster = 1234; pt2.proc = 0; pt2.subproc = 0; CheckThisEvent(__LINE__, ce11, &pt2, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce11, &pt2, CheckEvents::EVENT_ERROR, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce11.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_ERROR, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing terminate after post script terminate\n\n"); CheckEvents ce12; SubmitEvent se12; se12.cluster = 1234; se12.proc = 1; se12.subproc = 0; CheckThisEvent(__LINE__, ce12, &se12, CheckEvents::EVENT_OKAY, result); ExecuteEvent exec12; exec12.cluster = 1234; exec12.proc = 1; exec12.subproc = 0; CheckThisEvent(__LINE__, ce12, &exec12, CheckEvents::EVENT_OKAY, result); PostScriptTerminatedEvent pt12; pt12.cluster = 1234; pt12.proc = 1; pt12.subproc = 0; CheckThisEvent(__LINE__, ce12, &pt12, CheckEvents::EVENT_ERROR, result); JobTerminatedEvent te12; te12.cluster = 1234; te12.proc = 1; te12.subproc = 0; CheckThisEvent(__LINE__, ce12, &te12, CheckEvents::EVENT_ERROR, result); //------------------------------------------------------------------------- printf("\n### Testing parallel universe\n\n"); CheckEvents ce13; SubmitEvent se13; se13.cluster = 101176; se13.proc = 0; se13.subproc = 0; CheckThisEvent(__LINE__, ce13, &se13, CheckEvents::EVENT_OKAY, result); NodeExecuteEvent ne13; ne13.cluster = 101176; ne13.proc = 0; ne13.subproc = 0; CheckThisEvent(__LINE__, ce13, &ne13, CheckEvents::EVENT_OKAY, result); ne13.subproc = 1; CheckThisEvent(__LINE__, ce13, &ne13, CheckEvents::EVENT_OKAY, result); ExecuteEvent exec13; exec13.cluster = 101176; exec13.proc = 0; exec13.subproc = 0; CheckThisEvent(__LINE__, ce13, &exec13, CheckEvents::EVENT_OKAY, result); NodeExecuteEvent nt13; nt13.cluster = 101176; nt13.proc = 0; nt13.subproc = 0; CheckThisEvent(__LINE__, ce13, &nt13, CheckEvents::EVENT_OKAY, result); nt13.subproc = 1; CheckThisEvent(__LINE__, ce13, &nt13, CheckEvents::EVENT_OKAY, result); JobTerminatedEvent te13; te13.cluster = 101176; te13.proc = 0; te13.subproc = 0; CheckThisEvent(__LINE__, ce13, &te13, CheckEvents::EVENT_OKAY, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce13.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_OKAY, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing allowing duplicate events\n\n"); CheckEvents ce14(CheckEvents::ALLOW_DUPLICATE_EVENTS); SubmitEvent se14; se14.cluster = 123; se14.proc = 0; se14.subproc = 0; CheckThisEvent(__LINE__, ce14, &se14, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce14, &se14, CheckEvents::EVENT_BAD_EVENT, result); ExecuteEvent exec14; exec14.cluster = 123; exec14.proc = 0; exec14.subproc = 0; CheckThisEvent(__LINE__, ce14, &exec14, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce14, &exec14, CheckEvents::EVENT_OKAY, result); JobTerminatedEvent te14; te14.cluster = 123; te14.proc = 0; te14.subproc = 0; CheckThisEvent(__LINE__, ce14, &te14, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce14, &te14, CheckEvents::EVENT_BAD_EVENT, result); PostScriptTerminatedEvent pt14; pt14.cluster = 123; pt14.proc = 0; pt14.subproc = 0; CheckThisEvent(__LINE__, ce14, &pt14, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce14, &pt14, CheckEvents::EVENT_BAD_EVENT, result); CheckThisEvent(__LINE__, ce14, &te14, CheckEvents::EVENT_BAD_EVENT, result); //~~~~~~~~~~~~~~~~~~~~~ se14.cluster = 124; CheckThisEvent(__LINE__, ce14, &se14, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce14, &se14, CheckEvents::EVENT_BAD_EVENT, result); exec14.cluster = 124; CheckThisEvent(__LINE__, ce14, &exec14, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce14, &exec14, CheckEvents::EVENT_OKAY, result); JobAbortedEvent ae14; ae14.cluster = 124; ae14.proc = 0; ae14.subproc = 0; CheckThisEvent(__LINE__, ce14, &ae14, CheckEvents::EVENT_OKAY, result); CheckThisEvent(__LINE__, ce14, &ae14, CheckEvents::EVENT_BAD_EVENT, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce14.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_BAD_EVENT, tmpResult, errorMsg, result); //------------------------------------------------------------------------- printf("\n### Testing allowing terminated before submit\n\n"); CheckEvents ce15(CheckEvents::ALLOW_EXEC_BEFORE_SUBMIT); ExecuteEvent exec15; exec15.cluster = 123; exec15.proc = 0; exec15.subproc = 0; CheckThisEvent(__LINE__, ce15, &exec15, CheckEvents::EVENT_WARNING, result); JobTerminatedEvent te15; te15.cluster = 123; te15.proc = 0; te15.subproc = 0; CheckThisEvent(__LINE__, ce15, &te15, CheckEvents::EVENT_WARNING, result); SubmitEvent se15; se15.cluster = 123; se15.proc = 0; se15.subproc = 0; CheckThisEvent(__LINE__, ce15, &se15, CheckEvents::EVENT_BAD_EVENT, result); printf("\nTesting CheckAllJobs()... "); tmpResult = ce15.CheckAllJobs(errorMsg); CheckResult(__LINE__, CheckEvents::EVENT_OKAY, tmpResult, errorMsg, result); //------------------------------------------------------------------------- if ( result ) { printf("\nTest SUCCCEEDED\n"); return 0; } else { printf("\nTest FAILED!!!!!!!!!!!!!!!!!!!!!!!!!\n"); return 1; } }
bool HTCondorPeek::parse_args(int argc, char *argv[]) { std::string job_id; myDistro->Init( argc, argv ); config(); for (int i=1; i<argc; i++) { if (!strcmp(argv[i],"-help")) { usage(argv[0]); exit(0); } else if (!strcmp(argv[i],"-pool")) { i++; if(i==argc || !argv[i]) { fprintf(stderr,"-pool requires an argument.\n\n"); usage(argv[0]); exit(1); } m_pool = argv[i]; } else if (!strcmp(argv[i],"-name")) { i++; if (i==argc || !argv[i]) { fprintf(stderr,"-name requires an argument.\n\n"); usage(argv[0]); exit(1); } m_name = argv[i]; } else if (!strcmp(argv[i],"-maxbytes")) { i++; if(i==argc || !argv[i] || *argv[i] == '-') { fprintf(stderr,"-maxbytes requires an argument.\n\n"); usage(argv[0]); exit(1); } if ( ! parse_integer<size_t>(argv[i], m_max_bytes)) { fprintf(stderr, "Error: maxbytes (%s) is not valid\n\n", argv[i]); usage(argv[0]); exit(1); } } else if(!strcmp(argv[i],"-version")) { version(); exit(0); } else if(!strcmp(argv[i],"-debug")) { dprintf_set_tool_debug("TOOL", 0); } else if(!strcmp(argv[i],"-no-stdout")) { m_transfer_stdout = false; } else if(!strcmp(argv[i],"-stderr")) { m_transfer_stderr = true; } else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "-follow")) { m_follow = true; } else if (!strcmp(argv[i], "-auto-retry")) { m_auto_retry = true; } else if(!job_id.size()) { job_id = argv[i]; } else { m_filenames.push_back(argv[i]); m_offsets.push_back(-1); } } if( !m_transfer_stdout && !m_transfer_stderr && !m_filenames.size() ) { fprintf(stderr,"No file transfer specified.\n\n"); usage(argv[0]); exit(1); } if (!job_id.size()) { std::cerr << "Job ID not specified." << std::endl; usage(argv[0]); exit(1); } m_id = getProcByString(job_id.c_str()); if (m_id.cluster == -1) { std::cerr << "Invalid Job ID: " << job_id << std::endl; usage(argv[0]); exit(1); } return true; }
int main(int argc, char* argv[]) { Collectors = NULL; #ifdef HAVE_EXT_POSTGRESQL HistorySnapshot *historySnapshot; SQLQuery queryhor; SQLQuery queryver; QuillErrCode st; bool remotequill=false; char *quillName=NULL; AttrList *ad=0; int flag = 1; void **parameters; char *dbconn=NULL; char *completedsince = NULL; char *dbIpAddr=NULL, *dbName=NULL,*queryPassword=NULL; bool remoteread = false; #endif /* HAVE_EXT_POSTGRESQL */ const char *owner=NULL; bool readfromfile = true; bool fileisuserlog = false; char* JobHistoryFileName=NULL; const char * pcolon=NULL; GenericQuery constraint; // used to build a complex constraint. ExprTree *constraintExpr=NULL; std::string tmp; int i; myDistro->Init( argc, argv ); config(); #ifdef HAVE_EXT_POSTGRESQL parameters = (void **) malloc(NUM_PARAMETERS * sizeof(void *)); queryhor.setQuery(HISTORY_ALL_HOR, NULL); queryver.setQuery(HISTORY_ALL_VER, NULL); #endif /* HAVE_EXT_POSTGRESQL */ for(i=1; i<argc; i++) { if (is_dash_arg_prefix(argv[i],"long",1)) { longformat=TRUE; } else if (is_dash_arg_prefix(argv[i],"xml",3)) { use_xml = true; longformat = true; } else if (is_dash_arg_prefix(argv[i],"backwards",1)) { backwards=TRUE; } // must be at least -forw to avoid conflict with -f (for file) and -format else if (is_dash_arg_prefix(argv[i],"nobackwards",3) || is_dash_arg_prefix(argv[i],"forwards",4)) { backwards=FALSE; } else if (is_dash_arg_colon_prefix(argv[i],"wide", &pcolon, 1)) { wide_format=TRUE; if (pcolon) { wide_format_width = atoi(++pcolon); if ( ! mask.IsEmpty()) mask.SetOverallWidth(getDisplayWidth()-1); if (wide_format_width <= 80) wide_format = FALSE; } } else if (is_dash_arg_prefix(argv[i],"match",1) || is_dash_arg_prefix(argv[i],"limit",3)) { i++; if (argc <= i) { fprintf(stderr, "Error: Argument -match requires a number value " " as a parameter.\n"); exit(1); } specifiedMatch = atoi(argv[i]); } #ifdef HAVE_EXT_POSTGRESQL else if(is_dash_arg_prefix(argv[i], "dbname",1)) { i++; if (argc <= i) { fprintf( stderr, "Error: Argument -dbname requires the name of a quilld as a parameter\n" ); exit(1); } /* if( !(quillName = get_daemon_name(argv[i])) ) { fprintf( stderr, "Error: unknown host %s\n", get_host_part(argv[i]) ); printf("\n"); print_wrapped_text("Extra Info: The name given with the -dbname " "should be the name of a condor_quilld process. " "Normally it is either a hostname, or " "\"name@hostname\". " "In either case, the hostname should be the " "Internet host name, but it appears that it " "wasn't.", stderr); exit(1); } sprintf (tmp, "%s == \"%s\"", ATTR_NAME, quillName); quillQuery.addORConstraint (tmp); */ quillName = argv[i]; sprintf (tmp, "%s == \"%s\"", ATTR_SCHEDD_NAME, quillName); quillQuery.addORConstraint (tmp.c_str()); remotequill = false; readfromfile = false; } #endif /* HAVE_EXT_POSTGRESQL */ else if (is_dash_arg_prefix(argv[i],"file",2)) { if (i+1==argc || JobHistoryFileName) break; i++; JobHistoryFileName=argv[i]; readfromfile = true; } else if (is_dash_arg_prefix(argv[i],"userlog",1)) { if (i+1==argc || JobHistoryFileName) break; i++; JobHistoryFileName=argv[i]; readfromfile = true; fileisuserlog = true; } else if (is_dash_arg_prefix(argv[i],"help",1)) { Usage(argv[0],0); } else if (is_dash_arg_prefix(argv[i],"format",1)) { if (argc <= i + 2) { fprintf(stderr, "Error: Argument -format requires a spec and " "classad attribute name as parameters.\n"); fprintf(stderr, "\t\te.g. condor_history -format '%%d' ClusterId\n"); exit(1); } mask.registerFormat(argv[i + 1], argv[i + 2]); customFormat = true; i += 2; } else if (*(argv[i]) == '-' && (is_arg_colon_prefix(argv[i]+1,"af", &pcolon, 2) || is_arg_colon_prefix(argv[i]+1,"autoformat", &pcolon, 5))) { // make sure we have at least one argument to autoformat if (argc <= i+1 || *(argv[i+1]) == '-') { fprintf (stderr, "Error: Argument %s requires at last one attribute parameter\n", argv[i]); fprintf(stderr, "\t\te.g. condor_history %s ClusterId\n", argv[i]); exit(1); } if (pcolon) ++pcolon; // if there are options, skip over the colon to the options. int ixNext = parse_autoformat_args(argc, argv, i+1, pcolon, mask, diagnostic); if (ixNext > i) i = ixNext-1; customFormat = true; } else if (is_dash_arg_colon_prefix(argv[i], "print-format", &pcolon, 2)) { if ( (argc <= i+1) || (*(argv[i+1]) == '-' && (argv[i+1])[1] != 0)) { fprintf( stderr, "Error: Argument -print-format requires a filename argument\n"); exit( 1 ); } // hack allow -pr ! to disable use of user-default print format files. if (MATCH == strcmp(argv[i+1], "!")) { ++i; disable_user_print_files = true; continue; } if ( ! wide_format) mask.SetOverallWidth(getDisplayWidth()-1); customFormat = true; ++i; std::string where_expr; if (set_print_mask_from_stream(mask, where_expr, argv[i], true) < 0) { fprintf(stderr, "Error: cannot execute print-format file %s\n", argv[i]); exit (1); } if ( ! where_expr.empty()) { constraint.addCustomAND(where_expr.c_str()); } } else if (is_dash_arg_prefix(argv[i],"constraint",1)) { // make sure we have at least one more argument if (argc <= i+1) { fprintf( stderr, "Error: Argument %s requires another parameter\n", argv[i]); exit(1); } i++; constraint.addCustomAND(argv[i]); } #ifdef HAVE_EXT_POSTGRESQL else if (is_dash_arg_prefix(argv[i],"completedsince",3)) { i++; if (argc <= i) { fprintf(stderr, "Error: Argument -completedsince requires a date and " "optional timestamp as a parameter.\n"); fprintf(stderr, "\t\te.g. condor_history -completedsince \"2004-10-19 10:23:54\"\n"); exit(1); } if (constraint!="") break; completedsince = strdup(argv[i]); parameters[0] = completedsince; queryhor.setQuery(HISTORY_COMPLETEDSINCE_HOR,parameters); queryver.setQuery(HISTORY_COMPLETEDSINCE_VER,parameters); } #endif /* HAVE_EXT_POSTGRESQL */ else if (sscanf (argv[i], "%d.%d", &cluster, &proc) == 2) { std::string jobconst; formatstr (jobconst, "%s == %d && %s == %d", ATTR_CLUSTER_ID, cluster,ATTR_PROC_ID, proc); constraint.addCustomOR(jobconst.c_str()); #ifdef HAVE_EXT_POSTGRESQL parameters[0] = &cluster; parameters[1] = &proc; queryhor.setQuery(HISTORY_CLUSTER_PROC_HOR, parameters); queryver.setQuery(HISTORY_CLUSTER_PROC_VER, parameters); #endif /* HAVE_EXT_POSTGRESQL */ } else if (sscanf (argv[i], "%d", &cluster) == 1) { std::string jobconst; formatstr (jobconst, "%s == %d", ATTR_CLUSTER_ID, cluster); constraint.addCustomOR(jobconst.c_str()); #ifdef HAVE_EXT_POSTGRESQL parameters[0] = &cluster; queryhor.setQuery(HISTORY_CLUSTER_HOR, parameters); queryver.setQuery(HISTORY_CLUSTER_VER, parameters); #endif /* HAVE_EXT_POSTGRESQL */ } else if (is_dash_arg_prefix(argv[i],"debug",1)) { // dprintf to console dprintf_set_tool_debug("TOOL", 0); } else if (is_dash_arg_prefix(argv[i],"diagnostic",4)) { // dprintf to console diagnostic = true; } else if (is_dash_arg_prefix(argv[i], "name", 1)) { i++; if (argc <= i) { fprintf(stderr, "Error: Argument -name requires name of a remote schedd\n"); fprintf(stderr, "\t\te.g. condor_history -name submit.example.com \n"); exit(1); } g_name = argv[i]; readfromfile = false; #ifdef HAVE_EXT_POSTGRESQL remoteread = true; #endif } else if (is_dash_arg_prefix(argv[i], "pool", 1)) { i++; if (argc <= i) { fprintf(stderr, "Error: Argument -name requires name of a remote schedd\n"); fprintf(stderr, "\t\te.g. condor_history -name submit.example.com \n"); exit(1); } g_pool = argv[i]; readfromfile = false; #ifdef HAVE_EXT_POSTGRESQL remoteread = true; #endif } else { std::string ownerconst; owner = argv[i]; formatstr(ownerconst, "%s == \"%s\"", ATTR_OWNER, owner); constraint.addCustomOR(ownerconst.c_str()); #ifdef HAVE_EXT_POSTGRESQL parameters[0] = owner; queryhor.setQuery(HISTORY_OWNER_HOR, parameters); queryver.setQuery(HISTORY_OWNER_VER, parameters); #endif /* HAVE_EXT_POSTGRESQL */ } } if (i<argc) Usage(argv[0]); MyString my_constraint; constraint.makeQuery(my_constraint); if (diagnostic) { fprintf(stderr, "Using effective constraint: %s\n", my_constraint.c_str()); } if ( ! my_constraint.empty() && ParseClassAdRvalExpr( my_constraint.c_str(), constraintExpr ) ) { fprintf( stderr, "Error: could not parse constraint %s\n", my_constraint.c_str() ); exit( 1 ); } #ifdef HAVE_EXT_POSTGRESQL /* This call must happen AFTER config() is called */ if (checkDBconfig() == true && !readfromfile) { readfromfile = false; } else { readfromfile = true; } #endif /* HAVE_EXT_POSTGRESQL */ #ifdef HAVE_EXT_POSTGRESQL if(!readfromfile && !remoteread) { if(remotequill) { if (Collectors == NULL) { Collectors = CollectorList::create(); if(Collectors == NULL ) { printf("Error: Unable to get list of known collectors\n"); exit(1); } } result = Collectors->query ( quillQuery, quillList ); if(result != Q_OK) { printf("Fatal Error querying collectors\n"); exit(1); } if(quillList.MyLength() == 0) { printf("Error: Unknown quill server %s\n", quillName); exit(1); } quillList.Open(); while ((ad = quillList.Next())) { // get the address of the database dbIpAddr = dbName = queryPassword = NULL; if (!ad->LookupString(ATTR_QUILL_DB_IP_ADDR, &dbIpAddr) || !ad->LookupString(ATTR_QUILL_DB_NAME, &dbName) || !ad->LookupString(ATTR_QUILL_DB_QUERY_PASSWORD, &queryPassword) || (ad->LookupBool(ATTR_QUILL_IS_REMOTELY_QUERYABLE,flag) && !flag)) { printf("Error: The quill daemon \"%s\" is not set up " "for database queries\n", quillName); exit(1); } } } else { // they just typed 'condor_history' on the command line and want // to use quill, so get the schedd ad for the local machine if // we can, figure out the name of the schedd and the // jobqueuebirthdate Daemon schedd( DT_SCHEDD, 0, 0 ); if ( schedd.locate(Daemon::LOCATE_FULL) ) { char *scheddname = quillName; if (scheddname == NULL) { // none set explictly, look it up in the daemon ad scheddname = schedd.name(); ClassAd *daemonAd = schedd.daemonAd(); int scheddbirthdate; if(daemonAd) { if(daemonAd->LookupInteger( ATTR_JOB_QUEUE_BIRTHDATE, scheddbirthdate) ) { queryhor.setJobqueuebirthdate( (time_t)scheddbirthdate); queryver.setJobqueuebirthdate( (time_t)scheddbirthdate); } } } else { queryhor.setJobqueuebirthdate(0); queryver.setJobqueuebirthdate(0); } queryhor.setScheddname(scheddname); queryver.setScheddname(scheddname); } } dbconn = getDBConnStr(quillName,dbIpAddr,dbName,queryPassword); historySnapshot = new HistorySnapshot(dbconn); if (!customFormat) { printf ("\n\n-- Quill: %s : %s : %s\n", quillName, dbIpAddr, dbName); } queryhor.prepareQuery(); // create the query strings before sending off to historySnapshot queryver.prepareQuery(); st = historySnapshot->sendQuery(&queryhor, &queryver, longformat, false, customFormat, &mask, constraint.c_str()); //if there's a failure here and if we're not posing a query on a //remote quill daemon, we should instead query the local file if(st == QUILL_FAILURE) { printf( "-- Database at %s not reachable\n", dbIpAddr); if(!remotequill) { char *tmp_hist = param("HISTORY"); if (!customFormat) { printf( "--Failing over to the history file at %s instead --\n", tmp_hist ? tmp_hist : "(null)" ); } if(!tmp_hist) { free(tmp_hist); } readfromfile = true; } } // query history table if (historySnapshot->isHistoryEmpty()) { printf("No historical jobs in the database match your query\n"); } historySnapshot->release(); delete(historySnapshot); } #endif /* HAVE_EXT_POSTGRESQL */ if(readfromfile == true) { readHistoryFromFiles(fileisuserlog, JobHistoryFileName, my_constraint.c_str(), constraintExpr); } else { readHistoryRemote(constraintExpr); } #ifdef HAVE_EXT_POSTGRESQL if(completedsince) free(completedsince); if(parameters) free(parameters); if(dbIpAddr) free(dbIpAddr); if(dbName) free(dbName); if(queryPassword) free(queryPassword); if(dbconn) free(dbconn); #endif return 0; }
static void enable_debug( void ) { dprintf_set_tool_debug("TOOL", 0); }
int main( int argc, char *argv[] ) { const char *filename=0; char *pool=0; int command=-1; int i; bool use_tcp = false; bool with_ack = false; bool allow_multiple = false; myDistro->Init( argc, argv ); config(); for( i=1; i<argc; i++ ) { if(!strcmp(argv[i],"-help")) { usage(argv[0]); exit(0); } else if(!strcmp(argv[i],"-pool")) { i++; if(!argv[i]) { fprintf(stderr,"-pool requires an argument.\n\n"); usage(argv[0]); exit(1); } pool = argv[i]; } else if(!strncmp(argv[i],"-tcp",strlen(argv[i]))) { use_tcp = true; } else if(!strncmp(argv[i],"-multiple",strlen(argv[i]))) { // We don't set allow_multiple=true by default, because // existing users (e.g. glideinWMS) have stray blank lines // in the input file. allow_multiple = true; } else if(!strcmp(argv[i],"-version")) { version(); exit(0); } else if(!strcmp(argv[i],"-debug")) { // dprintf to console dprintf_set_tool_debug("TOOL", 0); } else if(argv[i][0]!='-' || !strcmp(argv[i],"-")) { if(command==-1) { command = getCollectorCommandNum(argv[i]); if(command==-1) { fprintf(stderr,"Unknown command name %s\n\n",argv[i]); usage(argv[0]); exit(1); } } else if(!filename) { filename = argv[i]; } else { fprintf(stderr,"Extra argument: %s\n\n",argv[i]); usage(argv[0]); exit(1); } } else { fprintf(stderr,"Unknown argument: %s\n\n",argv[i]); usage(argv[0]); exit(1); } } FILE *file; ClassAdList ads; Daemon *collector; Sock *sock; switch( command ) { case UPDATE_STARTD_AD_WITH_ACK: with_ack = true; break; } if( with_ack ) { use_tcp = true; } if(!filename || !strcmp(filename,"-")) { file = stdin; filename = "(stdin)"; } else { file = safe_fopen_wrapper_follow(filename,"r"); } if(!file) { fprintf(stderr,"couldn't open %s: %s\n",filename,strerror(errno)); return 1; } while(!feof(file)) { int eof=0,error=0,empty=0; char const *delim = "\n"; if( !allow_multiple ) { delim = "***"; } ClassAd *ad = new ClassAd(file,const_cast<char *>(delim),eof,error,empty); if(error) { fprintf(stderr,"couldn't parse ClassAd in %s\n",filename); delete ad; return 1; } if( empty ) { delete ad; break; } if( !allow_multiple && ads.Length() > 0 ) { fprintf(stderr,"ERROR: failed to parse '%s' as a ClassAd attribute\n",delim); delete ad; return 1; } ads.Insert(ad); } if(ads.Length() == 0) { fprintf(stderr,"%s is empty\n",filename); return 1; } CollectorList * collectors; if ( pool ) { collector = new Daemon( DT_COLLECTOR, pool, 0 ); collectors = new CollectorList(); collectors->append (collector); } else { collectors = CollectorList::create(); } bool had_error = false; collectors->rewind(); while (collectors->next(collector)) { dprintf(D_FULLDEBUG,"locating collector %s...\n", collector->name()); if(!collector->locate()) { fprintf(stderr,"couldn't locate collector: %s\n",collector->error()); had_error = true; continue; } dprintf(D_FULLDEBUG,"collector is %s located at %s\n", collector->hostname(),collector->addr()); sock = NULL; ClassAd *ad; int success_count = 0; int failure_count = 0; ads.Rewind(); while( (ad=ads.Next()) ) { // If there's no "MyAddress", generate one.. if( !ad->Lookup( ATTR_MY_ADDRESS ) ) { MyString tmp; tmp.formatstr( "<%s:0>", my_ip_string() ); ad->Assign( ATTR_MY_ADDRESS, tmp.Value() ); } if ( use_tcp ) { if( !sock ) { sock = collector->startCommand(command,Stream::reli_sock,20); } else { // Use existing connection. sock->encode(); sock->put(command); } } else { // We must open a new UDP socket each time. delete sock; sock = collector->startCommand(command,Stream::safe_sock,20); } int result = 0; if ( sock ) { result += putClassAd( sock, *ad ); result += sock->end_of_message(); } if ( result != 2 ) { fprintf(stderr,"failed to send classad to %s\n",collector->addr()); had_error = true; failure_count++; delete sock; sock = NULL; continue; } if( with_ack ) { sock->decode(); int ok = 0; if( !sock->get(ok) || !sock->end_of_message() ) { fprintf(stderr,"failed to get ack from %s\n",collector->addr()); had_error = true; failure_count++; delete sock; sock = NULL; continue; } // ack protocol does not allow for multiple updates, // so close the socket now delete sock; sock = NULL; } success_count++; } if( sock ) { CondorVersionInfo const *ver = sock->get_peer_version(); if( !ver || ver->built_since_version(7,7,3) ) { // graceful hangup so the collector knows we are done sock->encode(); int hangup_cmd = DC_NOP; sock->put(hangup_cmd); sock->end_of_message(); } delete sock; sock = NULL; } printf("Sent %d of %d ad%s to %s.\n", success_count, success_count + failure_count, success_count+failure_count == 1 ? "" : "s", collector->name()); } delete collectors; return (had_error)?1:0; }
int main( int argc, char *argv[] ) { char *machine_name = 0; char *log_name = 0; char *pool=0; int i; daemon_t type = DT_MASTER; myDistro->Init( argc, argv ); config(); for( i=1; i<argc; i++ ) { if(!strcmp(argv[i],"-help")) { usage(argv[0]); exit(0); } else if(!strcmp(argv[i],"-pool")) { i++; if(!argv[i]) { fprintf(stderr,"-pool requires an argument.\n\n"); usage(argv[0]); exit(1); } pool = argv[i]; } else if(!strcmp(argv[i],"-version")) { version(); exit(0); } else if(!strcmp(argv[i],"-debug")) { dprintf_set_tool_debug("TOOL", 0); } else if(argv[i][0]=='-') { type = stringToDaemonType(&argv[i][1]); if( type == DT_NONE || type == DT_DAGMAN) { usage(argv[0]); exit(1); } } else if(argv[i][0]!='-') { if(!machine_name) { machine_name = argv[i]; } else if(!log_name) { log_name = argv[i]; } else { fprintf(stderr,"Extra argument: %s\n\n",argv[i]); usage(argv[0]); exit(1); } } else { usage(argv[0]); exit(1); } } if( !machine_name || !log_name ) { usage(argv[0]); exit(1); } Daemon *daemon; ReliSock *sock; if (pool) { DCCollector col( pool ); if( ! col.addr() ) { fprintf( stderr, "Error: %s\n", col.error() ); exit(1); } daemon = new Daemon( type, machine_name, col.addr() ); } else { daemon = new Daemon( type, machine_name ); } dprintf(D_FULLDEBUG,"Locating daemon process on %s...\n",machine_name); if(!daemon->locate()) { fprintf(stderr,"Couldn't locate daemon on %s: %s\n",machine_name,daemon->error()); exit(1); } dprintf(D_FULLDEBUG,"Daemon %s is %s\n",daemon->hostname(),daemon->addr()); sock = (ReliSock*)daemon->startCommand( DC_FETCH_LOG, Sock::reli_sock); if(!sock) { fprintf(stderr,"couldn't connect to daemon %s at %s\n",daemon->hostname(),daemon->addr()); return 1; } int commandType = DC_FETCH_LOG_TYPE_PLAIN; if ((strcmp(log_name, "HISTORY") == 0) || (strcmp(log_name, "STARTD_HISTORY") == 0)) { commandType = DC_FETCH_LOG_TYPE_HISTORY; } if ((strcmp(log_name, "STARTD.PER_JOB_HISTORY_DIR") == 0) || (strcmp(log_name, "STARTD.PER_JOB_HISTORY_DIR") == 0)) { commandType = DC_FETCH_LOG_TYPE_HISTORY_DIR; } sock->put( commandType ); sock->put( log_name ); sock->end_of_message(); if (commandType == DC_FETCH_LOG_TYPE_HISTORY_DIR) { return handleHistoryDir(sock); } int result = -1; int exitcode = 1; const char *reason=NULL; filesize_t filesize; sock->decode(); sock->code(result); switch(result) { case -1: reason = "permission denied"; break; case DC_FETCH_LOG_RESULT_SUCCESS: result = sock->get_file(&filesize,1,0); if(result>=0) { exitcode = 0; } else { reason = "connection lost"; } break; case DC_FETCH_LOG_RESULT_NO_NAME: reason = "no log file by that name"; break; case DC_FETCH_LOG_RESULT_CANT_OPEN: reason = "server was unable to access it"; break; case DC_FETCH_LOG_RESULT_BAD_TYPE: reason = "server can't provide that type of log"; break; default: reason = "unknown error"; break; } if(exitcode!=0) { fprintf(stderr,"Couldn't fetch log: %s.\n",reason); } return exitcode; }
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 ); } } }
//--------------------------------------------------------------------------- int main(int argc, char *argv[]) { printf("\n"); // Set up the dprintf stuff to write to stderr, so that Condor // libraries which use it will write to the right place... dprintf_set_tool_debug("TOOL", 0); set_debug_flags(NULL, D_ALWAYS | D_NOHEADER); config(); // Initialize our Distribution object -- condor vs. hawkeye, etc. myDistro->Init( argc, argv ); // Load command-line arguments into the deepOpts and shallowOpts // structures. SubmitDagDeepOptions deepOpts; SubmitDagShallowOptions shallowOpts; // We're setting strScheddDaemonAdFile and strScheddAddressFile // here so that the classad updating feature (see gittrac #1782) // works properly. The problem is that the schedd daemon ad and // address files are normally defined relative to the $LOG value. // Because we specify a different log directory on the condor_dagman // command line, if we don't set the values here, condor_dagman // won't be able to find those files when it tries to communicate /// with the schedd. wenger 2013-03-11 shallowOpts.strScheddDaemonAdFile = param( "SCHEDD_DAEMON_AD_FILE" ); shallowOpts.strScheddAddressFile = param( "SCHEDD_ADDRESS_FILE" ); parseCommandLine(deepOpts, shallowOpts, argc, argv); int tmpResult; // Recursively run ourself on nested DAGs. We need to do this // depth-first so all of the lower-level .condor.sub files already // exist when we check for log files. if ( deepOpts.recurse ) { if ( param_boolean( "DAGMAN_USE_OLD_DAG_READER", false ) ) { fprintf( stderr, "Warning: DAGMAN_USE_OLD_DAG_READER " "is no longer supported\n" ); } tmpResult = doRecursionNew( deepOpts, shallowOpts ); if ( tmpResult != 0) { fprintf( stderr, "Recursive submit(s) failed; exiting without " "attempting top-level submit\n" ); return tmpResult; } } // Further work to get the shallowOpts structure set up properly. tmpResult = setUpOptions( deepOpts, shallowOpts ); if ( tmpResult != 0 ) return tmpResult; // Check whether the output files already exist; if so, we may // abort depending on the -f flag and whether we're running // a rescue DAG. ensureOutputFilesExist( deepOpts, shallowOpts ); // Make sure that all node jobs have log files, the files // aren't on NFS, etc. // Note that this MUST come after recursion, otherwise we'd // pass down the "preserved" values from the current .condor.sub // file. if ( deepOpts.updateSubmit ) { tmpResult = getOldSubmitFlags( shallowOpts ); if ( tmpResult != 0 ) return tmpResult; } // Write the actual submit file for DAGMan. writeSubmitFile( deepOpts, shallowOpts ); return submitDag( shallowOpts ); }
int main(int argc, char *argv[]) { char *arg; int nArgs = 0; // number of args int i, result; char* pool = NULL; char* scheddName = NULL; char* scheddAddr = NULL; MyString method; char *tmp; myDistro->Init( argc, argv ); MyName = condor_basename(argv[0]); config(); #if !defined(WIN32) install_sig_handler(SIGPIPE, SIG_IGN ); #endif // dig around in the config file looking for what the config file says // about getting files from Condor. This defaults with the global variable // initialization. tmp = param( "SANDBOX_TRANSFER_METHOD" ); if ( tmp != NULL ) { method = tmp; free( tmp ); string_to_stm( method, st_method ); } char **args = (char **)malloc(sizeof(char *) * argc); // args if ( ! args) exit(2); // parse the arguments. for( argv++; (arg = *argv); argv++ ) { if( arg[0] == '-' ) { if( ! arg[1] ) { usage(); } switch( arg[1] ) { case 'd': // dprintf to console dprintf_set_tool_debug("TOOL", 0); break; case 'c': args[nArgs] = arg; nArgs++; argv++; if( ! *argv ) { fprintf( stderr, "%s: -constraint requires another argument\n", MyName); exit(1); } args[nArgs] = *argv; nArgs++; break; case 'a': if( arg[2] && arg[2] == 'd' ) { argv++; if( ! *argv ) { fprintf( stderr, "%s: -addr requires another argument\n", MyName); exit(1); } if( is_valid_sinful(*argv) ) { scheddAddr = strdup(*argv); if( ! scheddAddr ) { fprintf( stderr, "Out of Memory!\n" ); exit(1); } } else { fprintf( stderr, "%s: \"%s\" is not a valid address\n", MyName, *argv ); fprintf( stderr, "Should be of the form " "<ip.address.here:port>\n" ); fprintf( stderr, "For example: <123.456.789.123:6789>\n" ); exit( 1 ); } break; } All = true; break; case 'n': // use the given name as the schedd name to connect to argv++; if( ! *argv ) { fprintf( stderr, "%s: -name requires another argument\n", MyName); exit(1); } if ( scheddName ) free(scheddName); scheddName = strdup(*argv); break; case 'p': // use the given name as the central manager to query argv++; if( ! *argv ) { fprintf( stderr, "%s: -pool requires another argument\n", MyName); exit(1); } if( pool ) { free( pool ); } pool = strdup( *argv ); break; case 's': argv++; if( ! *argv ) { fprintf( stderr, "%s: -stm requires another argument\n", MyName); exit(1); } method = *argv; string_to_stm(method, st_method); break; case 'v': version(); break; case 'h': usage(0); break; default: fprintf( stderr, "Unrecognized option: %s\n", arg ); usage(); break; } } else { if( All ) { // If -all is set, there should be no other // constraint arguments. usage(); } args[nArgs] = arg; nArgs++; } } // Check to make sure we have a valid sandbox transfer mechanism. if (st_method == STM_UNKNOWN) { fprintf( stderr, "%s: Unknown sandbox transfer method: %s\n", MyName, method.Value()); usage(); exit(1); } if( ! (All || nArgs) ) { // We got no indication of what to act on fprintf( stderr, "You did not specify any jobs\n" ); usage(); } // We're done parsing args, now make sure we know how to // contact the schedd. if( ! scheddAddr ) { // This will always do the right thing, even if either or // both of scheddName or pool are NULL. schedd = new DCSchedd( scheddName, pool ); } else { schedd = new DCSchedd( scheddAddr ); } if( ! schedd->locate() ) { fprintf( stderr, "%s: %s\n", MyName, schedd->error() ); exit( 1 ); } // Process the args. if( All ) { handleAll(); } else { for(i = 0; i < nArgs; i++) { if( match_prefix( args[i], "-constraint" ) ) { i++; addConstraint( args[i] ); } else { procArg(args[i]); } } } // Sanity check: make certain we now have a constraint if ( global_constraint.Length() <= 0 ) { fprintf( stderr, "Unable to create a job constraint!\n"); exit(1); } fprintf(stdout,"Fetching data files...\n"); switch(st_method) { case STM_USE_SCHEDD_ONLY: { // start block // Get the sandbox directly from the schedd. // And now, do the work. CondorError errstack; result = schedd->receiveJobSandbox(global_constraint.Value(), &errstack); if ( !result ) { fprintf( stderr, "\n%s\n", errstack.getFullText(true).c_str() ); fprintf( stderr, "ERROR: Failed to spool job files.\n" ); exit(1); } // All done return 0; } //end block break; case STM_USE_TRANSFERD: { // start block // NEW METHOD where we ask the schedd for a transferd, then get the // files from the transferd CondorError errstack; ClassAd respad; int invalid; MyString reason; MyString td_sinful; MyString td_cap; result = schedd->requestSandboxLocation(FTPD_DOWNLOAD, global_constraint, FTP_CFTP, &respad, &errstack); if ( !result ) { fprintf( stderr, "\n%s\n", errstack.getFullText(true).c_str() ); fprintf( stderr, "ERROR: Failed to spool job files.\n" ); exit(1); } respad.LookupInteger(ATTR_TREQ_INVALID_REQUEST, invalid); if (invalid == TRUE) { fprintf( stderr, "ERROR: Failed to spool job files.\n" ); respad.LookupString(ATTR_TREQ_INVALID_REASON, reason); fprintf( stderr, "%s\n", reason.Value()); exit(EXIT_FAILURE); } respad.LookupString(ATTR_TREQ_TD_SINFUL, td_sinful); respad.LookupString(ATTR_TREQ_CAPABILITY, td_cap); dprintf(D_ALWAYS, "td: %s, cap: %s\n", td_sinful.Value(), td_cap.Value()); DCTransferD dctd(td_sinful.Value()); result = dctd.download_job_files(&respad, &errstack); if ( !result ) { fprintf( stderr, "\n%s\n", errstack.getFullText(true).c_str() ); fprintf( stderr, "ERROR: Failed to spool job files.\n" ); exit(1); } } // end block break; default: EXCEPT("PROGRAMMER ERROR: st_method must be known."); break; } // All done return 0; }
int main(int argc, char **argv) { ClassAd ad, context; char *str; int i; float f; bool b; myDistro->Init(argc, argv); config(); dprintf_set_tool_debug("TEST", 0); ad.Assign("REEVALUATE_ATTRIBUTES", "INTEGER, FLOAT, STRING, BOOL, REF"); ad.AssignExpr("REEVALUATE_INTEGER_EXPR", "MY.INTEGER + 1"); ad.AssignExpr("REEVALUATE_FLOAT_EXPR", "MY.FLOAT + 0.1"); ad.AssignExpr("REEVALUATE_STRING_EXPR", "strcat(MY.STRING, \",\", MY.STRING)"); ad.AssignExpr("REEVALUATE_BOOL_EXPR", "MY.BOOL && FALSE"); ad.AssignExpr("REEVALUATE_REF_EXPR", "MY.REF + TARGET.REF"); ad.Assign("INTEGER", 1); ad.Assign("FLOAT", 1.0); ad.Assign("STRING", "Hello"); ad.Assign("BOOL", true); ad.Assign("REF", 3); context.Assign("REF", 2); dprintf(D_FULLDEBUG, "context ad:\n"); context.dPrint(D_FULLDEBUG); dprintf(D_FULLDEBUG, "ad to update:\n"); ad.dPrint(D_FULLDEBUG); if (!classad_reevaluate(&ad, &context)) { return 1; } dprintf(D_FULLDEBUG, "updated ad:\n"); ad.dPrint(D_FULLDEBUG); if (ad.LookupInteger("INTEGER", i)) { if (2 != i) { return 2; } } else { return 3; } if (ad.LookupFloat("FLOAT", f)) { if (1.1f != f) { return 4; } } else { return 5; } if (ad.LookupString("STRING", &str)) { if (strcmp(str, "Hello,Hello")) { free(str); return 6; } free(str); } else { return 7; } if (ad.LookupBool("BOOL", b)) { if (b) { return 8; } } else { return 9; } if (ad.LookupInteger("REF", i)) { if (5 != i) { return 10; } } else { return 11; } return 0; }