/* FUNCTION: smpd_service_stop PURPOSE: Stops the service PARAMETERS: none RETURN VALUE: none COMMENTS: If a ServiceStop procedure is going to take longer than 3 seconds to execute, it should spawn a thread to execute the stop code, and return. Otherwise, the ServiceControlManager will believe that the service has stopped responding. */ void smpd_service_stop() { SMPDU_Sock_set_t set; SMPDU_Sock_t sock; SMPDU_Sock_event_t event; char host[SMPD_MAX_HOST_LENGTH]; int iter; DWORD dwThreadID; int result; for (iter=0; iter<10; iter++) { smpd_process.hBombThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)smpd_bomb_thread, NULL, 0, &dwThreadID); if (smpd_process.hBombThread != NULL) break; Sleep(250); } /* stop the main thread */ smpd_process.service_stop = SMPD_TRUE; smpd_get_hostname(host, SMPD_MAX_HOST_LENGTH); result = SMPDU_Sock_create_set(&set); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_create_set failed,\nsock error: %s\n", get_sock_error_string(result)); SetEvent(smpd_process.hBombDiffuseEvent); WaitForSingleObject(smpd_process.hBombThread, (DWORD)3000); CloseHandle(smpd_process.hBombThread); ExitProcess((UINT)-1); } result = SMPDU_Sock_post_connect(set, NULL, host, smpd_process.port, &sock); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to connect to '%s:%d',\nsock error: %s\n", smpd_process.host_list->host, smpd_process.port, get_sock_error_string(result)); SetEvent(smpd_process.hBombDiffuseEvent); WaitForSingleObject(smpd_process.hBombThread, (DWORD)3000); CloseHandle(smpd_process.hBombThread); ExitProcess((UINT)-1); } result = SMPDU_Sock_wait(set, SMPDU_SOCK_INFINITE_TIME, &event); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to connect to '%s:%d',\nsock error: %s\n", smpd_process.host_list->host, smpd_process.port, get_sock_error_string(result)); SetEvent(smpd_process.hBombDiffuseEvent); WaitForSingleObject(smpd_process.hBombThread, (DWORD)3000); CloseHandle(smpd_process.hBombThread); ExitProcess((UINT)-1); } }
int smpd_parse_command_args(int *argcp, char **argvp[]) { int result = 0; #ifdef HAVE_WINDOWS_H char str[20], read_handle_str[20], write_handle_str[20]; int port; SMPDU_Sock_t listener; SMPDU_Sock_set_t set; HANDLE hWrite, hRead; DWORD num_written, num_read; #endif int dbg_flag; char domain[SMPD_MAX_HOST_LENGTH]; char opt[SMPD_MAX_NAME_LENGTH]; char opt_val[SMPD_MAX_VALUE_LENGTH]; char filename[SMPD_MAX_FILENAME]; int i; smpd_enter_fn(FCNAME); /* check for help option */ if ( #ifndef HAVE_WINDOWS_H *argcp < 2 || /* unix: print the options if no arguments are supplied */ #endif smpd_get_opt(argcp, argvp, "-help") || smpd_get_opt(argcp, argvp, "-?")) { smpd_print_options(); smpd_exit(0); } /* check for the printprocs option */ if (smpd_get_opt(argcp, argvp, "-printprocs")) { smpd_watch_processes(); smpd_exit(0); } if (smpd_get_opt(argcp, argvp, "-hosts")) { char first_host[SMPD_MAX_HOST_LENGTH], host[SMPD_MAX_HOST_LENGTH], alt_host[SMPD_MAX_HOST_LENGTH]; smpd_get_default_hosts(); result = smpd_get_next_hostname(first_host, alt_host); if (result != SMPD_SUCCESS) smpd_exit(result); printf("%s\n", first_host); result = smpd_get_next_hostname(host, alt_host); if (result != SMPD_SUCCESS) smpd_exit(result); while (strcmp(host, first_host) != 0) { printf("%s\n", host); result = smpd_get_next_hostname(host, alt_host); if (result != SMPD_SUCCESS) smpd_exit(result); } smpd_exit(0); } if (smpd_get_opt(argcp, argvp, "-sethosts")) { char *buffer, *iter; int i, length; length = (*argcp) * SMPD_MAX_HOST_LENGTH; buffer = MPIU_Malloc(length); if (buffer == NULL) { smpd_err_printf("unable to allocate memory to store the host names.\n"); smpd_exit(-1); } iter = buffer; for (i=1; i<*argcp; i++) { result = MPIU_Str_add_string(&iter, &length, (*argvp)[i]); if (result) { printf("unable to add host #%d, %s\n", i, (*argvp)[i]); MPIU_Free(buffer); smpd_exit(-1); } } /*printf("hosts: %s\n", buffer);*/ result = smpd_set_smpd_data("hosts", buffer); if (result == SMPD_SUCCESS) { printf("hosts data saved successfully.\n"); } else { printf("Error: unable to save the hosts data.\n"); } MPIU_Free(buffer); smpd_exit(0); } if (smpd_get_opt_two_strings(argcp, argvp, "-set", opt, SMPD_MAX_NAME_LENGTH, opt_val, SMPD_MAX_VALUE_LENGTH)) { /* The do loop allows for multiple -set operations to be specified on the command line */ do { if (strlen(opt) == 0) { printf("invalid option specified.\n"); smpd_exit(-1); } if (strlen(opt_val) == 0) { result = smpd_delete_smpd_data(opt); } else { result = smpd_set_smpd_data(opt, opt_val); } if (result == SMPD_SUCCESS) { printf("%s = %s\n", opt, opt_val); } else { printf("unable to set %s option.\n", opt); } } while (smpd_get_opt_two_strings(argcp, argvp, "-set", opt, SMPD_MAX_NAME_LENGTH, opt_val, SMPD_MAX_VALUE_LENGTH)); smpd_exit(0); } if (smpd_get_opt_string(argcp, argvp, "-get", opt, SMPD_MAX_NAME_LENGTH)) { if (strlen(opt) == 0) { printf("invalid option specified.\n"); smpd_exit(-1); } result = smpd_get_smpd_data(opt, opt_val, SMPD_MAX_VALUE_LENGTH); if (result == SMPD_SUCCESS) { printf("%s\n", opt_val); } else { printf("default\n"); } smpd_exit(0); } /* If we've made it here and there still is "-set" or "-get" on the command line then the user * probably didn't supply the correct number of parameters. So print the usage message * and exit. */ if (smpd_get_opt(argcp, argvp, "-set") || smpd_get_opt(argcp, argvp, "-get")) { smpd_print_options(); smpd_exit(-1); } if (smpd_get_opt(argcp, argvp, "-enumerate") || smpd_get_opt(argcp, argvp, "-enum")) { smpd_data_t *data; if (smpd_get_all_smpd_data(&data) == SMPD_SUCCESS) { smpd_data_t *iter = data; while (iter != NULL) { printf("%s\n%s\n", iter->name, iter->value); iter = iter->next; } while (data != NULL) { iter = data; data = data->next; MPIU_Free(iter); } } smpd_exit(0); } if (smpd_get_opt_string(argcp, argvp, "-query", domain, SMPD_MAX_HOST_LENGTH)) { printf("querying hosts in the %s domain:\n", domain); printf("Not implemented.\n"); smpd_exit(0); } if (smpd_get_opt(argcp, argvp, "-query")) { printf("querying hosts in the default domain:\n"); printf("Not implemented.\n"); smpd_exit(0); } /* check for the service/silent option */ #ifdef HAVE_WINDOWS_H smpd_process.bService = SMPD_TRUE; #endif if (smpd_get_opt(argcp, argvp, "-s")) { #ifdef HAVE_WINDOWS_H printf("The -s option is only available under unix.\n"); smpd_print_options(); smpd_exit(0); #else smpd_process.bNoTTY = SMPD_TRUE; #endif } if (smpd_get_opt(argcp, argvp, "-r")) { #ifdef HAVE_WINDOWS_H printf("The -r option is only available under unix.\n"); smpd_print_options(); #else printf("The -r root option is not yet implemented.\n"); #endif smpd_exit(0); } /* check for debug option */ if (smpd_get_opt_int(argcp, argvp, "-d", &dbg_flag)) { smpd_process.dbg_state = dbg_flag; smpd_process.bNoTTY = SMPD_FALSE; smpd_process.bService = SMPD_FALSE; } if (smpd_get_opt(argcp, argvp, "-d")) { smpd_process.dbg_state = SMPD_DBG_STATE_ERROUT | SMPD_DBG_STATE_STDOUT | SMPD_DBG_STATE_PREPEND_RANK | SMPD_DBG_STATE_TRACE; smpd_process.bNoTTY = SMPD_FALSE; smpd_process.bService = SMPD_FALSE; } if (smpd_get_opt_int(argcp, argvp, "-debug", &dbg_flag)) { smpd_process.dbg_state = dbg_flag; smpd_process.bNoTTY = SMPD_FALSE; smpd_process.bService = SMPD_FALSE; } if (smpd_get_opt(argcp, argvp, "-debug")) { smpd_process.dbg_state = SMPD_DBG_STATE_ERROUT | SMPD_DBG_STATE_STDOUT | SMPD_DBG_STATE_PREPEND_RANK | SMPD_DBG_STATE_TRACE; smpd_process.bNoTTY = SMPD_FALSE; smpd_process.bService = SMPD_FALSE; } /* check for port option */ smpd_get_opt_int(argcp, argvp, "-p", &smpd_process.port); smpd_get_opt_int(argcp, argvp, "-port", &smpd_process.port); if (smpd_get_opt(argcp, argvp, "-anyport")) { smpd_process.port = 0; smpd_process.dbg_state = 0; /* turn of debugging or you won't be able to read the port from stdout */ smpd_process.bNoTTY = SMPD_FALSE; smpd_process.bService = SMPD_FALSE; } smpd_process.noprompt = smpd_get_opt(argcp, argvp, "-noprompt"); #ifdef HAVE_WINDOWS_H /* check for service options */ if (smpd_get_opt(argcp, argvp, "-remove") || smpd_get_opt(argcp, argvp, "-unregserver") || smpd_get_opt(argcp, argvp, "-uninstall") || smpd_get_opt(argcp, argvp, "/Remove") || smpd_get_opt(argcp, argvp, "/Uninstall")) { /*RegDeleteKey(HKEY_CURRENT_USER, MPICHKEY);*/ smpd_remove_service(SMPD_TRUE); ExitProcess(0); } if (smpd_get_opt(argcp, argvp, "-install") || smpd_get_opt(argcp, argvp, "-regserver") || smpd_get_opt(argcp, argvp, "/Install") || smpd_get_opt(argcp, argvp, "/install") || smpd_get_opt(argcp, argvp, "/RegServer")) { char phrase[SMPD_PASSPHRASE_MAX_LENGTH]="", port_str[SMPD_MAX_PORT_STR_LENGTH]=""; if (smpd_remove_service(SMPD_FALSE) == SMPD_FALSE) { printf("Unable to remove the previous installation, install failed.\n"); ExitProcess(0); } if (smpd_get_opt_string(argcp, argvp, "-phrase", phrase, SMPD_PASSPHRASE_MAX_LENGTH) || smpd_get_win_opt_string(argcp, argvp, "/phrase", phrase, SMPD_PASSPHRASE_MAX_LENGTH)) { smpd_set_smpd_data("phrase", phrase); } if (smpd_get_opt(argcp, argvp, "-getphrase")) { printf("passphrase for smpd: ");fflush(stdout); smpd_get_password(phrase); smpd_set_smpd_data("phrase", phrase); } if (smpd_process.port != SMPD_LISTENER_PORT) { snprintf(port_str, SMPD_MAX_PORT_STR_LENGTH, "%d", smpd_process.port); smpd_set_smpd_data("port", port_str); } smpd_install_service(SMPD_FALSE, SMPD_TRUE, smpd_get_opt(argcp, argvp, "-delegation")); smpd_set_smpd_data("version", SMPD_VERSION); ExitProcess(0); } if (smpd_get_opt(argcp, argvp, "-start")) { smpd_start_service(); ExitProcess(0); } if (smpd_get_opt(argcp, argvp, "-stop")) { smpd_stop_service(); ExitProcess(0); } if (smpd_get_opt(argcp, argvp, "-register_spn")) { char filename[SMPD_MAX_FILENAME]; if(smpd_get_opt_string(argcp, argvp, "-f", filename, SMPD_MAX_FILENAME)){ result = smpd_setup_scps_with_file(filename); if(result != SMPD_SUCCESS){ printf("Failed to register smpd's Service Principal Names (at least one failed) with Domain Controller\n"); ExitProcess((UINT )-1); } } else{ result = smpd_setup_scp(NULL); if(result != SMPD_SUCCESS){ printf("Failed to register smpd's Service Principal Name with Domain Controller\n"); ExitProcess((UINT )-1); } } printf("Service Principal Name registered with the domain controller.\n"); printf("SMPD is now capable of launching processes using passwordless delegation.\n"); printf("The system administrator must ensure the following:\n"); printf(" 1) This host is trusted for delegation in Active Directory\n"); printf(" 2) All users who will run jobs are trusted for delegation.\n"); printf("Domain administrators can enable these options for hosts and users\nin Active Directory on the domain controller.\n"); ExitProcess(0); } if (smpd_get_opt(argcp, argvp, "-remove_spn")) { char filename[SMPD_MAX_FILENAME]; smpd_spn_list_hnd_t hnd; result = smpd_spn_list_init(&hnd); if(result != SMPD_SUCCESS){ printf("Unable to initialize SPN list\n"); ExitProcess((UINT ) -1); } if(smpd_get_opt_string(argcp, argvp, "-f", filename, SMPD_MAX_FILENAME)){ result = smpd_remove_scps_with_file(filename, hnd); if(result != SMPD_SUCCESS){ printf("Failed to remove smpd's Service Principal Names (at least one failed) with Domain Controller\n"); ExitProcess((UINT )-1); } printf("Removed smpd's Service Principal Names successfully\n"); } else{ result = smpd_remove_scp(NULL, hnd); if(result != SMPD_SUCCESS){ printf("Failed to remove smpd's Service Principal Name with Domain Controller\n"); ExitProcess((UINT )-1); } printf("Removed smpd's Service Principal Name successfully\n"); } smpd_spn_list_finalize(&hnd); ExitProcess(0); } if (smpd_get_opt(argcp, argvp, "-mgr")) { /* Set a ctrl-handler to kill child processes if this smpd is killed */ if (!SetConsoleCtrlHandler(smpd_ctrl_handler, TRUE)) { result = GetLastError(); smpd_dbg_printf("unable to set the ctrl handler for the smpd manager, error %d.\n", result); } #ifdef HAVE_WINDOWS_H { BOOL ret; ret = smpd_init_affinity_table(); if(!ret){ smpd_dbg_printf("Initializing smpd affinity table failed\n"); } } #endif smpd_process.bService = SMPD_FALSE; if (!smpd_get_opt_string(argcp, argvp, "-read", read_handle_str, 20)) { smpd_err_printf("manager started without a read pipe handle.\n"); smpd_exit_fn(FCNAME); return SMPD_FAIL; } if (!smpd_get_opt_string(argcp, argvp, "-write", write_handle_str, 20)) { smpd_err_printf("manager started without a write pipe handle.\n"); smpd_exit_fn(FCNAME); return SMPD_FAIL; } hRead = smpd_decode_handle(read_handle_str); hWrite = smpd_decode_handle(write_handle_str); smpd_dbg_printf("manager creating listener and session sets.\n"); result = SMPDU_Sock_create_set(&set); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_create_set(listener) failed,\nsock error: %s\n", get_sock_error_string(result)); smpd_exit_fn(FCNAME); return SMPD_FAIL; } smpd_process.set = set; smpd_dbg_printf("created set for manager listener, %d\n", SMPDU_Sock_get_sock_set_id(set)); port = 0; result = SMPDU_Sock_listen(set, NULL, &port, &listener); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_listen failed,\nsock error: %s\n", get_sock_error_string(result)); smpd_exit_fn(FCNAME); return SMPD_FAIL; } smpd_dbg_printf("smpd manager listening on port %d\n", port); result = smpd_create_context(SMPD_CONTEXT_LISTENER, set, listener, -1, &smpd_process.listener_context); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to create a context for the smpd listener.\n"); smpd_exit_fn(FCNAME); return result; } result = SMPDU_Sock_set_user_ptr(listener, smpd_process.listener_context); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_set_user_ptr failed,\nsock error: %s\n", get_sock_error_string(result)); smpd_exit_fn(FCNAME); return result; } smpd_process.listener_context->state = SMPD_MGR_LISTENING; memset(str, 0, 20); snprintf(str, 20, "%d", port); smpd_dbg_printf("manager writing port back to smpd.\n"); if (!WriteFile(hWrite, str, 20, &num_written, NULL)) { smpd_err_printf("WriteFile failed, error %d\n", GetLastError()); smpd_exit_fn(FCNAME); return SMPD_FAIL; } CloseHandle(hWrite); if (num_written != 20) { smpd_err_printf("wrote only %d bytes of 20\n", num_written); smpd_exit_fn(FCNAME); return SMPD_FAIL; } smpd_dbg_printf("manager reading account and password from smpd.\n"); if (!ReadFile(hRead, smpd_process.UserAccount, SMPD_MAX_ACCOUNT_LENGTH, &num_read, NULL)) { smpd_err_printf("ReadFile failed, error %d\n", GetLastError()); smpd_exit_fn(FCNAME); return SMPD_FAIL; } if (num_read != SMPD_MAX_ACCOUNT_LENGTH) { smpd_err_printf("read only %d bytes of %d\n", num_read, SMPD_MAX_ACCOUNT_LENGTH); smpd_exit_fn(FCNAME); return SMPD_FAIL; } if (!ReadFile(hRead, smpd_process.UserPassword, SMPD_MAX_PASSWORD_LENGTH, &num_read, NULL)) { smpd_err_printf("ReadFile failed, error %d\n", GetLastError()); smpd_exit_fn(FCNAME); return SMPD_FAIL; } if (num_read != SMPD_MAX_PASSWORD_LENGTH) { smpd_err_printf("read only %d bytes of %d\n", num_read, SMPD_MAX_PASSWORD_LENGTH); smpd_exit_fn(FCNAME); return SMPD_FAIL; } if (!ReadFile(hRead, smpd_process.passphrase, SMPD_PASSPHRASE_MAX_LENGTH, &num_read, NULL)) { smpd_err_printf("ReadFile failed, error %d\n", GetLastError()); smpd_exit_fn(FCNAME); return SMPD_FAIL; } if (num_read != SMPD_PASSPHRASE_MAX_LENGTH) { smpd_err_printf("read only %d bytes of %d\n", num_read, SMPD_PASSPHRASE_MAX_LENGTH); smpd_exit_fn(FCNAME); return SMPD_FAIL; } smpd_process.credentials_prompt = SMPD_FALSE; result = smpd_enter_at_state(set, SMPD_MGR_LISTENING); if (result != SMPD_SUCCESS) { smpd_err_printf("state machine failed.\n"); } /* result = SMPDU_Sock_finalize(); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_finalize failed,\nsock error: %s\n", get_sock_error_string(result)); } */ smpd_exit(0); smpd_exit_fn(FCNAME); ExitProcess(0); } #endif /* check for the status option */ if (smpd_get_opt_string(argcp, argvp, "-status", smpd_process.console_host, SMPD_MAX_HOST_LENGTH)) { smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_DO_STATUS; } else if (smpd_get_opt(argcp, argvp, "-status")) { smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_DO_STATUS; } /* check for console options */ if (smpd_get_opt_string(argcp, argvp, "-console", smpd_process.console_host, SMPD_MAX_HOST_LENGTH)) { smpd_process.do_console = 1; } else if (smpd_get_opt(argcp, argvp, "-console")) { smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); smpd_process.do_console = 1; } if (smpd_process.do_console) { /* This may need to be changed to avoid conflict */ if (smpd_get_opt(argcp, argvp, "-p")) { smpd_process.use_process_session = 1; } } if (smpd_get_opt_string(argcp, argvp, "-shutdown", smpd_process.console_host, SMPD_MAX_HOST_LENGTH)) { smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_SHUTDOWN; } else if (smpd_get_opt(argcp, argvp, "-shutdown")) { smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_SHUTDOWN; } if (smpd_get_opt_string(argcp, argvp, "-restart", smpd_process.console_host, SMPD_MAX_HOST_LENGTH)) { smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_RESTART; } else if (smpd_get_opt(argcp, argvp, "-restart")) { #ifdef HAVE_WINDOWS_H printf("restarting the smpd service...\n"); smpd_stop_service(); Sleep(1000); smpd_start_service(); smpd_exit(0); #else smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_RESTART; #endif } if (smpd_get_opt_string(argcp, argvp, "-version", smpd_process.console_host, SMPD_MAX_HOST_LENGTH)) { smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_VERSION; } else if (smpd_get_opt(argcp, argvp, "-version")) { printf("%s\n", SMPD_VERSION); fflush(stdout); smpd_exit(0); } /* These commands are handled by mpiexec although doing them here is an alternate solution. if (smpd_get_opt_two_strings(argcp, argvp, "-add_job", smpd_process.job_key, SMPD_MAX_NAME_LENGTH, smpd_process.job_key_account, SMPD_MAX_ACCOUNT_LENGTH)) { if (!smpd_get_opt_string(argcp, argvp, "-host", smpd_process.console_host, SMPD_MAX_HOST_LENGTH)) smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); if (smpd_get_opt_string(argcp, argvp, "-password", smpd_process.job_key_password, SMPD_MAX_PASSWORD_LENGTH) smpd_process.builtin_cmd = SMPD_CMD_ADD_JOB_KEY_AND_PASSWORD; else smpd_process.builtin_cmd = SMPD_CMD_ADD_JOB_KEY; smpd_process.do_console = 1; } if (smpd_get_opt_string(argcp, argvp, "-remove_job", smpd_process.job_key, SMPD_MAX_NAME_LENGTH)) { if (!smpd_get_opt_string(argcp, argvp, "-host", smpd_process.console_host, SMPD_MAX_HOST_LENGTH)) smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_REMOVE_JOB_KEY; } if (smpd_get_opt_string(argcp, argvp, "-associate_job", smpd_process.job_key, SMPD_MAX_NAME_LENGTH)) { if (!smpd_get_opt_string(argcp, argvp, "-host", smpd_process.console_host, SMPD_MAX_HOST_LENGTH)) smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_ASSOCIATE_JOB_KEY; } */ smpd_get_opt_string(argcp, argvp, "-phrase", smpd_process.passphrase, SMPD_PASSPHRASE_MAX_LENGTH); if (smpd_get_opt(argcp, argvp, "-getphrase")) { printf("passphrase for smpd: ");fflush(stdout); smpd_get_password(smpd_process.passphrase); } if (smpd_get_opt_string(argcp, argvp, "-smpdfile", smpd_process.smpd_filename, SMPD_MAX_FILENAME)) { struct stat s; if (stat(smpd_process.smpd_filename, &s) == 0) { if (s.st_mode & 00077) { printf(".smpd file cannot be readable by anyone other than the current user.\n"); smpd_exit_fn(FCNAME); return SMPD_FAIL; } } } if (smpd_get_opt_string(argcp, argvp, "-traceon", filename, SMPD_MAX_FILENAME)) { smpd_process.do_console_returns = SMPD_TRUE; if (*argcp > 1) { for (i=1; i<*argcp; i++) { strcpy(smpd_process.console_host, (*argvp)[i]); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_SET; strcpy(smpd_process.key, "logfile"); strcpy(smpd_process.val, filename); result = smpd_do_console(); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to set the logfile name on host '%s'\n", smpd_process.console_host); smpd_exit_fn(FCNAME); return result; } smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_SET; strcpy(smpd_process.key, "log"); strcpy(smpd_process.val, "yes"); result = smpd_do_console(); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to set the log option on host '%s'\n", smpd_process.console_host); smpd_exit_fn(FCNAME); return result; } smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_RESTART; result = smpd_do_console(); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to restart the smpd on host '%s'\n", smpd_process.console_host); smpd_exit_fn(FCNAME); return result; } } } else { result = smpd_set_smpd_data("logfile", filename); result = smpd_set_smpd_data("log", "yes"); #ifdef HAVE_WINDOWS_H printf("restarting the smpd service...\n"); smpd_stop_service(); Sleep(1000); smpd_start_service(); #else smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_RESTART; result = smpd_do_console(); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to restart the smpd on host '%s'\n", smpd_process.console_host); smpd_exit_fn(FCNAME); return result; } #endif } smpd_exit_fn(FCNAME); smpd_exit(result); } if (smpd_get_opt(argcp, argvp, "-traceoff")) { smpd_process.do_console_returns = SMPD_TRUE; if (*argcp > 1) { for (i=1; i<*argcp; i++) { strcpy(smpd_process.console_host, (*argvp)[i]); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_SET; strcpy(smpd_process.key, "log"); strcpy(smpd_process.val, "no"); result = smpd_do_console(); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to set the log option on host '%s'\n", smpd_process.console_host); smpd_exit_fn(FCNAME); return result; } smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_RESTART; result = smpd_do_console(); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to restart the smpd on host '%s'\n", smpd_process.console_host); smpd_exit_fn(FCNAME); return result; } } } else { result = smpd_set_smpd_data("log", "no"); #ifdef HAVE_WINDOWS_H printf("restarting the smpd service...\n"); smpd_stop_service(); Sleep(1000); smpd_start_service(); #else smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH); smpd_process.do_console = 1; smpd_process.builtin_cmd = SMPD_CMD_RESTART; result = smpd_do_console(); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to restart the smpd on host '%s'\n", smpd_process.console_host); smpd_exit_fn(FCNAME); return result; } #endif } smpd_exit_fn(FCNAME); smpd_exit(result); } if (smpd_process.do_console) { result = smpd_do_console(); smpd_exit_fn(FCNAME); return result; } smpd_exit_fn(FCNAME); return SMPD_SUCCESS; }
int smpd_do_console() { int result = -1; smpd_context_t *context; SMPDU_Sock_set_t set; SMPDU_Sock_t sock; SMPD_BOOL no_smpd = SMPD_FALSE; int saved_state = 0; int exit_code = 0; smpd_enter_fn(FCNAME); /* make sure we have a passphrase to authenticate connections to the smpds */ if (smpd_process.passphrase[0] == '\0') smpd_get_smpd_data("phrase", smpd_process.passphrase, SMPD_PASSPHRASE_MAX_LENGTH); if (smpd_process.passphrase[0] == '\0') { if (smpd_process.noprompt) { printf("Error: No smpd passphrase specified through the registry or .smpd file, exiting.\n"); goto quit_job; } printf("Please specify an authentication passphrase for smpd: "); fflush(stdout); smpd_get_password(smpd_process.passphrase); } result = SMPDU_Sock_create_set(&set); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_create_set failed,\nsock error: %s\n", get_sock_error_string(result)); goto quit_job; } smpd_process.set = set; /* set the id of the mpiexec node to zero */ smpd_process.id = 0; /* turn off output if do_status is selected to supress error messages */ if (smpd_process.builtin_cmd == SMPD_CMD_DO_STATUS) { saved_state = smpd_process.dbg_state; smpd_process.dbg_state = 0; } /* start connecting the tree by posting a connect to the first host */ result = smpd_create_context(SMPD_CONTEXT_LEFT_CHILD, set, SMPDU_SOCK_INVALID_SOCK/*sock*/, 1, &context); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to create a context.\n"); goto quit_job; } result = SMPDU_Sock_post_connect(set, context, smpd_process.console_host, smpd_process.port, &sock); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to connect to '%s:%d',\nsock error: %s\n", smpd_process.console_host, smpd_process.port, get_sock_error_string(result)); no_smpd = SMPD_TRUE; goto quit_job; } context->sock = sock; /* turn output back on */ if (smpd_process.builtin_cmd == SMPD_CMD_DO_STATUS) smpd_process.dbg_state = saved_state; context->state = SMPD_MPIEXEC_CONNECTING_SMPD; smpd_process.left_context = context; /* turn off output if do_status is selected to supress error messages */ if (smpd_process.builtin_cmd == SMPD_CMD_DO_STATUS) smpd_process.dbg_state = 0; result = smpd_enter_at_state(set, SMPD_MPIEXEC_CONNECTING_SMPD); if (result != SMPD_SUCCESS) { smpd_err_printf("state machine failed.\n"); no_smpd = SMPD_TRUE; goto quit_job; } /* turn output back on */ if (smpd_process.builtin_cmd == SMPD_CMD_DO_STATUS) smpd_process.dbg_state = saved_state; quit_job: if (result != SMPD_SUCCESS) { exit_code = result; } if (smpd_process.builtin_cmd == SMPD_CMD_DO_STATUS && (no_smpd || smpd_process.state_machine_ret_val != SMPD_SUCCESS)) { printf("no smpd running on %s\n", smpd_process.console_host); smpd_process.dbg_state = saved_state; } if (smpd_process.do_console_returns == SMPD_TRUE) { smpd_exit_fn(FCNAME); return exit_code; } /* finalize */ /* smpd_dbg_printf("calling SMPDU_Sock_finalize\n"); result = SMPDU_Sock_finalize(); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_finalize failed,\nsock error: %s\n", get_sock_error_string(result)); } */ #ifdef HAVE_WINDOWS_H if (smpd_process.hCloseStdinThreadEvent) SetEvent(smpd_process.hCloseStdinThreadEvent); if (smpd_process.hStdinThread != NULL) { /* close stdin so the input thread will exit */ CloseHandle(GetStdHandle(STD_INPUT_HANDLE)); if (WaitForSingleObject(smpd_process.hStdinThread, 3000) != WAIT_OBJECT_0) { TerminateThread(smpd_process.hStdinThread, 321); } CloseHandle(smpd_process.hStdinThread); } if (smpd_process.hCloseStdinThreadEvent) { CloseHandle(smpd_process.hCloseStdinThreadEvent); smpd_process.hCloseStdinThreadEvent = NULL; } #elif defined(USE_PTHREAD_STDIN_REDIRECTION) smpd_cancel_stdin_thread(); #endif smpd_exit_fn(FCNAME); smpd_exit(exit_code); return SMPD_SUCCESS; }
static int setup_stdin_redirection(smpd_process_t *process, SMPDU_Sock_set_t set) { int result; smpd_context_t *context_in; SMPDU_SOCK_NATIVE_FD stdin_fd; SMPDU_Sock_t insock; #ifdef HAVE_WINDOWS_H DWORD dwThreadID; SOCKET hWrite; #endif smpd_enter_fn("setup_stdin_redirection"); /* get a handle to stdin */ #ifdef HAVE_WINDOWS_H result = smpd_make_socket_loop((SOCKET*)&stdin_fd, &hWrite); if (result) { smpd_err_printf("Unable to make a local socket loop to forward stdin.\n"); smpd_exit_fn("setup_stdin_redirection"); return SMPD_FAIL; } #else stdin_fd = fileno(stdin); #endif /* convert the native handle to a sock */ result = SMPDU_Sock_native_to_sock(set, stdin_fd, NULL, &insock); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to create a sock from stdin,\nsock error: %s\n", get_sock_error_string(result)); smpd_exit_fn("setup_stdin_redirection"); return SMPD_FAIL; } /* create a context for reading from stdin */ result = smpd_create_context(SMPD_CONTEXT_MPIEXEC_STDIN_RSH, set, insock, -1, &context_in); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to create a context for stdin.\n"); smpd_exit_fn("setup_stdin_redirection"); return SMPD_FAIL; } SMPDU_Sock_set_user_ptr(insock, context_in); context_in->process = process; #ifdef HAVE_WINDOWS_H /* unfortunately, we cannot use stdin directly as a sock. So, use a thread to read and forward stdin to a sock */ smpd_process.hCloseStdinThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (smpd_process.hCloseStdinThreadEvent == NULL) { smpd_err_printf("Unable to create the stdin thread close event, error %d\n", GetLastError()); smpd_exit_fn("setup_stdin_redirection"); return SMPD_FAIL; } smpd_process.hStdinThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)smpd_stdin_thread, (void*)hWrite, 0, &dwThreadID); if (smpd_process.hStdinThread == NULL) { smpd_err_printf("Unable to create a thread to read stdin, error %d\n", GetLastError()); smpd_exit_fn("setup_stdin_redirection"); return SMPD_FAIL; } #endif /* set this variable first before posting the first read to avoid a race condition? */ smpd_process.stdin_redirecting = SMPD_TRUE; /* post a read for a user command from stdin */ context_in->read_state = SMPD_READING_STDIN; result = SMPDU_Sock_post_read(insock, context_in->read_cmd.cmd, 1, 1, NULL); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to post a read on stdin for an incoming user command, error:\n%s\n", get_sock_error_string(result)); smpd_exit_fn("setup_stdin_redirection"); return SMPD_FAIL; } smpd_exit_fn("setup_stdin_redirection"); return SMPD_SUCCESS; }
int smpd_init_context(smpd_context_t *context, smpd_context_type_t type, SMPDU_Sock_set_t set, SMPDU_Sock_t sock, int id) { int result; smpd_enter_fn(FCNAME); context->type = type; context->target = SMPD_TARGET_UNDETERMINED; context->access = SMPD_ACCESS_USER_PROCESS;/*SMPD_ACCESS_NONE;*/ context->host[0] = '\0'; context->id = id; context->rank = 0; context->write_list = NULL; context->wait_list = NULL; smpd_init_command(&context->read_cmd); context->next = NULL; context->set = set; context->sock = sock; context->state = SMPD_IDLE; context->read_state = SMPD_IDLE; context->write_state = SMPD_IDLE; context->account[0] = '\0'; context->domain[0] = '\0'; context->full_domain[0] = '\0'; context->connect_return_id = -1; context->connect_return_tag = -1; context->connect_to = NULL; context->spawn_context = NULL; context->cred_request[0] = '\0'; context->password[0] = '\0'; context->encrypted_password[0] = '\0'; context->port_str[0] = '\0'; context->pszChallengeResponse[0] = '\0'; context->pszCrypt[0] = '\0'; context->pwd_request[0] = '\0'; context->session[0] = '\0'; context->session_header[0] = '\0'; context->singleton_init_hostname[0] = '\0'; context->singleton_init_kvsname[0] = '\0'; context->singleton_init_domainname[0] = '\0'; context->singleton_init_pm_port = -1; context->smpd_pwd[0] = '\0'; #ifdef HAVE_WINDOWS_H context->wait.hProcess = NULL; context->wait.hThread = NULL; #else context->wait = 0; #endif context->process = NULL; context->sspi_header[0] = '\0'; context->sspi_context = NULL; context->sspi_type = SMPD_SSPI_DELEGATE; context->sspi_job_key[0] = '\0'; context->first_output_stderr = SMPD_TRUE; context->first_output_stdout = SMPD_TRUE; if (sock != SMPDU_SOCK_INVALID_SOCK) { result = SMPDU_Sock_set_user_ptr(sock, context); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to set the sock user ptr while initializing context,\nsock error: %s\n", get_sock_error_string(result)); } } smpd_exit_fn(FCNAME); return SMPD_SUCCESS; }
int main(int argc, char* argv[]) { int result = SMPD_SUCCESS; smpd_host_node_t *host_node_ptr; smpd_launch_node_t *launch_node_ptr; smpd_context_t *context; SMPDU_Sock_set_t set; SMPDU_Sock_t sock = SMPDU_SOCK_INVALID_SOCK; smpd_state_t state; smpd_enter_fn("main"); /* catch an empty command line */ if (argc < 2) { mp_print_options(); exit(0); } smpd_process.mpiexec_argv0 = argv[0]; /* initialize */ /* FIXME: Get rid of this hack - we already create * local KVS for all singleton clients by default */ putenv("PMI_SMPD_FD=0"); result = PMPI_Init(&argc, &argv); /* SMPD_CS_ENTER(); */ if (result != SMPD_SUCCESS) { smpd_err_printf("SMPD_Init failed,\nerror: %d\n", result); smpd_exit_fn("main"); return result; } result = SMPDU_Sock_init(); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_init failed,\nsock error: %s\n", get_sock_error_string(result)); smpd_exit_fn("main"); return result; } result = smpd_init_process(); if (result != SMPD_SUCCESS) { smpd_err_printf("smpd_init_process failed.\n"); goto quit_job; } smpd_process.dbg_state = SMPD_DBG_STATE_ERROUT; /* parse the command line */ smpd_dbg_printf("parsing the command line.\n"); result = mp_parse_command_args(&argc, &argv); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to parse the mpiexec command arguments.\n"); goto quit_job; } /* If we are using MS HPC job scheduler we only connect * to the local SMPD */ if(smpd_process.use_ms_hpc){ char host[100]; int id; /* Free the current host list */ result = smpd_free_host_list(); if(result != SMPD_SUCCESS){ smpd_err_printf("Unable to free the global host list\n"); goto quit_job; } /* Add local host to the host list */ result = smpd_get_hostname(host, 100); if(result != SMPD_SUCCESS){ smpd_err_printf("Unable to get the local hostname\n"); goto quit_job; } result = smpd_get_host_id(host, &id); if(result != SMPD_SUCCESS){ smpd_err_printf("Unable to get host id for local host\n"); goto quit_job; } /* Set the number of PMI procs since they are not launched by mpiexec */ smpd_process.nproc = smpd_process.launch_list->nproc; smpd_dbg_printf("Adding (%s:%d) == (localhost) to the host list\n", host, id); } /* print and see what we've got */ /* debugging output *************/ smpd_dbg_printf("host tree:\n"); host_node_ptr = smpd_process.host_list; if (!host_node_ptr) smpd_dbg_printf("<none>\n"); while (host_node_ptr) { smpd_dbg_printf(" host: %s, parent: %d, id: %d\n", host_node_ptr->host, host_node_ptr->parent, host_node_ptr->id); host_node_ptr = host_node_ptr->next; } smpd_dbg_printf("launch nodes:\n"); launch_node_ptr = smpd_process.launch_list; if (!launch_node_ptr) smpd_dbg_printf("<none>\n"); while (launch_node_ptr) { smpd_dbg_printf(" iproc: %d, id: %d, exe: %s\n", launch_node_ptr->iproc, launch_node_ptr->host_id, launch_node_ptr->exe); launch_node_ptr = launch_node_ptr->next; } /* end debug output *************/ /* set the id of the mpiexec node to zero */ smpd_process.id = 0; result = SMPDU_Sock_create_set(&set); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_create_set failed,\nsock error: %s\n", get_sock_error_string(result)); goto quit_job; } smpd_process.set = set; /* Check to see if the user wants to use a remote shell mechanism for launching the processes * instead of using the smpd process managers. */ if (smpd_process.rsh_mpiexec == SMPD_TRUE) { /* Do rsh or localonly stuff */ result = mpiexec_rsh(); /* skip over the non-rsh code and go to the cleanup section */ goto quit_job; } /* Start the timeout mechanism if specified */ /* This code occurs after the rsh_mpiexec option check because the rsh code implementes timeouts differently */ if (smpd_process.timeout > 0) { #ifdef HAVE_WINDOWS_H /* create a Windows thread to sleep until the timeout expires */ if (smpd_process.timeout_thread == NULL) { smpd_process.timeout_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)timeout_thread, NULL, 0, NULL); if (smpd_process.timeout_thread == NULL) { printf("Error: unable to create a timeout thread, errno %d.\n", GetLastError()); smpd_exit_fn("mp_parse_command_args"); return SMPD_FAIL; } } #elif defined(SIGALRM) /* create an alarm to signal mpiexec when the timeout expires */ smpd_signal(SIGALRM, timeout_function); alarm(smpd_process.timeout); #elif defined(HAVE_PTHREAD_H) /* create a pthread to sleep until the timeout expires */ result = pthread_create(&smpd_process.timeout_thread, NULL, timeout_thread, NULL); if (result != 0) { printf("Error: unable to create a timeout thread, errno %d.\n", result); smpd_exit_fn("mp_parse_command_args"); return SMPD_FAIL; } #else /* no timeout mechanism available */ #endif } /* make sure we have a passphrase to authenticate connections to the smpds */ if (smpd_process.passphrase[0] == '\0') smpd_get_smpd_data("phrase", smpd_process.passphrase, SMPD_PASSPHRASE_MAX_LENGTH); if (smpd_process.passphrase[0] == '\0') { if (smpd_process.noprompt) { printf("Error: No smpd passphrase specified through the registry or .smpd file, exiting.\n"); result = SMPD_FAIL; goto quit_job; } printf("Please specify an authentication passphrase for smpd: "); fflush(stdout); smpd_get_password(smpd_process.passphrase); } /* set the state to create a console session or a job session */ state = smpd_process.do_console ? SMPD_MPIEXEC_CONNECTING_SMPD : SMPD_MPIEXEC_CONNECTING_TREE; result = smpd_create_context(SMPD_CONTEXT_LEFT_CHILD, set, sock, 1, &context); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to create a context for the first host in the tree.\n"); goto quit_job; } #ifdef HAVE_WINDOWS_H if (!smpd_process.local_root) { #endif /* start connecting the tree by posting a connect to the first host */ result = SMPDU_Sock_post_connect(set, context, smpd_process.host_list->host, smpd_process.port, &sock); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to connect to '%s:%d',\nsock error: %s\n", smpd_process.host_list->host, smpd_process.port, get_sock_error_string(result)); goto quit_job; } #ifdef HAVE_WINDOWS_H } #endif context->sock = sock; context->state = state; context->connect_to = smpd_process.host_list; #ifdef HAVE_WINDOWS_H if (smpd_process.local_root) { int port; smpd_context_t *rc_context; /* The local_root option is implemented by having mpiexec act as the smpd * and launch the smpd manager. Then mpiexec connects to this manager just * as if it had been created by a real smpd. This causes all the processes * destined for the first smpd host to be launched by this child process of * mpiexec and not the smpd service. This allows for these processes to * create windows that are visible to the interactive user. It also means * that the job cannot be run in the context of a user other than the user * running mpiexec. */ /* get the path to smpd.exe because pszExe is currently mpiexec.exe */ smpd_get_smpd_data("binary", smpd_process.pszExe, SMPD_MAX_EXE_LENGTH); /* launch the manager process */ result = smpd_start_win_mgr(context, SMPD_FALSE); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to start the local smpd manager.\n"); goto quit_job; } /* connect to the manager */ smpd_dbg_printf("connecting a new socket.\n"); port = atol(context->port_str); if (port < 1) { smpd_err_printf("Invalid reconnect port read: %d\n", port); goto quit_job; } result = smpd_create_context(context->type, context->set, SMPDU_SOCK_INVALID_SOCK, context->id, &rc_context); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to create a new context for the reconnection.\n"); goto quit_job; } rc_context->state = context->state; rc_context->write_state = SMPD_RECONNECTING; context->state = SMPD_CLOSING; rc_context->connect_to = context->connect_to; rc_context->connect_return_id = context->connect_return_id; rc_context->connect_return_tag = context->connect_return_tag; strcpy(rc_context->host, context->host); smpd_process.left_context = rc_context; smpd_dbg_printf("posting a re-connect to %s:%d in %s context.\n", rc_context->connect_to->host, port, smpd_get_context_str(rc_context)); result = SMPDU_Sock_post_connect(rc_context->set, rc_context, rc_context->connect_to->host, port, &rc_context->sock); if (result != SMPD_SUCCESS) { smpd_err_printf("Unable to post a connect to '%s:%d',\nsock error: %s\n", rc_context->connect_to->host, port, get_sock_error_string(result)); if (smpd_post_abort_command("Unable to connect to '%s:%d',\nsock error: %s\n", rc_context->connect_to->host, port, get_sock_error_string(result)) != SMPD_SUCCESS) { goto quit_job; } } } else { #endif smpd_process.left_context = context; result = SMPDU_Sock_set_user_ptr(sock, context); if (result != SMPD_SUCCESS) { smpd_err_printf("unable to set the smpd sock user pointer,\nsock error: %s\n", get_sock_error_string(result)); goto quit_job; } #ifdef HAVE_WINDOWS_H } #endif #ifdef HAVE_WINDOWS_H { /* Create a break handler and a socket to handle aborting the job when mpiexec receives break signals */ smpd_context_t *reader_context; SMPDU_Sock_t sock_reader; SMPDU_SOCK_NATIVE_FD reader, writer; smpd_make_socket_loop((SOCKET*)&reader, (SOCKET*)&writer); result = SMPDU_Sock_native_to_sock(set, reader, NULL, &sock_reader); result = SMPDU_Sock_native_to_sock(set, writer, NULL, &smpd_process.mpiexec_abort_sock); result = smpd_create_context(SMPD_CONTEXT_MPIEXEC_ABORT, set, sock_reader, -1, &reader_context); reader_context->read_state = SMPD_READING_MPIEXEC_ABORT; result = SMPDU_Sock_post_read(sock_reader, &reader_context->read_cmd.cmd, 1, 1, NULL); if (!SetConsoleCtrlHandler(mpiexec_ctrl_handler, TRUE)) { /* Don't error out; allow the job to run without a ctrl handler? */ result = GetLastError(); smpd_dbg_printf("unable to set a ctrl handler for mpiexec, error %d\n", result); } } #endif result = smpd_enter_at_state(set, state); if (result != SMPD_SUCCESS) { smpd_err_printf("state machine failed.\n"); goto quit_job; } quit_job: if ((result != SMPD_SUCCESS) && (smpd_process.mpiexec_exit_code == 0)) { smpd_process.mpiexec_exit_code = -1; } /* finalize */ smpd_dbg_printf("calling SMPDU_Sock_finalize\n"); result = SMPDU_Sock_finalize(); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPDU_Sock_finalize failed,\nsock error: %s\n", get_sock_error_string(result)); } /* SMPD_Finalize called in smpd_exit() smpd_dbg_printf("calling SMPD_Finalize\n"); result = PMPI_Finalize(); if (result != SMPD_SUCCESS) { smpd_err_printf("SMPD_Finalize failed,\nerror: %d\n", result); } */ #ifdef HAVE_WINDOWS_H if (smpd_process.hCloseStdinThreadEvent) SetEvent(smpd_process.hCloseStdinThreadEvent); if (smpd_process.hStdinThread != NULL) { /* close stdin so the input thread will exit */ CloseHandle(GetStdHandle(STD_INPUT_HANDLE)); if (WaitForSingleObject(smpd_process.hStdinThread, 3000) != WAIT_OBJECT_0) { TerminateThread(smpd_process.hStdinThread, 321); } CloseHandle(smpd_process.hStdinThread); } if (smpd_process.hCloseStdinThreadEvent) { CloseHandle(smpd_process.hCloseStdinThreadEvent); smpd_process.hCloseStdinThreadEvent = NULL; } #elif defined(USE_PTHREAD_STDIN_REDIRECTION) smpd_cancel_stdin_thread(); #endif smpd_exit_fn("main"); /* SMPD_CS_EXIT(); */ return smpd_exit(smpd_process.mpiexec_exit_code); }