Example #1
0
ClassAd *ClassAdCollectionInterface::
_CreateSubView( const ViewName &viewName, const ViewName &parentViewName, 
	const string &constraint, const string &rank, const string &partitionExprs )
{
    ClassAd 	*rec;
	string		buffer;

	buffer = "[ ViewName = \"";
	buffer +=  viewName;
	buffer += "\" ; ParentViewName = \"";
	buffer += parentViewName;
	buffer += "\" ; Requirements = ";
	buffer += constraint=="" ? "true" : constraint;
	buffer += " ; PartitionExprs = ";
	if (string_is_empty(partitionExprs)) {
		buffer += "{}";
	} else {
		buffer += partitionExprs;
	}
	buffer += " ; Rank = ";
	if (string_is_empty(rank)) {
		buffer += "undefined";
	} else {
		buffer += rank;	
	}
	buffer += " ] ]";

	if( !( rec = parser.ParseClassAd( buffer ) ) ) {
		return( NULL );
	}
	rec->InsertAttr( "OpType", ClassAdCollOp_CreateSubView );
	return( rec );
}
Example #2
0
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",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;
	}
}
Example #3
0
Manageable::status_t
Triggerd::AddTrigger(std::string name, std::string query, std::string triggerText, std::string& text)
{
   std::string attr;
   ClassAd* ad = new ClassAd();
   Manageable::status_t ret_val;
   char* tmp;

   SetMyTypeName(*ad, "EventTrigger");
   SetTargetTypeName(*ad, "Trigger");
   tmp = strdup(name.c_str());
   ReplaceAllChars(tmp, '"', '\'');
   ad->Assign(ATTR_TRIGGER_NAME, tmp);
   free(tmp);

   tmp = strdup(query.c_str());
   ReplaceAllChars(tmp, '"', '\'');
   ad->Assign(ATTR_TRIGGER_QUERY, tmp);
   free(tmp);

   tmp = strdup(triggerText.c_str());
   ReplaceAllChars(tmp, '"', '\'');
   ad->Assign(ATTR_TRIGGER_TEXT, tmp);
   free(tmp);

   ret_val = AddTrigger(ad, text);
   delete ad;

   return ret_val;
}
Example #4
0
bool ClientTransaction::
LogAbort( FILE *fp, ClassAdUnParser *unp )
{
	if( state != PENDING ) {
		CondorErrno = ERR_BAD_TRANSACTION_STATE;
		CondorErrMsg = "transaction expected to be in COMMITTED state";
		return( false );
	}

	ClassAd	rec;
	string	buf;

    if(!rec.InsertAttr(ATTR_OP_TYPE,
			ClassAdCollectionInterface::ClassAdCollOp_AbortTransaction)
			|| !rec.InsertAttr( "XactionName", xactionName.c_str( ) ) ) {
		CondorErrMsg += "FATAL ERROR: failed to log transaction";
		return( false );
	}
	unp->Unparse( buf, &rec );
	if( fprintf( fp, "%s\n", buf.c_str( ) ) < 0 ) {
		CondorErrno = ERR_FILE_WRITE_FAILED;
		CondorErrMsg = "FATAL ERROR: failed fprintf()";
		return( false );
	}
	fsync( fileno( fp ) );
	return( true );
}
Example #5
0
int
LogSetAttribute::Play(void *data_structure)
{
	ClassAdHashTable *table = (ClassAdHashTable *)data_structure;
	int rval;
	ClassAd *ad = 0;
	if (table->lookup(HashKey(key), ad) < 0)
		return -1;
    if (value_expr) {
		// Such a shame, do we really need to make a
		// copy of value_expr here?  Seems like we could just
		// assign it and then set value_expr to NULL and avoid
		// copying a parse tree, since after we Play it I doubt
		// this class does anything more with value_expr beyond
		// deallocating it.  - Todd 11/13 <*****@*****.**>
        ExprTree * pTree = value_expr->Copy();
        rval = ad->Insert(name, pTree, false);
    } else {
        rval = ad->AssignExpr(name, value);
    }
	ad->SetDirtyFlag(name, is_dirty);

#if defined(HAVE_DLOPEN)
	ClassAdLogPluginManager::SetAttribute(key, name, value);
#endif

	return rval;
}
Example #6
0
//
// JobExit() is called after file transfer.
//
bool DockerProc::JobExit() {
	dprintf( D_ALWAYS, "DockerProc::JobExit()\n" );

	{
	TemporaryPrivSentry sentry(PRIV_ROOT);
	ClassAd dockerAd;
	CondorError error;
	int rv = DockerAPI::inspect( containerName, & dockerAd, error );
	if( rv < 0 ) {
		dprintf( D_ALWAYS | D_FAILURE, "Failed to inspect (for removal) container '%s'.\n", containerName.c_str() );
		return VanillaProc::JobExit();
	}

	bool running;
	if( ! dockerAd.LookupBool( "Running", running ) ) {
		dprintf( D_ALWAYS | D_FAILURE, "Inspection of container '%s' failed to reveal its running state.\n", containerName.c_str() );
		return VanillaProc::JobExit();
	}
	if( running ) {
		dprintf( D_ALWAYS | D_FAILURE, "Inspection reveals that container '%s' is still running.\n", containerName.c_str() );
		return VanillaProc::JobExit();
	}

	rv = DockerAPI::rm( containerName, error );
	if( rv < 0 ) {
		dprintf( D_ALWAYS | D_FAILURE, "Failed to remove container '%s'.\n", containerName.c_str() );
	}
	}

	return VanillaProc::JobExit();
}
Example #7
0
void cp_compute_consumption(ClassAd& job, ClassAd& resource, consumption_map_t& consumption) {
    consumption.clear();

    string mrv;
    if (!resource.LookupString(ATTR_MACHINE_RESOURCES, mrv)) {
        EXCEPT("Resource ad missing %s attribute", ATTR_MACHINE_RESOURCES);
    }

    StringList alist(mrv.c_str());
    alist.rewind();
    while (char* asset = alist.next()) {
        if (MATCH == strcasecmp(asset, "swap")) continue;

        string ra;
        string coa;
        formatstr(ra, "%s%s", ATTR_REQUEST_PREFIX, asset);
        formatstr(coa, "_condor_%s", ra.c_str());
        bool override = false;
        double ov=0;
        if (job.EvalFloat(coa.c_str(), NULL, ov)) {
            // Allow _condor_RequestedXXX to override RequestedXXX
            // this case is intended to be operative when a scheduler has set 
            // such values and sent them on to the startd that owns this resource
            // (e.g. I'd not expect this case to arise elsewhere, like the negotiator)
            string ta;
            formatstr(ta, "_cp_temp_%s", ra.c_str());
            job.CopyAttribute(ta.c_str(), ra.c_str());
            job.Assign(ra.c_str(), ov);
            override = true;
        }
void PandadClassAdLogPlugin::setAttribute( const char * key, const char * attribute, const char * value ) {
	int cluster = 0, proc = 0;
	if( shouldIgnoreJob( key, cluster, proc ) ) { return; }

	dprintf( D_FULLDEBUG, "PANDA: setAttribute( %s, %s, %s ).\n", key, attribute, value );

	std::string globalJobID;
	if( ! getGlobalJobID( cluster, proc, globalJobID ) ) { return; }

	// See comment in newClassAd(), above.
	if( strcmp( attribute, "ProcId" ) == 0 ) {
		ClassAd * clusterAd = ScheddGetJobAd( cluster, -1 );
		if( clusterAd != NULL ) {
			ExprTree * valueExpr = NULL;
			const char * attribute = NULL;

			clusterAd->ResetExpr();
			while( clusterAd->NextExpr( attribute, valueExpr ) ) {
				dprintf( D_FULLDEBUG, "PANDA: found %s in cluster ad.\n", attribute );
				if( shouldIgnoreAttribute( attribute ) ) { continue; }
				std::string valueString;
				classad::ClassAdUnParser unparser;
				unparser.Unparse( valueString, valueExpr );
				updatePandaJob( globalJobID.c_str(), attribute, valueString.c_str() );
			}
		} else {
			dprintf( D_FULLDEBUG, "PANDA: Failed to find cluster ad for %d.%d\n", cluster, proc );
		}
	}

	if( shouldIgnoreAttribute( attribute ) ) { return; }
	updatePandaJob( globalJobID.c_str(), attribute, value );
}
Example #9
0
void assign_preserve_integers(ClassAd& ad, const char* attr, double v) {
    if ((v - floor(v)) > 0.0) {
        ad.Assign(attr, v);
    } else {
        ad.Assign(attr, (long long)(v));
    }
}
Example #10
0
bool cp_supports_policy(ClassAd& resource, bool strict) {
    // currently, only p-slots can support a functional consumption policy
    if (strict) {
        bool part = false;
        if (!resource.LookupBool(ATTR_SLOT_PARTITIONABLE, part)) part = false;
        if (!part) return false;
    }

    // must support MachineResources attribute
    string mrv;
    if (!resource.LookupString(ATTR_MACHINE_RESOURCES, mrv)) return false;

    // must define ConsumptionXxx for all resources Xxx (including extensible resources)
    StringList alist(mrv.c_str());
    alist.rewind();
    while (char* asset = alist.next()) {
        if (MATCH == strcasecmp(asset, "swap")) continue;
        string ca;
        formatstr(ca, "%s%s", ATTR_CONSUMPTION_PREFIX, asset);
        ClassAd::iterator f(resource.find(ca));
        if (f == resource.end()) return false;
    }

    return true;
}
Example #11
0
bool
CCBListener::RegisterWithCCBServer(bool blocking)
{
	ClassAd msg;

	if( m_waiting_for_connect || m_reconnect_timer != -1 || m_waiting_for_registration || m_registered) {
			// already registered or being registered
		return m_registered;
	}

	msg.Assign( ATTR_COMMAND, CCB_REGISTER );
	if( !m_ccbid.IsEmpty() ) {
		// we are reconnecting; trying to preserve ccbid so that prospective
		// clients with stale information can still contact us
		msg.Assign( ATTR_CCBID, m_ccbid.Value() );
		msg.Assign( ATTR_CLAIM_ID, m_reconnect_cookie.Value() );
	}

		// for debugging purposes only, identify ourselves to the CCB server
	MyString name;
	name.formatstr("%s %s",get_mySubSystem()->getName(),daemonCore->publicNetworkIpAddr());
	msg.Assign( ATTR_NAME, name.Value() );

	bool success = SendMsgToCCB(msg,blocking);
	if( success ) {
		if( blocking ) {
			success = ReadMsgFromCCB();
		}
		else {
			// now we wait for CCB server to respond with our CCBID
			m_waiting_for_registration = true;
		}
	}
	return success;
}
Example #12
0
bool View::
SetConstraintExpr( ClassAdCollection *coll, ExprTree *constraint )
{
	ClassAd					*ad;
	ViewMembers::iterator	vmi;
	bool					match;
	string					key;

		// insert expression into ad in left context
	if( !( ad=evalEnviron.GetLeftAd() ) ||
		!ad->Insert( ATTR_REQUIREMENTS, constraint ) ) {
		CondorErrMsg += "; failed to set constraint on view";
		return( false );
	}

		// check if all members still belong to the view
	for( vmi = viewMembers.begin( ); vmi != viewMembers.end( ); vmi++ ) {
		vmi->GetKey( key );
		if( ( ad = coll->GetClassAd( key ) ) == NULL ) {
			CLASSAD_EXCEPT( "internal error: classad in view but not in collection" );
		}
		evalEnviron.ReplaceRightAd( ad );
		match = evalEnviron.EvaluateAttrBool("RightMatchesLeft",match) && match;
		evalEnviron.RemoveRightAd( );
			// if classad doesn't match constraint remove from view
		if( !match ) {
			ClassAdDeleted( coll, key, ad );
		}
	}

	return( true );
}
Example #13
0
void
CCBListener::ReportReverseConnectResult(ClassAd *connect_msg,bool success,char const *error_msg)
{
	ClassAd msg = *connect_msg;

	MyString request_id;
	MyString address;
	connect_msg->LookupString(ATTR_REQUEST_ID,request_id);
	connect_msg->LookupString(ATTR_MY_ADDRESS,address);
	if( !success ) {
		dprintf(D_ALWAYS,
				"CCBListener: failed to create reversed connection for "
				"request id %s to %s: %s\n",
				request_id.Value(),
				address.Value(),
				error_msg ? error_msg : "");
	}
	else {
		dprintf(D_FULLDEBUG|D_NETWORK,
				"CCBListener: created reversed connection for "
				"request id %s to %s: %s\n",
				request_id.Value(),
				address.Value(),
				error_msg ? error_msg : "");
	}

	msg.Assign(ATTR_RESULT,success);
	if( error_msg ) {
		msg.Assign(ATTR_ERROR_STRING,error_msg);
	}
	WriteMsgToCCB( msg );
}
Example #14
0
bool
CCBListener::HandleCCBRequest( ClassAd &msg )
{
	MyString address;
	MyString connect_id;
	MyString request_id;
	MyString name;
	if( !msg.LookupString( ATTR_MY_ADDRESS, address) ||
		!msg.LookupString( ATTR_CLAIM_ID, connect_id) ||
		!msg.LookupString( ATTR_REQUEST_ID, request_id) )
	{
		MyString msg_str;
		msg.sPrint(msg_str);
		EXCEPT("CCBListener: invalid CCB request from %s: %s\n",
			   m_ccb_address.Value(),
			   msg_str.Value() );
	}

	msg.LookupString( ATTR_NAME, name );

	if( name.find(address.Value())<0 ) {
		name.formatstr_cat(" with reverse connect address %s",address.Value());
	}
	dprintf(D_FULLDEBUG|D_NETWORK,
			"CCBListener: received request to connect to %s, request id %s.\n",
			name.Value(), request_id.Value());

	return DoReversedCCBConnect( address.Value(), connect_id.Value(), request_id.Value(), name.Value() );
}
Example #15
0
  int
  classad_put_string_list_attribute (classad_context *cad, 
                                     const char *name, 
                                     char **value)
   {
    if (value == NULL) return C_CLASSAD_INVALID_VALUE;

    ClassAd *ad;
    if ((*cad) == NULL) 
     {
      ad = new ClassAd;
      (*cad) = (classad_context) ad;
     }
    else ad = (ClassAd *)(*cad);

    char **str_val;

    std::vector<ExprTree*> et_ads;

    // Traverse NULL-terminated string array.
    for(str_val=value; (*str_val) != NULL; str_val++) 
     {
      Value v;
      v.SetStringValue(*str_val);
      et_ads.push_back(Literal::MakeLiteral(v));
     }

    ExprList *et_value;
    et_value = ExprList::MakeExprList(et_ads);

    if (ad->Insert (name, et_value)) return C_CLASSAD_NO_ERROR; 
    else                             return C_CLASSAD_INSERT_FAILED;
   }
Example #16
0
int
CondorQ::fetchQueueFromDB (ClassAdList &list,
						   char *&lastUpdate,
						   const char *dbconn,
						   CondorError*  /*errstack*/)
{
#ifndef HAVE_EXT_POSTGRESQL
	(void) list;
	(void) lastUpdate;
	(void) dbconn;
#else
	int     		result;
	JobQueueSnapshot	*jqSnapshot;
	const char 		*constraint;
	ClassAd        *ad;
	QuillErrCode   rv;
	ExprTree *tree;

	jqSnapshot = new JobQueueSnapshot(dbconn);

	rv = jqSnapshot->startIterateAllClassAds(clusterarray,
						 numclusters,
						 procarray,
						 numprocs,
						 schedd,
						 FALSE,
						 scheddBirthdate,
						 lastUpdate);

	if (rv == QUILL_FAILURE) {
		delete jqSnapshot;
		return Q_COMMUNICATION_ERROR;
	} else if (rv == JOB_QUEUE_EMPTY) {
		delete jqSnapshot;
		return Q_OK;
	}

	// make the query ad
	if ((result = query.makeQuery (tree)) != Q_OK) {
		delete jqSnapshot;
		return result;
	}

	constraint = ExprTreeToString(tree);
	delete tree;

	ad = getDBNextJobByConstraint(constraint, jqSnapshot);

	while (ad != (ClassAd *) 0) {
		ad->ChainCollapse();
		list.Insert(ad);
		ad = getDBNextJobByConstraint(constraint, jqSnapshot);
	}	

	delete jqSnapshot;
#endif /* HAVE_EXT_POSTGRESQL */

	return Q_OK;
}
Example #17
0
// For now, just return true if the constraint worked on at least
// one job, false if not.  Someday, we can fix up the tool to take
// advantage of all the slick info the schedd gives us back about this
// request.  
bool
doWorkByConstraint( const char* constraint, CondorError * errstack )
{
	ClassAd* ad = 0;
	int total_jobs = -1;
	bool rval = true;
	switch( mode ) {
	case JA_RELEASE_JOBS:
		ad = schedd->releaseJobs( constraint, actionReason, errstack );
		break;
	case JA_REMOVE_X_JOBS:
		ad = schedd->removeXJobs( constraint, actionReason, errstack );
		break;
	case JA_VACATE_JOBS:
		ad = schedd->vacateJobs( constraint, VACATE_GRACEFUL, errstack );
		break;
	case JA_VACATE_FAST_JOBS:
		ad = schedd->vacateJobs( constraint, VACATE_FAST, errstack );
		break;
	case JA_REMOVE_JOBS:
		ad = schedd->removeJobs( constraint, actionReason, errstack );
		break;
	case JA_HOLD_JOBS:
		ad = schedd->holdJobs( constraint, actionReason, holdReasonSubCode, errstack );
		break;
	case JA_SUSPEND_JOBS:
		ad = schedd->suspendJobs( constraint, actionReason, errstack );
		break;
	case JA_CONTINUE_JOBS:
		ad = schedd->continueJobs( constraint, actionReason, errstack );
		break;
	default:
		EXCEPT( "impossible: unknown mode in doWorkByConstraint" );
	}
	if( ! ad ) {
		had_error = true;
		rval = false;
	} else {
		int result = FALSE;
		if( !ad->LookupInteger(ATTR_ACTION_RESULT, result) ) {
			had_error = true;
			rval = false;
		}
		else if( !result ) {
			// There were no ads acted upon, but that doesn't
			// mean there was an error.  It's possible the schedd
			// had no jobs
		        if( !ad->LookupInteger(ATTR_TOTAL_JOB_ADS, total_jobs) || total_jobs > 0 ) {
				had_error = true;
			} else {
				// There were no jobs in the queue, so add a
				// more meaningful error message
				errstack->push("condor_rm", 0, "There are no jobs in the queue");
			}
			rval = false;
		}
	}
	return rval;
}
Example #18
0
bool
VMUniverseMgr::allocVM(pid_t s_pid, ClassAd &ad, char const *execute_dir)
{
	if( canCreateVM(&ad) == false ) {
		return false;
	}

	// Find memory for VM
	int vm_mem = 0;
	if( (ad.LookupInteger(ATTR_JOB_VM_MEMORY, vm_mem) != 1) &&
	    (ad.LookupInteger(ATTR_REQUEST_MEMORY, vm_mem) != 1) ) {
		dprintf(D_ALWAYS, "Can't find VM memory in Job ClassAd\n");
		return false;
	}

	int vcpus = 0;
	if( (ad.LookupInteger(ATTR_JOB_VM_VCPUS, vcpus) != 1) &&
	    (ad.LookupInteger(ATTR_REQUEST_CPUS, vcpus) != 1) )
	  {
	    dprintf(D_FULLDEBUG, "Defaulting to one CPU\n");
	    vcpus = 1;
	  }

	// check whether this pid already exists
	VMStarterInfo *oldinfo = findVMStarterInfoWithStarterPid(s_pid);
	if( oldinfo ) {
		freeVM(s_pid);
		// oldinfo is freed 
		oldinfo = NULL;
	}
	
	VMStarterInfo *newinfo = new VMStarterInfo;
	ASSERT(newinfo);

	m_vm_used_memory += vm_mem;

	newinfo->m_pid = s_pid;
	newinfo->m_memory = vm_mem;
	newinfo->m_job_ad = ad; 
	newinfo->m_execute_dir = execute_dir;
	newinfo->m_vcpus = vcpus;

	// If there exists MAC or IP address for a checkpointed VM,
	// we use them as initial values.
	MyString string_value;
	if( ad.LookupString(ATTR_VM_CKPT_MAC, string_value) == 1 ) {
		newinfo->m_vm_mac = string_value;
	}
	/*
	string_value = "";
	if( ad.LookupString(ATTR_VM_CKPT_IP, string_value) == 1 ) {
		newinfo->m_vm_ip = string_value;
	}
	*/

	m_vm_starter_list.Append(newinfo);
	return true;
}
Example #19
0
// specialization: this GetFullAd has to retrieve its classad attributes
// from the history file based on index pointers
void
HistoryJobImpl::GetFullAd ( ClassAd& _ad) const
{
    // fseek to he.start
    // ClassAd method to deserialize from a file with "***"

    FILE * hFile;
    int end = 0;
    int error = 0;
    int empty = 0;
    std::ostringstream buf;
    // placeholder in case we want to expose error details to UI
    std::string text;

    // TODO: move the ClassAd/file deserialize back to HistoryFile???
    const char* fName = m_he.file.c_str();
    if ( ! ( hFile = safe_fopen_wrapper ( fName, "r" ) ) )
    {
        buf <<  "unable to open history file " << m_he.file;
        text = buf.str();
        dprintf ( D_ALWAYS, "%s\n", text.c_str());
        _ad.Assign("JOB_AD_ERROR",text.c_str());
        return;
    }
    if ( fseek ( hFile , m_he.start , SEEK_SET ) )
    {
        buf << "bad seek in " << m_he.file << " at " << m_he.start;
        text = buf.str();
        dprintf ( D_ALWAYS, "%s\n", text.c_str());
        _ad.Assign("JOB_AD_ERROR",text.c_str());
        return;
    }

    ClassAd myJobAd ( hFile, "***", end, error, empty );
    fclose ( hFile );

    // TODO: debug logging and error to i/f for now
    // we might not have our original history file anymore
    if ( error )
    {
        buf <<  "malformed ad for job '" << m_job->GetKey() << "' in " << m_he.file;
        text = buf.str();
        dprintf ( D_FULLDEBUG, "%s\n", text.c_str());
        _ad.Assign("JOB_AD_ERROR",text.c_str());
        return;
    }
    if ( empty )
    {
        buf << "empty ad for job '" << m_job->GetKey() << "' in " << m_he.file;
        text = buf.str();
        dprintf ( D_FULLDEBUG,"%s\n", text.c_str());
        _ad.Assign("JOB_AD_ERROR",text.c_str());
        return;
    }

    _ad = myJobAd;

}
Example #20
0
ULogEventOutcome
ReadUserLog::readEventXML( ULogEvent *& event )
{
	classad::ClassAdXMLParser xmlp;

	// we obtain a write lock here not because we want to write
	// anything, but because we want to ensure we don't read
	// mid-way through someone else's write
	Lock( true );

	// store file position so that if we are unable to read the event, we can
	// rewind to this location
  	long     filepos;
  	if (!m_fp || ((filepos = ftell(m_fp)) == -1L))
  	{
  		Unlock( true );
		event = NULL;
  		return ULOG_UNK_ERROR;
  	}

	ClassAd* eventad = new ClassAd();
	if ( !xmlp.ParseClassAd(m_fp, *eventad) ) {
		delete eventad;
		eventad = NULL;
	}

	Unlock( true );

	if( !eventad ) {
		// we don't have the full event in the stream yet; restore file
		// position and return
		if( fseek(m_fp, filepos, SEEK_SET) )	{
			dprintf(D_ALWAYS, "fseek() failed in ReadUserLog::readEvent");
			return ULOG_UNK_ERROR;
		}
		clearerr(m_fp);
		event = NULL;
		return ULOG_NO_EVENT;
	}

	int enmbr;
	if( !eventad->LookupInteger("EventTypeNumber", enmbr) ) {
		event = NULL;
		delete eventad;
		return ULOG_NO_EVENT;
	}

	if( !(event = instantiateEvent((ULogEventNumber) enmbr)) ) {
		event = NULL;
		delete eventad;
		return ULOG_UNK_ERROR;
	}

	event->initFromClassAd(eventad);

	delete eventad;
	return ULOG_OK;
}
Example #21
0
void ScheddStatistics::Unpublish(ClassAd & ad) const
{
   ad.Delete("StatsLifetime");
   ad.Delete("StatsLastUpdateTime");
   ad.Delete("RecentStatsLifetime");
   ad.Delete("RecentStatsTickTime");
   ad.Delete("RecentWindowMax");
   Pool.Unpublish(ad);
}
Example #22
0
int do_command_upload_sandbox(void *arg, Stream*) {
	dprintf(D_ALWAYS, "FTGAHP: upload sandbox\n");

	Gahp_Args args;
	parse_gahp_command ((char*)arg, &args);

	// first two args: result id and sandbox id:
	std::string rid = args.argv[1];
	std::string sid = args.argv[2];

	// third arg: job ad
	ClassAd ad;
	classad::ClassAdParser my_parser;

	if (!(my_parser.ParseClassAd(args.argv[3], ad))) {
		// FAIL
		write_to_pipe( ChildErrorPipe, "Failed to parse job ad" );
		return 1;
	}

	// rewrite the IWD to the actual sandbox dir
	std::string iwd;
	define_sandbox_path(sid, iwd);
	ad.Assign(ATTR_JOB_IWD, iwd.c_str());
	char ATTR_SANDBOX_ID[] = "SandboxId";
	ad.Assign(ATTR_SANDBOX_ID, sid.c_str());

	// directory was created, let's set up the FileTransfer object
	FileTransfer ft;

	if (!ft.Init(&ad)) {
		// FAIL
		write_to_pipe( ChildErrorPipe, "Failed to initialize FileTransfer" );
		return 1;
	}

	// lookup ATTR_VERSION and set it.  this changes the wire
	// protocol and it is important that this happens before
	// calling UploadFiles.
	char* peer_version = NULL;
	ad.LookupString(ATTR_VERSION, &peer_version);
	ft.setPeerVersion(peer_version);
	free (peer_version);

	dprintf(D_ALWAYS, "BOSCO: calling upload files\n");

	// the "true" param to UploadFiles here means blocking (i.e. "in the foreground")
	if (!ft.UploadFiles(true)) {
		// FAIL
		write_to_pipe( ChildErrorPipe, ft.GetInfo().error_desc.Value() );
		return 1;
	}

	// SUCCEED
	return 0;

}
Example #23
0
bool
Defrag::drain(const ClassAd &startd_ad)
{
	std::string name;
	startd_ad.LookupString(ATTR_NAME,name);

	dprintf(D_ALWAYS,"Initiating %s draining of %s.\n",
			m_draining_schedule_str.c_str(),name.c_str());

	DCStartd startd( &startd_ad );

	int graceful_completion = 0;
	startd_ad.LookupInteger(ATTR_EXPECTED_MACHINE_GRACEFUL_DRAINING_COMPLETION,graceful_completion);
	int quick_completion = 0;
	startd_ad.LookupInteger(ATTR_EXPECTED_MACHINE_QUICK_DRAINING_COMPLETION,quick_completion);
	int graceful_badput = 0;
	startd_ad.LookupInteger(ATTR_EXPECTED_MACHINE_GRACEFUL_DRAINING_BADPUT,graceful_badput);
	int quick_badput = 0;
	startd_ad.LookupInteger(ATTR_EXPECTED_MACHINE_QUICK_DRAINING_BADPUT,quick_badput);

	time_t now = time(NULL);
	std::string draining_check_expr;
	double badput_growth_tolerance = 1.25; // for now, this is hard-coded
	int negligible_badput = 1200;
	int negligible_deadline_slippage = 1200;
	if( m_draining_schedule <= DRAIN_GRACEFUL ) {
		dprintf(D_ALWAYS,"Expected draining completion time is %ds; expected draining badput is %d cpu-seconds\n",
				(int)(graceful_completion-now),graceful_badput);
		sprintf(draining_check_expr,"%s <= %d && %s <= %d",
				ATTR_EXPECTED_MACHINE_GRACEFUL_DRAINING_COMPLETION,
				graceful_completion + negligible_deadline_slippage,
				ATTR_EXPECTED_MACHINE_GRACEFUL_DRAINING_BADPUT,
				(int)(badput_growth_tolerance*graceful_badput) + negligible_badput);
	}
	else { // DRAIN_FAST and DRAIN_QUICK are effectively equivalent here
		dprintf(D_ALWAYS,"Expected draining completion time is %ds; expected draining badput is %d cpu-seconds\n",
				(int)(quick_completion-now),quick_badput);
		sprintf(draining_check_expr,"%s <= %d && %s <= %d",
				ATTR_EXPECTED_MACHINE_QUICK_DRAINING_COMPLETION,
				quick_completion + negligible_deadline_slippage,
				ATTR_EXPECTED_MACHINE_QUICK_DRAINING_BADPUT,
				(int)(badput_growth_tolerance*quick_badput) + negligible_badput);
	}

	std::string request_id;
	bool resume_on_completion = true;
	bool rval = startd.drainJobs( m_draining_schedule, resume_on_completion, draining_check_expr.c_str(), request_id );
	if( !rval ) {
		dprintf(D_ALWAYS,"Failed to send request to drain %s: %s\n",startd.name(),startd.error());
		m_stats.DrainFailures += 1;
		return false;
	}
	m_stats.DrainSuccesses += 1;

	return true;
}
Example #24
0
void CollectorEngine::
cleanHashTable (CollectorHashTable &hashTable, time_t now, HashFunc makeKey)
{
	ClassAd  *ad;
	int   	 timeStamp;
	int		 max_lifetime;
	AdNameHashKey  hk;
	double   timeDiff;
	MyString	hkString;

	hashTable.startIterations ();
	while (hashTable.iterate (ad))
	{
		// Read the timestamp of the ad
		if (!ad->LookupInteger (ATTR_LAST_HEARD_FROM, timeStamp)) {
			dprintf (D_ALWAYS, "\t\tError looking up time stamp on ad\n");
			continue;
		}

		// how long has it been since the last update?
		timeDiff = difftime( now, timeStamp );

		if( !ad->LookupInteger( ATTR_CLASSAD_LIFETIME, max_lifetime ) ) {
			max_lifetime = machineUpdateInterval;
		}

		// check if it has expired
		if ( timeDiff > (double) max_lifetime )
		{
			// then remove it from the segregated table
			(*makeKey) (hk, ad);
			hk.sprint( hkString );
			if( timeStamp == 0 ) {
				dprintf (D_ALWAYS,"\t\t**** Removing invalidated ad: \"%s\"\n", hkString.Value() );
			}
			else {
				dprintf (D_ALWAYS,"\t\t**** Removing stale ad: \"%s\"\n", hkString.Value() );
			    /* let the off-line plug-in know we are about to expire this ad, so it can
				   potentially mark the ad absent. if expire() returns false, then delete
				   the ad as planned; if it return true, it was likely marked as absent,
				   so then this ad should NOT be deleted. */
				if ( CollectorDaemon::offline_plugin_.expire( *ad ) == true ) {
					// plugin say to not delete this ad, so continue
					continue;
				} else {
					dprintf (D_ALWAYS,"\t\t**** Removing stale ad: \"%s\"\n", hkString.Value() );
				}
			}
			if (hashTable.remove (hk) == -1)
			{
				dprintf (D_ALWAYS, "\t\tError while removing ad\n");
			}
			delete ad;
		}
	}
}
Example #25
0
  int
  classad_get_string_list_attribute (classad_context cad, 
                                     const char *attribute_name, 
                                     char ***result)
   {
    if (cad == NULL) return C_CLASSAD_INVALID_CONTEXT;

    int n_results = 0;
    (*result) = (char **)malloc(sizeof(char **));
    if ((*result) == NULL) return C_CLASSAD_OUT_OF_MEMORY;

    (*result)[0] = NULL;

    ClassAd *ad = (ClassAd *)cad;

    Value vl;
    ad->EvaluateAttr(attribute_name, vl);

    const ExprList *et_result;
    if (vl.IsListValue(et_result)) 
     {
      std::vector<ExprTree*> ads;
      et_result->GetComponents(ads);
      // Get string values.
      for(std::vector<ExprTree*>::const_iterator it = ads.begin();
          it != ads.end(); ++it) 
       {
        if ((*it)->GetKind() == ExprTree::LITERAL_NODE) 
         {
          Value v;
          EvalState       state;
          state.SetScopes( ad );

          (*it)->Evaluate(state,v);

          std::string res_str;
          if (v.IsStringValue( res_str ))
           {
            // add string value to result, which is a NULL-terminated
            // string array.
            n_results++;
            (*result) = (char **)realloc(*result, (n_results+1)*sizeof(char *));
            if ((*result) == NULL) return C_CLASSAD_OUT_OF_MEMORY;
            (*result)[n_results-1] = strdup(res_str.c_str());
            (*result)[n_results] = NULL;
           }
         }
       }
      return C_CLASSAD_NO_ERROR;
     }
    
    // The result list needs to be freed on success only.
    classad_free_string_list(*result);
    (*result) = NULL;
    return C_CLASSAD_VALUE_NOT_FOUND;
   }
Example #26
0
bool
BaseShadow::jobWantsGracefulRemoval()
{
	bool job_wants_graceful_removal = false;
	ClassAd *thejobAd = getJobAd();
	if( thejobAd ) {
		thejobAd->LookupBool( ATTR_WANT_GRACEFUL_REMOVAL, job_wants_graceful_removal );
	}
	return job_wants_graceful_removal;
}
Example #27
0
 void
 classad_dump (classad_context cad)
  {
   ClassAd *ad;
   if (cad != NULL)
    {
     ad = (ClassAd *)cad;
     ad->Puke();
    }
  }
Example #28
0
void stats_recent_counter_timer::Unpublish(ClassAd & ad, const char * pattr) const
{
   ad.Delete(pattr);
   MyString attr;
   attr.sprintf("Recent%s",pattr);
   ad.Delete(attr.Value());
   attr.sprintf("Recent%sRuntime",pattr);
   ad.Delete(attr.Value());
   ad.Delete(attr.Value()+6); // +6 to skip "Recent" prefix
}
Example #29
0
void StarterStatistics::Publish(ClassAd& ad, int flags) const {
    if ((flags & IF_PUBLEVEL) > 0) {
        ad.Assign("StatsLifetime", (int)StatsLifetime);
        if (flags & IF_VERBOSEPUB)
            ad.Assign("StatsLastUpdateTime", (int)StatsLastUpdateTime);
        if (flags & IF_RECENTPUB) {
            ad.Assign("RecentStatsLifetime", (int)RecentStatsLifetime);
            if (flags & IF_VERBOSEPUB) {
                ad.Assign("RecentWindowMax", (int)RecentWindowMax);
                ad.Assign("RecentStatsTickTime", (int)RecentStatsTickTime);
            }
        }
    }

    Pool.Publish(ad, flags);

    if ((flags & IF_PUBLEVEL) > 0) {
        ad.Assign(ATTR_BLOCK_READ_KBYTES, this->BlockReadBytes.value / 1024);
        ad.Assign(ATTR_BLOCK_WRITE_KBYTES, this->BlockWriteBytes.value / 1024);
        if (flags & IF_RECENTPUB) {
            ad.Assign("Recent" ATTR_BLOCK_WRITE_KBYTES, this->BlockWriteBytes.recent / 1024);
            ad.Assign("Recent" ATTR_BLOCK_READ_KBYTES, this->BlockReadBytes.recent / 1024);
        }
    }
}
Example #30
0
Starter*
StarterMgr::makeStarter( const char* path )
{
	Starter* new_starter;
	FILE* fp;
	char *args[] = { const_cast<char*>(path),
					 const_cast<char*>("-classad"),
					 NULL };
	char buf[1024];

		// first, try to execute the given path with a "-classad"
		// option, and grab the output as a ClassAd
		// note we run the starter here as root if possible,
		// since that is how the starter will be invoked for real,
		// and the real uid of the starter may influence the
		// list of capabilities the "-classad" option returns.
	{
		TemporaryPrivSentry sentry(PRIV_ROOT);
		fp = my_popenv( args, "r", FALSE );
	}

	if( ! fp ) {
		dprintf( D_ALWAYS, "Failed to execute %s, ignoring\n", path );
		return NULL;
	}
	ClassAd* ad = new ClassAd;
	bool read_something = false;
	while( fgets(buf, 1024, fp) ) {
		read_something = true;
		if( ! ad->Insert(buf) ) {
			dprintf( D_ALWAYS, "Failed to insert \"%s\" into ClassAd, "
					 "ignoring invalid starter\n", buf );
			delete( ad );
			pclose( fp );
			return NULL;
		}
	}
	my_pclose( fp );
	if( ! read_something ) {
		dprintf( D_ALWAYS, 
				 "\"%s -classad\" did not produce any output, ignoring\n", 
				 path ); 
		delete( ad );
		return NULL;
	}

	new_starter = new Starter();
	new_starter->setAd( ad );
	new_starter->setPath( path );
	int is_dc = 0;
	ad->LookupBool( ATTR_IS_DAEMON_CORE, is_dc );
	new_starter->setIsDC( (bool)is_dc );

	return new_starter;
}