int request_pipe_handler(Service*, int) { std::string* next_line; while ((next_line = request_buffer.GetNextLine()) != NULL) { dprintf (D_FULLDEBUG, "got work request: %s\n", next_line->c_str()); Gahp_Args args; // Parse the command... if (!(parse_gahp_command (next_line->c_str(), &args) && handle_gahp_command (args.argv, args.argc))) { dprintf (D_ALWAYS, "ERROR processing %s\n", next_line->c_str()); } // Clean up... delete next_line; } // check for an error in GetNextLine if (request_buffer.IsError() || request_buffer.IsEOF()) { dprintf (D_ALWAYS, "Request pipe closed. Exiting...\n"); DC_Exit (1); } return TRUE; }
void init_pipes() { dprintf (D_FULLDEBUG, "PRE Request pipe initialized\n"); (void)daemonCore->Register_Pipe ( request_buffer.getPipeEnd(), "request pipe", (PipeHandler)&request_pipe_handler, "request_pipe_handler"); dprintf (D_FULLDEBUG, "Request pipe initialized\n"); }
void main_init( int argc, char ** const argv ) { dprintf(D_FULLDEBUG, "Welcome to the C-GAHP\n"); // handle specific command line args int i = 1; while ( i < argc ) { if ( argv[i][0] != '-' ) usage(); switch( argv[i][1] ) { case 's': // don't check parent for schedd addr. use this one instead if ( argc <= i + 1 ) usage(); ScheddAddr = strdup( argv[i + 1] ); i++; break; case 'P': // specify what pool (i.e. collector) to lookup the schedd name if ( argc <= i + 1 ) usage(); ScheddPool = strdup( argv[i + 1] ); i++; break; default: usage(); break; } i++; } // Setup dprintf to display pid DebugId = display_dprintf_header; Init(); Register(); Reconfig(); // inherit the DaemonCore pipes that our parent created REQUEST_INBOX = daemonCore->Inherit_Pipe(fileno(stdin), false, // read pipe true, // registerable false); // blocking RESULT_OUTBOX = daemonCore->Inherit_Pipe(fileno(stdout), true, // write pipe false, // nonregistrable false); // blocking request_buffer.setPipeEnd( REQUEST_INBOX ); daemonCore->Register_Timer(0, init_pipes, "init_pipes" ); // Just set up timers.... contactScheddTid = daemonCore->Register_Timer( contact_schedd_interval, doContactSchedd, "doContactSchedD" ); }
int stdin_pipe_handler(Service*, int) { std::string* line; while ((line = stdin_buffer.GetNextLine()) != NULL) { const char * command = line->c_str(); // CREATE_CONDOR_SECURITY_SESSION contains sensitive data that // normally shouldn't be written to a publically-readable log. // We should conceal it unless GAHP_DEBUG_HIDE_SENSITIVE_DATA // says not to. if ( param_boolean( "GAHP_DEBUG_HIDE_SENSITIVE_DATA", true ) && strncmp( command, GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION, strlen( GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION ) ) == 0 ) { dprintf( D_ALWAYS, "got stdin: %s XXXXXXXX\n", GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION ); } else { dprintf (D_ALWAYS, "got stdin: %s\n", command); } Gahp_Args args; if (parse_gahp_command (command, &args) && verify_gahp_command (args.argv, args.argc)) { // Catch "special commands first if (strcasecmp (args.argv[0], GAHP_COMMAND_RESULTS) == 0) { // Print number of results std::string rn_buff; formatstr( rn_buff, "%d", result_list.number() ); const char * commands [] = { GAHP_RESULT_SUCCESS, rn_buff.c_str() }; gahp_output_return (commands, 2); // Print each result line char * next; result_list.rewind(); while ((next = result_list.next()) != NULL) { printf ("%s\n", next); fflush(stdout); dprintf(D_FULLDEBUG,"put stdout: %s\n",next); result_list.deleteCurrent(); } new_results_signaled = FALSE; } else if (strcasecmp (args.argv[0], GAHP_COMMAND_VERSION) == 0) { printf ("S %s\n", version); fflush (stdout); dprintf(D_FULLDEBUG,"put stdout: S %s\n",version); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); DC_Exit(0); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_ON) == 0) { async_mode = TRUE; new_results_signaled = FALSE; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_OFF) == 0) { async_mode = FALSE; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); return 0; // exit } else if (strcasecmp (args.argv[0], GAHP_COMMAND_COMMANDS) == 0) { const char * commands [] = { GAHP_RESULT_SUCCESS, GAHP_COMMAND_DOWNLOAD_SANDBOX, GAHP_COMMAND_UPLOAD_SANDBOX, GAHP_COMMAND_DESTROY_SANDBOX, GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION, GAHP_COMMAND_CONDOR_VERSION, GAHP_COMMAND_ASYNC_MODE_ON, GAHP_COMMAND_ASYNC_MODE_OFF, GAHP_COMMAND_RESULTS, GAHP_COMMAND_QUIT, GAHP_COMMAND_VERSION, GAHP_COMMAND_COMMANDS}; gahp_output_return (commands, 12); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION) == 0) { ClaimIdParser claimid( args.argv[1] ); if ( !daemonCore->getSecMan()->CreateNonNegotiatedSecuritySession( DAEMON, claimid.secSessionId(), claimid.secSessionKey(), claimid.secSessionInfo(), CONDOR_PARENT_FQU, NULL, 0 ) ) { gahp_output_return_error(); } else { sec_session_id = claimid.secSessionId(); gahp_output_return_success(); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_CONDOR_VERSION) == 0) { peer_condor_version = args.argv[1]; const char *reply [] = { GAHP_RESULT_SUCCESS, escapeGahpString( CondorVersion() ) }; gahp_output_return( reply, 2 ); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_DOWNLOAD_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_download_sandbox, (void*)strdup(command), NULL, download_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created download_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); const char * res[2] = { "Worker thread failed", "NULL" }; enqueue_result(args.argv[1], res, 2); close( fds[0] ); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_UPLOAD_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_upload_sandbox, (void*)strdup(command), NULL, upload_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created upload_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); const char * res[1] = { "Worker thread failed" }; enqueue_result(args.argv[1], res, 1); close( fds[0] ); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_DESTROY_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_destroy_sandbox, (void*)strdup(command), NULL, destroy_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created destroy_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); const char * res[1] = { "Worker thread failed" }; enqueue_result(args.argv[1], res, 1); close( fds[0] ); } } else { // should never get here if verify does its job dprintf(D_ALWAYS, "FTGAHP: got bad command: %s\n", args.argv[0]); gahp_output_return_error(); } } else { gahp_output_return_error(); } delete line; } // check if GetNextLine() returned NULL because of an error or EOF if (stdin_buffer.IsError() || stdin_buffer.IsEOF()) { dprintf (D_ALWAYS, "stdin buffer closed, exiting\n"); DC_Exit (1); } return TRUE; }
void main_init( int, char ** const) { dprintf(D_ALWAYS, "FT-GAHP IO thread\n"); dprintf(D_SECURITY | D_FULLDEBUG, "FT-GAHP IO thread\n"); int stdin_pipe = -1; #if defined(WIN32) // if our parent is not DaemonCore, then our assumption that // the pipe we were passed in via stdin is overlapped-mode // is probably wrong. we therefore create a new pipe with the // read end overlapped and start a "forwarding thread" if (daemonCore->InfoCommandSinfulString(daemonCore->getppid()) == NULL) { dprintf(D_FULLDEBUG, "parent is not DaemonCore; creating a forwarding thread\n"); int pipe_ends[2]; if (daemonCore->Create_Pipe(pipe_ends, true) == FALSE) { EXCEPT("failed to create forwarding pipe"); } forwarding_pipe = pipe_ends[1]; HANDLE thread_handle = (HANDLE)_beginthreadex(NULL, // default security 0, // default stack size pipe_forward_thread, // start function NULL, // arg: write end of pipe 0, // not suspended NULL); // don't care about the ID if (thread_handle == NULL) { EXCEPT("failed to create forwarding thread"); } CloseHandle(thread_handle); stdin_pipe = pipe_ends[0]; } #endif if (stdin_pipe == -1) { // create a DaemonCore pipe from our stdin stdin_pipe = daemonCore->Inherit_Pipe(fileno(stdin), false, // read pipe true, // registerable false); // blocking } stdin_buffer.setPipeEnd(stdin_pipe); (void)daemonCore->Register_Pipe (stdin_buffer.getPipeEnd(), "stdin pipe", (PipeHandler)&stdin_pipe_handler, "stdin_pipe_handler"); // Setup dprintf to display pid DebugId = display_dprintf_header; // Print out the GAHP version to the screen // now we're ready to roll printf ("%s\n", version); fflush(stdout); dprintf(D_FULLDEBUG,"put stdout: %s\n",version); download_sandbox_reaper_id = daemonCore->Register_Reaper( "download_sandbox_reaper", &download_sandbox_reaper, "download_sandbox", NULL ); dprintf(D_FULLDEBUG, "registered download_sandbox_reaper() at %i\n", download_sandbox_reaper_id); upload_sandbox_reaper_id = daemonCore->Register_Reaper( "upload_sandbox_reaper", &upload_sandbox_reaper, "upload_sandbox", NULL ); dprintf(D_FULLDEBUG, "registered upload_sandbox_reaper() at %i\n", upload_sandbox_reaper_id); destroy_sandbox_reaper_id = daemonCore->Register_Reaper( "destroy_sandbox_reaper", &destroy_sandbox_reaper, "destroy_sandbox", NULL ); dprintf(D_FULLDEBUG, "registered destroy_sandbox_reaper() at %i\n", destroy_sandbox_reaper_id); dprintf (D_FULLDEBUG, "FT-GAHP IO initialized\n"); }
int stdin_pipe_handler(Service*, int) { std::string* line; while ((line = stdin_buffer.GetNextLine()) != NULL) { const char * command = line->c_str(); dprintf (D_ALWAYS, "got stdin: %s\n", command); Gahp_Args args; if (parse_gahp_command (command, &args) && verify_gahp_command (args.argv, args.argc)) { // Catch "special commands first if (strcasecmp (args.argv[0], GAHP_COMMAND_RESULTS) == 0) { // Print number of results std::string rn_buff; formatstr( rn_buff, "%d", result_list.number() ); const char * commands [] = { GAHP_RESULT_SUCCESS, rn_buff.c_str() }; gahp_output_return (commands, 2); // Print each result line char * next; result_list.rewind(); while ((next = result_list.next()) != NULL) { printf ("%s\n", next); fflush(stdout); dprintf(D_FULLDEBUG,"put stdout: %s\n",next); result_list.deleteCurrent(); } new_results_signaled = FALSE; } else if (strcasecmp (args.argv[0], GAHP_COMMAND_VERSION) == 0) { printf ("S %s\n", version); fflush (stdout); dprintf(D_FULLDEBUG,"put stdout: S %s\n",version); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); DC_Exit(0); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_ON) == 0) { async_mode = TRUE; new_results_signaled = FALSE; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_OFF) == 0) { async_mode = FALSE; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); return 0; // exit } else if (strcasecmp (args.argv[0], GAHP_COMMAND_COMMANDS) == 0) { const char * commands [] = { GAHP_RESULT_SUCCESS, GAHP_COMMAND_DOWNLOAD_SANDBOX, GAHP_COMMAND_UPLOAD_SANDBOX, GAHP_COMMAND_DESTROY_SANDBOX, GAHP_COMMAND_ASYNC_MODE_ON, GAHP_COMMAND_ASYNC_MODE_OFF, GAHP_COMMAND_RESULTS, GAHP_COMMAND_QUIT, GAHP_COMMAND_VERSION, GAHP_COMMAND_COMMANDS}; gahp_output_return (commands, 10); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_DOWNLOAD_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!\n" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_download_sandbox, (void*)strdup(command), NULL, download_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created download_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); close( fds[0] ); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_UPLOAD_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!\n" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_upload_sandbox, (void*)strdup(command), NULL, upload_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created upload_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); close( fds[0] ); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_DESTROY_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!\n" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_destroy_sandbox, (void*)strdup(command), NULL, destroy_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created destroy_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); close( fds[0] ); } } else { // should never get here if verify does its job dprintf(D_ALWAYS, "FTGAHP: got bad command: %s\n", args.argv[0]); gahp_output_return_error(); } } else { gahp_output_return_error(); } delete line; } // check if GetNextLine() returned NULL because of an error or EOF if (stdin_buffer.IsError() || stdin_buffer.IsEOF()) { dprintf (D_ALWAYS, "stdin buffer closed, exiting\n"); DC_Exit (1); } return TRUE; }