// 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( ); }
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 ); }