int part_send_job( int test_starter, char *host, int &reason, char *capability, char * /*schedd*/, PROC *proc, int &sd1, int &sd2, char **name) { int reply; ReliSock *sock = NULL; StartdRec stRec; PORTS ports; bool done = false; int retry_delay = 3; int num_retries = 0; // make sure we have the job classad InitJobAd(proc->id.cluster, proc->id.proc); while( !done ) { Daemon startd(DT_STARTD, host, NULL); if (!(sock = (ReliSock*)startd.startCommand ( ACTIVATE_CLAIM, Stream::reli_sock, 90))) { dprintf( D_ALWAYS, "startCommand(ACTIVATE_CLAIM) to startd failed\n"); goto returnfailure; } // Send the capability ClaimIdParser idp( capability ); dprintf(D_FULLDEBUG, "send capability %s\n", idp.publicClaimId() ); if( !sock->put_secret(capability) ) { dprintf( D_ALWAYS, "sock->put(\"%s\") failed\n",idp.publicClaimId()); goto returnfailure; } // Send the starter number if( test_starter ) { dprintf( D_ALWAYS, "Requesting Alternate Starter %d\n", test_starter ); } else { dprintf( D_ALWAYS, "Requesting Primary Starter\n" ); } if( !sock->code(test_starter) ) { dprintf( D_ALWAYS, "sock->code(%d) failed\n", test_starter ); goto returnfailure; } // Send the job info if( !JobAd->put(*sock) ) { dprintf( D_ALWAYS, "failed to send job ad\n" ); goto returnfailure; } if( !sock->end_of_message() ) { dprintf( D_ALWAYS, "failed to send message to startd\n" ); goto returnfailure; } // We're done sending. Now, get the reply. sock->decode(); if( !sock->code(reply) || !sock->end_of_message() ) { dprintf( D_ALWAYS, "failed to receive reply from startd\n" ); goto returnfailure; } switch( reply ) { case OK: dprintf( D_ALWAYS, "Shadow: Request to run a job was ACCEPTED\n" ); done = true; break; case NOT_OK: dprintf( D_ALWAYS, "Shadow: Request to run a job was REFUSED\n"); goto returnfailure; break; case CONDOR_TRY_AGAIN: num_retries++; dprintf( D_ALWAYS, "Shadow: Request to run a job was TEMPORARILY REFUSED\n" ); if( num_retries > 20 ) { dprintf( D_ALWAYS, "Shadow: Too many retries, giving up.\n" ); goto returnfailure; } delete sock; dprintf( D_ALWAYS, "Shadow: will try again in %d seconds\n", retry_delay ); sleep( retry_delay ); break; default: dprintf(D_ALWAYS,"Unknown reply from startd for command ACTIVATE_CLAIM\n"); dprintf(D_ALWAYS,"Shadow: Request to run a job was REFUSED\n"); goto returnfailure; break; } } /* start flock : dhruba */ sock->decode(); memset( &stRec, '\0', sizeof(stRec) ); if( !sock->code(stRec) || !sock->end_of_message() ) { dprintf(D_ALWAYS, "Can't read reply from startd.\n"); goto returnfailure; } ports = stRec.ports; if( stRec.ip_addr ) { host = stRec.server_name; if(name) { *name = strdup(stRec.server_name); } dprintf(D_FULLDEBUG, "host = %s inet_addr = 0x%x port1 = %d port2 = %d\n", host, stRec.ip_addr,ports.port1, ports.port2 ); } else { dprintf(D_FULLDEBUG, "host = %s port1 = %d port2 = %d\n", host, ports.port1, ports.port2 ); } if( ports.port1 == 0 ) { dprintf( D_ALWAYS, "Shadow: Request to run a job on %s was REFUSED\n", host ); goto returnfailure; } /* end flock ; dhruba */ // We don't use the server_name in the StartdRec, because our // DNS query may fail or may give us the wrong IP address // (either because it's stale or because we're talking to a // machine with multiple network interfaces). Sadly, we can't // use the ip_addr either, because the startd doesn't send it in // the correct byte ordering on little-endian machines. So, we // grab the IP address from the ReliSock, since we konw the // startd always uses the same IP address for all of its // communication. char sinfulstring[SINFUL_STRING_BUF_SIZE]; generate_sinful(sinfulstring, SINFUL_STRING_BUF_SIZE, sock->peer_ip_str(), ports.port1); if( (sd1 = do_connect(sinfulstring, (char *)0, (u_short)ports.port1)) < 0 ) { dprintf( D_ALWAYS, "failed to connect to scheduler on %s\n", sinfulstring ); goto returnfailure; } generate_sinful(sinfulstring, SINFUL_STRING_BUF_SIZE, sock->peer_ip_str(), ports.port2); if( (sd2 = do_connect(sinfulstring, (char *)0, (u_short)ports.port2)) < 0 ) { dprintf( D_ALWAYS, "failed to connect to scheduler on %s\n", sinfulstring ); close(sd1); goto returnfailure; } delete sock; sock = NULL; if ( stRec.server_name ) { free( stRec.server_name ); } return 0; returnfailure: reason = JOB_NOT_STARTED; delete sock; return -1; }
int main( int argc, char* argv[] ) { int i; param_functions *p_funcs = NULL; set_mySubSystem( "DAEMON-TOOL", SUBSYSTEM_TYPE_TOOL ); MyName = argv[0]; myDistro->Init( argc, argv ); FILE *input_fp = stdin; for( i=1; i<argc; i++ ) { if( match_prefix( argv[i], "-daemontype" ) ) { if( argv[i + 1] ) { get_mySubSystem()->setName( argv[++i] ); get_mySubSystem()->setTypeFromName( ); } else { usage(); } } else if( match_prefix( argv[i], "-debug" ) ) { // dprintf to console Termlog = 1; p_funcs = get_param_functions(); dprintf_config( "DAEMON-TOOL", p_funcs ); set_debug_flags(NULL, D_FULLDEBUG|D_SECURITY); } else if( match_prefix( argv[i], "-" ) ) { usage(); } else { usage(); } } // If we didn't get told what subsystem we should use, set it // to "TOOL". if( !get_mySubSystem()->isNameValid() ) { get_mySubSystem()->setName( "DAEMON-TOOL" ); } config( 0, true ); IpVerify ipverify; MyString line; while( line.readLine(input_fp) ) { line.chomp(); if( line.IsEmpty() || line[0] == '#' ) { printf("%s\n",line.Value()); continue; } StringList fields(line.Value()," "); fields.rewind(); char const *perm_str = fields.next(); char const *fqu = fields.next(); char const *ip = fields.next(); char const *expected = fields.next(); MyString sin_str = generate_sinful(ip, 0); condor_sockaddr addr; if( !addr.from_sinful(sin_str) ) { fprintf(stderr,"Invalid ip address: %s\n",ip); exit(1); } DCpermission perm = StringToDCpermission(perm_str); if( perm == LAST_PERM ) { fprintf(stderr,"Invalid permission level: %s\n",perm_str); exit(1); } if( strcmp(fqu,"*") == 0 ) { fqu = ""; } char const *result; MyString reason; if( ipverify.Verify(perm,addr,fqu,&reason,&reason) != USER_AUTH_SUCCESS ) { result = "DENIED"; } else { result = "ALLOWED"; } if( expected && strcasecmp(expected,result) != 0 ) { printf("Got wrong result '%s' for '%s': reason: %s!\n", result,line.Value(),reason.Value()); printf("Aborting.\n"); exit(1); } if( expected ) { printf("%s\n",line.Value()); } else { printf("%s %s\n",line.Value(),result); } } }