bool caInsert( ClassAd* target, ClassAd* source, const char* attr, const char* prefix ) { ExprTree* tree; if( !attr ) { EXCEPT( "caInsert called with NULL attribute" ); } if( !target || !source ) { EXCEPT( "caInsert called with NULL classad" ); } MyString new_attr; if( prefix ) { new_attr = prefix; } new_attr += attr; tree = source->LookupExpr( attr ); if( !tree ) { target->Delete(new_attr.Value()); return false; } tree = tree->Copy(); if ( !target->Insert(new_attr.Value(), tree, false) ) { dprintf( D_ALWAYS, "caInsert: Can't insert %s into target classad.\n", attr ); delete tree; return false; } return true; }
void HookPrepareJobClient::hookExited(int exit_status) { HookClient::hookExited(exit_status); if (WIFSIGNALED(exit_status) || WEXITSTATUS(exit_status) != 0) { MyString status_msg = ""; statusString(exit_status, status_msg); int subcode; if (WIFSIGNALED(exit_status)) { subcode = -1 * WTERMSIG(exit_status); } else { subcode = WEXITSTATUS(exit_status); } MyString err_msg; err_msg.sprintf("HOOK_PREPARE_JOB (%s) failed (%s)", m_hook_path, status_msg.Value()); dprintf(D_ALWAYS|D_FAILURE, "ERROR in StarterHookMgr::tryHookPrepareJob: %s\n", err_msg.Value()); Starter->jic->notifyStarterError(err_msg.Value(), true, CONDOR_HOLD_CODE_HookPrepareJobFailure, subcode); Starter->RemoteShutdownFast(0); } else { // Make an update ad from the stdout of the hook MyString out(*getStdOut()); ClassAd updateAd; updateAd.initFromString(out.Value(), NULL); dprintf(D_FULLDEBUG, "Prepare hook output classad\n"); updateAd.dPrint(D_FULLDEBUG); // Insert each expr from the update ad into the job ad updateAd.ResetExpr(); ClassAd* job_ad = Starter->jic->jobClassAd(); const char *name; ExprTree *et; while (updateAd.NextExpr(name, et)) { ExprTree *pCopy = et->Copy(); job_ad->Insert(name, pCopy, false); } dprintf(D_FULLDEBUG, "After Prepare hook: merged job classad:\n"); job_ad->dPrint(D_FULLDEBUG); Starter->jobEnvironmentReady(); } }
void ParametricAd::checkInputSandbox(std::vector<std::string>& extracted){ GLITE_STACK_TRY("ParametricAd::checkInputSandbox(std::vector<std::string>&)"); // This vector contains all ISB string extracted Values unsigned int iter_i = extracted.size(); // This Vector will replace the old InputSanbox with the extracted values vector<ExprTree*> isVect ; ExprTree* isbTree = Lookup (JDL::INPUTSB); if (!isbTree){ /* No inputFiles found: return */ return; } // These variables are needed when extracting const string wmpURI = (hasAttribute(JDL::WMPISB_BASE_URI))? (getString(JDL::WMPISB_BASE_URI)):""; const string isbURI= (hasAttribute(JDL::ISB_BASE_URI)) ? (getString(JDL::ISB_BASE_URI) ):""; Value val ; string isb ; EvaluateExpr(isbTree,val); inputRemotes.clear(); switch ( val.GetType() ){ case Value::UNDEFINED_VALUE: inputRemotes.push_back(isbTree->Copy()); isVect.push_back(isbTree->Copy()); break; case Value::STRING_VALUE: val.IsStringValue(isb); toBretrieved=extractFiles (JDL::INPUTSB, isb, extracted, lookInto_b,wmpURI,isbURI,extractedAd.get()) || toBretrieved; // put the extracted files back into the InputSandbox attribute for(;iter_i<extracted.size();iter_i++){ // Iterate ONLY over new value(s) val.SetStringValue(extracted[iter_i]); // create classad Value isVect.push_back(Literal::MakeLiteral(val)); // Update ISB value } break; case Value::LIST_VALUE:{ const ExprList *el; val.IsListValue( el ); vector<ExprTree*> vectList ; el->GetComponents(vectList) ; for ( unsigned int i = 0; i< vectList.size() ; i++){ if (vectList[i]->GetKind()!=ExprTree::LITERAL_NODE){ // not a literal node inputRemotes.push_back( vectList[i]->Copy() ); isVect.push_back(vectList[i]->Copy()); } else if (vectList[i]->Evaluate(val)){ switch (val.GetType()){ case Value::STRING_VALUE: val.IsStringValue(isb); toBretrieved=extractFiles (JDL::INPUTSB, isb, extracted, lookInto_b,wmpURI,isbURI,extractedAd.get()) || toBretrieved; // put the extracted files back into the InputSandbox attribute for(;iter_i<extracted.size();iter_i++){ // Iterate ONLY over new value(s) val.SetStringValue(extracted[iter_i]); // create classad Value isVect.push_back(Literal::MakeLiteral(val)); // Update ISB value } break; case Value::UNDEFINED_VALUE: // It's an Expression evaluated inputRemotes.push_back( vectList[i]->Copy() ); isVect.push_back(vectList[i]->Copy()); break; default: throw AdMismatchException (__FILE__,__LINE__, METHOD,WMS_JDLMISMATCH , JDL::INPUTSB ); } }else{ // It's an Expression not evaluated, leave it unchanged inputRemotes.push_back( vectList[i]->Copy() ); isVect.push_back(vectList[i]->Copy()); } val.Clear() ; } } break; default: throw AdMismatchException (__FILE__ , __LINE__ ,METHOD, WMS_JDLMISMATCH , JDL::INPUTSB ); break; } classad:ExprTree* tmp_expr = ExprList::MakeExprList(isVect); Insert (JDL::INPUTSB , tmp_expr) ; GLITE_STACK_JDL_CATCH_ALL() ; //Exiting from method: remove line from stack trace }
int ClassAdLog::ExamineTransaction(const char *key, const char *name, char *&val, ClassAd* &ad) { bool AdDeleted=false, ValDeleted=false, ValFound=false; int attrsAdded = 0; if (!active_transaction) return 0; for (LogRecord *log = active_transaction->FirstEntry(key); log; log = active_transaction->NextEntry()) { switch (log->get_op_type()) { case CondorLogOp_NewClassAd: { if (AdDeleted) { // check to see if ad is created after a delete AdDeleted = false; } break; } case CondorLogOp_DestroyClassAd: { AdDeleted = true; if ( ad ) { delete ad; ad = NULL; attrsAdded = 0; } break; } case CondorLogOp_SetAttribute: { char const *lname = ((LogSetAttribute *)log)->get_name(); if (name && strcasecmp(lname, name) == 0) { if (ValFound) { free(val); } val = strdup(((LogSetAttribute *)log)->get_value()); ValFound = true; ValDeleted = false; } if (!name) { if ( !ad ) { ad = new ClassAd; ASSERT(ad); } if (val) { free(val); val = NULL; } ExprTree* expr = ((LogSetAttribute *)log)->get_expr(); if (expr) { expr = expr->Copy(); ad->Insert(lname, expr, false); } else { val = strdup(((LogSetAttribute *)log)->get_value()); ad->AssignExpr(lname, val); } attrsAdded++; } break; } case CondorLogOp_DeleteAttribute: { char const *lname = ((LogDeleteAttribute *)log)->get_name(); if (name && strcasecmp(lname, name) == 0) { if (ValFound) { free(val); } ValFound = false; ValDeleted = true; } if (!name) { if (ad) { ad->Delete(lname); attrsAdded--; } } break; } default: break; } } if ( name ) { if (AdDeleted || ValDeleted) return -1; if (ValFound) return 1; return 0; } else { if (attrsAdded < 0 ) { return 0; } return attrsAdded; } }
// download the files associated with the jobads to the sandbox at td_sinful // with the supplied capability. // The work_ad should contain: // ATTR_TREQ_CAPABILITY // ATTR_TREQ_FTP // ATTR_TREQ_JOBID_ALLOW_LIST bool DCTransferD::download_job_files(ClassAd *work_ad, CondorError * errstack) { ReliSock *rsock = NULL; int timeout = 60 * 60 * 8; // transfers take a long time... int i; ClassAd reqad, respad; std::string cap; int ftp; int invalid; int protocol; std::string reason; int num_transfers; ClassAd jad; const char *lhstr = NULL; ExprTree *tree = NULL; ////////////////////////////////////////////////////////////////////////// // Connect to the transferd and authenticate ////////////////////////////////////////////////////////////////////////// // This call with automatically connect to _addr, which was set in the // constructor of this object to be the transferd in question. rsock = (ReliSock*)startCommand(TRANSFERD_READ_FILES, Stream::reli_sock, timeout, errstack); if( ! rsock ) { dprintf( D_ALWAYS, "DCTransferD::download_job_files: " "Failed to send command (TRANSFERD_READ_FILES) " "to the schedd\n" ); errstack->push("DC_TRANSFERD", 1, "Failed to start a TRANSFERD_READ_FILES command."); return false; } // First, if we're not already authenticated, force that now. if (!forceAuthentication( rsock, errstack )) { dprintf( D_ALWAYS, "DCTransferD::download_job_files() authentication " "failure: %s\n", errstack->getFullText().c_str() ); errstack->push("DC_TRANSFERD", 1, "Failed to authenticate properly."); return false; } rsock->encode(); ////////////////////////////////////////////////////////////////////////// // Query the transferd about the capability/protocol and see if I can // download my files. It will respond with a classad saying good or bad. ////////////////////////////////////////////////////////////////////////// work_ad->LookupString(ATTR_TREQ_CAPABILITY, cap); work_ad->LookupInteger(ATTR_TREQ_FTP, ftp); reqad.Assign(ATTR_TREQ_CAPABILITY, cap); reqad.Assign(ATTR_TREQ_FTP, ftp); // This request ad to the transferd should contain: // ATTR_TREQ_CAPABILITY // ATTR_TREQ_FTP reqad.put(*rsock); rsock->end_of_message(); rsock->decode(); // This response ad from the transferd should contain: // ATTR_TREQ_INVALID_REQUEST (set to true) // ATTR_TREQ_INVALID_REASON // // OR // // ATTR_TREQ_INVALID_REQUEST (set to false) // ATTR_TREQ_NUM_TRANSFERS // respad.initFromStream(*rsock); rsock->end_of_message(); respad.LookupInteger(ATTR_TREQ_INVALID_REQUEST, invalid); if (invalid == TRUE) { // The transferd rejected my attempt to upload the fileset delete rsock; respad.LookupString(ATTR_TREQ_INVALID_REASON, reason); errstack->push("DC_TRANSFERD", 1, reason.c_str()); return false; } respad.LookupInteger(ATTR_TREQ_NUM_TRANSFERS, num_transfers); ////////////////////////////////////////////////////////////////////////// // Based upon the protocol I've chosen, use that method to download the // files. When using the FileTrans protocol, a child process on the // transferd side will be sending me individual job ads and then // instantiating a filetransfer object for that ad. ////////////////////////////////////////////////////////////////////////// dprintf(D_ALWAYS, "Receiving fileset"); work_ad->LookupInteger(ATTR_TREQ_FTP, protocol); switch(protocol) { case FTP_CFTP: // download the files using the FileTransfer Object for (i = 0; i < num_transfers; i++) { // Grab a job ad the server is sending us so we know what // to receive. jad.initFromStream(*rsock); rsock->end_of_message(); // translate the job ad by replacing the // saved SUBMIT_ attributes so the download goes into the // correct place. jad.ResetExpr(); while( jad.NextExpr(lhstr, tree) ) { if ( lhstr && strncasecmp("SUBMIT_",lhstr,7)==0 ) { // this attr name starts with SUBMIT_ // compute new lhs (strip off the SUBMIT_) const char *new_attr_name = strchr(lhstr,'_'); ExprTree * pTree; ASSERT(new_attr_name); new_attr_name++; // insert attribute pTree = tree->Copy(); jad.Insert(new_attr_name, pTree, false); } } // while next expr // instantiate a filetransfer object and have it accept the // files. FileTransfer ftrans; if ( !ftrans.SimpleInit(&jad, false, false, rsock) ) { delete rsock; errstack->push("DC_TRANSFERD", 1, "Failed to initate uploading of files."); return false; } // We want files to be copied to their final places, so apply // any filename remaps when downloading. if ( !ftrans.InitDownloadFilenameRemaps(&jad) ) { return false; } ftrans.setPeerVersion( version() ); if ( !ftrans.DownloadFiles() ) { delete rsock; errstack->push("DC_TRANSFERD", 1, "Failed to download files."); return false; } dprintf(D_ALWAYS | D_NOHEADER, "."); } rsock->end_of_message(); dprintf(D_ALWAYS | D_NOHEADER, "\n"); break; default: // Bail due to user error. This client doesn't support the unknown // protocol. delete rsock; errstack->push("DC_TRANSFERD", 1, "Unknown file transfer protocol selected."); return false; break; } ////////////////////////////////////////////////////////////////////////// // Get the response from the transferd once it sees a completed // movement of files to the child process. ////////////////////////////////////////////////////////////////////////// rsock->decode(); respad.initFromStream(*rsock); rsock->end_of_message(); // close up shop delete rsock; respad.LookupInteger(ATTR_TREQ_INVALID_REQUEST, invalid); if ( invalid == TRUE ) { respad.LookupString(ATTR_TREQ_INVALID_REASON, reason); errstack->push("DC_TRANSFERD", 1, reason.c_str()); return false; } return true; }
void BaseJob::JobAdUpdateFromSchedd( const ClassAd *new_ad, bool full_ad ) { static const char *held_removed_update_attrs[] = { ATTR_JOB_STATUS, ATTR_HOLD_REASON, ATTR_HOLD_REASON_CODE, ATTR_HOLD_REASON_SUBCODE, ATTR_LAST_HOLD_REASON, ATTR_RELEASE_REASON, ATTR_LAST_RELEASE_REASON, ATTR_ENTERED_CURRENT_STATUS, ATTR_NUM_SYSTEM_HOLDS, ATTR_REMOVE_REASON, NULL }; int new_condor_state; new_ad->LookupInteger( ATTR_JOB_STATUS, new_condor_state ); if ( new_condor_state == condorState ) { if ( !full_ad ) { MergeClassAds( jobAd, const_cast<ClassAd*>(new_ad), true, false ); } return; } if ( new_condor_state == REMOVED && condorState == HELD ) { int release_status = IDLE; jobAd->LookupInteger( ATTR_JOB_STATUS_ON_RELEASE, release_status ); if ( release_status == REMOVED ) { // We already know about this REMOVED state and have // decided to go on hold afterwards, so ignore this // "update". return; } } if ( new_condor_state == REMOVED || new_condor_state == HELD ) { for ( int i = 0; held_removed_update_attrs[i] != NULL; i++ ) { ExprTree *expr; if ( (expr = new_ad->LookupExpr( held_removed_update_attrs[i] )) != NULL ) { ExprTree * pTree = expr->Copy(); jobAd->Insert( held_removed_update_attrs[i], pTree, false ); } else { jobAd->Delete( held_removed_update_attrs[i] ); } jobAd->SetDirtyFlag( held_removed_update_attrs[i], false ); } if ( new_condor_state == HELD && writeUserLog && !holdLogged ) { // TODO should this log event be delayed until gridmanager is // done dealing with the job? WriteHoldEventToUserLog( jobAd ); holdLogged = true; } // If we're about to put a job on hold and learn that it's been // removed, make sure the state returns to removed when it is // released. This is normally checked in JobHeld(), but it's // possible to learn of the removal just as we're about to // update the schedd with the hold. if ( new_condor_state == REMOVED && condorState == HELD ) { bool dirty; jobAd->GetDirtyFlag( ATTR_JOB_STATUS, NULL, &dirty ); if ( dirty ) { jobAd->Assign( ATTR_JOB_STATUS_ON_RELEASE, REMOVED ); } } condorState = new_condor_state; // TODO do we need to call UpdateRuntimeStats() here? UpdateRuntimeStats(); SetEvaluateState(); } else if ( new_condor_state == COMPLETED ) { condorState = new_condor_state; // TODO do we need to update any other attributes? SetEvaluateState(); } else if ( !full_ad ) { MergeClassAds( jobAd, const_cast<ClassAd*>(new_ad), true, false ); } }
bool DCSchedd::receiveJobSandbox(const char* constraint, CondorError * errstack, int * numdone /*=0*/) { if(numdone) { *numdone = 0; } ExprTree *tree = NULL; const char *lhstr; int reply; int i; ReliSock rsock; int JobAdsArrayLen; bool use_new_command = true; if ( version() ) { CondorVersionInfo vi( version() ); if ( vi.built_since_version(6,7,7) ) { use_new_command = true; } else { use_new_command = false; } } // // // // // // // // // On the wire protocol // // // // // // // // rsock.timeout(20); // years of research... :) if( ! rsock.connect(_addr) ) { dprintf( D_ALWAYS, "DCSchedd::receiveJobSandbox: " "Failed to connect to schedd (%s)\n", _addr ); return false; } if ( use_new_command ) { if( ! startCommand(TRANSFER_DATA_WITH_PERMS, (Sock*)&rsock, 0, errstack) ) { dprintf( D_ALWAYS, "DCSchedd::receiveJobSandbox: " "Failed to send command (TRANSFER_DATA_WITH_PERMS) " "to the schedd\n" ); return false; } } else { if( ! startCommand(TRANSFER_DATA, (Sock*)&rsock, 0, errstack) ) { dprintf( D_ALWAYS, "DCSchedd::receiveJobSandbox: " "Failed to send command (TRANSFER_DATA) " "to the schedd\n" ); return false; } } // First, if we're not already authenticated, force that now. if (!forceAuthentication( &rsock, errstack )) { dprintf( D_ALWAYS, "DCSchedd::receiveJobSandbox: authentication failure: %s\n", errstack ? errstack->getFullText().c_str() : "" ); return false; } rsock.encode(); // Send our version if using the new command if ( use_new_command ) { // Need to use a named variable, else the wrong version of // code() is called. char *my_version = strdup( CondorVersion() ); if ( !rsock.code(my_version) ) { dprintf(D_ALWAYS,"DCSchedd:receiveJobSandbox: " "Can't send version string to the schedd\n"); free( my_version ); return false; } free( my_version ); } // Send the constraint char * nc_constraint = strdup( constraint ); // de-const if ( !rsock.code(nc_constraint) ) { free( nc_constraint ); dprintf(D_ALWAYS,"DCSchedd:receiveJobSandbox: " "Can't send JobAdsArrayLen to the schedd\n"); return false; } free( nc_constraint ); if ( !rsock.end_of_message() ) { std::string errmsg; formatstr(errmsg, "Can't send initial message (version + constraint) to schedd (%s)", _addr); dprintf(D_ALWAYS,"DCSchedd::receiveJobSandbox: %s\n", errmsg.c_str()); if( errstack ) { errstack->push( "DCSchedd::receiveJobSandbox", CEDAR_ERR_EOM_FAILED, errmsg.c_str()); } return false; } // Now, read how many jobs matched the constraint. rsock.decode(); if ( !rsock.code(JobAdsArrayLen) ) { std::string errmsg; formatstr(errmsg, "Can't receive JobAdsArrayLen from the schedd (%s)", _addr); dprintf(D_ALWAYS,"DCSchedd::receiveJobSandbox: %s\n", errmsg.c_str()); if( errstack ) { errstack->push( "DCSchedd::receiveJobSandbox", CEDAR_ERR_GET_FAILED, errmsg.c_str()); } return false; } rsock.end_of_message(); dprintf(D_FULLDEBUG,"DCSchedd:receiveJobSandbox: " "%d jobs matched my constraint (%s)\n", JobAdsArrayLen, constraint); // Now read all the files via the file transfer object for (i=0; i<JobAdsArrayLen; i++) { FileTransfer ftrans; ClassAd job; // grab job ClassAd if ( !getClassAd(&rsock, job) ) { std::string errmsg; formatstr(errmsg, "Can't receive job ad %d from the schedd", i); dprintf(D_ALWAYS, "DCSchedd::receiveJobSandbox: %s\n", errmsg.c_str()); if( errstack ) { errstack->push( "DCSchedd::receiveJobSandbox", CEDAR_ERR_GET_FAILED, errmsg.c_str()); } return false; } rsock.end_of_message(); // translate the job ad by replacing the // saved SUBMIT_ attributes job.ResetExpr(); while( job.NextExpr(lhstr, tree) ) { if ( lhstr && strncasecmp("SUBMIT_",lhstr,7)==0 ) { // this attr name starts with SUBMIT_ // compute new lhs (strip off the SUBMIT_) const char *new_attr_name = strchr(lhstr,'_'); ExprTree * pTree; ASSERT(new_attr_name); new_attr_name++; // insert attribute pTree = tree->Copy(); job.Insert(new_attr_name, pTree, false); } } // while next expr if ( !ftrans.SimpleInit(&job,false,false,&rsock) ) { if( errstack ) { int cluster = -1, proc = -1; job.LookupInteger(ATTR_CLUSTER_ID,cluster); job.LookupInteger(ATTR_PROC_ID,proc); errstack->pushf( "DCSchedd::receiveJobSandbox", FILETRANSFER_INIT_FAILED, "File transfer initialization failed for target job %d.%d", cluster, proc ); } return false; } // We want files to be copied to their final places, so apply // any filename remaps when downloading. if ( !ftrans.InitDownloadFilenameRemaps(&job) ) { return false; } if ( use_new_command ) { ftrans.setPeerVersion( version() ); } if ( !ftrans.DownloadFiles() ) { if( errstack ) { FileTransfer::FileTransferInfo ft_info = ftrans.GetInfo(); int cluster = -1, proc = -1; job.LookupInteger(ATTR_CLUSTER_ID,cluster); job.LookupInteger(ATTR_PROC_ID,proc); errstack->pushf( "DCSchedd::receiveJobSandbox", FILETRANSFER_DOWNLOAD_FAILED, "File transfer failed for target job %d.%d: %s", cluster, proc, ft_info.error_desc.Value() ); } return false; } } rsock.end_of_message(); rsock.encode(); reply = OK; rsock.code(reply); rsock.end_of_message(); if(numdone) { *numdone = JobAdsArrayLen; } return true; }
void VMUniverseMgr::publish( ClassAd* ad, amask_t /*mask*/ ) { if( !ad ) { return; } if( !m_starter_has_vmcode || ( m_vm_type.Length() == 0 )) { ad->Assign(ATTR_HAS_VM, false); return; } ad->Assign(ATTR_HAS_VM, true); // publish the number of still executable Virtual machines if( m_vm_max_num > 0 ) { int avail_vm_num = m_vm_max_num - numOfRunningVM(); ad->Assign(ATTR_VM_AVAIL_NUM, avail_vm_num); }else { // no limit of the number of executable VM ad->Assign(ATTR_VM_AVAIL_NUM, VM_AVAIL_UNLIMITED_NUM); } // we will publish all information provided by vmgahp server m_vmgahp_info.ResetExpr(); ExprTree* expr = NULL; const char *attr_name = NULL; while(m_vmgahp_info.NextExpr(attr_name, expr)) { // we need to adjust available vm memory if( strcasecmp(attr_name, ATTR_VM_MEMORY) == MATCH ) { int freemem = getFreeVMMemSize(); ad->Assign(ATTR_VM_MEMORY, freemem); }else if( strcasecmp(attr_name, ATTR_VM_NETWORKING) == MATCH ) { ad->Assign(ATTR_VM_NETWORKING, m_vm_networking); }else { ExprTree * pTree = expr->Copy(); ad->Insert(attr_name, pTree, false); } } // Now, we will publish mac and ip addresses of all guest VMs. MyString all_macs; MyString all_ips; VMStarterInfo *info = NULL; const char* guest_ip = NULL; const char* guest_mac = NULL; m_vm_starter_list.Rewind(); while( m_vm_starter_list.Next(info) ) { guest_ip = info->getIPForVM(); if( guest_ip ) { if( all_ips.IsEmpty() == false ) { all_ips += ","; } all_ips += guest_ip; } guest_mac = info->getMACForVM(); if( guest_mac ) { if( all_macs.IsEmpty() == false ) { all_macs += ","; } all_macs += guest_mac; } } if( all_ips.IsEmpty() == false ) { ad->Assign(ATTR_VM_ALL_GUEST_IPS, all_ips); } if( all_macs.IsEmpty() == false ) { ad->Assign(ATTR_VM_ALL_GUEST_MACS, all_macs); } }
void VMRegister::requestHostClassAds(void) { // find host startd daemon if( !m_vm_host_daemon ) m_vm_host_daemon = vmapi_findDaemon( m_vm_host_name, DT_STARTD); if( !m_vm_host_daemon ) { dprintf( D_FULLDEBUG, "Can't find host(%s) Startd daemon\n", m_vm_host_name ); return; } ClassAd query_ad; query_ad.SetMyTypeName(QUERY_ADTYPE); query_ad.SetTargetTypeName(STARTD_ADTYPE); query_ad.Assign(ATTR_REQUIREMENTS, true); char *addr = m_vm_host_daemon->addr(); Daemon hstartd(DT_STARTD, addr); ReliSock ssock; ssock.timeout( VM_SOCKET_TIMEOUT ); ssock.encode(); if( !ssock.connect(addr) ) { dprintf( D_FULLDEBUG, "Failed to connect to host startd(%s)\n to get host classAd", addr); return; } if(!hstartd.startCommand( QUERY_STARTD_ADS, &ssock )) { dprintf( D_FULLDEBUG, "Failed to send QUERY_STARTD_ADS command to host startd(%s)\n", addr); return; } if( !query_ad.put(ssock) ) { dprintf(D_FULLDEBUG, "Failed to send query Ad to host startd(%s)\n", addr); } if( !ssock.end_of_message() ) { dprintf(D_FULLDEBUG, "Failed to send query EOM to host startd(%s)\n", addr); } // Read host classAds ssock.timeout( VM_SOCKET_TIMEOUT ); ssock.decode(); int more = 1, num_ads = 0; ClassAdList adList; ClassAd *ad; while (more) { if( !ssock.code(more) ) { ssock.end_of_message(); return; } if(more) { ad = new ClassAd; if( !ad->initFromStream(ssock) ) { ssock.end_of_message(); delete ad; return; } adList.Insert(ad); num_ads++; } } ssock.end_of_message(); dprintf(D_FULLDEBUG, "Got %d classAds from host\n", num_ads); // Although we can get more than one classAd from host machine, // we use only the first one classAd adList.Rewind(); ad = adList.Next(); #if !defined(WANT_OLD_CLASSADS) ad->AddTargetRefs( TargetJobAttrs ); #endif // Get each Attribute from the classAd // added "HOST_" in front of each Attribute name const char *name; ExprTree *expr; ad->ResetExpr(); while( ad->NextExpr(name, expr) ) { MyString attr; attr += "HOST_"; attr += name; // Insert or Update an attribute to host_classAd in a VMRegister object ExprTree * pTree = expr->Copy(); host_classad->Insert(attr.Value(), pTree, true); } }