コード例 #1
0
bool IsAHalfMatch( compat_classad::ClassAd *my, compat_classad::ClassAd *target )
{
		// The collector relies on this function to check the target type.
		// Eventually, we should move that check either into the collector
		// or into the requirements expression.
	char const *my_target_type = GetTargetTypeName(*my);
	char const *target_type = GetMyTypeName(*target);
	if( !my_target_type ) {
		my_target_type = "";
	}
	if( !target_type ) {
		target_type = "";
	}
	if( strcasecmp(target_type,my_target_type) &&
		strcasecmp(my_target_type,ANY_ADTYPE) )
	{
		return false;
	}

	classad::MatchClassAd *mad = compat_classad::getTheMatchAd( my, target );

	bool result = mad->rightMatchesLeft();

	compat_classad::releaseTheMatchAd();
	return result;
}
コード例 #2
0
ファイル: classad_log.cpp プロジェクト: AmesianX/htcondor
void
ClassAdLog::LogState(FILE *fp)
{
	LogRecord	*log=NULL;
	ClassAd		*ad=NULL;
	ExprTree	*expr=NULL;
	HashKey		hashval;
	MyString	key;
	const char	*attr_name = NULL;

	// This must always be the first entry in the log.
	log = new LogHistoricalSequenceNumber( historical_sequence_number, m_original_log_birthdate );
	if (log->Write(fp) < 0) {
		EXCEPT("write to %s failed, errno = %d", logFilename(), errno);
	}
	delete log;

	table.startIterations();
	while(table.iterate(ad) == 1) {
		table.getCurrentKey(hashval);
		hashval.sprint(key);
		log = new LogNewClassAd(key.Value(), GetMyTypeName(*ad), GetTargetTypeName(*ad));
		if (log->Write(fp) < 0) {
			EXCEPT("write to %s failed, errno = %d", logFilename(), errno);
		}
		delete log;
			// Unchain the ad -- we just want to write out this ads exprs,
			// not all the exprs in the chained ad as well.
		AttrList *chain = dynamic_cast<AttrList*>(ad->GetChainedParentAd());
		ad->Unchain();
		ad->ResetName();
		attr_name = ad->NextNameOriginal();
		while (attr_name) {
			expr = ad->LookupExpr(attr_name);
				// This conditional used to check whether the ExprTree is
				// invisible, but no codepath sets any attributes
				// invisible for this call.
			if (expr) {
				log = new LogSetAttribute(key.Value(), attr_name,
										  ExprTreeToString(expr));
				if (log->Write(fp) < 0) {
					EXCEPT("write to %s failed, errno = %d", logFilename(),
						   errno);
				}
				delete log;
			}
			attr_name = ad->NextNameOriginal();
		}
			// ok, now that we're done writing out this ad, restore the chain
		ad->ChainToAd(chain);
	}
	if (fflush(fp) !=0){
	  EXCEPT("fflush of %s failed, errno = %d", logFilename(), errno);
	}
	if (condor_fsync(fileno(fp)) < 0) {
		EXCEPT("fsync of %s failed, errno = %d", logFilename(), errno);
	} 
}
コード例 #3
0
bool ClassAdCollection::NewClassAd(const char* key, ClassAd* ad)
{
  LogRecord* log=new LogNewClassAd(key,GetMyTypeName(*ad),GetTargetTypeName(*ad));
  ClassAdLog::AppendLog(log);
  const char *name;
  ExprTree* expr;
  ad->ResetExpr();
  while (ad->NextExpr(name, expr)) {
    LogRecord* l=new LogSetAttribute(key,name,ExprTreeToString(expr));
    ClassAdLog::AppendLog(l);
  }
  // return AddClassAd(0,key);
  return true;
}
コード例 #4
0
ファイル: offline_plugin.cpp プロジェクト: AlainRoy/htcondor
bool 
OfflineCollectorPlugin::expire ( 
	ClassAd &ad )
{
	classad::Value result;
	bool val;

	dprintf (
		D_FULLDEBUG,
		"In OfflineCollectorPlugin::expire()\n" );

	/* bail out if the plug-in is not enabled, or if no ABSENT_REQUIREMENTS
	   have been defined */
	if ( !enabled() || !AbsentReq ) {
		return false;	// return false tells collector to delete this ad
	}

	/* for now, if the ad is of any type other than a startd ad, bail out. currently
	   absent ads only supported for ads of type Machine, because our offline storage
	   assumes that. */
	if ( strcmp(GetMyTypeName(ad),STARTD_ADTYPE) ) {
		return false;	// return false tells collector to delete this ad
	}
	/*	The ad may be a STARTD_PVT_ADTYPE, even though GetMyTypeName() claims 
		it is a STARTD_ADTYPE. Sigh. This is because the startd sends private 
		ads w/ the wrong type, because the query object queries private ads w/ the 
		wrong type. If I were to fix the startd to label private ads with the proper
		type, an incompatibility between startd/negotiator would have to be dealt with.
		So here we try to distinguish if this ad is really a STARTD_PVT_ADTYPE by seeing
		if a Capability attr is present and a State attr is not present. */
	if ( ad.Lookup(ATTR_CAPABILITY) && !ad.Lookup(ATTR_STATE) ) {
		// looks like a private ad, we don't want to store these
		return false;	// return false tells collector to delete this ad
	}


	/* If the ad is alraedy has ABSENT=True and it is expiring, then
	   let it be deleted as in this case it already sat around absent
	   for the absent lifetime. */
	bool already_absent = false;
	ad.LookupBool(ATTR_ABSENT,already_absent);
	if (already_absent) {
		MyString s;
		const char *key = makeOfflineKey(ad,s);
		if (key) {
			persistentRemoveAd(key);
		}
		return false; // return false tells collector to delete this ad
	}

	/* Test is ad against the absent requirements expression, and
	   mark the ad absent if true */
	if (EvalExprTree(AbsentReq,&ad,NULL,result) &&
		result.IsBooleanValue(val) && val) 
	{
		int lifetime, timestamp;

		lifetime = param_integer ( 
			"ABSENT_EXPIRE_ADS_AFTER",
			60 * 60 * 24 * 30 );	// default expire absent ads in a month		
		if ( lifetime == 0 ) lifetime = INT_MAX; // 0 means forever

		ad.Assign ( ATTR_ABSENT, true );
		ad.Assign ( ATTR_CLASSAD_LIFETIME, lifetime );
		timestamp = time(NULL);
		ad.Assign(ATTR_LAST_HEARD_FROM, timestamp);
		ad.Assign ( ATTR_MY_CURRENT_TIME, timestamp );
		persistentStoreAd(NULL,ad);
		// if we marked this ad as absent, we want to keep it in the collector
		return true;	// return true tells the collector to KEEP this ad
	}

	return false;	// return false tells collector to delete this ad
}
コード例 #5
0
ClassAd *CollectorEngine::
collect (int command,ClassAd *clientAd,const condor_sockaddr& from,int &insert,Sock *sock)
{
	ClassAd		*retVal;
	ClassAd		*pvtAd;
	int		insPvt;
	AdNameHashKey		hk;
	HashString	hashString;
	static int repeatStartdAds = -1;		// for debugging
	ClassAd		*clientAdToRepeat = NULL;
	_condor_auto_accum_runtime<collector_runtime_probe> rt(CollectorEngine_rucc_runtime);
	double rt_last = rt.begin;

	if (repeatStartdAds == -1) {
		repeatStartdAds = param_integer("COLLECTOR_REPEAT_STARTD_ADS",0);
	}

	if( !ValidateClassAd(command,clientAd,sock) ) {
		return NULL;
	}

	CollectorEngine_rucc_validateAd_runtime.Add(rt.tick(rt_last));

	// mux on command
	switch (command)
	{
	  case UPDATE_STARTD_AD:
	  case UPDATE_STARTD_AD_WITH_ACK:
		if ( repeatStartdAds > 0 ) {
			clientAdToRepeat = new ClassAd(*clientAd);
		}
		if (!makeStartdAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );

		CollectorEngine_rucc_makeHashKey_runtime.Add(rt.tick(rt_last));

		retVal=updateClassAd (StartdAds, "StartdAd     ", "Start",
							  clientAd, hk, hashString, insert, from );

		if (last_updateClassAd_was_insert) { CollectorEngine_rucc_insertAd_runtime.Add(rt.tick(rt_last));
		} else { CollectorEngine_rucc_updateAd_runtime.Add(rt.tick(rt_last)); }

		// if we want to store private ads
		if (!sock)
		{
			dprintf (D_ALWAYS, "Want private ads, but no socket given!\n");
			break;
		}
		else
		{
			if (!(pvtAd = new ClassAd))
			{
				EXCEPT ("Memory error!");
			}
			if( !getClassAd(sock, *pvtAd) )
			{
				dprintf(D_FULLDEBUG,"\t(Could not get startd's private ad)\n");
				delete pvtAd;
				break;
			}

				// Fix up some stuff in the private ad that we depend on.
				// We started doing this in 7.2.0, so once we no longer
				// care about compatibility with stuff from before then,
				// the startd could stop bothering to send these attributes.

				// Queries of private ads depend on the following:
			SetMyTypeName( *pvtAd, STARTD_ADTYPE );

				// Negotiator matches up private ad with public ad by
				// using the following.
			if( retVal ) {
				CopyAttribute( ATTR_MY_ADDRESS, *pvtAd, *retVal );
				CopyAttribute( ATTR_NAME, *pvtAd, *retVal );
			}

			CollectorEngine_rucc_getPvtAd_runtime.Add(rt.tick(rt_last));

			// insert the private ad into its hashtable --- use the same
			// hash key as the public ad
			(void) updateClassAd (StartdPrivateAds, "StartdPvtAd  ",
								  "StartdPvt", pvtAd, hk, hashString, insPvt,
								  from );
			if (last_updateClassAd_was_insert) { CollectorEngine_rucc_insertPvtAd_runtime.Add(rt.tick(rt_last));
			} else { CollectorEngine_rucc_updatePvtAd_runtime.Add(rt.tick(rt_last)); }
		}

		// create fake duplicates of this ad, each with a different name, if
		// we are told to do so.  this feature exists for developer
		// scalability testing.
		if ( repeatStartdAds > 0 && clientAdToRepeat ) {
			ClassAd *fakeAd;
			int n;
			char newname[150],oldname[130];
			oldname[0] = '\0';
			clientAdToRepeat->LookupString("Name",oldname,sizeof(oldname));
			for (n=0;n<repeatStartdAds;n++) {
				fakeAd = new ClassAd(*clientAdToRepeat);
				snprintf(newname,sizeof(newname),
						 "Name=\"fake%d-%s\"",n,oldname);
				fakeAd->Insert(newname);
				makeStartdAdHashKey (hk, fakeAd);
				hashString.Build( hk );
				if (! updateClassAd (StartdAds, "StartdAd     ", "Start",
							  fakeAd, hk, hashString, insert, from ) )
				{
					// don't leak memory if there is some failure
					delete fakeAd;
				}
			}
			delete clientAdToRepeat;
			clientAdToRepeat = NULL;
			CollectorEngine_rucc_repeatAd_runtime.Add(rt.tick(rt_last));
		}
		break;

	  case MERGE_STARTD_AD:
		if (!makeStartdAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=mergeClassAd (StartdAds, "StartdAd     ", "Start",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_SCHEDD_AD:
		if (!makeScheddAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=updateClassAd (ScheddAds, "ScheddAd     ", "Schedd",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_SUBMITTOR_AD:
		// use the same hashkey function as a schedd ad
		if (!makeScheddAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		// since submittor ads always follow a schedd ad, and a master check is
		// performed for schedd ads, we don't need a master check in here
		hashString.Build( hk );
		retVal=updateClassAd (SubmittorAds, "SubmittorAd  ", "Submittor",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_LICENSE_AD:
		// use the same hashkey function as a schedd ad
		if (!makeLicenseAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		// since submittor ads always follow a schedd ad, and a master check is
		// performed for schedd ads, we don't need a master check in here
		hashString.Build( hk );
		retVal=updateClassAd (LicenseAds, "LicenseAd  ", "License",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_MASTER_AD:
		if (!makeMasterAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=updateClassAd (MasterAds, "MasterAd     ", "Master",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_CKPT_SRVR_AD:
		if (!makeCkptSrvrAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=updateClassAd (CkptServerAds, "CkptSrvrAd   ", "CkptSrvr",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_COLLECTOR_AD:
		if (!makeCollectorAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=updateClassAd (CollectorAds, "CollectorAd  ", "Collector",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_STORAGE_AD:
		if (!makeStorageAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=updateClassAd (StorageAds, "StorageAd  ", "Storage",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_ACCOUNTING_AD:
		if (!makeAccountingAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=updateClassAd (AccountingAds, "AccountingAd  ", "Accouting",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_NEGOTIATOR_AD:
		if (!makeNegotiatorAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		if (m_allowOnlyOneNegotiator) {
			// first, purge all the existing negotiator ads, since we
			// want to enforce that *ONLY* 1 negotiator is in the
			// collector any given time.
			purgeHashTable( NegotiatorAds );
		}
		retVal=updateClassAd (NegotiatorAds, "NegotiatorAd  ", "Negotiator",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_HAD_AD:
		if (!makeHadAdHashKey (hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=updateClassAd (HadAds, "HadAd  ", "HAD",
							  clientAd, hk, hashString, insert, from );
		break;

	  case UPDATE_GRID_AD:
		if (!makeGridAdHashKey(hk, clientAd))
		{
			dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			insert = -3;
			retVal = 0;
			break;
		}
		hashString.Build( hk );
		retVal=updateClassAd (GridAds, "GridAd  ", "Grid",
							  clientAd, hk, hashString, insert, from );
          break;

	  case UPDATE_AD_GENERIC:
	  {
		  const char *type_str = GetMyTypeName(*clientAd);
		  if (type_str == NULL) {
			  dprintf(D_ALWAYS, "collect: UPDATE_AD_GENERIC: ad has no type\n");
			  insert = -3;
			  retVal = 0;
			  break;
		  }
		  MyString type(type_str);
		  CollectorHashTable *cht = findOrCreateTable(type);
		  if (cht == NULL) {
			  dprintf(D_ALWAYS, "collect: findOrCreateTable failed\n");
			  insert = -3;
			  retVal = 0;
			  break;
		  }
		  if (!makeGenericAdHashKey (hk, clientAd))
		  {
			  dprintf(D_ALWAYS, "Could not make hashkey --- ignoring ad\n");
			  insert = -3;
			  retVal = 0;
			  break;
		  }
		  hashString.Build(hk);
		  retVal = updateClassAd(*cht, type_str, type_str, clientAd,
					 hk, hashString, insert, from);
		  break;
	  }

	  case QUERY_STARTD_ADS:
	  case QUERY_SCHEDD_ADS:
	  case QUERY_MASTER_ADS:
	  case QUERY_SUBMITTOR_ADS:
	  case QUERY_CKPT_SRVR_ADS:
	  case QUERY_STARTD_PVT_ADS:
	  case QUERY_COLLECTOR_ADS:
  	  case QUERY_NEGOTIATOR_ADS:
  	  case QUERY_HAD_ADS:
	  case QUERY_GENERIC_ADS:
	  case INVALIDATE_STARTD_ADS:
	  case INVALIDATE_SCHEDD_ADS:
	  case INVALIDATE_MASTER_ADS:
	  case INVALIDATE_CKPT_SRVR_ADS:
	  case INVALIDATE_SUBMITTOR_ADS:
	  case INVALIDATE_COLLECTOR_ADS:
	  case INVALIDATE_NEGOTIATOR_ADS:
	  case INVALIDATE_HAD_ADS:
	  case INVALIDATE_ADS_GENERIC:
		// these are not implemented in the engine, but we allow another
		// daemon to detect that these commands have been given
	    insert = -2;
		retVal = 0;
	    break;

	  default:
		dprintf (D_ALWAYS, "Received illegal command: %d\n", command);
		insert = -1;
		retVal = 0;
	}

	if (command != UPDATE_STARTD_AD && command != UPDATE_STARTD_AD_WITH_ACK) {
		CollectorEngine_rucc_other_runtime.Add(rt.tick(rt_last));
	}


	// return the updated ad
	return retVal;
}