This source file includes following definitions.
- orte_iof_base_setup_prefork
- orte_iof_base_setup_child
- orte_iof_base_setup_parent
- orte_iof_base_setup_output_files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include "orte_config.h"
31 #include "orte/constants.h"
32
33 #include <stdlib.h>
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37 #include <errno.h>
38 #include <sys/types.h>
39 #ifdef HAVE_SYS_WAIT_H
40 #include <sys/wait.h>
41 #endif
42 #include <signal.h>
43 #ifdef HAVE_UTIL_H
44 #include <util.h>
45 #endif
46 #ifdef HAVE_PTY_H
47 #include <pty.h>
48 #endif
49 #ifdef HAVE_FCNTL_H
50 #include <fcntl.h>
51 #endif
52 #ifdef HAVE_TERMIOS_H
53 #include <termios.h>
54 # ifdef HAVE_TERMIO_H
55 # include <termio.h>
56 # endif
57 #endif
58 #ifdef HAVE_LIBUTIL_H
59 #include <libutil.h>
60 #endif
61
62 #include "opal/util/opal_pty.h"
63 #include "opal/util/opal_environ.h"
64 #include "opal/util/os_dirpath.h"
65 #include "opal/util/output.h"
66 #include "opal/util/argv.h"
67 #include "opal/util/printf.h"
68
69 #include "orte/mca/errmgr/errmgr.h"
70 #include "orte/util/name_fns.h"
71 #include "orte/runtime/orte_globals.h"
72
73 #include "orte/mca/iof/iof.h"
74 #include "orte/mca/iof/base/base.h"
75 #include "orte/mca/iof/base/iof_base_setup.h"
76
77 int
78 orte_iof_base_setup_prefork(orte_iof_base_io_conf_t *opts)
79 {
80 int ret = -1;
81
82 fflush(stdout);
83
84
85 #if OPAL_ENABLE_PTY_SUPPORT
86 if (opts->usepty) {
87
88
89
90
91
92
93
94
95
96
97 ret = opal_openpty(&(opts->p_stdout[0]), &(opts->p_stdout[1]),
98 (char*)NULL, (struct termios*)NULL, (struct winsize*)NULL);
99 }
100 #else
101 opts->usepty = 0;
102 #endif
103
104 if (ret < 0) {
105 opts->usepty = 0;
106 if (pipe(opts->p_stdout) < 0) {
107 ORTE_ERROR_LOG(ORTE_ERR_SYS_LIMITS_PIPES);
108 return ORTE_ERR_SYS_LIMITS_PIPES;
109 }
110 }
111 if (opts->connect_stdin) {
112 if (pipe(opts->p_stdin) < 0) {
113 ORTE_ERROR_LOG(ORTE_ERR_SYS_LIMITS_PIPES);
114 return ORTE_ERR_SYS_LIMITS_PIPES;
115 }
116 }
117 if( !orte_iof_base.redirect_app_stderr_to_stdout ) {
118 if (pipe(opts->p_stderr) < 0) {
119 ORTE_ERROR_LOG(ORTE_ERR_SYS_LIMITS_PIPES);
120 return ORTE_ERR_SYS_LIMITS_PIPES;
121 }
122 }
123 #if OPAL_PMIX_V1
124 if (pipe(opts->p_internal) < 0) {
125 ORTE_ERROR_LOG(ORTE_ERR_SYS_LIMITS_PIPES);
126 return ORTE_ERR_SYS_LIMITS_PIPES;
127 }
128 #endif
129 return ORTE_SUCCESS;
130 }
131
132
133 int
134 orte_iof_base_setup_child(orte_iof_base_io_conf_t *opts, char ***env)
135 {
136 int ret;
137 #if OPAL_PMIX_V1
138 char *str;
139 #endif
140
141 if (opts->connect_stdin) {
142 close(opts->p_stdin[1]);
143 }
144 close(opts->p_stdout[0]);
145 if( !orte_iof_base.redirect_app_stderr_to_stdout ) {
146 close(opts->p_stderr[0]);
147 }
148 #if OPAL_PMIX_V1
149 close(opts->p_internal[0]);
150 #endif
151
152 if (opts->usepty) {
153
154 struct termios term_attrs;
155 if (tcgetattr(opts->p_stdout[1], &term_attrs) < 0) {
156 return ORTE_ERR_PIPE_SETUP_FAILURE;
157 }
158 term_attrs.c_lflag &= ~ (ECHO | ECHOE | ECHOK |
159 ECHOCTL | ECHOKE | ECHONL);
160 term_attrs.c_iflag &= ~ (ICRNL | INLCR | ISTRIP | INPCK | IXON);
161 term_attrs.c_oflag &= ~ (
162 #ifdef OCRNL
163
164
165 OCRNL |
166 #endif
167 ONLCR);
168 if (tcsetattr(opts->p_stdout[1], TCSANOW, &term_attrs) == -1) {
169 return ORTE_ERR_PIPE_SETUP_FAILURE;
170 }
171 ret = dup2(opts->p_stdout[1], fileno(stdout));
172 if (ret < 0) {
173 return ORTE_ERR_PIPE_SETUP_FAILURE;
174 }
175 if( orte_iof_base.redirect_app_stderr_to_stdout ) {
176 ret = dup2(opts->p_stdout[1], fileno(stderr));
177 if (ret < 0) {
178 return ORTE_ERR_PIPE_SETUP_FAILURE;
179 }
180 }
181 close(opts->p_stdout[1]);
182 } else {
183 if(opts->p_stdout[1] != fileno(stdout)) {
184 ret = dup2(opts->p_stdout[1], fileno(stdout));
185 if (ret < 0) {
186 return ORTE_ERR_PIPE_SETUP_FAILURE;
187 }
188 if( orte_iof_base.redirect_app_stderr_to_stdout ) {
189 ret = dup2(opts->p_stdout[1], fileno(stderr));
190 if (ret < 0) {
191 return ORTE_ERR_PIPE_SETUP_FAILURE;
192 }
193 }
194 close(opts->p_stdout[1]);
195 }
196 }
197 if (opts->connect_stdin) {
198 if(opts->p_stdin[0] != fileno(stdin)) {
199 ret = dup2(opts->p_stdin[0], fileno(stdin));
200 if (ret < 0) {
201 return ORTE_ERR_PIPE_SETUP_FAILURE;
202 }
203 close(opts->p_stdin[0]);
204 }
205 } else {
206 int fd;
207
208
209 fd = open("/dev/null", O_RDONLY, 0);
210 if(fd != fileno(stdin)) {
211 dup2(fd, fileno(stdin));
212 close(fd);
213 }
214 }
215
216 if(opts->p_stderr[1] != fileno(stderr)) {
217 if( !orte_iof_base.redirect_app_stderr_to_stdout ) {
218 ret = dup2(opts->p_stderr[1], fileno(stderr));
219 if (ret < 0) return ORTE_ERR_PIPE_SETUP_FAILURE;
220 close(opts->p_stderr[1]);
221 }
222 }
223
224 #if OPAL_PMIX_V1
225 if (!orte_map_stddiag_to_stderr && !orte_map_stddiag_to_stdout ) {
226
227
228 opal_asprintf(&str, "%d", opts->p_internal[1]);
229 if (NULL != str) {
230 opal_setenv("OPAL_OUTPUT_STDERR_FD", str, true, env);
231 free(str);
232 }
233 } else if( orte_map_stddiag_to_stdout ) {
234 opal_setenv("OPAL_OUTPUT_INTERNAL_TO_STDOUT", "1", true, env);
235 }
236 #endif
237
238 return ORTE_SUCCESS;
239 }
240
241
242 int
243 orte_iof_base_setup_parent(const orte_process_name_t* name,
244 orte_iof_base_io_conf_t *opts)
245 {
246 int ret;
247
248
249 if (opts->connect_stdin) {
250
251 ret = orte_iof.pull(name, ORTE_IOF_STDIN, opts->p_stdin[1]);
252 if(ORTE_SUCCESS != ret) {
253 ORTE_ERROR_LOG(ret);
254 return ret;
255 }
256 }
257
258
259 ret = orte_iof.push(name, ORTE_IOF_STDOUT, opts->p_stdout[0]);
260 if(ORTE_SUCCESS != ret) {
261 ORTE_ERROR_LOG(ret);
262 return ret;
263 }
264
265 if( !orte_iof_base.redirect_app_stderr_to_stdout ) {
266 ret = orte_iof.push(name, ORTE_IOF_STDERR, opts->p_stderr[0]);
267 if(ORTE_SUCCESS != ret) {
268 ORTE_ERROR_LOG(ret);
269 return ret;
270 }
271 }
272
273 #if OPAL_PMIX_V1
274 ret = orte_iof.push(name, ORTE_IOF_STDDIAG, opts->p_internal[0]);
275 if(ORTE_SUCCESS != ret) {
276 ORTE_ERROR_LOG(ret);
277 return ret;
278 }
279 #endif
280
281 return ORTE_SUCCESS;
282 }
283
284 int orte_iof_base_setup_output_files(const orte_process_name_t* dst_name,
285 orte_job_t *jobdat,
286 orte_iof_proc_t *proct)
287 {
288 int rc;
289 char *dirname, *outdir, *outfile;
290 int np, numdigs, fdout, i;
291 char *p, **s;
292 bool usejobid = true;
293
294
295 dirname = NULL;
296 if (orte_get_attribute(&jobdat->attributes, ORTE_JOB_OUTPUT_TO_FILE, (void**)&dirname, OPAL_STRING) &&
297 NULL != dirname) {
298 np = jobdat->num_procs / 10;
299
300 numdigs = 1;
301 while (np > 0) {
302 numdigs++;
303 np = np / 10;
304 }
305
306 if (NULL != (p = strchr(dirname, ':'))) {
307 *p = '\0';
308 ++p;
309
310 s = opal_argv_split(p, ',');
311 for (i=0; NULL != s[i]; i++) {
312 if (0 == strcasecmp(s[i], "nojobid")) {
313 usejobid = false;
314 } else if (0 == strcasecmp(s[i], "nocopy")) {
315 proct->copy = false;
316 }
317 }
318 }
319
320
321 if (usejobid) {
322 opal_asprintf(&outdir, "%s/%d/rank.%0*lu", dirname,
323 (int)ORTE_LOCAL_JOBID(proct->name.jobid),
324 numdigs, (unsigned long)proct->name.vpid);
325 } else {
326 opal_asprintf(&outdir, "%s/rank.%0*lu", dirname,
327 numdigs, (unsigned long)proct->name.vpid);
328 }
329
330 if (OPAL_SUCCESS != (rc = opal_os_dirpath_create(outdir, S_IRWXU|S_IRGRP|S_IXGRP))) {
331 ORTE_ERROR_LOG(rc);
332 free(outdir);
333 return rc;
334 }
335 if (NULL != proct->revstdout && NULL == proct->revstdout->sink) {
336
337 opal_asprintf(&outfile, "%s/stdout", outdir);
338 fdout = open(outfile, O_CREAT|O_RDWR|O_TRUNC, 0644);
339 free(outfile);
340 if (fdout < 0) {
341
342 ORTE_ERROR_LOG(ORTE_ERR_FILE_OPEN_FAILURE);
343 return ORTE_ERR_FILE_OPEN_FAILURE;
344 }
345
346 ORTE_IOF_SINK_DEFINE(&proct->revstdout->sink, dst_name,
347 fdout, ORTE_IOF_STDOUT,
348 orte_iof_base_write_handler);
349 }
350
351 if (NULL != proct->revstderr && NULL == proct->revstderr->sink) {
352
353
354
355 if (orte_get_attribute(&jobdat->attributes, ORTE_JOB_MERGE_STDERR_STDOUT, NULL, OPAL_BOOL)) {
356
357 OBJ_RETAIN(proct->revstdout->sink);
358 proct->revstdout->sink->tag = ORTE_IOF_STDMERGE;
359 proct->revstderr->sink = proct->revstdout->sink;
360 } else {
361 opal_asprintf(&outfile, "%s/stderr", outdir);
362 fdout = open(outfile, O_CREAT|O_RDWR|O_TRUNC, 0644);
363 free(outfile);
364 if (fdout < 0) {
365
366 ORTE_ERROR_LOG(ORTE_ERR_FILE_OPEN_FAILURE);
367 return ORTE_ERR_FILE_OPEN_FAILURE;
368 }
369
370 ORTE_IOF_SINK_DEFINE(&proct->revstderr->sink, dst_name,
371 fdout, ORTE_IOF_STDERR,
372 orte_iof_base_write_handler);
373 }
374 }
375 #if OPAL_PMIX_V1
376 if (NULL != proct->revstddiag && NULL == proct->revstddiag->sink) {
377
378 OBJ_RETAIN(proct->revstderr->sink);
379 proct->revstddiag->sink = proct->revstderr->sink;
380 }
381 #endif
382 }
383
384 return ORTE_SUCCESS;
385 }