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; }
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; if (repeatStartdAds == -1) { repeatStartdAds = param_integer("COLLECTOR_REPEAT_STARTD_ADS",0); } if( !ValidateClassAd(command,clientAd,sock) ) { return NULL; } // mux on command switch (command) { case UPDATE_STARTD_AD: case UPDATE_STARTD_AD_WITH_ACK: #if !defined(WANT_OLD_CLASSADS) clientAd->AddTargetRefs( TargetJobAttrs ); #endif 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 ); retVal=updateClassAd (StartdAds, "StartdAd ", "Start", clientAd, hk, hashString, insert, from ); // 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( !pvtAd->initFromStream(*sock) ) { 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: pvtAd->SetMyTypeName( STARTD_ADTYPE ); // Negotiator matches up private ad with public ad by // using the following. if( retVal ) { pvtAd->CopyAttribute( ATTR_MY_ADDRESS, retVal ); pvtAd->CopyAttribute( ATTR_NAME, retVal ); } // 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 ); } // 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->InsertOrUpdate(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; } break; case MERGE_STARTD_AD: #if !defined(WANT_OLD_CLASSADS) clientAd->AddTargetRefs( TargetJobAttrs ); #endif 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; #ifdef HAVE_EXT_POSTGRESQL case UPDATE_QUILL_AD: if (!makeQuillAdHashKey (hk, clientAd)) { dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n"); insert = -3; retVal = 0; break; } hashString.Build( hk ); retVal=updateClassAd (QuillAds, "QuillAd ", "Quill", clientAd, hk, hashString, insert, from ); break; #endif /* HAVE_EXT_POSTGRESQL */ 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; } // CRUFT: Before 7.3.2, submitter ads had a MyType of // "Scheduler". The only way to tell the difference // was that submitter ads didn't have ATTR_NUM_USERS. // Coerce MyStype to "Submitter" for ads coming from // these older schedds. // Before 7.7.3, submitter ads for parallel universe // jobs had a MyType of "Scheduler". clientAd->SetMyTypeName( SUBMITTER_ADTYPE ); // 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_NEGOTIATOR_AD: if (!makeNegotiatorAdHashKey (hk, clientAd)) { dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n"); insert = -3; retVal = 0; break; } hashString.Build( hk ); // 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 = clientAd->GetMyTypeName(); 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 haskey --- 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 UPDATE_XFER_SERVICE_AD: if (!makeXferServiceAdHashKey (hk, clientAd)) { dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n"); insert = -3; retVal = 0; break; } hashString.Build( hk ); retVal=updateClassAd (XferServiceAds, "XferServiceAd ", "XferService", clientAd, hk, hashString, insert, from ); break; case UPDATE_LEASE_MANAGER_AD: if (!makeLeaseManagerAdHashKey (hk, clientAd)) { dprintf (D_ALWAYS, "Could not make hashkey --- ignoring ad\n"); insert = -3; retVal = 0; break; } hashString.Build( hk ); // first, purge all the existing LeaseManager ads, since we // want to enforce that *ONLY* 1 manager is in the // collector any given time. purgeHashTable( LeaseManagerAds ); retVal=updateClassAd (LeaseManagerAds, "LeaseManagerAd ", "LeaseManager", clientAd, hk, hashString, insert, from ); break; case QUERY_STARTD_ADS: case QUERY_SCHEDD_ADS: case QUERY_MASTER_ADS: case QUERY_GATEWAY_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_XFER_SERVICE_ADS: case QUERY_LEASE_MANAGER_ADS: case QUERY_GENERIC_ADS: case INVALIDATE_STARTD_ADS: case INVALIDATE_SCHEDD_ADS: case INVALIDATE_MASTER_ADS: case INVALIDATE_GATEWAY_ADS: case INVALIDATE_CKPT_SRVR_ADS: case INVALIDATE_SUBMITTOR_ADS: case INVALIDATE_COLLECTOR_ADS: case INVALIDATE_NEGOTIATOR_ADS: case INVALIDATE_HAD_ADS: case INVALIDATE_XFER_SERVICE_ADS: case INVALIDATE_LEASE_MANAGER_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; } // return the updated ad return retVal; }