Skip to content

Commit 1dbb440

Browse files
committed
Work on enabling PTY operations
Provide a cmd line option to specify the user wants to spawn a PTY - e.g., to run a shell on a remote node. Correct error code returns when pipes don't properly get setup, and add an error log so we can see where that happens. When using PTYs, setup all standard IO file descriptors as pty's. Set their term attributes and window sizes to match those of the user's endpoint (i.e., prterun or prun). Signed-off-by: Ralph Castain <[email protected]>
1 parent 6b0217c commit 1dbb440

File tree

10 files changed

+345
-87
lines changed

10 files changed

+345
-87
lines changed

src/mca/iof/base/iof_base_setup.c

Lines changed: 231 additions & 81 deletions
Large diffs are not rendered by default.

src/mca/iof/base/iof_base_setup.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* All rights reserved.
1212
* Copyright (c) 2008-2020 Cisco Systems, Inc. All rights reserved
1313
* Copyright (c) 2016-2019 Intel, Inc. All rights reserved.
14-
* Copyright (c) 2021 Nanook Consulting. All rights reserved.
14+
* Copyright (c) 2021-2025 Nanook Consulting All rights reserved.
1515
* $COPYRIGHT$
1616
*
1717
* Additional copyrights may follow
@@ -26,13 +26,20 @@
2626
#include "prte_config.h"
2727
#include "types.h"
2828

29+
#include "src/runtime/prte_globals.h"
2930
#include "src/mca/iof/base/base.h"
3031

