示例#1
0
QuillErrCode FILESQL::file_updateEvent(const char *eventType, 
									   AttrList *info, 
									   AttrList *condition) {
	int retval = 0;
	struct stat file_status;

    if (is_dummy) return QUILL_SUCCESS;
	if(!is_open)
	{
		dprintf(D_ALWAYS,"Error in logging event to Quill SQL Log : File not open\n");
		return QUILL_FAILURE;
	}

	if(file_lock() == QUILL_FAILURE) {
		return QUILL_FAILURE;
	}

	fstat(outfiledes, &file_status);

		// only write to the log if it's not exceeding the log size limit
	if (file_status.st_size < FILESIZELIMT) {
		retval = write(outfiledes,"UPDATE ", strlen("UPDATE "));
		retval = write(outfiledes,eventType, strlen(eventType));
		retval = write(outfiledes,"\n", strlen("\n"));

		MyString temp, temp1;
		const char *tempv;

		retval = sPrintAd(temp, *info);
		tempv = temp.Value();
		retval = write(outfiledes,tempv, strlen(tempv));

		retval = write(outfiledes,"***",3); /* Now the delimitor*/
		retval = write(outfiledes,"\n",1); /* Now the newline*/

		retval = sPrintAd(temp1, *condition);
		tempv = temp1.Value();
		retval = write(outfiledes,tempv, strlen(tempv));
		
		retval = write(outfiledes,"***",3); /* Now the delimitor*/
		retval = write(outfiledes,"\n",1); /* Now the newline*/	
	}

	if(file_unlock() == QUILL_FAILURE) {
		return QUILL_FAILURE;
	}

	if (retval < 0) {
		return QUILL_FAILURE;	
	} else {
		return QUILL_SUCCESS;	
	}
}
示例#2
0
//function:getQpidPort- reads port # from the classAd
char* getQpidPort(char *hName){
  
  config();
  char* port;
  MyString daemonHost = "pigeon@";

  daemonHost += hName;
  DaemonAllowLocateFull dObj(DT_GENERIC, daemonHost.Value(), NULL);
  dObj.setSubsystem("PIGEON");
  bool flag = dObj.locate(Daemon::LOCATE_FULL);
  if(!flag){
  	fprintf(stderr, "Problem locating daemon object: %s \n", dObj.error());
    return NULL;
  }
  
  ClassAd *qpidAd = dObj.daemonAd();

  if(qpidAd){
    MyString inBuf="";
    sPrintAd(inBuf, *qpidAd);
    char* start =strstr(inBuf.Value(),"PORT =");
    char* end =strstr(start,"\n");
    int len = end - start -9;
    port = (char*)malloc(sizeof(len+1));

    char *ports = strncpy(port,start+8,len);
    port[len]='\0';
    ports = NULL;
  } else {
  	fprintf(stderr, "Problem retrieving pigeon Ad \n");
  }

  return (port);
}
示例#3
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;
		sPrintAd(msg_str, msg);
		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() );
}
示例#4
0
int TransferQueueManager::HandleRequest(int cmd,Stream *stream)
{
	ReliSock *sock = (ReliSock *)stream;
	ASSERT( cmd == TRANSFER_QUEUE_REQUEST );

	ClassAd msg;
	sock->decode();
	if( !getClassAd( sock, msg ) || !sock->end_of_message() ) {
		dprintf(D_ALWAYS,
				"TransferQueueManager: failed to receive transfer request "
				"from %s.\n", sock->peer_description() );
		return FALSE;
	}

	bool downloading = false;
	MyString fname;
	MyString jobid;
	MyString queue_user;
	filesize_t sandbox_size;
	if( !msg.LookupBool(ATTR_DOWNLOADING,downloading) ||
		!msg.LookupString(ATTR_FILE_NAME,fname) ||
		!msg.LookupString(ATTR_JOB_ID,jobid) ||
		!msg.LookupString(ATTR_USER,queue_user) ||
		!msg.LookupInteger(ATTR_SANDBOX_SIZE,sandbox_size))
	{
		MyString msg_str;
		sPrintAd(msg_str, msg);
		dprintf(D_ALWAYS,"TransferQueueManager: invalid request from %s: %s\n",
				sock->peer_description(), msg_str.Value());
		return FALSE;
	}

		// Currently, we just create the client with the default max queue
		// age.  If it becomes necessary to customize the maximum age
		// on a case-by-case basis, it should be easy to adjust.

	TransferQueueRequest *client =
		new TransferQueueRequest(
			sock,
			sandbox_size,
			fname.Value(),
			jobid.Value(),
			queue_user.Value(),
			downloading,
			m_default_max_queue_age);

	if( !AddRequest( client ) ) {
		delete client;
		return KEEP_STREAM; // we have already closed this socket
	}

	return KEEP_STREAM;
}
示例#5
0
bool BaseResource::SendUpdate () {

    ClassAd ad;

	/* Set the correct types */
    SetMyTypeName ( ad, GRID_ADTYPE );

    /* populate class ad with the relevant resource information */
    PublishResourceAd ( &ad );

	daemonCore->publish( &ad );

	std::string tmp;
    sPrintAd ( tmp, ad );
    dprintf (
        D_FULLDEBUG,
        "BaseResource::UpdateResource: \n%s\n",
        tmp.c_str() );

	return daemonCore->sendUpdates( UPDATE_GRID_AD, &ad, NULL, true ) > 0;
}
示例#6
0
bool
CCBListener::ReadMsgFromCCB()
{
	if( !m_sock ) {
		return false;
	}
	m_sock->timeout(CCB_TIMEOUT);
	ClassAd msg;
	if( !getClassAd( m_sock, msg ) || !m_sock->end_of_message() ) {
		dprintf(D_ALWAYS,
				"CCBListener: failed to receive message from CCB server %s\n",
				m_ccb_address.Value());
		Disconnected();
		return false;
	}

	m_last_contact_from_peer = time(NULL);
	RescheduleHeartbeat();

	int cmd = -1;
	msg.LookupInteger( ATTR_COMMAND, cmd );
	switch( cmd ) {
	case CCB_REGISTER:
		return HandleCCBRegistrationReply( msg );
	case CCB_REQUEST:
		return HandleCCBRequest( msg );
	case ALIVE:
		dprintf(D_FULLDEBUG,"CCBListener: received heartbeat from server.\n");
		return true;
	}

	MyString msg_str;
	sPrintAd(msg_str, msg);
	dprintf( D_ALWAYS,
			 "CCBListener: Unexpected message received from CCB "
			 "server: %s\n",
			 msg_str.Value() );
	return false;
}
示例#7
0
bool
CCBListener::HandleCCBRegistrationReply( ClassAd &msg )
{
	if( !msg.LookupString(ATTR_CCBID,m_ccbid) ) {
		MyString msg_str;
		sPrintAd(msg_str, msg);
		EXCEPT("CCBListener: no ccbid in registration reply: %s",
			   msg_str.Value() );
	}
	msg.LookupString(ATTR_CLAIM_ID,m_reconnect_cookie);
	dprintf(D_ALWAYS,
			"CCBListener: registered with CCB server %s as ccbid %s",
			m_ccb_address.Value(),
			m_ccbid.Value() );

	m_waiting_for_registration = false;
	m_registered = true;

	daemonCore->daemonContactInfoChanged();

	return true;
}
示例#8
0
bool DCSchedd::getJobConnectInfo(
	PROC_ID jobid,
	int subproc,
	char const *session_info,
	int timeout,
	CondorError *errstack,
	MyString &starter_addr,
	MyString &starter_claim_id,
	MyString &starter_version,
	MyString &slot_name,
	MyString &error_msg,
	bool &retry_is_sensible,
	int &job_status,
	MyString &hold_reason)
{
	ClassAd input;
	ClassAd output;

	input.Assign(ATTR_CLUSTER_ID,jobid.cluster);
	input.Assign(ATTR_PROC_ID,jobid.proc);
	if( subproc != -1 ) {
		input.Assign(ATTR_SUB_PROC_ID,subproc);
	}
	input.Assign(ATTR_SESSION_INFO,session_info);

	ReliSock sock;
	if( !connectSock(&sock,timeout,errstack) ) {
		error_msg = "Failed to connect to schedd";
		dprintf( D_ALWAYS, "%s\n",error_msg.Value());
		return false;
	}

	if( !startCommand(GET_JOB_CONNECT_INFO, &sock, timeout, errstack) ) {
		error_msg = "Failed to send GET_JOB_CONNECT_INFO to schedd";
		dprintf( D_ALWAYS, "%s\n",error_msg.Value());
		return false;
	}

	if( !forceAuthentication(&sock, errstack) ) {
		error_msg = "Failed to authenticate";
		dprintf( D_ALWAYS, "%s\n",error_msg.Value());
		return false;
	}

	sock.encode();
	if( !putClassAd(&sock, input) || !sock.end_of_message() ) {
		error_msg = "Failed to send GET_JOB_CONNECT_INFO to schedd";
		dprintf( D_ALWAYS, "%s\n",error_msg.Value());
		return false;
	}

	sock.decode();
	if( !getClassAd(&sock, output) || !sock.end_of_message() ) {
		error_msg = "Failed to get response from schedd";
		dprintf( D_ALWAYS, "%s\n",error_msg.Value());
		return false;
	}

	if( IsFulldebug(D_FULLDEBUG) ) {
		std::string adstr;
		sPrintAd(adstr, output, true);
		dprintf(D_FULLDEBUG,"Response for GET_JOB_CONNECT_INFO:\n%s\n",
				adstr.c_str());
	}

	bool result=false;
	output.LookupBool(ATTR_RESULT,result);

	if( !result ) {
		output.LookupString(ATTR_HOLD_REASON,hold_reason);
		output.LookupString(ATTR_ERROR_STRING,error_msg);
		retry_is_sensible = false;
		output.LookupBool(ATTR_RETRY,retry_is_sensible);
		output.LookupInteger(ATTR_JOB_STATUS,job_status);
	}
	else {
		output.LookupString(ATTR_STARTER_IP_ADDR,starter_addr);
		output.LookupString(ATTR_CLAIM_ID,starter_claim_id);
		output.LookupString(ATTR_VERSION,starter_version);
		output.LookupString(ATTR_REMOTE_HOST,slot_name);
	}

	return result;
}
示例#9
0
void
CCBServer::HandleRequestResultsMsg( CCBTarget *target )
{
		// Reply from target daemon about whether it succeeded in
		// connecting to the requested client.

	Sock *sock = target->getSock();

	ClassAd msg;
	sock->decode();
	if( !getClassAd( sock, msg ) || !sock->end_of_message() ) {
			// disconnect
		dprintf(D_FULLDEBUG,
				"CCB: received disconnect from target daemon %s "
				"with ccbid %lu.\n",
				sock->peer_description(), target->getCCBID() );
		RemoveTarget( target );
		return;
	}

	int command = 0;
	if( msg.LookupInteger( ATTR_COMMAND, command ) && command == ALIVE ) {
		SendHeartbeatResponse( target );
		return;
	}

	target->decPendingRequestResults();

	bool success = false;
	MyString error_msg;
	MyString reqid_str;
	CCBID reqid;
	MyString connect_id;
	msg.LookupBool( ATTR_RESULT, success );
	msg.LookupString( ATTR_ERROR_STRING, error_msg );
	msg.LookupString( ATTR_REQUEST_ID, reqid_str );
	msg.LookupString( ATTR_CLAIM_ID, connect_id );

	if( !CCBIDFromString( reqid, reqid_str.Value() ) ) {
		MyString msg_str;
		sPrintAd(msg_str, msg);
		dprintf(D_ALWAYS,
				"CCB: received reply from target daemon %s with ccbid %lu "
				"without a valid request id: %s\n",
				sock->peer_description(),
				target->getCCBID(),
				msg_str.Value());
		RemoveTarget( target );
		return;
	}

	CCBServerRequest *request = GetRequest( reqid );
	if( request && request->getSock()->readReady() ) {
		// Request socket must have just closed.  To avoid noise in
		// logs when we fail to write to it, delete the request now.
		RemoveRequest( request );
		request = NULL;
	}

	char const *request_desc = "(client which has gone away)";
	if( request ) {
		request_desc = request->getSock()->peer_description();
	}

	if( success ) {
		dprintf(D_FULLDEBUG,"CCB: received 'success' from target daemon %s "
				"with ccbid %lu for "
				"request %s from %s.\n",
				sock->peer_description(),
				target->getCCBID(),
				reqid_str.Value(),
				request_desc);
	}
	else {
		dprintf(D_FULLDEBUG,"CCB: received error from target daemon %s "
				"with ccbid %lu for "
				"request %s from %s: %s\n",
				sock->peer_description(),
				target->getCCBID(),
				reqid_str.Value(),
				request_desc,
				error_msg.Value());
	}

	if( !request ) {
		if( success ) {
				// expected: the client has gone away; it got what it wanted
			return;
		}
		dprintf( D_FULLDEBUG,
				 "CCB: client for request %s to target daemon %s with ccbid "
				 "%lu disappeared before receiving error details.\n",
				 reqid_str.Value(),
				 sock->peer_description(),
				 target->getCCBID());
		return;
	}
	if( connect_id != request->getConnectID() ) {
		MyString msg_str;
		sPrintAd(msg_str, msg);
		dprintf( D_FULLDEBUG,
				 "CCB: received wrong connect id (%s) from target daemon %s "
				 "with ccbid %lu for "
				 "request %s\n",
				 connect_id.Value(),
				 sock->peer_description(),
				 target->getCCBID(),
				 reqid_str.Value());
		RemoveTarget( target );
		return;
	}

	RequestFinished( request, success, error_msg.Value() );
}
示例#10
0
int
CCBServer::HandleRequest(int cmd,Stream *stream)
{
	ReliSock *sock = (ReliSock *)stream;
	ASSERT( cmd == CCB_REQUEST );

		// Avoid lengthy blocking on communication with our peer.
		// This command-handler should not get called until data
		// is ready to read.
	sock->timeout(1);

	ClassAd msg;
	sock->decode();
	if( !getClassAd( sock, msg ) || !sock->end_of_message() ) {
		dprintf(D_ALWAYS,
				"CCB: failed to receive request "
				"from %s.\n", sock->peer_description() );
		return FALSE;
	}

	MyString name;
	if( msg.LookupString(ATTR_NAME,name) ) {
			// client name is purely for debugging purposes
		name.formatstr_cat(" on %s",sock->peer_description());
		sock->set_peer_description(name.Value());
	}
	MyString target_ccbid_str;
	MyString return_addr;
	MyString connect_id; // id target daemon should present to requester
	CCBID target_ccbid;

		// NOTE: using ATTR_CLAIM_ID for connect id so that it is
		// automatically treated as a secret over the network.
		// It must be presented by the target daemon when connecting
		// to the requesting client, so the client can confirm that
		// the connection is in response to its request.

	if( !msg.LookupString(ATTR_CCBID,target_ccbid_str) ||
		!msg.LookupString(ATTR_MY_ADDRESS,return_addr) ||
		!msg.LookupString(ATTR_CLAIM_ID,connect_id) )
	{
		MyString ad_str;
		sPrintAd(ad_str, msg);
		dprintf(D_ALWAYS,
				"CCB: invalid request from %s: %s\n",
				sock->peer_description(), ad_str.Value() );
		return FALSE;
	}
	if( !CCBIDFromString(target_ccbid,target_ccbid_str.Value()) ) {
		dprintf(D_ALWAYS,
				"CCB: request from %s contains invalid CCBID %s\n",
				sock->peer_description(), target_ccbid_str.Value() );
		return FALSE;
	}

	CCBTarget *target = GetTarget( target_ccbid );
	if( !target ) {
		dprintf(D_ALWAYS,
			"CCB: rejecting request from %s for ccbid %s because no daemon is "
			"currently registered with that id "
			"(perhaps it recently disconnected).\n",
			sock->peer_description(), target_ccbid_str.Value());

		MyString error_msg;
		error_msg.formatstr(
			"CCB server rejecting request for ccbid %s because no daemon is "
			"currently registered with that id "
			"(perhaps it recently disconnected).", target_ccbid_str.Value());
		RequestReply( sock, false, error_msg.Value(), 0, target_ccbid );
		return FALSE;
	}

	SetSmallBuffers(sock);

	CCBServerRequest *request =
		new CCBServerRequest(
			sock,
			target_ccbid,
			return_addr.Value(),
			connect_id.Value() );
	AddRequest( request, target );

	dprintf(D_FULLDEBUG,
			"CCB: received request id %lu from %s for target ccbid %s "
			"(registered as %s)\n",
			request->getRequestID(),
			request->getSock()->peer_description(),
			target_ccbid_str.Value(),
			target->getSock()->peer_description());

	ForwardRequestToTarget( request, target );

	return KEEP_STREAM;
}
示例#11
0
int 
main( int argc, char **argv ) {
    CURL* handle = NULL;
    ClassAd stats_ad;
    FileTransferStats stats;
    int retry_count = 0;
    int rval = -1;
    int diagnostic = 0;
    MyString stats_string;

    // Point the global curl_stats pointer to our local object
    ft_stats = &stats;

    if(argc == 2 && strcmp(argv[1], "-classad") == 0) {
        printf("%s",
            "PluginVersion = \"0.1\"\n"
            "PluginType = \"FileTransfer\"\n"
            "SupportedMethods = \"http,https,ftp,file\"\n"
            );

        return 0;
    }

    if ((argc > 3) && ! strcmp(argv[3],"-diagnostic")) {
        diagnostic = 1;
    } 
    else if(argc != 3) {
        return -1;
    }

    // Initialize win32 + SSL socket libraries.
    // Do not initialize these separately! Doing so causes https:// transfers
    // to segfault.
    int init = curl_global_init( CURL_GLOBAL_DEFAULT );
    if( init != 0 ) {
        fprintf( stderr, "Error: curl_plugin initialization failed with error"
                                                " code %d\n", init ); 
        return -1;
    }

    if ( ( handle = curl_easy_init() ) == NULL ) {
        return -1;
    }

    // Initialize the stats structure
    init_stats( argv );
    stats.TransferStartTime = condor_gettimestamp_double();

    // Enter the loop that will attempt/retry the curl request
    for(;;) {
    
        // The sleep function is defined differently in Windows and Linux
        #ifdef WIN32
            Sleep( ( retry_count++ ) * 1000 );
        #else
            sleep( retry_count++ );
        #endif
        
        rval = send_curl_request( argv, diagnostic, handle, ft_stats );

        // If curl request is successful, break out of the loop
        if( rval == CURLE_OK ) {    
            break;
        }
        // If we have not exceeded the maximum number of retries, and we encounter
        // a non-fatal error, stay in the loop and try again
        else if( retry_count <= MAX_RETRY_ATTEMPTS && 
                                  ( rval == CURLE_COULDNT_CONNECT ||
                                    rval == CURLE_PARTIAL_FILE || 
                                    rval == CURLE_READ_ERROR || 
                                    rval == CURLE_OPERATION_TIMEDOUT || 
                                    rval == CURLE_SEND_ERROR || 
                                    rval == CURLE_RECV_ERROR ) ) {
            continue;
        }
        // On fatal errors, break out of the loop
        else {
            break;
        }
    }

    stats.TransferEndTime = condor_gettimestamp_double();

    // If the transfer was successful, output the statistics to stdout
    if( rval != -1 ) {
        stats.Publish( stats_ad );
        sPrintAd( stats_string, stats_ad );
        fprintf( stdout, "%s", stats_string.c_str() );
    }

    // Cleanup 
    curl_easy_cleanup(handle);
    curl_global_cleanup();

    return rval;    // 0 on success
}
示例#12
0
int
pseudo_ulog( ClassAd *ad )
{
	ULogEvent *event = instantiateEvent(ad);
	int result = 0;
	char const *critical_error = NULL;
	MyString CriticalErrorBuf;
	bool event_already_logged = false;
	bool put_job_on_hold = false;
	char const *hold_reason = NULL;
	char *hold_reason_buf = NULL;
	int hold_reason_code = 0;
	int hold_reason_sub_code = 0;

	if(!event) {
		MyString add_str;
		sPrintAd(add_str, *ad);
		dprintf(
		  D_ALWAYS,
		  "invalid event ClassAd in pseudo_ulog: %s\n",
		  add_str.Value());
		return -1;
	}

	if(ad->LookupInteger(ATTR_HOLD_REASON_CODE,hold_reason_code)) {
		put_job_on_hold = true;
		ad->LookupInteger(ATTR_HOLD_REASON_SUBCODE,hold_reason_sub_code);
		ad->LookupString(ATTR_HOLD_REASON,&hold_reason_buf);
		if(hold_reason_buf) {
			hold_reason = hold_reason_buf;
		}
	}

	if( event->eventNumber == ULOG_REMOTE_ERROR ) {
		RemoteErrorEvent *err = (RemoteErrorEvent *)event;

		if(!err->getExecuteHost() || !*err->getExecuteHost()) {
			//Insert remote host information.
			char *execute_host = NULL;
			thisRemoteResource->getMachineName(execute_host);
			err->setExecuteHost(execute_host);
			delete[] execute_host;
		}

		if(err->isCriticalError()) {
			CriticalErrorBuf.formatstr(
			  "Error from %s: %s",
			  err->getExecuteHost(),
			  err->getErrorText());

			critical_error = CriticalErrorBuf.Value();
			if(!hold_reason) {
				hold_reason = critical_error;
			}

			//Temporary: the following causes critical remote errors
			//to be logged as ShadowExceptionEvents, rather than
			//RemoteErrorEvents.  The result is ugly, but guaranteed to
			//be compatible with other user-log reading tools.
			BaseShadow::log_except(critical_error);
			event_already_logged = true;
		}
	}

	if( !event_already_logged && !Shadow->uLog.writeEvent( event, ad ) ) {
		MyString add_str;
		sPrintAd(add_str, *ad);
		dprintf(
		  D_ALWAYS,
		  "unable to log event in pseudo_ulog: %s\n",
		  add_str.Value());
		result = -1;
	}

	if(put_job_on_hold) {
		hold_reason = critical_error;
		if(!hold_reason) {
			hold_reason = "Job put on hold by remote host.";
		}
		Shadow->holdJobAndExit(hold_reason,hold_reason_code,hold_reason_sub_code);
		//should never get here, because holdJobAndExit() exits.
	}

	if( critical_error ) {
		//Suppress ugly "Shadow exception!"
		Shadow->exception_already_logged = true;

		//lame: at the time of this writing, EXCEPT does not want const:
		EXCEPT("%s", critical_error);
	}

	delete event;
	return result;
}
示例#13
0
int
JobRouterHookMgr::hookJobCleanup(RoutedJob* r_job)
{
	ClassAd temp_ad;
	char* hook_cleanup = getHookPath(HOOK_JOB_CLEANUP, r_job->src_ad);

	if (NULL == hook_cleanup)
	{
		// hook not defined
		dprintf(D_FULLDEBUG, "HOOK_JOB_CLEANUP not configured.\n");
		return 0;
	}

	if (0 >= r_job->dest_ad.size())
	{
		return 0;
	}

	// Verify the cleanup hook hasn't already been spawned and that
	// we're not waiting for it to return.
	std::string key = r_job->dest_key;
	if (true == JobRouterHookMgr::checkHookKnown(key.c_str(), HOOK_JOB_CLEANUP))
	{
		dprintf(D_FULLDEBUG, "JobRouterHookMgr::hookJobCleanup "
			"retried while still waiting for cleanup hook to "
			"return for job with key %s - ignoring\n", key.c_str());
		return 1;
	}


	temp_ad = r_job->dest_ad;

	MyString hook_stdin;
	sPrintAd(hook_stdin, temp_ad);

	CleanupClient* cleanup_client = new CleanupClient(hook_cleanup, r_job);
	if (NULL == cleanup_client)
	{
		dprintf(D_ALWAYS|D_FAILURE, 
			"ERROR in JobRouterHookMgr::hookJobCleanup: "
			"failed to create status update client\n");
		return -1;
	}

	set_user_priv_from_ad(r_job->src_ad);
	if (0 == spawn(cleanup_client, NULL, &hook_stdin, PRIV_USER_FINAL))
	{
		dprintf(D_ALWAYS|D_FAILURE,
				"ERROR in JobRouterHookMgr::JobCleanup: "
				"failed to spawn HOOK_JOB_CLEANUP (%s)\n", hook_cleanup);
		delete cleanup_client;
		return -1;

	}
	uninit_user_ids();

	// Add our info to the list of hooks currently running for this job.
	if (false == JobRouterHookMgr::addKnownHook(key.c_str(), HOOK_JOB_CLEANUP))
	{
		dprintf(D_ALWAYS, "ERROR in JobRouterHookMgr::hookJobCleanup: "
				"failed to add HOOK_JOB_CLEANUP to list of "
				"hooks running for job key %s\n", key.c_str());
	}

	dprintf(D_FULLDEBUG, "HOOK_JOB_CLEANUP (%s) invoked.\n",
			hook_cleanup);
	return 1;
}
示例#14
0
int
JobRouterHookMgr::hookJobExit(RoutedJob* r_job)
{
	ClassAd temp_ad;
	char* hook_job_exit = getHookPath(HOOK_JOB_EXIT, r_job->src_ad);

	if (NULL == hook_job_exit)
	{
		// hook not defined
		dprintf(D_FULLDEBUG, "HOOK_JOB_EXIT not configured.\n");
		return 0;
	}

	// Verify the exit hook hasn't already been spawned and that
	// we're not waiting for it to return.
	std::string key = r_job->dest_key;
	if (true == JobRouterHookMgr::checkHookKnown(key.c_str(),HOOK_JOB_EXIT))
	{
		dprintf(D_FULLDEBUG, "JobRouterHookMgr::hookJobExit "
			"retried while still waiting for exit hook to return "
			"for job with key %s - ignoring\n", key.c_str());
		return 1;
	}

	temp_ad = r_job->src_ad;

	MyString hook_stdin;
	sPrintAd(hook_stdin, temp_ad);
	hook_stdin += "\n------\n";

	temp_ad = r_job->dest_ad;
	sPrintAd(hook_stdin, temp_ad);

	ExitClient *exit_client = new ExitClient(hook_job_exit, r_job);
	if (NULL == exit_client)
	{
		dprintf(D_ALWAYS|D_FAILURE, 
			"ERROR in JobRouterHookMgr::hookJobExit: "
			"failed to create exit client\n");
		return -1;
	}

	set_user_priv_from_ad(r_job->src_ad);
	if (0 == spawn(exit_client, NULL, &hook_stdin, PRIV_USER_FINAL))
	{
		dprintf(D_ALWAYS|D_FAILURE,
				"ERROR in JobRouterHookMgr::hookJobExit: "
				"failed to spawn HOOK_JOB_EXIT (%s)\n", hook_job_exit);
		delete exit_client;
		return -1;

	}
	uninit_user_ids();
	
	// Add our info to the list of hooks currently running for this job.
	if (false == JobRouterHookMgr::addKnownHook(key.c_str(), HOOK_JOB_EXIT))
	{
		dprintf(D_ALWAYS, "ERROR in JobRouterHookMgr::hookJobExit: "
				"failed to add HOOK_JOB_EXIT to list of "
				"hooks running for job key %s\n", key.c_str());
	}

	dprintf(D_FULLDEBUG, "HOOK_JOB_EXIT (%s) invoked.\n", hook_job_exit);
	return 1;
}
示例#15
0
int
JobRouterHookMgr::hookTranslateJob(RoutedJob* r_job, std::string &route_info)
{
	ClassAd temp_ad;
	char* hook_translate = getHookPath(HOOK_TRANSLATE_JOB, r_job->src_ad);

	if (NULL == hook_translate)
	{
		// hook not defined, which is ok
		dprintf(D_FULLDEBUG, "HOOK_TRANSLATE_JOB not configured.\n");
		return 0;
	}

	// Verify the translate hook hasn't already been spawned and that
	// we're not waiting for it to return.
	std::string key = r_job->src_key;
	if (true == JobRouterHookMgr::checkHookKnown(key.c_str(), HOOK_TRANSLATE_JOB))
	{
		dprintf(D_FULLDEBUG, "JobRouterHookMgr::hookTranslateJob "
			"retried while still waiting for translate hook to "
			"return for job with key %s - ignoring\n", key.c_str());
		return 1;
	}

	temp_ad = r_job->src_ad;

	MyString hook_stdin;
	hook_stdin = route_info.c_str();
	hook_stdin += "\n------\n";
	sPrintAd(hook_stdin, temp_ad);

	TranslateClient* translate_client = new TranslateClient(hook_translate, r_job);
	if (NULL == translate_client)
	{
		dprintf(D_ALWAYS|D_FAILURE, 
			"ERROR in JobRouterHookMgr::hookTranslateJob: "
			"failed to create translation client\n");
		return -1;
	}

	set_user_priv_from_ad(r_job->src_ad);
	if (0 == spawn(translate_client, NULL, &hook_stdin, PRIV_USER_FINAL))
	{
		dprintf(D_ALWAYS|D_FAILURE,
				"ERROR in JobRouterHookMgr::hookTranslateJob: "
				"failed to spawn HOOK_TRANSLATE_JOB (%s)\n", hook_translate);
		delete translate_client;
		return -1;
	}
	uninit_user_ids();
	
	// Add our info to the list of hooks currently running for this job.
	if (false == JobRouterHookMgr::addKnownHook(key.c_str(), HOOK_TRANSLATE_JOB))
	{
		dprintf(D_ALWAYS, "ERROR in JobRouterHookMgr::hookTranslateJob: "
				"failed to add HOOK_TRANSLATE_JOB to list of "
				"hooks running for job key %s\n", key.c_str());
	}

	dprintf(D_FULLDEBUG, "HOOK_TRANSLATE_JOB (%s) invoked.\n",
			hook_translate);
	return 1;
}
示例#16
0
int vanilla2grid(int argc, char **argv)
{
    if(argc != 3) {
        fprintf(stderr, "Usage:\n"
                "  %s filename 'gridurl'\n"
                "     filename - filename of classad to process\n"
                "     girdurl - Unified grid URL\n", argv[0]);
        return 1;
    }


    // Load old classad string.
    MyString s_jobad = slurp_file(argv[1]);
    // Read in as old ClassAds format
    ClassAd jobad((char *)s_jobad.Value(),'\n');

    int orig_cluster;
    if( ! jobad.EvaluateAttrInt(ATTR_CLUSTER_ID, orig_cluster) ) {
        dprintf(D_ALWAYS, "Vanilla job lacks a cluster\n");
        return 1;
    }
    int orig_proc;
    if( ! jobad.EvaluateAttrInt(ATTR_PROC_ID, orig_proc) ) {
        dprintf(D_ALWAYS, "Vanilla job lacks a proc\n");
        return 1;
    }

    //====================================================================
    // Do something interesting:
    VanillaToGrid::vanillaToGrid(&jobad, argv[2]);

    printf("Claiming job %d.%d\n", orig_cluster, orig_proc);
    MyString errors;
    switch(claim_job(jobad, NULL, NULL, orig_cluster, orig_proc, &errors, MYID))
    {
    case CJR_OK:
        break;
    case CJR_BUSY:
        fprintf(stderr, "Unable to claim original job %d.%d because it's busy (%s)\n.  Continuing anyway.\n", orig_cluster, orig_proc, errors.Value());
        break;
    case CJR_ERROR:
        fprintf(stderr, "Unable to claim original job %d.%d because of an error: %s\n.  Continuing anyway.\n", orig_cluster, orig_proc, errors.Value());
        break;
    }

    int cluster,proc;
    if( ! submit_job( jobad, 0, 0, &cluster, &proc ) ) {
        fprintf(stderr, "Failed to submit job\n");
    }
    printf("Successfully submitted %d.%d\n",cluster,proc);


    if(0) // Print the transformed add.
    {
        // Convert to old classad string
        MyString out;
        sPrintAd(out, jobad);
        printf("%s\n", out.Value());
    }


    return 0;
}
示例#17
0
bool
DCTransferQueue::PollForTransferQueueSlot(int timeout,bool &pending,MyString &error_desc)
{
	if( GoAheadAlways( m_xfer_downloading ) ) {
		return true;
	}
	CheckTransferQueueSlot();

	if( !m_xfer_queue_pending ) {
		// status of request is known
		pending = false;
		if( !m_xfer_queue_go_ahead ) {
			error_desc = m_xfer_rejected_reason;
		}
		return m_xfer_queue_go_ahead;
	}

	Selector selector;
	selector.add_fd( m_xfer_queue_sock->get_file_desc(), Selector::IO_READ );
	time_t start = time(NULL);
	do {
		int t = timeout - (time(NULL) - start);
		selector.set_timeout( t >= 0 ? t : 0 );
		selector.execute();
	} while( selector.signalled() );

	if( selector.timed_out() ) {
			// It is expected that we may time out while waiting for a
			// response.  The caller should keep calling this function
			// periodically until we get a result.
		pending = true;
		return false;
	}

	m_xfer_queue_sock->decode();
	ClassAd msg;
	if( !getClassAd(m_xfer_queue_sock, msg) ||
		!m_xfer_queue_sock->end_of_message() )
	{
		formatstr(m_xfer_rejected_reason,
			"Failed to receive transfer queue response from %s for job %s "
			"(initial file %s).",
			m_xfer_queue_sock->peer_description(),
			m_xfer_jobid.c_str(),
			m_xfer_fname.c_str());
		goto request_failed;
	}

	int result; // this should be one of the values in XFER_QUEUE_ENUM
	if( !msg.LookupInteger(ATTR_RESULT,result) ) {
		std::string msg_str;
		sPrintAd(msg_str, msg);
		formatstr(m_xfer_rejected_reason,
			"Invalid transfer queue response from %s for job %s (%s): %s",
			m_xfer_queue_sock->peer_description(),
			m_xfer_jobid.c_str(),
			m_xfer_fname.c_str(),
			msg_str.c_str());
		goto request_failed;
	}

	if( result == XFER_QUEUE_GO_AHEAD ) {
		m_xfer_queue_go_ahead = true;
	}
	else {
		m_xfer_queue_go_ahead = false;
		std::string reason;
		msg.LookupString(ATTR_ERROR_STRING,reason);
		formatstr(m_xfer_rejected_reason,
			"Request to transfer files for %s (%s) was rejected by %s: %s",
			m_xfer_jobid.c_str(), m_xfer_fname.c_str(),
			m_xfer_queue_sock->peer_description(),
			reason.c_str());

		goto request_failed;
	}

	{
		int report_interval = 0;
		if( msg.LookupInteger(ATTR_REPORT_INTERVAL,report_interval) ) {
			m_report_interval = (unsigned)report_interval;
			m_last_report.getTime();
			m_next_report = m_last_report.seconds() + m_report_interval;
		}
	}

	m_xfer_queue_pending = false;
	pending = m_xfer_queue_pending;
	return true;

 request_failed:
	error_desc = m_xfer_rejected_reason;
	dprintf(D_ALWAYS, "%s\n", m_xfer_rejected_reason.c_str());
	m_xfer_queue_pending = false;
	m_xfer_queue_go_ahead = false;
	pending = m_xfer_queue_pending;
	return false;
}
示例#18
0
bool
Rooster::wakeUp(ClassAd *startd_ad)
{
	ASSERT( startd_ad );

	MyString name;
	startd_ad->LookupString(ATTR_NAME,name);

	dprintf(D_ALWAYS,"Sending wakeup call to %s.\n",name.Value());

	int stdin_pipe_fds[2];
	stdin_pipe_fds[0] = -1; // child's side
	stdin_pipe_fds[1] = -1; // my side
	if( !daemonCore->Create_Pipe(stdin_pipe_fds) ) {
		dprintf(D_ALWAYS,"Rooster::wakeUp: failed to create stdin pipe.");
		return false;
	}

	int stdout_pipe_fds[2];
	stdout_pipe_fds[0] = -1; // my side
	stdout_pipe_fds[1] = -1; // child's side
	if( !daemonCore->Create_Pipe(stdout_pipe_fds) ) {
		dprintf(D_ALWAYS,"Rooster::wakeUp: failed to create stdout pipe.");
		daemonCore->Close_Pipe(stdin_pipe_fds[0]);
		daemonCore->Close_Pipe(stdin_pipe_fds[1]);
		return false;
	}

	int std_fds[3];
	std_fds[0] = stdin_pipe_fds[0];
	std_fds[1] = stdout_pipe_fds[1];
	std_fds[2] = stdout_pipe_fds[1];

	int pid = daemonCore->Create_Process(
		m_wakeup_args.GetArg(0),
		m_wakeup_args,
		PRIV_CONDOR_FINAL,
		0,
		FALSE,
		NULL,
		NULL,
		NULL,
		NULL,
		std_fds);

	daemonCore->Close_Pipe(stdin_pipe_fds[0]);
	daemonCore->Close_Pipe(stdout_pipe_fds[1]);

	if( pid == -1 ) {
		dprintf(D_ALWAYS,"Failed to run %s: %s\n",
				m_wakeup_cmd.Value(), strerror(errno));
		daemonCore->Close_Pipe(stdin_pipe_fds[1]);
		daemonCore->Close_Pipe(stdout_pipe_fds[0]);
		return false;
	}

	MyString stdin_str;
	sPrintAd(stdin_str, *startd_ad);

		// Beware: the following code assumes that we will not
		// deadlock by filling up the stdin pipe while the tool blocks
		// filling up the stdout pipe.  The tool must consume all
		// input before generating more than a pipe buffer full of output.

	int n = daemonCore->Write_Pipe(stdin_pipe_fds[1],stdin_str.Value(),stdin_str.Length());
	if( n != stdin_str.Length() ) {
		dprintf(D_ALWAYS,"Rooster::wakeUp: failed to write to %s: %s\n",
				m_wakeup_cmd.Value(), strerror(errno));
		daemonCore->Close_Pipe(stdin_pipe_fds[1]);
		daemonCore->Close_Pipe(stdout_pipe_fds[0]);
		return false;
	}

		// done writing to tool
	daemonCore->Close_Pipe(stdin_pipe_fds[1]);

	MyString stdout_str;
	while( true ) {
		char pipe_buf[1024];
		n = daemonCore->Read_Pipe(stdout_pipe_fds[0],pipe_buf,1023);
		if( n <= 0 ) {
			break;
		}
		ASSERT( n < 1024 );
		pipe_buf[n] = '\0';
		stdout_str += pipe_buf;
	}

		// done reading from tool
	daemonCore->Close_Pipe(stdout_pipe_fds[0]);

	if( stdout_str.Length() ) {
			// log debugging output from the tool
		dprintf(D_ALWAYS|D_NOHEADER,"%s",stdout_str.Value());
	}

		// Would be nice to get final exit status of tool, but
		// daemonCore() doesn't provide a waitpid() equivalent.
		// Why didn't I just use my_popen()?  Because it doesn't
		// allow us to write to the tool _and_ log debugging output.
	return true;
}