1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 * (C) 2001 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
5 */
6
7 #include <stdio.h>
8 #include "mpiexec.h"
9 #include "smpd.h"
10 #include <stdlib.h>
11 #ifdef HAVE_STRING_H
12 #include <string.h>
13 #endif
14 #ifdef HAVE_SYS_TYPES_H
15 #include <sys/types.h>
16 #endif
17 #ifdef HAVE_SYS_STAT_H
18 #include <sys/stat.h>
19 #endif
20 #ifdef HAVE_UNISTD_H
21 #include <unistd.h>
22 #endif
23 #if defined(HAVE_DIRECT_H) || defined(HAVE_WINDOWS_H)
24 #include <direct.h>
25 #endif
26 #ifdef HAVE_WINDOWS_H
27 #include <crtdbg.h>
28 #endif
29 #ifdef HAVE_CTYPE_H
30 #include <ctype.h>
31 #endif
32
33 /* The supported values right now are "newtcp" & "nd" */
34 #define SMPD_MAX_NEMESIS_NETMOD_LENGTH 10
35
mp_print_options(void)36 void mp_print_options(void)
37 {
38 printf("\n");
39 printf("Usage:\n");
40 printf("mpiexec -n <maxprocs> [options] executable [args ...]\n");
41 printf("mpiexec [options] executable [args ...] : [options] exe [args] : ...\n");
42 printf("mpiexec -configfile <configfile>\n");
43 printf("\n");
44 printf("options:\n");
45 printf("\n");
46 printf("standard:\n");
47 printf("-n <maxprocs>\n");
48 printf("-wdir <working directory>\n");
49 printf("-configfile <filename> -\n");
50 printf(" each line contains a complete set of mpiexec options\n");
51 printf(" including the executable and arguments\n");
52 printf("-host <hostname>\n");
53 /*
54 printf("-soft <Fortran90 triple> - acceptable number of processes up to maxprocs\n");
55 printf(" a or a:b or a:b:c where\n");
56 printf(" 1) a = a\n");
57 printf(" 2) a:b = a, a+1, a+2, ..., b\n");
58 printf(" 3) a:b:c = a, a+c, a+2c, a+3c, ..., a+kc\n");
59 printf(" where a+kc <= b if c>0\n");
60 printf(" a+kc >= b if c<0\n");
61 */
62 printf("-path <search path for executable, ; separated>\n");
63 /*printf("-arch <architecture> - sun, linux, rs6000, ...\n");*/
64 printf("\n");
65 printf("extensions:\n");
66 printf("-env <variable value>\n");
67 printf("-hosts <n host1 host2 ... hostn>\n");
68 printf("-hosts <n host1 m1 host2 m2 ... hostn mn>\n");
69 printf("-machinefile <filename> - one host per line, #commented\n");
70 printf("-localonly <numprocs>\n");
71 printf("-exitcodes - print the exit codes of processes as they exit\n");
72 /*
73 printf("-genvall - pass all env vars in current environment\n");
74 printf("-genvnone - pass no env vars\n");
75 */
76 printf("-genvlist <list of env var names a,b,c,...> - pass current values of these vars\n");
77 printf("-g<local arg name> - global version of local options\n");
78 printf(" genv, gwdir, ghost, gpath, gmap\n");
79 printf("-file <filename> - old mpich1 job configuration file\n");
80 printf("\n");
81 printf("examples:\n");
82 printf("mpiexec -n 4 cpi\n");
83 printf("mpiexec -n 1 -host foo master : -n 8 worker\n");
84 printf("\n");
85 printf("For a list of all mpiexec options, execute 'mpiexec -help2'\n");
86 }
87
mp_print_extra_options(void)88 void mp_print_extra_options(void)
89 {
90 printf("\n");
91 printf("All options to mpiexec:\n");
92 printf("\n");
93 printf("-n x\n");
94 printf("-np x\n");
95 printf(" launch x processes\n");
96 printf("-localonly x\n");
97 printf("-n x -localonly\n");
98 printf(" launch x processes on the local machine\n");
99 printf("-machinefile filename\n");
100 printf(" use a file to list the names of machines to launch on\n");
101 printf("-host hostname\n");
102 printf("-hosts n host1 host2 ... hostn\n");
103 printf("-hosts n host1 m1 host2 m2 ... hostn mn\n");
104 printf(" launch on the specified hosts\n");
105 printf(" In the second version the number of processes = m1 + m2 + ... + mn\n");
106 printf("-binding proc_binding_scheme\n");
107 printf(" Set the proc binding for each of the launched processes to a single core.\n");
108 printf(" Currently \"auto\" and \"user\" are supported as the proc_binding_schemes \n");
109 printf("-map drive:\\\\host\\share\n");
110 printf(" map a drive on all the nodes\n");
111 printf(" this mapping will be removed when the processes exit\n");
112 printf("-mapall\n");
113 printf(" map all of the current network drives\n");
114 printf(" this mapping will be removed when the processes exit\n");
115 printf(" (Available currently only on windows)\n");
116 printf("-dir drive:\\my\\working\\directory\n");
117 printf("-wdir /my/working/directory\n");
118 printf(" launch processes in the specified directory\n");
119 printf("-env var val\n");
120 printf(" set environment variable before launching the processes\n");
121 printf("-logon\n");
122 printf(" prompt for user account and password\n");
123 printf("-pwdfile filename\n");
124 printf(" read the account and password from the file specified\n");
125 printf(" put the account on the first line and the password on the second\n");
126 /*
127 printf("-nocolor\n");
128 printf(" don't use process specific output coloring\n");
129 */
130 printf("-nompi\n");
131 printf(" launch processes without the mpi startup mechanism\n");
132 /*
133 printf("-nomapping\n");
134 printf(" don't try to map the current directory on the remote nodes\n");
135 */
136 printf("-nopopup_debug\n");
137 printf(" disable the system popup dialog if the process crashes\n");
138 /*
139 printf("-dbg\n");
140 printf(" catch unhandled exceptions\n");
141 */
142 printf("-exitcodes\n");
143 printf(" print the process exit codes when each process exits.\n");
144 printf("-noprompt\n");
145 printf(" prevent mpiexec from prompting for user credentials.\n");
146 printf("-priority class[:level]\n");
147 printf(" set the process startup priority class and optionally level.\n");
148 printf(" class = 0,1,2,3,4 = idle, below, normal, above, high\n");
149 printf(" level = 0,1,2,3,4,5 = idle, lowest, below, normal, above, highest\n");
150 printf(" the default is -priority 1:3\n");
151 printf("-localroot\n");
152 printf(" launch the root process directly from mpiexec if the host is local.\n");
153 printf(" (This allows the root process to create windows and be debugged.)\n");
154 printf("-port port\n");
155 printf("-p port\n");
156 printf(" specify the port that smpd is listening on.\n");
157 printf("-phrase passphrase\n");
158 printf(" specify the passphrase to authenticate connections to smpd with.\n");
159 printf("-smpdfile filename\n");
160 printf(" specify the file where the smpd options are stored including the passphrase.\n");
161 /*
162 printf("-soft Fortran90_triple\n");
163 printf(" acceptable number of processes to launch up to maxprocs\n");
164 */
165 printf("-path search_path\n");
166 printf(" search path for executable, ; separated\n");
167 /*
168 printf("-arch architecture\n");
169 printf(" sun, linux, rs6000, ...\n");
170 */
171 printf("-register [-user n]\n");
172 printf(" encrypt a user name and password to the Windows registry.\n");
173 printf(" optionally specify a user slot index\n");
174 printf("-remove [-user n]\n");
175 printf(" delete the encrypted credentials from the Windows registry.\n");
176 printf(" If no user index is specified then all entries are removed.\n");
177 printf("-validate [-user n] [-host hostname]\n");
178 printf(" validate the encrypted credentials for the current or specified host.\n");
179 printf(" A specific user index can be specified otherwise index 0 is the default.\n");
180 printf("-user n\n");
181 printf(" use the registered user credentials from slot n to launch the job.\n");
182 printf("-timeout seconds\n");
183 printf(" timeout for the job.\n");
184 printf("-plaintext\n");
185 printf(" don't encrypt the data on the wire.\n");
186 printf("-delegate\n");
187 printf(" use passwordless delegation to launch processes\n");
188 printf("-impersonate\n");
189 printf(" use passwordless authentication to launch processes\n");
190 printf("-add_job <job_name> <domain\\user>\n");
191 printf("-add_job <job_name> <domain\\user> -host <hostname>\n");
192 printf(" add a job key for the specified domain user on the local or specified host\n");
193 printf(" requires administrator privileges\n");
194 printf("-remove_job <name>\n");
195 printf("-remove_job <name> -host <hostname>\n");
196 printf(" remove a job key from the local or specified host\n");
197 printf(" requires administrator privileges\n");
198 printf("-associate_job <name>\n");
199 printf("-associate_job <name> -host <hostname>\n");
200 printf(" associate the current user's token with the specified job on the local or specified host\n");
201 printf("-job <name>\n");
202 printf(" launch the processes in the context of the specified job\n");
203 printf("-whomai\n");
204 printf(" print the current user name\n");
205 printf("-l\n");
206 printf(" prefix output with the process number. (This option is a lowercase L not the number one)\n");
207 }
208
209 #ifdef HAVE_WINDOWS_H
210
211 /* check to see if a path is on a network mapped drive and would need to be mapped on a remote system */
NeedToMap(char * pszFullPath,char * pDrive,char * pszShare)212 SMPD_BOOL NeedToMap(char *pszFullPath, char *pDrive, char *pszShare)
213 {
214 DWORD dwResult;
215 DWORD dwLength;
216 char pBuffer[4096];
217 REMOTE_NAME_INFO *info = (REMOTE_NAME_INFO*)pBuffer;
218 char pszTemp[SMPD_MAX_EXE_LENGTH];
219
220 if (*pszFullPath == '"')
221 {
222 strncpy(pszTemp, &pszFullPath[1], SMPD_MAX_EXE_LENGTH);
223 pszTemp[SMPD_MAX_EXE_LENGTH-1] = '\0';
224 if (pszTemp[strlen(pszTemp)-1] == '"')
225 pszTemp[strlen(pszTemp)-1] = '\0';
226 pszFullPath = pszTemp;
227 }
228 dwLength = 4096;
229 info->lpConnectionName = NULL;
230 info->lpRemainingPath = NULL;
231 info->lpUniversalName = NULL;
232 dwResult = WNetGetUniversalName(pszFullPath, REMOTE_NAME_INFO_LEVEL, info, &dwLength);
233 if (dwResult == NO_ERROR)
234 {
235 *pDrive = *pszFullPath;
236 strcpy(pszShare, info->lpConnectionName);
237 return SMPD_TRUE;
238 }
239
240 /*printf("WNetGetUniversalName: '%s'\n error %d\n", pszExe, dwResult);*/
241 return SMPD_FALSE;
242 }
243
244 /* convert an executable name to a universal naming convention version so that it can be used on a remote system */
ExeToUnc(char * pszExe,int length)245 void ExeToUnc(char *pszExe, int length)
246 {
247 DWORD dwResult;
248 DWORD dwLength;
249 char pBuffer[4096];
250 REMOTE_NAME_INFO *info = (REMOTE_NAME_INFO*)pBuffer;
251 char pszTemp[SMPD_MAX_EXE_LENGTH];
252 SMPD_BOOL bQuoted = SMPD_FALSE;
253 char *pszOriginal;
254
255 pszOriginal = pszExe;
256
257 if (*pszExe == '"')
258 {
259 bQuoted = SMPD_TRUE;
260 strncpy(pszTemp, &pszExe[1], SMPD_MAX_EXE_LENGTH);
261 pszTemp[SMPD_MAX_EXE_LENGTH-1] = '\0';
262 if (pszTemp[strlen(pszTemp)-1] == '"')
263 pszTemp[strlen(pszTemp)-1] = '\0';
264 pszExe = pszTemp;
265 }
266 dwLength = 4096;
267 info->lpConnectionName = NULL;
268 info->lpRemainingPath = NULL;
269 info->lpUniversalName = NULL;
270 dwResult = WNetGetUniversalName(pszExe, REMOTE_NAME_INFO_LEVEL, info, &dwLength);
271 if (dwResult == NO_ERROR)
272 {
273 if (bQuoted)
274 snprintf(pszOriginal, length, "\"%s\"", info->lpUniversalName);
275 else
276 {
277 strncpy(pszOriginal, info->lpUniversalName, length);
278 pszOriginal[length-1] = '\0';
279 }
280 }
281 }
282
283 #endif
284
strip_args(int * argcp,char ** argvp[],int n)285 static int strip_args(int *argcp, char **argvp[], int n)
286 {
287 int i;
288
289 if (n+1 > (*argcp))
290 {
291 printf("Error: cannot strip %d args, only %d left.\n", n, (*argcp)-1);
292 return SMPD_FAIL;
293 }
294 for (i=n+1; i<=(*argcp); i++)
295 {
296 (*argvp)[i-n] = (*argvp)[i];
297 }
298 (*argcp) -= n;
299 return SMPD_SUCCESS;
300 }
301
smpd_isnumber(char * str)302 static SMPD_BOOL smpd_isnumber(char *str)
303 {
304 size_t i, n = strlen(str);
305 for (i=0; i<n; i++)
306 {
307 if (!isdigit(str[i]))
308 return SMPD_FALSE;
309 }
310 return SMPD_TRUE;
311 }
312
313 #ifdef HAVE_WINDOWS_H
mpiexec_assert_hook(int reportType,char * message,int * returnValue)314 static int mpiexec_assert_hook( int reportType, char *message, int *returnValue )
315 {
316 SMPD_UNREFERENCED_ARG(reportType);
317
318 fprintf(stderr, "%s", message);
319 if (returnValue != NULL)
320 exit(*returnValue);
321 exit(-1);
322 }
323
324 /* This function reads the user binding option and sets the affinity map.
325 * The user option is of the form "user:a,b,c" where a, b, c are integers denoting
326 * the cores in the affinity map
327 */
read_user_affinity_map(char * option)328 static int read_user_affinity_map(char *option)
329 {
330 char *p = NULL, *q = NULL, *context = NULL;
331 int i=0, map_sz = 0;
332
333 if(smpd_process.affinity_map != NULL){
334 printf("Error: duplicate user affinity map option\n");
335 return SMPD_FAIL;
336 }
337 if(option == NULL){
338 printf("Error: NULL user affinity option\n");
339 return SMPD_FAIL;
340 }
341
342 /* option = "user:1,2,3" */
343 p = option;
344 p = strtok_s(p, ":", &context);
345 if(p == NULL){
346 printf("Error parsing user affinity map\n");
347 return SMPD_FAIL;
348 }
349 p = strtok_s(NULL, ":", &context);
350 if(p == NULL){
351 printf("Error parsing user affinity map\n");
352 return SMPD_FAIL;
353 }
354
355 /* p should now point to the affinity map separated by comma's */
356 map_sz = 1;
357 q = p;
358 /* parse to find the number of elements in the map */
359 while(*q != '\0'){
360 if(*q == ','){
361 map_sz++;
362 }
363 q++;
364 }
365
366 /* Allocate the mem for map */
367 smpd_process.affinity_map = (int *)MPIU_Malloc(sizeof(int) * map_sz);
368 if(smpd_process.affinity_map == NULL){
369 printf("Unable to allocate memory for affinity map\n");
370 return SMPD_FAIL;
371 }
372 smpd_process.affinity_map_sz = map_sz;
373
374 context = NULL;
375 p = strtok_s(p, ",", &context);
376 i = 0;
377 while(p != NULL){
378 /* FIXME: We don't detect overflow case in atoi */
379 smpd_process.affinity_map[i++] = atoi(p);
380 p = strtok_s(NULL, ",", &context);
381 }
382
383 smpd_dbg_printf("The user affinity map is : [ ");
384 for(i=0; i<map_sz; i++){
385 smpd_dbg_printf(" %d ,",smpd_process.affinity_map[i]);
386 }
387 smpd_dbg_printf(" ] \n");
388
389 return SMPD_SUCCESS;
390 }
391 #endif
392
393 #undef FCNAME
394 #define FCNAME "mp_parse_command_args"
mp_parse_command_args(int * argcp,char ** argvp[])395 int mp_parse_command_args(int *argcp, char **argvp[])
396 {
397 int cur_rank;
398 int affinity_map_index;
399 int argc, next_argc;
400 char **next_argv;
401 char *exe_ptr;
402 int num_args_to_strip;
403 int nproc;
404 char machine_file_name[SMPD_MAX_FILENAME];
405 int use_machine_file = SMPD_FALSE;
406 smpd_map_drive_node_t *map_node, *drive_map_list;
407 smpd_map_drive_node_t *gmap_node, *gdrive_map_list;
408 smpd_env_node_t *env_node, *env_list;
409 smpd_env_node_t *genv_list;
410 char *env_str, env_data[SMPD_MAX_ENV_LENGTH];
411 char wdir[SMPD_MAX_DIR_LENGTH];
412 char gwdir[SMPD_MAX_DIR_LENGTH];
413 int use_debug_flag;
414 char pwd_file_name[SMPD_MAX_FILENAME];
415 int use_pwd_file;
416 smpd_host_node_t *host_node_ptr, *host_list, *host_node_iter;
417 smpd_host_node_t *ghost_list;
418 int no_drive_mapping;
419 int n_priority_class, n_priority;
420 int index, i;
421 char configfilename[SMPD_MAX_FILENAME];
422 int use_configfile, delete_configfile;
423 char exe[SMPD_MAX_EXE_LENGTH], *exe_iter;
424 char exe_path[SMPD_MAX_EXE_LENGTH], *namepart;
425 smpd_launch_node_t *launch_node, *launch_node_iter;
426 int exe_len_remaining;
427 char path[SMPD_MAX_PATH_LENGTH];
428 char gpath[SMPD_MAX_PATH_LENGTH];
429 char temp_password[SMPD_MAX_PASSWORD_LENGTH];
430 FILE *fin_config = NULL;
431 int result;
432 int maxlen;
433 int appnum = 0;
434 char channel[SMPD_MAX_NAME_LENGTH] = "";
435 /* smpd configured settings */
436 char smpd_setting_tmp_buffer[20];
437 char smpd_setting_channel[20] = "";
438 char smpd_setting_internode_channel[20] = "";
439 SMPD_BOOL smpd_setting_timeout = SMPD_INVALID_SETTING;
440 SMPD_BOOL smpd_setting_priority_class = SMPD_INVALID_SETTING;
441 SMPD_BOOL smpd_setting_priority = SMPD_INVALID_SETTING;
442 char smpd_setting_path[SMPD_MAX_PATH_LENGTH] = "";
443 SMPD_BOOL smpd_setting_localonly = SMPD_INVALID_SETTING;
444 char nemesis_netmod[SMPD_MAX_NEMESIS_NETMOD_LENGTH];
445
446 #ifdef HAVE_WINDOWS_H
447 int user_index;
448 char user_index_str[20];
449 #endif
450
451 smpd_enter_fn(FCNAME);
452
453 #ifdef HAVE_WINDOWS_H
454 /* prevent mpiexec from bringing up an error message window if it crashes */
455 _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
456 _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
457 _CrtSetReportHook(mpiexec_assert_hook);
458
459 /* check for windows specific arguments */
460 if (*argcp > 1)
461 {
462 if (strcmp((*argvp)[1], "-register") == 0)
463 {
464 char register_filename[SMPD_MAX_FILENAME];
465 user_index = 0;
466 smpd_get_opt_int(argcp, argvp, "-user", &user_index);
467 if (user_index < 0)
468 {
469 user_index = 0;
470 }
471 register_filename[0] = '\0';
472 if(smpd_get_opt_string(argcp, argvp, "-file", register_filename, SMPD_MAX_FILENAME))
473 {
474 smpd_dbg_printf("Registering username/password to a file\n");
475 }
476 for (;;)
477 {
478 smpd_get_account_and_password(smpd_process.UserAccount, smpd_process.UserPassword);
479 fprintf(stderr, "confirm password: ");fflush(stderr);
480 smpd_get_password(temp_password);
481 if (strcmp(smpd_process.UserPassword, temp_password) == 0)
482 break;
483 printf("passwords don't match, please try again.\n");
484 }
485 if(strlen(register_filename) > 0)
486 {
487 if(smpd_save_cred_to_file(register_filename, smpd_process.UserAccount, smpd_process.UserPassword))
488 {
489 printf("Username/password encrypted and saved to registry file\n");
490 }
491 else
492 {
493 smpd_err_printf("Error saving username/password to registry file\n");
494 }
495 smpd_exit(0);
496 }
497 if (smpd_save_password_to_registry(user_index, smpd_process.UserAccount, smpd_process.UserPassword, SMPD_TRUE))
498 {
499 printf("Password encrypted into the Registry.\n");
500 smpd_delete_cached_password();
501 }
502 else
503 {
504 printf("Error: Unable to save encrypted password.\n");
505 }
506 fflush(stdout);
507 smpd_exit(0);
508 }
509 if ( (strcmp((*argvp)[1], "-remove") == 0) || (strcmp((*argvp)[1], "-unregister") == 0) )
510 {
511 user_index = 0;
512 if (smpd_get_opt_string(argcp, argvp, "-user", user_index_str, 20))
513 {
514 if (user_index_str[0] == 'a' && user_index_str[1] == 'l' && user_index_str[2] == 'l' && user_index_str[3] == '\0')
515 {
516 user_index = -1;
517 }
518 else
519 {
520 user_index = atoi(user_index_str);
521 if (user_index < 0)
522 {
523 user_index = 0;
524 }
525 }
526 }
527 if (smpd_delete_current_password_registry_entry(user_index))
528 {
529 smpd_delete_cached_password();
530 printf("Account and password removed from the Registry.\n");
531 }
532 else
533 {
534 printf("ERROR: Unable to remove the encrypted password.\n");
535 }
536 fflush(stdout);
537 smpd_exit(0);
538 }
539 if (strcmp((*argvp)[1], "-validate") == 0)
540 {
541 user_index = 0;
542 smpd_get_opt_int(argcp, argvp, "-user", &user_index);
543 if (user_index < 0)
544 {
545 user_index = 0;
546 }
547 if (smpd_read_password_from_registry(user_index, smpd_process.UserAccount, smpd_process.UserPassword))
548 {
549 if (!smpd_get_opt_string(argcp, argvp, "-host", smpd_process.console_host, SMPD_MAX_HOST_LENGTH))
550 {
551 smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH);
552 }
553 smpd_get_opt_int(argcp, argvp, "-port", &smpd_process.port);
554 smpd_get_opt_string(argcp, argvp, "-phrase", smpd_process.passphrase, SMPD_PASSPHRASE_MAX_LENGTH);
555 smpd_process.builtin_cmd = SMPD_CMD_VALIDATE;
556 smpd_do_console();
557 }
558 else
559 {
560 printf("FAIL: Unable to read the credentials from the registry.\n");fflush(stdout);
561 }
562 fflush(stdout);
563 smpd_exit(0);
564 }
565 if (strcmp((*argvp)[1], "-whoami") == 0)
566 {
567 char username[100] = "";
568 ULONG len = 100;
569 if (GetUserNameEx(NameSamCompatible, username, &len))
570 {
571 printf("%s\n", username);
572 }
573 else if (GetUserName(username, &len))
574 {
575 printf("%s\n", username);
576 }
577 else
578 {
579 printf("ERROR: Unable to determine the current username.\n");
580 }
581 fflush(stdout);
582 smpd_exit(0);
583 }
584
585 if (strcmp((*argvp)[1], "-add_job") == 0)
586 {
587 if (smpd_get_opt(argcp, argvp, "-verbose"))
588 {
589 smpd_process.verbose = SMPD_TRUE;
590 smpd_process.dbg_state |= SMPD_DBG_STATE_ERROUT | SMPD_DBG_STATE_STDOUT | SMPD_DBG_STATE_TRACE;
591 }
592
593 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))
594 {
595 if (!smpd_get_opt_string(argcp, argvp, "-host", smpd_process.console_host, SMPD_MAX_HOST_LENGTH))
596 {
597 smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH);
598 }
599 smpd_get_opt_int(argcp, argvp, "-port", &smpd_process.port);
600 smpd_get_opt_string(argcp, argvp, "-phrase", smpd_process.passphrase, SMPD_PASSPHRASE_MAX_LENGTH);
601 if (smpd_get_opt_string(argcp, argvp, "-password", smpd_process.job_key_password, SMPD_MAX_PASSWORD_LENGTH))
602 {
603 smpd_process.builtin_cmd = SMPD_CMD_ADD_JOB_AND_PASSWORD;
604 }
605 else
606 {
607 smpd_process.builtin_cmd = SMPD_CMD_ADD_JOB;
608 }
609 smpd_do_console();
610 fflush(stdout);
611 smpd_exit(0);
612 }
613 printf("Invalid number of arguments passed to -add_job <job_key> <user_account>\n");
614 fflush(stdout);
615 smpd_exit(-1);
616 }
617
618 if (strcmp((*argvp)[1], "-remove_job") == 0)
619 {
620 if (smpd_get_opt(argcp, argvp, "-verbose"))
621 {
622 smpd_process.verbose = SMPD_TRUE;
623 smpd_process.dbg_state |= SMPD_DBG_STATE_ERROUT | SMPD_DBG_STATE_STDOUT | SMPD_DBG_STATE_TRACE;
624 }
625
626 if (smpd_get_opt_string(argcp, argvp, "-remove_job", smpd_process.job_key, SMPD_MAX_NAME_LENGTH))
627 {
628 if (!smpd_get_opt_string(argcp, argvp, "-host", smpd_process.console_host, SMPD_MAX_HOST_LENGTH))
629 {
630 smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH);
631 }
632 smpd_get_opt_int(argcp, argvp, "-port", &smpd_process.port);
633 smpd_get_opt_string(argcp, argvp, "-phrase", smpd_process.passphrase, SMPD_PASSPHRASE_MAX_LENGTH);
634 smpd_process.builtin_cmd = SMPD_CMD_REMOVE_JOB;
635 smpd_do_console();
636 fflush(stdout);
637 smpd_exit(0);
638 }
639 printf("Invalid number of arguments passed to -remove_job <job_key>\n");
640 fflush(stdout);
641 smpd_exit(-1);
642 }
643
644 if (strcmp((*argvp)[1], "-associate_job") == 0)
645 {
646 if (smpd_get_opt(argcp, argvp, "-verbose"))
647 {
648 smpd_process.verbose = SMPD_TRUE;
649 smpd_process.dbg_state |= SMPD_DBG_STATE_ERROUT | SMPD_DBG_STATE_STDOUT | SMPD_DBG_STATE_TRACE;
650 }
651
652 if (smpd_get_opt_string(argcp, argvp, "-associate_job", smpd_process.job_key, SMPD_MAX_NAME_LENGTH))
653 {
654 if (!smpd_get_opt_string(argcp, argvp, "-host", smpd_process.console_host, SMPD_MAX_HOST_LENGTH))
655 {
656 smpd_get_hostname(smpd_process.console_host, SMPD_MAX_HOST_LENGTH);
657 }
658 smpd_get_opt_int(argcp, argvp, "-port", &smpd_process.port);
659 smpd_get_opt_string(argcp, argvp, "-phrase", smpd_process.passphrase, SMPD_PASSPHRASE_MAX_LENGTH);
660 smpd_process.builtin_cmd = SMPD_CMD_ASSOCIATE_JOB;
661 smpd_do_console();
662 fflush(stdout);
663 smpd_exit(0);
664 }
665 printf("Invalid number of arguments passed to -associate_job <job_key>\n");
666 fflush(stdout);
667 smpd_exit(-1);
668 }
669 }
670 #endif
671
672 if ((*argcp == 2) &&
673 ((strcmp((*argvp)[1], "-pmiserver") == 0) || (strcmp((*argvp)[1], "-pmi_server") == 0)))
674 {
675 smpd_err_printf("Error: No number of processes specified after the %s option\n", (*argvp)[1]);
676 return SMPD_FAIL;
677 }
678
679 if (*argcp >= 3)
680 {
681 if ((strcmp((*argvp)[1], "-pmiserver") == 0) || (strcmp((*argvp)[1], "-pmi_server") == 0))
682 {
683 char host[100];
684 int id;
685
686 smpd_process.use_pmi_server = SMPD_TRUE;
687
688 if (smpd_get_opt(argcp, argvp, "-verbose"))
689 {
690 smpd_process.verbose = SMPD_TRUE;
691 smpd_process.dbg_state |= SMPD_DBG_STATE_ERROUT | SMPD_DBG_STATE_STDOUT | SMPD_DBG_STATE_TRACE;
692 }
693
694 if(smpd_get_opt(argcp, argvp, "-hide_console")){
695 #ifdef HAVE_WINDOWS_H
696 FreeConsole();
697 #endif
698 }
699
700 #ifdef HAVE_WINDOWS_H
701 if(smpd_get_opt(argcp, argvp, "-impersonate"))
702 {
703 smpd_process.use_sspi = SMPD_TRUE;
704 smpd_process.use_delegation = SMPD_FALSE;
705 }
706 if(smpd_get_opt(argcp, argvp, "-delegate"))
707 {
708 smpd_process.use_sspi = SMPD_TRUE;
709 smpd_process.use_delegation = SMPD_TRUE;
710 }
711 #endif
712 smpd_process.nproc = atoi((*argvp)[2]);
713 if (smpd_process.nproc < 1)
714 {
715 smpd_err_printf("invalid number of processes: %s\n", (*argvp)[2]);
716 return SMPD_FAIL;
717 }
718
719 /* set up the host list to connect to only the local host */
720 smpd_get_hostname(host, 100);
721 result = smpd_get_host_id(host, &id);
722 if (result != SMPD_SUCCESS)
723 {
724 smpd_err_printf("unable to get a id for host %s\n", host);
725 return SMPD_FAIL;
726 }
727
728 if (*argcp >= 5){
729 smpd_process.singleton_client_port = atoi((*argvp)[4]);
730 if(smpd_process.singleton_client_port < 1){
731 smpd_err_printf("Invalid singleton client port = %d\n",
732 smpd_process.singleton_client_port);
733 return SMPD_FAIL;
734 }
735 }
736
737 /* Return without creating any launch_nodes. This will result in an mpiexec connected to the local smpd
738 * and no processes launched.
739 */
740 return SMPD_SUCCESS;
741 }
742 }
743
744 /* Get settings saved in smpd */
745 /* These settings have the lowest priority.
746 * First are settings on the command line,
747 * second are settings from environment variables and
748 * these are last.
749 */
750 result = smpd_get_smpd_data("channel", smpd_setting_channel, 20);
751 result = smpd_get_smpd_data("internode_channel", smpd_setting_internode_channel, 20);
752 smpd_setting_tmp_buffer[0] = '\0';
753 result = smpd_get_smpd_data("timeout", smpd_setting_tmp_buffer, 20);
754 if (result == SMPD_SUCCESS)
755 {
756 smpd_setting_timeout = atoi(smpd_setting_tmp_buffer);
757 if (smpd_setting_timeout < 1)
758 {
759 smpd_setting_timeout = SMPD_INVALID_SETTING;
760 }
761 }
762 smpd_process.output_exit_codes = smpd_option_on("exitcodes");
763 if (smpd_option_on("noprompt") == SMPD_TRUE)
764 {
765 smpd_process.noprompt = SMPD_TRUE;
766 smpd_process.credentials_prompt = SMPD_FALSE;
767 }
768 env_str = getenv("MPIEXEC_NOPROMPT");
769 if (env_str)
770 {
771 smpd_process.noprompt = SMPD_TRUE;
772 smpd_process.credentials_prompt = SMPD_FALSE;
773 }
774 smpd_setting_tmp_buffer[0] = '\0';
775 result = smpd_get_smpd_data("priority", smpd_setting_tmp_buffer, 20);
776 if (result == SMPD_SUCCESS)
777 {
778 if (smpd_isnumbers_with_colon(smpd_setting_tmp_buffer))
779 {
780 char *str;
781 smpd_setting_priority_class = atoi(smpd_setting_tmp_buffer); /* This assumes atoi will stop at the colon and return a number */
782 str = strchr(smpd_setting_tmp_buffer, ':');
783 if (str)
784 {
785 str++;
786 smpd_setting_priority = atoi(str);
787 }
788 else
789 {
790 smpd_setting_priority = SMPD_DEFAULT_PRIORITY;
791 }
792 if (smpd_setting_priority_class < 0 || smpd_setting_priority_class > 4 || smpd_setting_priority < 0 || smpd_setting_priority > 5)
793 {
794 /* ignore invalid priority settings */
795 smpd_setting_priority_class = SMPD_INVALID_SETTING;
796 smpd_setting_priority = SMPD_INVALID_SETTING;
797 }
798 }
799 }
800 result = smpd_get_smpd_data("app_path", smpd_setting_path, SMPD_MAX_PATH_LENGTH);
801 smpd_process.plaintext = smpd_option_on("plaintext");
802 smpd_setting_localonly = smpd_option_on("localonly");
803 result = smpd_get_smpd_data("port", smpd_setting_tmp_buffer, 20);
804 if (result == SMPD_SUCCESS)
805 {
806 if (smpd_isnumber(smpd_setting_tmp_buffer))
807 {
808 result = atoi(smpd_setting_tmp_buffer);
809 if (result != 0)
810 smpd_process.port = result;
811 }
812 }
813
814 env_str = getenv("MPIEXEC_SMPD_PORT");
815 if (env_str)
816 {
817 if (smpd_isnumber(env_str))
818 {
819 result = atoi(env_str);
820 if (result != 0)
821 smpd_process.port = result;
822 }
823 }
824
825 /* check for mpi options */
826 /*
827 * Required:
828 * -n <maxprocs>
829 * -host <hostname>
830 * -soft <Fortran90 triple> - represents allowed number of processes up to maxprocs
831 * a or a:b or a:b:c where
832 * 1) a = a
833 * 2) a:b = a, a+1, a+2, ..., b
834 * 3) a:b:c = a, a+c, a+2c, a+3c, ..., a+kc
835 * where a+kc <= b if c>0
836 * a+kc >= b if c<0
837 * -wdir <working directory>
838 * -path <search path for executable>
839 * -arch <architecture> - sun, linux, rs6000, ...
840 * -configfile <filename> - each line contains a complete set of mpiexec options, #commented
841 *
842 * Extensions:
843 * -env <variable=value>
844 * -env <variable=value;variable2=value2;...>
845 * -hosts <n host1 host2 ... hostn>
846 * -hosts <n host1 m1 host2 m2 ... hostn mn>
847 * -machinefile <filename> - one host per line, #commented
848 * -localonly <numprocs>
849 * -nompi - don't require processes to be SMPD processes (don't have to call SMPD_Init or PMI_Init)
850 * -exitcodes - print the exit codes of processes as they exit
851 * -verbose - same as setting environment variable to SMPD_DBG_OUTPUT=stdout
852 * -quiet_abort - minimize the output when a job is aborted
853 * -file - mpich1 job configuration file
854 *
855 * Windows extensions:
856 * -map <drive:\\host\share>
857 * -pwdfile <filename> - account on the first line and password on the second
858 * -nomapping - don't copy the current directory mapping on the remote nodes
859 * -dbg - debug
860 * -noprompt - don't prompt for user credentials, fail with an error message
861 * -logon - force the prompt for user credentials
862 * -priority <class[:level]> - set the process startup priority class and optionally level.
863 * class = 0,1,2,3,4 = idle, below, normal, above, high
864 * level = 0,1,2,3,4,5 = idle, lowest, below, normal, above, highest
865 * -localroot - launch the root process without smpd if the host is local.
866 * (This allows the root process to create windows and be debugged.)
867 *
868 * Backwards compatibility
869 * -np <numprocs>
870 * -dir <working directory>
871 */
872
873 /* Get a list of hosts from a file or the registry to be used with the -n,-np options */
874 smpd_get_default_hosts();
875
876 cur_rank = 0;
877 affinity_map_index = 0;
878 gdrive_map_list = NULL;
879 genv_list = NULL;
880 gwdir[0] = '\0';
881 gpath[0] = '\0';
882 ghost_list = NULL;
883 next_argc = *argcp;
884 next_argv = *argvp + 1;
885 exe_ptr = **argvp;
886 do
887 {
888 /* calculate the current argc and find the next argv */
889 argc = 1;
890 while ( (*next_argv) != NULL && (**next_argv) != ':')
891 {
892 argc++;
893 next_argc--;
894 next_argv++;
895 }
896 if ( (*next_argv) != NULL && (**next_argv) == ':')
897 {
898 (*next_argv) = NULL;
899 next_argv++;
900 }
901 argcp = &argc;
902
903 /* reset block global variables */
904 use_configfile = SMPD_FALSE;
905 delete_configfile = SMPD_FALSE;
906 configfile_loop:
907 nproc = 0;
908 drive_map_list = NULL;
909 env_list = NULL;
910 wdir[0] = '\0';
911 use_debug_flag = SMPD_FALSE;
912 use_pwd_file = SMPD_FALSE;
913 host_list = NULL;
914 no_drive_mapping = SMPD_FALSE;
915 n_priority_class = (smpd_setting_priority_class == SMPD_INVALID_SETTING) ? SMPD_DEFAULT_PRIORITY_CLASS : smpd_setting_priority_class;
916 n_priority = (smpd_setting_priority == SMPD_INVALID_SETTING) ? SMPD_DEFAULT_PRIORITY : smpd_setting_priority;
917 use_machine_file = SMPD_FALSE;
918 if (smpd_setting_path[0] != '\0')
919 {
920 strncpy(path, smpd_setting_path, SMPD_MAX_PATH_LENGTH);
921 }
922 else
923 {
924 path[0] = '\0';
925 }
926
927 /* Check for the -configfile option. It must be the first and only option in a group. */
928 if ((*argvp)[1] && (*argvp)[1][0] == '-')
929 {
930 if ((*argvp)[1][1] == '-')
931 {
932 /* double -- option provided, trim it to a single - */
933 index = 2;
934 while ((*argvp)[1][index] != '\0')
935 {
936 (*argvp)[1][index-1] = (*argvp)[1][index];
937 index++;
938 }
939 (*argvp)[1][index-1] = '\0';
940 }
941 if (strcmp(&(*argvp)[1][1], "configfile") == 0)
942 {
943 if (use_configfile)
944 {
945 printf("Error: -configfile option is not valid from within a configuration file.\n");
946 smpd_exit_fn(FCNAME);
947 return SMPD_FAIL;
948 }
949 if (argc < 3)
950 {
951 printf("Error: no filename specifed after -configfile option.\n");
952 smpd_exit_fn(FCNAME);
953 return SMPD_FAIL;
954 }
955 strncpy(configfilename, (*argvp)[2], SMPD_MAX_FILENAME);
956 use_configfile = SMPD_TRUE;
957 fin_config = fopen(configfilename, "r");
958 if (fin_config == NULL)
959 {
960 printf("Error: unable to open config file '%s'\n", configfilename);
961 smpd_exit_fn(FCNAME);
962 return SMPD_FAIL;
963 }
964 if (!smpd_get_argcv_from_file(fin_config, argcp, argvp))
965 {
966 fclose(fin_config);
967 printf("Error: unable to parse config file '%s'\n", configfilename);
968 smpd_exit_fn(FCNAME);
969 return SMPD_FAIL;
970 }
971 }
972 if (strcmp(&(*argvp)[1][1], "file") == 0)
973 {
974 if (argc < 3)
975 {
976 printf("Error: no filename specifed after -file option.\n");
977 smpd_exit_fn(FCNAME);
978 return SMPD_FAIL;
979 }
980 mp_parse_mpich1_configfile((*argvp)[2], configfilename, SMPD_MAX_FILENAME);
981 delete_configfile = SMPD_TRUE;
982 use_configfile = SMPD_TRUE;
983 fin_config = fopen(configfilename, "r");
984 if (fin_config == NULL)
985 {
986 printf("Error: unable to open config file '%s'\n", configfilename);
987 smpd_exit_fn(FCNAME);
988 return SMPD_FAIL;
989 }
990 if (!smpd_get_argcv_from_file(fin_config, argcp, argvp))
991 {
992 fclose(fin_config);
993 printf("Error: unable to parse config file '%s'\n", configfilename);
994 smpd_exit_fn(FCNAME);
995 return SMPD_FAIL;
996 }
997 }
998 }
999
1000 /* parse the current block */
1001
1002 /* parse the mpiexec options */
1003 while ((*argvp)[1] && (*argvp)[1][0] == '-')
1004 {
1005 if ((*argvp)[1][1] == '-')
1006 {
1007 /* double -- option provided, trim it to a single - */
1008 index = 2;
1009 while ((*argvp)[1][index] != '\0')
1010 {
1011 (*argvp)[1][index-1] = (*argvp)[1][index];
1012 index++;
1013 }
1014 (*argvp)[1][index-1] = '\0';
1015 }
1016
1017 num_args_to_strip = 1;
1018 if ((strcmp(&(*argvp)[1][1], "np") == 0) || (strcmp(&(*argvp)[1][1], "n") == 0))
1019 {
1020 if (nproc != 0)
1021 {
1022 printf("Error: only one option is allowed to determine the number of processes.\n");
1023 printf(" -hosts, -n, -np and -localonly x are mutually exclusive\n");
1024 smpd_exit_fn(FCNAME);
1025 return SMPD_FAIL;
1026 }
1027 if (argc < 3)
1028 {
1029 printf("Error: no number specified after %s option.\n", (*argvp)[1]);
1030 smpd_exit_fn(FCNAME);
1031 return SMPD_FAIL;
1032 }
1033 nproc = atoi((*argvp)[2]);
1034 if (nproc < 1)
1035 {
1036 printf("Error: must specify a number greater than 0 after the %s option\n", (*argvp)[1]);
1037 smpd_exit_fn(FCNAME);
1038 return SMPD_FAIL;
1039 }
1040 num_args_to_strip = 2;
1041 }
1042 else if (strcmp(&(*argvp)[1][1], "localonly") == 0)
1043 {
1044 /* check to see if there is a number after the localonly option */
1045 if (argc > 2)
1046 {
1047 if (smpd_isnumber((*argvp)[2]))
1048 {
1049 if (nproc != 0)
1050 {
1051 printf("Error: only one option is allowed to determine the number of processes.\n");
1052 printf(" -hosts, -n, -np and -localonly x are mutually exclusive\n");
1053 smpd_exit_fn(FCNAME);
1054 return SMPD_FAIL;
1055 }
1056 nproc = atoi((*argvp)[2]);
1057 if (nproc < 1)
1058 {
1059 printf("Error: If you specify a number after -localonly option,\n it must be greater than 0.\n");
1060 smpd_exit_fn(FCNAME);
1061 return SMPD_FAIL;
1062 }
1063 num_args_to_strip = 2;
1064 }
1065 }
1066 /* Use localroot to implement localonly */
1067 smpd_process.local_root = SMPD_TRUE;
1068 /* create a host list of one and set nproc to -1 to be replaced by nproc after parsing the block */
1069 host_list = (smpd_host_node_t*)MPIU_Malloc(sizeof(smpd_host_node_t));
1070 if (host_list == NULL)
1071 {
1072 printf("failed to allocate memory for a host node.\n");
1073 smpd_exit_fn(FCNAME);
1074 return SMPD_FAIL;
1075 }
1076 host_list->next = NULL;
1077 host_list->left = NULL;
1078 host_list->right = NULL;
1079 host_list->connected = SMPD_FALSE;
1080 host_list->connect_cmd_tag = -1;
1081 host_list->connect_cmd_tag = -1;
1082 host_list->nproc = -1;
1083 host_list->alt_host[0] = '\0';
1084 smpd_get_hostname(host_list->host, SMPD_MAX_HOST_LENGTH);
1085 }
1086 else if (strcmp(&(*argvp)[1][1], "machinefile") == 0)
1087 {
1088 if (smpd_process.s_host_list != NULL)
1089 {
1090 printf("Error: -machinefile can only be specified once per section.\n");
1091 smpd_exit_fn(FCNAME);
1092 return SMPD_FAIL;
1093 }
1094 if (argc < 3)
1095 {
1096 printf("Error: no filename specified after -machinefile option.\n");
1097 smpd_exit_fn(FCNAME);
1098 return SMPD_FAIL;
1099 }
1100 strncpy(machine_file_name, (*argvp)[2], SMPD_MAX_FILENAME);
1101 use_machine_file = SMPD_TRUE;
1102 smpd_parse_machine_file(machine_file_name);
1103 num_args_to_strip = 2;
1104 }
1105 #ifdef HAVE_WINDOWS_H
1106 else if (strcmp(&(*argvp)[1][1], "binding") == 0)
1107 {
1108 if(strcmp(&(*argvp)[2][0], "auto") == 0)
1109 {
1110 smpd_process.set_affinity = TRUE;
1111 smpd_process.affinity_map = NULL;
1112 smpd_process.affinity_map_sz = 0;
1113 }
1114 else if(strncmp(&(*argvp)[2][0], "user", 4) == 0)
1115 {
1116 smpd_process.set_affinity = TRUE;
1117 if(read_user_affinity_map(&(*argvp)[2][0]) != SMPD_SUCCESS)
1118 {
1119 printf("Error parsing user binding scheme\n");
1120 smpd_exit_fn(FCNAME);
1121 }
1122 }
1123 else
1124 {
1125 printf("Error: Process binding schemes supported are \"auto\", \"user\" \n");
1126 smpd_exit_fn(FCNAME);
1127 return SMPD_FAIL;
1128 }
1129 num_args_to_strip = 2;
1130 }
1131 #endif
1132 else if (strcmp(&(*argvp)[1][1], "map") == 0)
1133 {
1134 if (argc < 3)
1135 {
1136 printf("Error: no drive specified after -map option.\n");
1137 smpd_exit_fn(FCNAME);
1138 return SMPD_FAIL;
1139 }
1140 if (smpd_parse_map_string((*argvp)[2], &drive_map_list) != SMPD_SUCCESS)
1141 {
1142 printf("Error: unable to parse the drive mapping option - '%s'\n", (*argvp)[2]);
1143 smpd_exit_fn(FCNAME);
1144 return SMPD_FAIL;
1145 }
1146 num_args_to_strip = 2;
1147 }
1148 else if (strcmp(&(*argvp)[1][1], "mapall") == 0){
1149 #ifdef HAVE_WINDOWS_H
1150 if(smpd_mapall(&drive_map_list) != SMPD_SUCCESS){
1151 printf("Error: unable to map all network drives");
1152 smpd_exit_fn(FCNAME);
1153 return SMPD_FAIL;
1154 }
1155 #endif
1156 num_args_to_strip = 1;
1157 }
1158 else if (strcmp(&(*argvp)[1][1], "gmap") == 0)
1159 {
1160 if (argc < 3)
1161 {
1162 printf("Error: no drive specified after -gmap option.\n");
1163 smpd_exit_fn(FCNAME);
1164 return SMPD_FAIL;
1165 }
1166 if (smpd_parse_map_string((*argvp)[2], &gdrive_map_list) != SMPD_SUCCESS)
1167 {
1168 printf("Error: unable to parse the drive mapping option - '%s'\n", (*argvp)[2]);
1169 smpd_exit_fn(FCNAME);
1170 return SMPD_FAIL;
1171 }
1172 num_args_to_strip = 2;
1173 }
1174 else if ( (strcmp(&(*argvp)[1][1], "dir") == 0) || (strcmp(&(*argvp)[1][1], "wdir") == 0) )
1175 {
1176 if (argc < 3)
1177 {
1178 printf("Error: no directory after %s option\n", (*argvp)[1]);
1179 smpd_exit_fn(FCNAME);
1180 return SMPD_FAIL;
1181 }
1182 strncpy(wdir, (*argvp)[2], SMPD_MAX_DIR_LENGTH);
1183 num_args_to_strip = 2;
1184 }
1185 else if ( (strcmp(&(*argvp)[1][1], "gdir") == 0) || (strcmp(&(*argvp)[1][1], "gwdir") == 0) )
1186 {
1187 if (argc < 3)
1188 {
1189 printf("Error: no directory after %s option\n", (*argvp)[1]);
1190 smpd_exit_fn(FCNAME);
1191 return SMPD_FAIL;
1192 }
1193 strncpy(gwdir, (*argvp)[2], SMPD_MAX_DIR_LENGTH);
1194 num_args_to_strip = 2;
1195 }
1196 else if (strcmp(&(*argvp)[1][1], "env") == 0)
1197 {
1198 if (argc < 4)
1199 {
1200 printf("Error: no environment variable after -env option\n");
1201 smpd_exit_fn(FCNAME);
1202 return SMPD_FAIL;
1203 }
1204 env_node = (smpd_env_node_t*)MPIU_Malloc(sizeof(smpd_env_node_t));
1205 if (env_node == NULL)
1206 {
1207 printf("Error: malloc failed to allocate structure to hold an environment variable.\n");
1208 smpd_exit_fn(FCNAME);
1209 return SMPD_FAIL;
1210 }
1211 strncpy(env_node->name, (*argvp)[2], SMPD_MAX_NAME_LENGTH);
1212 strncpy(env_node->value, (*argvp)[3], SMPD_MAX_VALUE_LENGTH);
1213 env_node->next = env_list;
1214 env_list = env_node;
1215 if (strcmp(env_node->name, "MPI_DLL_NAME") == 0)
1216 {
1217 MPIU_Strncpy(smpd_process.env_dll, env_node->value, SMPD_MAX_FILENAME);
1218 }
1219 if (strcmp(env_node->name, "MPI_WRAP_DLL_NAME") == 0)
1220 {
1221 MPIU_Strncpy(smpd_process.env_wrap_dll, env_node->value, SMPD_MAX_FILENAME);
1222 }
1223 #ifdef HAVE_WINDOWS_H
1224 if ((strcmp(env_node->name, "MPICH_CHOP_ERROR_STACK") == 0) && ((env_node->value[0] == '\0') || (env_node->value[0] == '-')))
1225 {
1226 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
1227 if (hConsole != INVALID_HANDLE_VALUE)
1228 {
1229 CONSOLE_SCREEN_BUFFER_INFO info;
1230 if (GetConsoleScreenBufferInfo(hConsole, &info))
1231 {
1232 /* The user chose default so set the value to the width of the current output console window */
1233 snprintf(env_node->value, SMPD_MAX_VALUE_LENGTH, "%d", info.dwMaximumWindowSize.X);
1234 /*printf("width = %d\n", info.dwMaximumWindowSize.X);*/
1235 }
1236 }
1237 }
1238 #endif
1239 num_args_to_strip = 3;
1240 }
1241 else if (strcmp(&(*argvp)[1][1], "envlist") == 0){
1242 char *str, *token, *value;
1243 if (argc < 4){
1244 printf("Error: no environment variable after -envlist option\n");
1245 smpd_exit_fn(FCNAME);
1246 return SMPD_FAIL;
1247 }
1248 str = MPIU_Strdup((*argvp)[2]);
1249 if (str == NULL){
1250 printf("Error: unable to allocate memory for copying envlist - '%s'\n", (*argvp)[2]);
1251 smpd_exit_fn(FCNAME);
1252 return SMPD_FAIL;
1253 }
1254 token = strtok(str, ",");
1255 while (token){
1256 value = getenv(token);
1257 if (value != NULL){
1258 env_node = (smpd_env_node_t*)MPIU_Malloc(sizeof(smpd_env_node_t));
1259 if (env_node == NULL){
1260 printf("Error: malloc failed to allocate structure to hold an environment variable.\n");
1261 smpd_exit_fn(FCNAME);
1262 return SMPD_FAIL;
1263 }
1264 strncpy(env_node->name, token, SMPD_MAX_NAME_LENGTH);
1265 strncpy(env_node->value, value, SMPD_MAX_VALUE_LENGTH);
1266 env_node->next = env_list;
1267 env_list = env_node;
1268 }
1269 else{
1270 printf("Error: Cannot obtain value of env variable : %s\n", token);
1271 }
1272 token = strtok(NULL, ",");
1273 }
1274 MPIU_Free(str);
1275 num_args_to_strip = 2;
1276 }
1277 else if (strcmp(&(*argvp)[1][1], "envnone") == 0){
1278 printf("-envnone option is not implemented\n");
1279 num_args_to_strip = 1;
1280 }
1281 else if (strcmp(&(*argvp)[1][1], "genv") == 0)
1282 {
1283 if (argc < 4)
1284 {
1285 printf("Error: no environment variable after -genv option\n");
1286 smpd_exit_fn(FCNAME);
1287 return SMPD_FAIL;
1288 }
1289 env_node = (smpd_env_node_t*)MPIU_Malloc(sizeof(smpd_env_node_t));
1290 if (env_node == NULL)
1291 {
1292 printf("Error: malloc failed to allocate structure to hold an environment variable.\n");
1293 smpd_exit_fn(FCNAME);
1294 return SMPD_FAIL;
1295 }
1296 strncpy(env_node->name, (*argvp)[2], SMPD_MAX_NAME_LENGTH);
1297 strncpy(env_node->value, (*argvp)[3], SMPD_MAX_VALUE_LENGTH);
1298 env_node->next = genv_list;
1299 genv_list = env_node;
1300 #ifdef HAVE_WINDOWS_H
1301 if ((strcmp(env_node->name, "MPICH_CHOP_ERROR_STACK") == 0) && ((env_node->value[0] == '\0') || (env_node->value[0] == '-')))
1302 {
1303 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
1304 if (hConsole != INVALID_HANDLE_VALUE)
1305 {
1306 CONSOLE_SCREEN_BUFFER_INFO info;
1307 if (GetConsoleScreenBufferInfo(hConsole, &info))
1308 {
1309 /* The user chose default so set the value to the width of the current output console window */
1310 snprintf(env_node->value, SMPD_MAX_VALUE_LENGTH, "%d", info.dwMaximumWindowSize.X);
1311 /*printf("width = %d\n", info.dwMaximumWindowSize.X);*/
1312 }
1313 }
1314 }
1315 #endif
1316 num_args_to_strip = 3;
1317 }
1318 else if (strcmp(&(*argvp)[1][1], "genvall") == 0)
1319 {
1320 printf("-genvall option not implemented\n");
1321 num_args_to_strip = 1;
1322 }
1323 else if (strcmp(&(*argvp)[1][1], "genvnone") == 0)
1324 {
1325 printf("-genvnone option not implemented\n");
1326 num_args_to_strip = 1;
1327 }
1328 else if (strcmp(&(*argvp)[1][1], "genvlist") == 0)
1329 {
1330 char *str, *token, *value;
1331 if (argc < 4)
1332 {
1333 printf("Error: no environment variables after -genvlist option\n");
1334 smpd_exit_fn(FCNAME);
1335 return SMPD_FAIL;
1336 }
1337 str = MPIU_Strdup((*argvp)[2]);
1338 if (str == NULL)
1339 {
1340 printf("Error: unable to allocate memory for a string - '%s'\n", (*argvp)[2]);
1341 smpd_exit_fn(FCNAME);
1342 return SMPD_FAIL;
1343 }
1344 token = strtok(str, ",");
1345 while (token)
1346 {
1347 value = getenv(token);
1348 if (value != NULL)
1349 {
1350 env_node = (smpd_env_node_t*)MPIU_Malloc(sizeof(smpd_env_node_t));
1351 if (env_node == NULL)
1352 {
1353 printf("Error: malloc failed to allocate structure to hold an environment variable.\n");
1354 smpd_exit_fn(FCNAME);
1355 return SMPD_FAIL;
1356 }
1357 strncpy(env_node->name, token, SMPD_MAX_NAME_LENGTH);
1358 strncpy(env_node->value, value, SMPD_MAX_VALUE_LENGTH);
1359 env_node->next = genv_list;
1360 genv_list = env_node;
1361 }
1362 token = strtok(NULL, ",");
1363 }
1364 MPIU_Free(str);
1365 num_args_to_strip = 2;
1366 }
1367 else if ( (strcmp(&(*argvp)[1][1], "logon") == 0) || (strcmp(&(*argvp)[1][1], "login") == 0) )
1368 {
1369 smpd_process.logon = SMPD_TRUE;
1370 }
1371 else if ( (strcmp(&(*argvp)[1][1], "impersonate") == 0) || (strcmp(&(*argvp)[1][1], "impersonation") == 0) )
1372 {
1373 smpd_process.use_sspi = SMPD_TRUE;
1374 smpd_process.use_delegation = SMPD_FALSE;
1375 }
1376 else if ( (strcmp(&(*argvp)[1][1], "delegate") == 0) || (strcmp(&(*argvp)[1][1], "delegation") == 0) )
1377 {
1378 smpd_process.use_sspi = SMPD_TRUE;
1379 smpd_process.use_delegation = SMPD_TRUE;
1380 }
1381 else if (strcmp(&(*argvp)[1][1], "job") == 0)
1382 {
1383 smpd_process.use_delegation = SMPD_FALSE;
1384 smpd_process.use_sspi_job_key = SMPD_TRUE;
1385 if (argc < 3)
1386 {
1387 printf("Error: no job key specified after the -job option\n");
1388 smpd_exit_fn(FCNAME);
1389 return SMPD_FAIL;
1390 }
1391 strncpy(smpd_process.job_key, (*argvp)[2], SMPD_SSPI_JOB_KEY_LENGTH);
1392 num_args_to_strip = 2;
1393 }
1394 else if (strcmp(&(*argvp)[1][1], "dbg") == 0)
1395 {
1396 use_debug_flag = SMPD_TRUE;
1397 }
1398 else if (strcmp(&(*argvp)[1][1], "pwdfile") == 0)
1399 {
1400 use_pwd_file = SMPD_TRUE;
1401 if (argc < 3)
1402 {
1403 printf("Error: no filename specified after -pwdfile option\n");
1404 smpd_exit_fn(FCNAME);
1405 return SMPD_FAIL;
1406 }
1407 strncpy(pwd_file_name, (*argvp)[2], SMPD_MAX_FILENAME);
1408 smpd_get_pwd_from_file(pwd_file_name);
1409 num_args_to_strip = 2;
1410 }
1411 #ifdef HAVE_WINDOWS_H
1412 else if (strcmp(&(*argvp)[1][1], "registryfile") == 0)
1413 {
1414 char reg_file_name[SMPD_MAX_FILENAME];
1415 if (argc < 3)
1416 {
1417 printf("Error: no filename specified after -registryfile option\n");
1418 smpd_exit_fn(FCNAME);
1419 return SMPD_FAIL;
1420 }
1421 strncpy(reg_file_name, (*argvp)[2], SMPD_MAX_FILENAME);
1422 if(!smpd_read_cred_from_file(reg_file_name, smpd_process.UserAccount, SMPD_MAX_ACCOUNT_LENGTH, smpd_process.UserPassword, SMPD_MAX_PASSWORD_LENGTH)){
1423 printf("Error: Could not read credentials from registry file\n");
1424 smpd_exit_fn(FCNAME);
1425 return SMPD_FAIL;
1426 }
1427 num_args_to_strip = 2;
1428 }
1429 #endif
1430 else if (strcmp(&(*argvp)[1][1], "configfile") == 0)
1431 {
1432 printf("Error: The -configfile option must be the first and only option specified in a block.\n");
1433 smpd_exit_fn(FCNAME);
1434 return SMPD_FAIL;
1435 /*
1436 if (argc < 3)
1437 {
1438 printf("Error: no filename specifed after -configfile option.\n");
1439 smpd_exit_fn(FCNAME);
1440 return SMPD_FAIL;
1441 }
1442 strncpy(configfilename, (*argvp)[2], SMPD_MAX_FILENAME);
1443 use_configfile = SMPD_TRUE;
1444 num_args_to_strip = 2;
1445 */
1446 }
1447 else if (strcmp(&(*argvp)[1][1], "file") == 0)
1448 {
1449 printf("Error: The -file option must be the first and only option specified in a block.\n");
1450 smpd_exit_fn(FCNAME);
1451 return SMPD_FAIL;
1452 /*
1453 if (argc < 3)
1454 {
1455 printf("Error: no filename specifed after -file option.\n");
1456 smpd_exit_fn(FCNAME);
1457 return SMPD_FAIL;
1458 }
1459 strncpy(configfilename, (*argvp)[2], SMPD_MAX_FILENAME);
1460 use_configfile = SMPD_TRUE;
1461 num_args_to_strip = 2;
1462 */
1463 }
1464 else if (strcmp(&(*argvp)[1][1], "host") == 0)
1465 {
1466 if (argc < 3)
1467 {
1468 printf("Error: no host specified after -host option.\n");
1469 smpd_exit_fn(FCNAME);
1470 return SMPD_FAIL;
1471 }
1472 if (host_list != NULL)
1473 {
1474 printf("Error: -host option can only be specified once and it cannot be combined with -hosts.\n");
1475 smpd_exit_fn(FCNAME);
1476 return SMPD_FAIL;
1477 }
1478 /* create a host list of one and set nproc to -1 to be replaced by
1479 nproc after parsing the block */
1480 host_list = (smpd_host_node_t*)MPIU_Malloc(sizeof(smpd_host_node_t));
1481 if (host_list == NULL)
1482 {
1483 printf("failed to allocate memory for a host node.\n");
1484 smpd_exit_fn(FCNAME);
1485 return SMPD_FAIL;
1486 }
1487 host_list->next = NULL;
1488 host_list->left = NULL;
1489 host_list->right = NULL;
1490 host_list->connected = SMPD_FALSE;
1491 host_list->connect_cmd_tag = -1;
1492 host_list->nproc = -1;
1493 host_list->alt_host[0] = '\0';
1494 strncpy(host_list->host, (*argvp)[2], SMPD_MAX_HOST_LENGTH);
1495 num_args_to_strip = 2;
1496 smpd_add_host_to_default_list((*argvp)[2]);
1497 }
1498 else if (strcmp(&(*argvp)[1][1], "ghost") == 0)
1499 {
1500 if (argc < 3)
1501 {
1502 printf("Error: no host specified after -ghost option.\n");
1503 smpd_exit_fn(FCNAME);
1504 return SMPD_FAIL;
1505 }
1506 if (ghost_list != NULL)
1507 {
1508 printf("Error: -ghost option can only be specified once.\n");
1509 smpd_exit_fn(FCNAME);
1510 return SMPD_FAIL;
1511 }
1512 /* create a host list of one and set nproc to -1 to be replaced by
1513 nproc after parsing the block */
1514 ghost_list = (smpd_host_node_t*)MPIU_Malloc(sizeof(smpd_host_node_t));
1515 if (ghost_list == NULL)
1516 {
1517 printf("failed to allocate memory for a host node.\n");
1518 smpd_exit_fn(FCNAME);
1519 return SMPD_FAIL;
1520 }
1521 ghost_list->next = NULL;
1522 ghost_list->left = NULL;
1523 ghost_list->right = NULL;
1524 ghost_list->connected = SMPD_FALSE;
1525 ghost_list->connect_cmd_tag = -1;
1526 ghost_list->nproc = -1;
1527 ghost_list->alt_host[0] = '\0';
1528 strncpy(ghost_list->host, (*argvp)[2], SMPD_MAX_HOST_LENGTH);
1529 num_args_to_strip = 2;
1530 smpd_add_host_to_default_list((*argvp)[2]);
1531 }
1532 #ifdef HAVE_WINDOWS_H
1533 else if (strcmp(&(*argvp)[1][1], "ms_hpc") == 0)
1534 {
1535 smpd_process.use_ms_hpc = SMPD_TRUE;
1536 /* Enable SSPI for authenticating PMs */
1537 smpd_process.use_sspi = SMPD_TRUE;
1538 smpd_process.use_delegation = SMPD_FALSE;
1539 /* Use mpiexec as PMI server */
1540 smpd_process.use_pmi_server = SMPD_TRUE;
1541
1542 num_args_to_strip = 1;
1543 }
1544 #endif
1545 else if (strcmp(&(*argvp)[1][1], "hosts") == 0)
1546 {
1547 if (nproc != 0)
1548 {
1549 printf("Error: only one option is allowed to determine the number of processes.\n");
1550 printf(" -hosts, -n, -np and -localonly x are mutually exclusive\n");
1551 smpd_exit_fn(FCNAME);
1552 return SMPD_FAIL;
1553 }
1554 if (host_list != NULL)
1555 {
1556 printf("Error: -hosts option can only be called once and it cannot be combined with -host.\n");
1557 smpd_exit_fn(FCNAME);
1558 return SMPD_FAIL;
1559 }
1560 if (argc > 2)
1561 {
1562 if (smpd_isnumber((*argvp)[2]))
1563 {
1564 /* initially set nproc to be the number of hosts */
1565 nproc = atoi((*argvp)[2]);
1566 if (nproc < 1)
1567 {
1568 printf("Error: You must specify a number greater than 0 after -hosts.\n");
1569 smpd_exit_fn(FCNAME);
1570 return SMPD_FAIL;
1571 }
1572 num_args_to_strip = 2 + nproc;
1573 index = 3;
1574 for (i=0; i<nproc; i++)
1575 {
1576 if (index >= argc)
1577 {
1578 printf("Error: missing host name after -hosts option.\n");
1579 smpd_exit_fn(FCNAME);
1580 return SMPD_FAIL;
1581 }
1582 host_node_ptr = (smpd_host_node_t*)MPIU_Malloc(sizeof(smpd_host_node_t));
1583 if (host_node_ptr == NULL)
1584 {
1585 printf("failed to allocate memory for a host node.\n");
1586 smpd_exit_fn(FCNAME);
1587 return SMPD_FAIL;
1588 }
1589 host_node_ptr->next = NULL;
1590 host_node_ptr->left = NULL;
1591 host_node_ptr->right = NULL;
1592 host_node_ptr->connected = SMPD_FALSE;
1593 host_node_ptr->connect_cmd_tag = -1;
1594 host_node_ptr->nproc = 1;
1595 host_node_ptr->alt_host[0] = '\0';
1596 strncpy(host_node_ptr->host, (*argvp)[index], SMPD_MAX_HOST_LENGTH);
1597 smpd_add_host_to_default_list((*argvp)[index]);
1598 index++;
1599 if (argc > index)
1600 {
1601 if (smpd_isnumber((*argvp)[index]))
1602 {
1603 host_node_ptr->nproc = atoi((*argvp)[index]);
1604 index++;
1605 num_args_to_strip++;
1606 }
1607 }
1608 if (host_list == NULL)
1609 {
1610 host_list = host_node_ptr;
1611 }
1612 else
1613 {
1614 host_node_iter = host_list;
1615 while (host_node_iter->next)
1616 host_node_iter = host_node_iter->next;
1617 host_node_iter->next = host_node_ptr;
1618 }
1619 }
1620
1621 /* adjust nproc to be the actual number of processes */
1622 host_node_iter = host_list;
1623 nproc = 0;
1624 while (host_node_iter)
1625 {
1626 nproc += host_node_iter->nproc;
1627 host_node_iter = host_node_iter->next;
1628 }
1629 }
1630 else
1631 {
1632 printf("Error: You must specify the number of hosts after the -hosts option.\n");
1633 smpd_exit_fn(FCNAME);
1634 return SMPD_FAIL;
1635 }
1636 }
1637 else
1638 {
1639 printf("Error: not enough arguments specified for -hosts option.\n");
1640 smpd_exit_fn(FCNAME);
1641 return SMPD_FAIL;
1642 }
1643 }
1644 else if (strcmp(&(*argvp)[1][1], "nocolor") == 0)
1645 {
1646 smpd_process.do_multi_color_output = SMPD_FALSE;
1647 }
1648 else if (strcmp(&(*argvp)[1][1], "nompi") == 0)
1649 {
1650 smpd_process.no_mpi = SMPD_TRUE;
1651 }
1652 else if (strcmp(&(*argvp)[1][1], "nomapping") == 0)
1653 {
1654 no_drive_mapping = SMPD_TRUE;
1655 }
1656 else if (strcmp(&(*argvp)[1][1], "nopopup_debug") == 0)
1657 {
1658 #ifdef HAVE_WINDOWS_H
1659 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
1660 #endif
1661 }
1662 else if (strcmp(&(*argvp)[1][1], "help") == 0 || (*argvp)[1][1] == '?')
1663 {
1664 mp_print_options();
1665 exit(0);
1666 }
1667 else if (strcmp(&(*argvp)[1][1], "help2") == 0)
1668 {
1669 mp_print_extra_options();
1670 exit(0);
1671 }
1672 else if (strcmp(&(*argvp)[1][1], "exitcodes") == 0)
1673 {
1674 smpd_process.output_exit_codes = SMPD_TRUE;
1675 }
1676 else if (strcmp(&(*argvp)[1][1], "localroot") == 0)
1677 {
1678 smpd_process.local_root = SMPD_TRUE;
1679 }
1680 else if (strcmp(&(*argvp)[1][1], "priority") == 0)
1681 {
1682 if (argc < 3)
1683 {
1684 printf("Error: you must specify a priority after the -priority option.\n");
1685 smpd_exit_fn(FCNAME);
1686 return SMPD_FAIL;
1687 }
1688 if (smpd_isnumbers_with_colon((*argvp)[2]))
1689 {
1690 char *str;
1691 n_priority_class = atoi((*argvp)[2]); /* This assumes atoi will stop at the colon and return a number */
1692 str = strchr((*argvp)[2], ':');
1693 if (str)
1694 {
1695 str++;
1696 n_priority = atoi(str);
1697 }
1698 if (n_priority_class < 0 || n_priority_class > 4 || n_priority < 0 || n_priority > 5)
1699 {
1700 printf("Error: priorities must be between 0-4:0-5\n");
1701 smpd_exit_fn(FCNAME);
1702 return SMPD_FAIL;
1703 }
1704 }
1705 else
1706 {
1707 printf("Error: you must specify a priority after the -priority option.\n");
1708 smpd_exit_fn(FCNAME);
1709 return SMPD_FAIL;
1710 }
1711 smpd_dbg_printf("priorities = %d:%d\n", n_priority_class, n_priority);
1712 num_args_to_strip = 2;
1713 }
1714 else if (strcmp(&(*argvp)[1][1], "iproot") == 0)
1715 {
1716 smpd_process.use_iproot = SMPD_TRUE;
1717 }
1718 else if (strcmp(&(*argvp)[1][1], "noiproot") == 0)
1719 {
1720 smpd_process.use_iproot = SMPD_FALSE;
1721 }
1722 else if (strcmp(&(*argvp)[1][1], "verbose") == 0)
1723 {
1724 smpd_process.verbose = SMPD_TRUE;
1725 smpd_process.dbg_state |= SMPD_DBG_STATE_ERROUT | SMPD_DBG_STATE_STDOUT | SMPD_DBG_STATE_TRACE;
1726 }
1727 else if ( (strcmp(&(*argvp)[1][1], "p") == 0) || (strcmp(&(*argvp)[1][1], "port") == 0))
1728 {
1729 if (argc > 2)
1730 {
1731 if (smpd_isnumber((*argvp)[2]))
1732 {
1733 smpd_process.port = atoi((*argvp)[2]);
1734 }
1735 else
1736 {
1737 printf("Error: you must specify the port smpd is listening on after the %s option.\n", (*argvp)[1]);
1738 smpd_exit_fn(FCNAME);
1739 return SMPD_FAIL;
1740 }
1741 }
1742 else
1743 {
1744 printf("Error: you must specify the port smpd is listening on after the %s option.\n", (*argvp)[1]);
1745 smpd_exit_fn(FCNAME);
1746 return SMPD_FAIL;
1747 }
1748 num_args_to_strip = 2;
1749 }
1750 else if (strcmp(&(*argvp)[1][1], "path") == 0)
1751 {
1752 if (argc < 3)
1753 {
1754 printf("Error: no path specifed after -path option.\n");
1755 smpd_exit_fn(FCNAME);
1756 return SMPD_FAIL;
1757 }
1758 strncpy(path, (*argvp)[2], SMPD_MAX_PATH_LENGTH);
1759 num_args_to_strip = 2;
1760 }
1761 else if (strcmp(&(*argvp)[1][1], "gpath") == 0)
1762 {
1763 if (argc < 3)
1764 {
1765 printf("Error: no path specifed after -gpath option.\n");
1766 smpd_exit_fn(FCNAME);
1767 return SMPD_FAIL;
1768 }
1769 strncpy(gpath, (*argvp)[2], SMPD_MAX_PATH_LENGTH);
1770 num_args_to_strip = 2;
1771 }
1772 else if (strcmp(&(*argvp)[1][1], "noprompt") == 0)
1773 {
1774 smpd_process.noprompt = SMPD_TRUE;
1775 smpd_process.credentials_prompt = SMPD_FALSE;
1776 }
1777 else if (strcmp(&(*argvp)[1][1], "phrase") == 0)
1778 {
1779 if (argc < 3)
1780 {
1781 printf("Error: no passphrase specified afterh -phrase option.\n");
1782 smpd_exit_fn(FCNAME);
1783 return SMPD_FAIL;
1784 }
1785 strncpy(smpd_process.passphrase, (*argvp)[2], SMPD_PASSPHRASE_MAX_LENGTH);
1786 num_args_to_strip = 2;
1787 }
1788 else if (strcmp(&(*argvp)[1][1], "smpdfile") == 0)
1789 {
1790 if (argc < 3)
1791 {
1792 printf("Error: no file name specified after -smpdfile option.\n");
1793 smpd_exit_fn(FCNAME);
1794 return SMPD_FAIL;
1795 }
1796 strncpy(smpd_process.smpd_filename, (*argvp)[2], SMPD_MAX_FILENAME);
1797 {
1798 struct stat s;
1799
1800 if (stat(smpd_process.smpd_filename, &s) == 0)
1801 {
1802 if (s.st_mode & 00077)
1803 {
1804 printf("Error: .smpd file cannot be readable by anyone other than the current user.\n");
1805 smpd_exit_fn(FCNAME);
1806 return SMPD_FAIL;
1807 }
1808 }
1809 }
1810 num_args_to_strip = 2;
1811 }
1812 else if (strcmp(&(*argvp)[1][1], "timeout") == 0)
1813 {
1814 if (argc < 3)
1815 {
1816 printf("Error: no timeout specified after -timeout option.\n");
1817 smpd_exit_fn(FCNAME);
1818 return SMPD_FAIL;
1819 }
1820 smpd_process.timeout = atoi((*argvp)[2]);
1821 if (smpd_process.timeout < 1)
1822 {
1823 printf("Warning: invalid timeout specified, ignoring timeout value of '%s'\n", (*argvp)[2]);
1824 smpd_process.timeout = -1;
1825 }
1826 num_args_to_strip = 2;
1827 }
1828 else if (strcmp(&(*argvp)[1][1], "hide_console") == 0)
1829 {
1830 #ifdef HAVE_WINDOWS_H
1831 FreeConsole();
1832 #endif
1833 }
1834 else if (strcmp(&(*argvp)[1][1], "quiet_abort") == 0)
1835 {
1836 smpd_process.verbose_abort_output = SMPD_FALSE;
1837 }
1838 else if ((strcmp(&(*argvp)[1][1], "rsh") == 0) || (strcmp(&(*argvp)[1][1], "ssh") == 0))
1839 {
1840 smpd_process.rsh_mpiexec = SMPD_TRUE;
1841 if (smpd_process.mpiexec_inorder_launch == SMPD_FALSE)
1842 {
1843 smpd_launch_node_t *temp_node, *ordered_list = NULL;
1844 /* sort any existing reverse order nodes to be in order */
1845 while (smpd_process.launch_list)
1846 {
1847 temp_node = smpd_process.launch_list->next;
1848 smpd_process.launch_list->next = ordered_list;
1849 ordered_list = smpd_process.launch_list;
1850 smpd_process.launch_list = temp_node;
1851 }
1852 smpd_process.launch_list = ordered_list;
1853 }
1854 smpd_process.mpiexec_inorder_launch = SMPD_TRUE;
1855 }
1856 else if ((strcmp(&(*argvp)[1][1], "nosmpd") == 0) || (strcmp(&(*argvp)[1][1], "no_smpd") == 0) || (strcmp(&(*argvp)[1][1], "nopm") == 0))
1857 {
1858 smpd_process.use_pmi_server = SMPD_FALSE;
1859 }
1860 else if (strcmp(&(*argvp)[1][1], "plaintext") == 0)
1861 {
1862 smpd_process.plaintext = SMPD_TRUE;
1863 }
1864 else if (strcmp(&(*argvp)[1][1], "channel") == 0)
1865 {
1866 if (argc < 3)
1867 {
1868 printf("Error: no name specified after -channel option.\n");
1869 smpd_exit_fn(FCNAME);
1870 return SMPD_FAIL;
1871 }
1872 strncpy(channel, (*argvp)[2], SMPD_MAX_NAME_LENGTH);
1873 if((strcmp(channel, "shm") == 0) || (strcmp(channel, "ssm") == 0))
1874 {
1875 printf("WARNING: SHM & SSM channels are no longer available. Use the NEMESIS channel instead.\n");
1876 return SMPD_FAIL;
1877 }
1878 num_args_to_strip = 2;
1879 }
1880 else if (strcmp(&(*argvp)[1][1], "log") == 0)
1881 {
1882 /* -log is a shortcut to create log files using the mpe wrapper dll */
1883 env_node = (smpd_env_node_t*)MPIU_Malloc(sizeof(smpd_env_node_t));
1884 if (env_node == NULL)
1885 {
1886 printf("Error: malloc failed to allocate structure to hold an environment variable.\n");
1887 smpd_exit_fn(FCNAME);
1888 return SMPD_FAIL;
1889 }
1890 strncpy(env_node->name, "MPI_WRAP_DLL_NAME", SMPD_MAX_NAME_LENGTH);
1891 strncpy(env_node->value, "mpe", SMPD_MAX_VALUE_LENGTH);
1892 env_node->next = env_list;
1893 env_list = env_node;
1894 }
1895 #ifdef HAVE_WINDOWS_H
1896 else if (strcmp(&(*argvp)[1][1], "user") == 0)
1897 {
1898 if (argc < 3)
1899 {
1900 printf("Error: no index specified after -user option.\n");
1901 smpd_exit_fn(FCNAME);
1902 return SMPD_FAIL;
1903 }
1904 smpd_process.user_index = atoi((*argvp)[2]);
1905 if (smpd_process.user_index < 0)
1906 smpd_process.user_index = 0;
1907 num_args_to_strip = 2;
1908 smpd_delete_cached_password();
1909 }
1910 #endif
1911 else if (strcmp(&(*argvp)[1][1], "l") == 0)
1912 {
1913 smpd_process.prefix_output = SMPD_TRUE;
1914 }
1915 else
1916 {
1917 printf("Unknown option: %s\n", (*argvp)[1]);
1918 }
1919 strip_args(argcp, argvp, num_args_to_strip);
1920 }
1921
1922 /* check to see if a timeout is specified by the environment variable only if
1923 * a timeout has not been specified on the command line
1924 */
1925 if (smpd_process.timeout == -1)
1926 {
1927 char *p = getenv("MPIEXEC_TIMEOUT");
1928 if (p)
1929 {
1930 smpd_process.timeout = atoi(p);
1931 if (smpd_process.timeout < 1)
1932 {
1933 smpd_process.timeout = -1;
1934 }
1935 }
1936 else
1937 {
1938 /* If a timeout is specified in the smpd settings but not in an env variable and not on the command line then use it. */
1939 if (smpd_setting_timeout != SMPD_INVALID_SETTING)
1940 {
1941 smpd_process.timeout = smpd_setting_timeout;
1942 }
1943 }
1944 }
1945
1946 /* Check to see if the environment wants all processes to run locally.
1947 * This is useful for test scripts.
1948 */
1949 env_str = getenv("MPIEXEC_LOCALONLY");
1950 if (env_str == NULL && smpd_setting_localonly == SMPD_TRUE)
1951 {
1952 smpd_setting_tmp_buffer[0] = '1';
1953 smpd_setting_tmp_buffer[1] = '\0';
1954 env_str = smpd_setting_tmp_buffer;
1955 }
1956 if (env_str != NULL)
1957 {
1958 if (smpd_is_affirmative(env_str) || strcmp(env_str, "1") == 0)
1959 {
1960 #if 1
1961 /* This block creates a host list of one host to implement -localonly */
1962
1963 if (host_list == NULL)
1964 {
1965 /* Use localroot to implement localonly */
1966 smpd_process.local_root = SMPD_TRUE;
1967 /* create a host list of one and set nproc to -1 to be replaced by
1968 nproc after parsing the block */
1969 host_list = (smpd_host_node_t*)MPIU_Malloc(sizeof(smpd_host_node_t));
1970 if (host_list == NULL)
1971 {
1972 printf("failed to allocate memory for a host node.\n");
1973 smpd_exit_fn(FCNAME);
1974 return SMPD_FAIL;
1975 }
1976 host_list->next = NULL;
1977 host_list->left = NULL;
1978 host_list->right = NULL;
1979 host_list->connected = SMPD_FALSE;
1980 host_list->connect_cmd_tag = -1;
1981 host_list->nproc = -1;
1982 host_list->alt_host[0] = '\0';
1983 smpd_get_hostname(host_list->host, SMPD_MAX_HOST_LENGTH);
1984 }
1985 else
1986 {
1987 smpd_dbg_printf("host_list not null, not using localonly\n");
1988 }
1989 #else
1990 /* This block uses the rsh code to implement -localonly */
1991
1992 smpd_process.mpiexec_run_local = SMPD_TRUE;
1993 smpd_process.rsh_mpiexec = SMPD_TRUE;
1994 if (smpd_process.mpiexec_inorder_launch == SMPD_FALSE)
1995 {
1996 smpd_launch_node_t *temp_node, *ordered_list = NULL;
1997 /* sort any existing reverse order nodes to be in order */
1998 while (smpd_process.launch_list)
1999 {
2000 temp_node = smpd_process.launch_list->next;
2001 smpd_process.launch_list->next = ordered_list;
2002 ordered_list = smpd_process.launch_list;
2003 smpd_process.launch_list = temp_node;
2004 }
2005 smpd_process.launch_list = ordered_list;
2006 }
2007 smpd_process.mpiexec_inorder_launch = SMPD_TRUE;
2008 #endif
2009 }
2010 else
2011 {
2012 smpd_dbg_printf("MPIEXEC_LOCALONLY env is not affirmative: '%s'\n", env_str);
2013 }
2014 }
2015
2016 /* remaining args are the executable and it's args */
2017 if (argc < 2)
2018 {
2019 printf("Error: no executable specified\n");
2020 smpd_exit_fn(FCNAME);
2021 return SMPD_FAIL;
2022 }
2023
2024 exe_iter = exe;
2025 exe_len_remaining = SMPD_MAX_EXE_LENGTH;
2026 if (!((*argvp)[1][0] == '\\' && (*argvp)[1][1] == '\\') && (*argvp)[1][0] != '/' &&
2027 !(strlen((*argvp)[1]) > 3 && (*argvp)[1][1] == ':' && (*argvp)[1][2] == '\\') )
2028 {
2029 /* an absolute path was not specified so find the executable an save the path */
2030 if (smpd_get_full_path_name((*argvp)[1], SMPD_MAX_EXE_LENGTH, exe_path, &namepart))
2031 {
2032 if (path[0] != '\0')
2033 {
2034 if (strlen(path) < SMPD_MAX_PATH_LENGTH)
2035 {
2036 strcat(path, ";");
2037 strncat(path, exe_path, SMPD_MAX_PATH_LENGTH - strlen(path));
2038 path[SMPD_MAX_PATH_LENGTH-1] = '\0';
2039 }
2040 }
2041 else
2042 {
2043 strncpy(path, exe_path, SMPD_MAX_PATH_LENGTH);
2044 }
2045 result = MPIU_Str_add_string(&exe_iter, &exe_len_remaining, namepart);
2046 if (result != MPIU_STR_SUCCESS)
2047 {
2048 printf("Error: insufficient buffer space for the command line.\n");
2049 smpd_exit_fn(FCNAME);
2050 return SMPD_FAIL;
2051 }
2052 }
2053 else
2054 {
2055 result = MPIU_Str_add_string(&exe_iter, &exe_len_remaining, (*argvp)[1]);
2056 if (result != MPIU_STR_SUCCESS)
2057 {
2058 printf("Error: insufficient buffer space for the command line.\n");
2059 smpd_exit_fn(FCNAME);
2060 return SMPD_FAIL;
2061 }
2062 }
2063 }
2064 else
2065 {
2066 /* an absolute path was specified */
2067 #ifdef HAVE_WINDOWS_H
2068 char *pTemp = (char*)MPIU_Malloc(SMPD_MAX_EXE_LENGTH);
2069 if (pTemp == NULL)
2070 {
2071 smpd_exit_fn(FCNAME);
2072 return SMPD_FAIL;
2073 }
2074 strncpy(pTemp, (*argvp)[1], SMPD_MAX_EXE_LENGTH);
2075 pTemp[SMPD_MAX_EXE_LENGTH-1] = '\0';
2076 ExeToUnc(pTemp, SMPD_MAX_EXE_LENGTH);
2077 result = MPIU_Str_add_string(&exe_iter, &exe_len_remaining, pTemp);
2078 MPIU_Free(pTemp);
2079 if (result != MPIU_STR_SUCCESS)
2080 {
2081 printf("Error: insufficient buffer space for the command line.\n");
2082 smpd_exit_fn(FCNAME);
2083 return SMPD_FAIL;
2084 }
2085 #else
2086 result = MPIU_Str_add_string(&exe_iter, &exe_len_remaining, (*argvp)[1]);
2087 if (result != MPIU_STR_SUCCESS)
2088 {
2089 printf("Error: insufficient buffer space for the command line.\n");
2090 smpd_exit_fn(FCNAME);
2091 return SMPD_FAIL;
2092 }
2093 #endif
2094 }
2095 for (i=2; i<argc; i++)
2096 {
2097 result = MPIU_Str_add_string(&exe_iter, &exe_len_remaining, (*argvp)[i]);
2098 }
2099 /* remove the trailing space */
2100 exe[strlen(exe)-1] = '\0';
2101 smpd_dbg_printf("handling executable:\n%s\n", exe);
2102
2103 if (nproc == 0){
2104 /* By default assume "mpiexec foo" => "mpiexec -n 1 foo" */
2105 nproc = 1;
2106 }
2107 if (ghost_list != NULL && host_list == NULL && use_machine_file != SMPD_TRUE)
2108 {
2109 host_list = (smpd_host_node_t*)MPIU_Malloc(sizeof(smpd_host_node_t));
2110 if (host_list == NULL)
2111 {
2112 printf("failed to allocate memory for a host node.\n");
2113 smpd_exit_fn(FCNAME);
2114 return SMPD_FAIL;
2115 }
2116 host_list->next = NULL;
2117 host_list->left = NULL;
2118 host_list->right = NULL;
2119 host_list->connected = SMPD_FALSE;
2120 host_list->connect_cmd_tag = -1;
2121 host_list->nproc = -1;
2122 host_list->alt_host[0] = '\0';
2123 strncpy(host_list->host, ghost_list->host, SMPD_MAX_HOST_LENGTH);
2124 }
2125 if (host_list != NULL && host_list->nproc == -1)
2126 {
2127 /* -host specified, replace nproc field */
2128 host_list->nproc = nproc;
2129 }
2130
2131 smpd_dbg_printf("Processing environment variables \n");
2132 /* add environment variables */
2133 env_data[0] = '\0';
2134 env_str = env_data;
2135 maxlen = SMPD_MAX_ENV_LENGTH;
2136 /* add and destroy the local environment variable list */
2137 while (env_list)
2138 {
2139 MPIU_Str_add_string_arg(&env_str, &maxlen, env_list->name, env_list->value);
2140 /*
2141 env_str += snprintf(env_str,
2142 SMPD_MAX_ENV_LENGTH - (env_str - env_data),
2143 "%s=%s", env_list->name, env_list->value);
2144 if (env_list->next)
2145 {
2146 env_str += snprintf(env_str, SMPD_MAX_ENV_LENGTH - (env_str - env_data), ";");
2147 }
2148 */
2149 env_node = env_list;
2150 env_list = env_list->next;
2151 MPIU_Free(env_node);
2152 }
2153 /* add the global environment variable list */
2154 env_node = genv_list;
2155 while (env_node)
2156 {
2157 MPIU_Str_add_string_arg(&env_str, &maxlen, env_node->name, env_node->value);
2158 env_node = env_node->next;
2159 }
2160 if (env_str > env_data)
2161 {
2162 /* trim the trailing white space */
2163 env_str--;
2164 *env_str = '\0';
2165 }
2166
2167 smpd_dbg_printf("Processing drive mappings\n");
2168 /* merge global drive mappings with the local drive mappings */
2169 gmap_node = gdrive_map_list;
2170 while (gmap_node)
2171 {
2172 map_node = drive_map_list;
2173 while (map_node)
2174 {
2175 if (map_node->drive == gmap_node->drive)
2176 {
2177 /* local option trumps the global option */
2178 break;
2179 }
2180 if (map_node->next == NULL)
2181 {
2182 /* add a copy of the global node to the end of the list */
2183 map_node->next = (smpd_map_drive_node_t*)MPIU_Malloc(sizeof(smpd_map_drive_node_t));
2184 if (map_node->next == NULL)
2185 {
2186 printf("Error: malloc failed to allocate map structure.\n");
2187 smpd_exit_fn(FCNAME);
2188 return SMPD_FAIL;
2189 }
2190 map_node = map_node->next;
2191 map_node->ref_count = 0;
2192 map_node->drive = gmap_node->drive;
2193 strncpy(map_node->share, gmap_node->share, SMPD_MAX_EXE_LENGTH);
2194 map_node->next = NULL;
2195 break;
2196 }
2197 map_node = map_node->next;
2198 }
2199 if (drive_map_list == NULL)
2200 {
2201 map_node = (smpd_map_drive_node_t*)MPIU_Malloc(sizeof(smpd_map_drive_node_t));
2202 if (map_node == NULL)
2203 {
2204 printf("Error: malloc failed to allocate map structure.\n");
2205 smpd_exit_fn(FCNAME);
2206 return SMPD_FAIL;
2207 }
2208 map_node->ref_count = 0;
2209 map_node->drive = gmap_node->drive;
2210 strncpy(map_node->share, gmap_node->share, SMPD_MAX_EXE_LENGTH);
2211 map_node->next = NULL;
2212 drive_map_list = map_node;
2213 }
2214 gmap_node = gmap_node->next;
2215 }
2216
2217 smpd_dbg_printf("Creating launch nodes (%d)\n", nproc);
2218 for (i=0; i<nproc; i++)
2219 {
2220 /* create a launch_node */
2221 launch_node = (smpd_launch_node_t*)MPIU_Malloc(sizeof(smpd_launch_node_t));
2222 if (launch_node == NULL)
2223 {
2224 smpd_err_printf("unable to allocate a launch node structure.\n");
2225 smpd_exit_fn(FCNAME);
2226 return SMPD_FAIL;
2227 }
2228 launch_node->clique[0] = '\0';
2229 smpd_get_next_host(&host_list, launch_node);
2230 smpd_dbg_printf("Adding host (%s) to launch list \n", launch_node->hostname);
2231 launch_node->iproc = cur_rank++;
2232 #ifdef HAVE_WINDOWS_H
2233 if(smpd_process.affinity_map_sz > 0){
2234 launch_node->binding_proc =
2235 smpd_process.affinity_map[affinity_map_index % smpd_process.affinity_map_sz];
2236 affinity_map_index++;
2237 }
2238 else{
2239 launch_node->binding_proc = -1;
2240 }
2241 #endif
2242 launch_node->appnum = appnum;
2243 launch_node->priority_class = n_priority_class;
2244 launch_node->priority_thread = n_priority;
2245 launch_node->env = launch_node->env_data;
2246 strcpy(launch_node->env_data, env_data);
2247 if (launch_node->alt_hostname[0] != '\0')
2248 {
2249 if (smpd_append_env_option(launch_node->env_data, SMPD_MAX_ENV_LENGTH, "MPICH_INTERFACE_HOSTNAME", launch_node->alt_hostname) != SMPD_SUCCESS)
2250 {
2251 smpd_err_printf("unable to add the MPICH_INTERFACE_HOSTNAME environment variable to the launch command.\n");
2252 smpd_exit_fn(FCNAME);
2253 return SMPD_FAIL;
2254 }
2255 }
2256 if (wdir[0] != '\0')
2257 {
2258 strcpy(launch_node->dir, wdir);
2259 }
2260 else
2261 {
2262 if (gwdir[0] != '\0')
2263 {
2264 strcpy(launch_node->dir, gwdir);
2265 }
2266 else
2267 {
2268 launch_node->dir[0] = '\0';
2269 getcwd(launch_node->dir, SMPD_MAX_DIR_LENGTH);
2270 }
2271 }
2272 if (path[0] != '\0')
2273 {
2274 strcpy(launch_node->path, path);
2275 /* should the gpath be appended to the local path? */
2276 }
2277 else
2278 {
2279 if (gpath[0] != '\0')
2280 {
2281 strcpy(launch_node->path, gpath);
2282 }
2283 else
2284 {
2285 launch_node->path[0] = '\0';
2286 }
2287 }
2288 launch_node->map_list = drive_map_list;
2289 if (drive_map_list)
2290 {
2291 /* ref count the list so when freeing the launch_node it can be known when to free the list */
2292 drive_map_list->ref_count++;
2293 }
2294 strcpy(launch_node->exe, exe);
2295 launch_node->args[0] = '\0';
2296 if (smpd_process.mpiexec_inorder_launch == SMPD_TRUE)
2297 {
2298 /* insert the node in order */
2299 launch_node->next = NULL;
2300 if (smpd_process.launch_list == NULL)
2301 {
2302 smpd_process.launch_list = launch_node;
2303 launch_node->prev = NULL;
2304 }
2305 else
2306 {
2307 launch_node_iter = smpd_process.launch_list;
2308 while (launch_node_iter->next)
2309 launch_node_iter = launch_node_iter->next;
2310 launch_node_iter->next = launch_node;
2311 launch_node->prev = launch_node_iter;
2312 }
2313 }
2314 else
2315 {
2316 /* insert the node in reverse order */
2317 launch_node->next = smpd_process.launch_list;
2318 if (smpd_process.launch_list)
2319 smpd_process.launch_list->prev = launch_node;
2320 smpd_process.launch_list = launch_node;
2321 launch_node->prev = NULL;
2322 }
2323 }
2324
2325 /* advance the application number for each : separated command line block or line in a configuration file */
2326 appnum++;
2327
2328 if (smpd_process.s_host_list)
2329 {
2330 /* free the current host list */
2331 while (smpd_process.s_host_list)
2332 {
2333 host_node_iter = smpd_process.s_host_list;
2334 smpd_process.s_host_list = smpd_process.s_host_list->next;
2335 MPIU_Free(host_node_iter);
2336 }
2337 }
2338
2339 if (use_configfile)
2340 {
2341 if (smpd_get_argcv_from_file(fin_config, argcp, argvp))
2342 {
2343 /* FIXME: How do we tell the difference between an error parsing the file and parsing the last entry? */
2344 goto configfile_loop;
2345 }
2346 fclose(fin_config);
2347 if (delete_configfile)
2348 {
2349 unlink(configfilename);
2350 }
2351 }
2352
2353 /* move to the next block */
2354 *argvp = next_argv - 1;
2355 if (*next_argv)
2356 **argvp = exe_ptr;
2357 } while (*next_argv);
2358
2359 launch_node_iter = smpd_process.launch_list;
2360 while (launch_node_iter)
2361 {
2362 /* add nproc to all the launch nodes */
2363 launch_node_iter->nproc = cur_rank;
2364 launch_node_iter = launch_node_iter->next;
2365 }
2366
2367 /* create the cliques */
2368 smpd_create_cliques(smpd_process.launch_list);
2369
2370 if (smpd_process.launch_list != NULL)
2371 {
2372 if ((channel[0] == '\0') && (smpd_setting_channel[0] != '\0'))
2373 {
2374 /* channel specified in the smpd settings */
2375 strncpy(channel, smpd_setting_channel, 20);
2376 }
2377 if (channel[0] != '\0')
2378 {
2379 smpd_launch_node_t *iter;
2380 /* If the user specified auto channel selection then set the channel here */
2381 /* shm < 8 processes on one node
2382 * ssm multiple nodes
2383 */
2384 if ((strcmp(channel, "auto") == 0) && (smpd_process.launch_list != NULL))
2385 {
2386 strncpy(channel, "nemesis", SMPD_MAX_NAME_LENGTH);
2387 }
2388
2389 nemesis_netmod[0] = '\0';
2390 #ifdef HAVE_WINDOWS_H
2391 /* See if there is a netmod specified with the channel
2392 * eg: -channel nemesis:newtcp | -channel nemesis:nd | -channel nemesis:none
2393 */
2394 if(strlen(channel) > 0){
2395 char seps[]=":";
2396 char *tok, *ctxt;
2397
2398 tok = strtok_s(channel, seps, &ctxt);
2399 if(tok != NULL){
2400 tok = strtok_s(NULL, seps, &ctxt);
2401 if(tok != NULL){
2402 MPIU_Strncpy(nemesis_netmod, tok, SMPD_MAX_NEMESIS_NETMOD_LENGTH);
2403 }
2404 }
2405 }
2406 #endif
2407
2408 /* add the channel to the environment of each process */
2409 iter = smpd_process.launch_list;
2410 while (iter)
2411 {
2412 maxlen = (int)strlen(iter->env);
2413 env_str = &iter->env[maxlen];
2414 maxlen = SMPD_MAX_ENV_LENGTH - maxlen - 1;
2415
2416 if (maxlen > 15) /* At least 16 characters are needed to store MPICH2_CHANNEL=x */
2417 {
2418 *env_str = ' ';
2419 env_str++;
2420 MPIU_Str_add_string_arg(&env_str, &maxlen, "MPICH2_CHANNEL", channel);
2421 /* trim the trailing white space */
2422 env_str--;
2423 *env_str = '\0';
2424 }
2425 if ((strlen(nemesis_netmod) > 0) && (maxlen > 32)) /* At least 31 characters are needed to store " MPICH_NEMESIS_NETMOD=x" */
2426 {
2427 *env_str = ' ';
2428 env_str++;
2429 MPIU_Str_add_string_arg(&env_str, &maxlen, "MPICH_NEMESIS_NETMOD", nemesis_netmod);
2430 /* trim the trailing white space */
2431 env_str--;
2432 *env_str = '\0';
2433 }
2434
2435 iter = iter->next;
2436 }
2437
2438 /* Save the channel to be used by spawn commands */
2439 MPIU_Strncpy(smpd_process.env_channel, channel, 10);
2440 if(strlen(nemesis_netmod) > 0){
2441 MPIU_Strncpy(smpd_process.env_netmod, nemesis_netmod, 10);
2442 }
2443 }
2444 }
2445
2446 smpd_fix_up_host_tree(smpd_process.host_list);
2447
2448 smpd_exit_fn(FCNAME);
2449 return SMPD_SUCCESS;
2450 }
2451