Skip to content

Commit 1bf5a3f

Browse files
committed
flux-job: handle log and output messages with pty attach
Problem: When a job uses an interactive pty, such as with flux-alloc(1), the job's output eventlog is ignored because it is presumed all output is being handled through the pty. However, this means that all log messages, including error messages, are suppressed. This can result in confusing behavior. For instance, if the shell cannot change its working directory, it logs an error message. If the user does not see this message they may think the software is broken for other reasons. Process the output eventlog with `flux job attach` even when interactively attaching to a pty. Task output and log messages are sent the users original terminal. Since the terminal is assumed to be in raw mode, add the missing carriage return ('\r') to these messages to avoid leaving the cursor in the wrong column. If interactive pty output is also being captured via the pty.capture option, then skip output for rank 0 since it will likely be duplicated. Fixes #5272
1 parent 6597d10 commit 1bf5a3f

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

src/cmd/flux-job.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,7 @@ struct attach_ctx {
15761576
flux_watcher_t *sigtstp_w;
15771577
flux_watcher_t *notify_timer;
15781578
struct flux_pty_client *pty_client;
1579+
int pty_capture;
15791580
struct timespec t_sigint;
15801581
flux_watcher_t *stdin_w;
15811582
zlist_t *stdin_rpcs;
@@ -1646,6 +1647,15 @@ static void handle_output_data (struct attach_ctx *ctx, json_t *context)
16461647
log_msg_exit ("stream data read before header");
16471648
if (iodecode (context, &stream, &rank, &data, &len, NULL) < 0)
16481649
log_msg_exit ("malformed event context");
1650+
/*
1651+
* If this process is attached to a pty (ctx->pty_client != NULL)
1652+
* and output corresponds to rank 0 and the interactive pty is being
1653+
* captured, then this data is a duplicate, so do nothing.
1654+
*/
1655+
if (ctx->pty_client != NULL
1656+
&& streq (rank, "0")
1657+
&& ctx->pty_capture)
1658+
goto out;
16491659
if (streq (stream, "stdout"))
16501660
fp = stdout;
16511661
else
@@ -1654,8 +1664,14 @@ static void handle_output_data (struct attach_ctx *ctx, json_t *context)
16541664
if (optparse_hasopt (ctx->p, "label-io"))
16551665
fprintf (fp, "%s: ", rank);
16561666
fwrite (data, len, 1, fp);
1667+
/* If attached to a pty, terminal is in raw mode so a carriage
1668+
* return will be necessary to return cursor to the start of line.
1669+
*/
1670+
if (ctx->pty_client)
1671+
fputc ('\r', fp);
16571672
fflush (fp);
16581673
}
1674+
out:
16591675
free (data);
16601676
}
16611677

@@ -1725,6 +1741,11 @@ static void handle_output_log (struct attach_ctx *ctx,
17251741
fprintf (stderr, ":%d", line);
17261742
}
17271743
fprintf (stderr, ": %s\n", msg);
1744+
/* If attached to a pty, terminal is in raw mode so a carriage
1745+
* return will be necessary to return cursor to the start of line.
1746+
*/
1747+
if (ctx->pty_client)
1748+
fprintf (stderr, "\r");
17281749
}
17291750
}
17301751

@@ -2314,13 +2335,15 @@ void attach_exec_event_continuation (flux_future_t *f, void *arg)
23142335
if (streq (name, "shell.init")) {
23152336
const char *pty_service = NULL;
23162337
if (json_unpack (context,
2317-
"{s:i s:s s?s}",
2338+
"{s:i s:s s?s s?i}",
23182339
"leader-rank",
23192340
&ctx->leader_rank,
23202341
"service",
23212342
&service,
23222343
"pty",
2323-
&pty_service) < 0)
2344+
&pty_service,
2345+
"capture",
2346+
&ctx->pty_capture) < 0)
23242347
log_err_exit ("error decoding shell.init context");
23252348
if (!(ctx->service = strdup (service)))
23262349
log_err_exit ("strdup service from shell.init");
@@ -2333,15 +2356,14 @@ void attach_exec_event_continuation (flux_future_t *f, void *arg)
23332356
* to process normal stdio. (This may be because the job is
23342357
* already complete).
23352358
*/
2359+
attach_output_start (ctx);
23362360
if (pty_service) {
23372361
if (ctx->readonly)
23382362
log_msg_exit ("Cannot connect to pty in readonly mode");
23392363
attach_pty (ctx, pty_service);
23402364
}
2341-
else {
2365+
else
23422366
attach_setup_stdin (ctx);
2343-
attach_output_start (ctx);
2344-
}
23452367
} else if (streq (name, "shell.start")) {
23462368
if (MPIR_being_debugged)
23472369
setup_mpir_interface (ctx, context);

0 commit comments

Comments
 (0)