3132
struct prte_iof_base_io_conf_t {
3233
int usepty;
3334
bool connect_stdin;
3435

35-
/* private - callers should not modify these fields */
36+
char *slave_stdin;
37+
char *slave_stdout;
38+
char *slave_stderr;
39+
40+
/* When using pty's:
41+
* pty masters are in the 0 position,
42+
* pty slaves are in the 1 position */
3643
int p_stdin[2];
3744
int p_stdout[2];
3845
int p_stderr[2];
@@ -45,9 +52,11 @@ typedef struct prte_iof_base_io_conf_t prte_iof_base_io_conf_t;
4552
* Do all stdio forwarding that must be done before fork() is called.
4653
* This might include creating pipes or ptys or similar work.
4754
*/
48-
PRTE_EXPORT int prte_iof_base_setup_prefork(prte_iof_base_io_conf_t *opts);
55+
PRTE_EXPORT int prte_iof_base_setup_prefork(prte_iof_base_io_conf_t *opts,
56+
prte_job_t *jdata);
4957

50-
PRTE_EXPORT int prte_iof_base_setup_child(prte_iof_base_io_conf_t *opts, char ***env);
58+
PRTE_EXPORT int prte_iof_base_setup_child(prte_iof_base_io_conf_t *opts,
59+
char ***env);
5160

5261
PRTE_EXPORT int prte_iof_base_setup_parent(const pmix_proc_t *name, prte_iof_base_io_conf_t *opts);
5362

src/mca/odls/base/odls_base_default_fns.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,7 +1565,7 @@ void prte_odls_base_default_launch_local(int fd, short sd, void *cbdata)
15651565
} else {
15661566
cd->opts.connect_stdin = false;
15671567
}
1568-
if (PRTE_SUCCESS != (rc = prte_iof_base_setup_prefork(&cd->opts))) {
1568+
if (PRTE_SUCCESS != (rc = prte_iof_base_setup_prefork(&cd->opts, jobdat))) {
15691569
PRTE_ERROR_LOG(rc);
15701570
child->exit_code = rc;
15711571
PMIX_RELEASE(cd);
@@ -2178,7 +2178,7 @@ int prte_odls_base_default_restart_proc(prte_proc_t *child,
21782178
} else {
21792179
cd->opts.connect_stdin = false;
21802180
}
2181-
if (PRTE_SUCCESS != (rc = prte_iof_base_setup_prefork(&cd->opts))) {
2181+
if (PRTE_SUCCESS != (rc = prte_iof_base_setup_prefork(&cd->opts, jobdat))) {
21822182
PRTE_ERROR_LOG(rc);
21832183
child->exit_code = rc;
21842184
PMIX_RELEASE(cd);

src/mca/schizo/prte/help-prun.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ option to the help request as "--help <option>".
219219
| | disable (false) its internal library's GPU |
220220
| | support |
221221
+----------------------+-----------------------------------------------+
222+
| "--pty" | Spawn a pseudo-terminal |
223+
+----------------------+-----------------------------------------------+
222224

223225
+----------------------+-----------------------------------------------+
224226
| | Specific Options |

src/mca/schizo/prte/schizo_prte.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ static struct option prunoptions[] = {
341341
PMIX_OPTION_DEFINE(PRTE_CLI_GPU_SUPPORT, PMIX_ARG_REQD),
342342
PMIX_OPTION_DEFINE(PRTE_CLI_APP_PREFIX, PMIX_ARG_REQD),
343343
PMIX_OPTION_DEFINE(PRTE_CLI_NO_APP_PREFIX, PMIX_ARG_NONE),
344+
PMIX_OPTION_DEFINE(PRTE_CLI_PTY, PMIX_ARG_NONE),
344345

345346
// output options
346347
PMIX_OPTION_DEFINE(PRTE_CLI_OUTPUT, PMIX_ARG_REQD),

src/prted/pmix/pmix_server_dyn.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,28 @@ int prte_pmix_xfer_job_info(prte_job_t *jdata,
562562
jdata->stdin_target = strtoul(info->value.data.string, NULL, 10);
563563
}
564564

565+
#ifdef PMIX_SPAWN_PTY
566+
/*** SPAWN PTY ***/
567+
} else if (PMIX_CHECK_KEY(info, PMIX_SPAWN_PTY)) {
568+
flag = PMIX_INFO_TRUE(info);
569+
prte_set_attribute(&jdata->attributes, PRTE_JOB_PTY, PRTE_ATTR_GLOBAL,
570+
&flag, PMIX_BOOL);
571+
#endif
572+
573+
#ifdef PMIX_PTY_TERMIO
574+
/*** PTY TERMIO ***/
575+
} else if (PMIX_CHECK_KEY(info, PMIX_PTY_TERMIO)) {
576+
prte_set_attribute(&jdata->attributes, PRTE_JOB_PTY_TERMIO, PRTE_ATTR_GLOBAL,
577+
&info->value.data.bo, PMIX_BYTE_OBJECT);
578+
#endif
579+
580+
#ifdef PMIX_PTY_WSIZE
581+
/*** PTY WIN SIZES ***/
582+
} else if (PMIX_CHECK_KEY(info, PMIX_PTY_WSIZE)) {
583+
prte_set_attribute(&jdata->attributes, PRTE_JOB_PTY_WSIZE, PRTE_ATTR_GLOBAL,
584+
&info->value.data.bo, PMIX_BYTE_OBJECT);
585+
#endif
586+
565587
/*** INDEX ARGV ***/
566588
} else if (PMIX_CHECK_KEY(info, PMIX_INDEX_ARGV)) {
567589
flag = PMIX_INFO_TRUE(info);

src/prted/prun_common.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
#include "src/util/pmix_environ.h"
8383
#include "src/util/pmix_getcwd.h"
8484
#include "src/util/pmix_show_help.h"
85+
#include "src/util/pmix_tty.h"
8586

8687
#include "src/class/pmix_pointer_array.h"
8788
#include "src/runtime/prte_progress_threads.h"
@@ -544,6 +545,69 @@ int prun_common(pmix_cli_result_t *results,
544545
/* we want to be notified upon job completion */
545546
PMIX_INFO_LIST_ADD(ret, jinfo, PMIX_NOTIFY_COMPLETION, &flag, PMIX_BOOL);
546547

548+
#ifdef PMIX_SPAWN_PTY
549+
// see if they want to use a pty
550+
if (pmix_cmd_line_is_taken(results, PRTE_CLI_PTY)) {
551+
PMIX_INFO_LIST_ADD(ret, jinfo, PMIX_SPAWN_PTY, NULL, PMIX_BOOL);
552+
#ifdef PMIX_PTY_TERMIO
553+
{
554+
// pass our termio settings
555+
struct termios terms;
556+
pmix_byte_object_t tbo;
557+
tbo.bytes = malloc(2 * sizeof(struct termios));
558+
tbo.size = 2 * sizeof(struct termios);
559+
ret = pmix_gettermios(STDIN_FILENO, &terms);
560+
if (PMIX_SUCCESS != ret) {
561+
free(tbo.bytes);
562+
PMIX_INFO_LIST_RELEASE(jinfo);
563+
PRTE_UPDATE_EXIT_STATUS(ret);
564+
goto DONE;
565+
}
566+
memcpy(tbo.bytes, &terms, sizeof(struct termios));
567+
memset(&terms, 0, sizeof(struct termios));
568+
ret = pmix_gettermios(STDOUT_FILENO, &terms);
569+
if (PMIX_SUCCESS != ret) {
570+
free(tbo.bytes);
571+
PMIX_INFO_LIST_RELEASE(jinfo);
572+
PRTE_UPDATE_EXIT_STATUS(ret);
573+
goto DONE;
574+
}
575+
memcpy(tbo.bytes+sizeof(struct termios), &terms, sizeof(struct termios));
576+
PMIX_INFO_LIST_ADD(ret, jinfo, PMIX_PTY_TERMIO, &tbo, PMIX_BYTE_OBJECT);
577+
PMIX_BYTE_OBJECT_DESTRUCT(&tbo);
578+
}
579+
#endif
580+
#ifdef PMIX_PTY_WSIZE
581+
{
582+
// pass our window size
583+
struct winsize ws;
584+
pmix_byte_object_t tbo;
585+
tbo.bytes = malloc(2 * sizeof(struct winsize));
586+
tbo.size = 2 * sizeof(struct winsize);
587+
ret = pmix_getwinsz(STDIN_FILENO, &ws);
588+
if (PMIX_SUCCESS != ret) {
589+
free(tbo.bytes);
590+
PMIX_INFO_LIST_RELEASE(jinfo);
591+
PRTE_UPDATE_EXIT_STATUS(ret);
592+
goto DONE;
593+
}
594+
memcpy(tbo.bytes, &ws, sizeof(struct winsize));
595+
memset(&ws, 0, sizeof(struct winsize));
596+
ret = pmix_getwinsz(STDOUT_FILENO, &ws);
597+
if (PMIX_SUCCESS != ret) {
598+
free(tbo.bytes);
599+
PMIX_INFO_LIST_RELEASE(jinfo);
600+
PRTE_UPDATE_EXIT_STATUS(ret);
601+
goto DONE;
602+
}
603+
memcpy(tbo.bytes+sizeof(struct winsize), &ws, sizeof(struct winsize));
604+
PMIX_INFO_LIST_ADD(ret, jinfo, PMIX_PTY_WSIZE, &tbo, PMIX_BYTE_OBJECT);
605+
PMIX_BYTE_OBJECT_DESTRUCT(&tbo);
606+
}
607+
#endif
608+
}
609+
#endif
610+
547611
/* pickup any relevant envars */
548612
ninfo = 4;
549613
PMIX_INFO_CREATE(iptr, ninfo);

src/util/attr.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,12 @@ const char *prte_attr_key_to_str(prte_attribute_key_t key)
517517
return "PRTE-JOB-PMIX-PREFIX";
518518
case PRTE_JOB_FWD_ENVIRONMENT:
519519
return "FWD ENVIRONMENT";
520+
case PRTE_JOB_PTY:
521+
return "PTY";
522+
case PRTE_JOB_PTY_TERMIO:
523+
return "PTY TERMIOS";
524+
case PRTE_JOB_PTY_WSIZE:
525+
return "PTY WSIZES";
520526

521527
case PRTE_PROC_NOBARRIER:
522528
return "PROC-NOBARRIER";

src/util/attr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ typedef uint16_t prte_job_flags_t;
235235
#define PRTE_JOB_PREFIX (PRTE_JOB_START_KEY + 118) // string - PRTE_PREFIX for daemons
236236
#define PRTE_JOB_PMIX_PREFIX (PRTE_JOB_START_KEY + 119) // string - PMIX_PREFIX for daemons
237237
#define PRTE_JOB_FWD_ENVIRONMENT (PRTE_JOB_START_KEY + 120) // bool - forward local environment to procs in this job
238+
#define PRTE_JOB_PTY (PRTE_JOB_START_KEY + 121) // bool - Spawn a pseudo-terminal
239+
#define PRTE_JOB_PTY_TERMIO (PRTE_JOB_START_KEY + 122) // pmix_byte_object_t - termio structs for stdin, stdout
240+
#define PRTE_JOB_PTY_WSIZE (PRTE_JOB_START_KEY + 123) // pmix_byte_object_t - winsize structs for stdin, stdout
238241

239242
#define PRTE_JOB_MAX_KEY (PRTE_JOB_START_KEY + 200)
240243

src/util/prte_cmd_line.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ BEGIN_C_DECLS
114114
#define PRTE_CLI_DISABLE_RECOVERY "disable-recovery" // none
115115
#define PRTE_CLI_MEM_ALLOC_KIND "memory-alloc-kinds" // required
116116
#define PRTE_CLI_GPU_SUPPORT "gpu-support" // required
117+
#define PRTE_CLI_PTY "pty" // none
117118

118119
// Placement options
119120
#define PRTE_CLI_MAPBY "map-by" // required

0 commit comments

Comments
 (0)