예제 #1
0
int
CollectorList::sendUpdates (int cmd, ClassAd * ad1, ClassAd* ad2, bool nonblocking) {
	int success_count = 0;

	if ( ! adSeq) {
		adSeq = new DCCollectorAdSequences();
	}

	// advance the sequence numbers for these ads
	//
	time_t now = time(NULL);
	DCCollectorAdSeq * seqgen = adSeq->getAdSeq(*ad1);
	if (seqgen) { seqgen->advance(now); }

	this->rewind();
	DCCollector * daemon;
	while (this->next(daemon)) {
		dprintf( D_FULLDEBUG, 
				 "Trying to update collector %s\n", 
				 daemon->addr() );
		if( daemon->sendUpdate(cmd, ad1, *adSeq, ad2, nonblocking) ) {
			success_count++;
		} 
	}

	return success_count;
}
예제 #2
0
// Copy constructor for the Ad Sequence Number
DCCollectorAdSeq::DCCollectorAdSeq( const DCCollectorAdSeq &ref )
{
	const char *tmp;

	tmp = ref.getName( );
	if ( tmp ) {
		this->Name = strdup( tmp );
	} else {
		this->Name = NULL;
	}

	tmp = ref.getMyType( );
	if ( tmp ) {
		this->MyType = strdup( tmp );
	} else {
		this->MyType = NULL;
	}

	tmp = ref.getMachine( );
	if ( tmp ) {
		this->Machine = strdup( tmp );
	} else {
		this->Machine = NULL;
	}

	this->sequence = ref.getSequence( );
}
예제 #3
0
// Get the sequence number
unsigned
DCCollectorAdSeqMan::getSequence( const ClassAd *ad )
{
	int					adNum;
	char				*name = NULL;
	char				*myType = NULL;
	char				*machine = NULL;
	DCCollectorAdSeq	*adSeq = NULL;

	// Extract the 'key' attributes of the ClassAd
	ad->LookupString( ATTR_NAME, &name );
	ad->LookupString( ATTR_MY_TYPE, &myType );
	ad->LookupString( ATTR_MACHINE, &machine );

	// Walk through the ads that we know of, find a match...
	for ( adNum = 0;  adNum < numAds;  adNum++ ) {
		if ( adSeqInfo[adNum]->Match( name, myType, machine ) ) {
			adSeq = adSeqInfo[adNum];
			break;
		}
	}

	// No matches; create a new one, add to the list
	if ( ! adSeq ) {
		adSeq = new DCCollectorAdSeq ( name, myType, machine );
		adSeqInfo[numAds++] = adSeq;
	}

	// Free up memory...
	if ( name ) {
		free( name );
		name = NULL;
	}
	if ( myType ) {
		free( myType );
		myType = NULL;
	}
	if ( machine ) {
		free( machine );
		machine = NULL;
	}

	// Finally, return the sequence
	return adSeq->getSequenceAndIncrement( );
}
예제 #4
0
bool
DCCollector::sendUpdate( int cmd, ClassAd* ad1, DCCollectorAdSequences& adSeq, ClassAd* ad2, bool nonblocking ) 
{
	if( ! _is_configured ) {
			// nothing to do, treat it as success...
		return true;
	}

	if(!use_nonblocking_update || !daemonCore) {
			// Either caller OR config may turn off nonblocking updates.
			// In other words, both must be true to enable nonblocking.
			// Also, must have DaemonCore intialized.
		nonblocking = false;
	}

	// Add start time & seq # to the ads before we publish 'em
	if ( ad1 ) {
		ad1->Assign(ATTR_DAEMON_START_TIME, startTime);
	}
	if ( ad2 ) {
		ad2->Assign(ATTR_DAEMON_START_TIME, startTime);
	}

	if ( ad1 ) {
		DCCollectorAdSeq* seqgen = adSeq.getAdSeq(*ad1);
		if (seqgen) {
			long long seq = seqgen->getSequence();
			ad1->Assign(ATTR_UPDATE_SEQUENCE_NUMBER, seq);
			if (ad2) { ad2->Assign(ATTR_UPDATE_SEQUENCE_NUMBER, seq); }
		}
	}

		// Prior to 7.2.0, the negotiator depended on the startd
		// supplying matching MyAddress in public and private ads.
	if ( ad1 && ad2 ) {
		ad2->CopyAttribute(ATTR_MY_ADDRESS,ad1);
	}

		// We never want to try sending an update to port 0.  If we're
		// about to try that, and we're trying to talk to a local
		// collector, we should try re-reading the address file and
		// re-setting our port.
	if( _port == 0 ) {
		dprintf( D_HOSTNAME, "About to update collector with port 0, "
				 "attempting to re-read address file\n" );
		if( readAddressFile(_subsys) ) {
			_port = string_to_port( _addr );
			parseTCPInfo(); // update use_tcp
			dprintf( D_HOSTNAME, "Using port %d based on address \"%s\"\n",
					 _port, _addr );
		}
	}

	if( _port <= 0 ) {
			// If it's still 0, we've got to give up and fail.
		std::string err_msg;
		formatstr(err_msg, "Can't send update: invalid collector port (%d)",
						 _port );
		newError( CA_COMMUNICATION_ERROR, err_msg.c_str() );
		return false;
	}

	//
	// We don't want the collector to send TCP updates to itself, since
	// this could cause it to deadlock.  Since the only ad a collector
	// will ever advertise is its own, only check for *_COLLECTOR_ADS.
	//
	if( cmd == UPDATE_COLLECTOR_AD || cmd == INVALIDATE_COLLECTOR_ADS ) {
		if( daemonCore ) {
			const char * myOwnSinful = daemonCore->InfoCommandSinfulString();
			if( myOwnSinful == NULL ) {
				dprintf( D_ALWAYS, "Unable to determine my own address, will not update or invalidate collector ad to avoid potential deadlock.\n" );
				return false;
			}
			if( _addr == NULL ) {
				dprintf( D_ALWAYS, "Failing attempt to update or invalidate collector ad because of missing daemon address (probably an unresolved hostname; daemon name is '%s').\n", _name );
				return false;
			}
			if( strcmp( myOwnSinful, _addr ) == 0 ) {
				EXCEPT( "Collector attempted to send itself an update.\n" );
			}
		}
	}

	if( use_tcp ) {
		return sendTCPUpdate( cmd, ad1, ad2, nonblocking );
	}
	return sendUDPUpdate( cmd, ad1, ad2, nonblocking );
}