예제 #1
0
파일: util.cpp 프로젝트: AlainRoy/htcondor
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;
}
예제 #2
0
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();
	}
}
예제 #3
0
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
}
예제 #4
0
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;
	}
}
예제 #5
0
// 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;
}
예제 #6
0
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 );
    }

}
예제 #7
0
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;
}
예제 #8
0
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);
	}
}
예제 #9
0
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);
	}
}