From 159e591b77ef8543351598480e6db459062189b4 Mon Sep 17 00:00:00 2001
From: Mark Grondona <mgrondona@llnl.gov>
Date: Tue, 8 Apr 2003 20:19:59 +0000
Subject: [PATCH]  o implement user requested option --unbuffered (do not
 buffer stdout)

---
 doc/man/man1/srun.1 |  6 +++++-
 src/srun/io.c       | 11 ++++++++++-
 src/srun/opt.c      | 28 +++++++++++++++++-----------
 src/srun/opt.h      |  1 +
 4 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1
index fa9d14a4ecd..11a101c69c2 100644
--- a/doc/man/man1/srun.1
+++ b/doc/man/man1/srun.1
@@ -98,9 +98,13 @@ default value is the smaller of 10 or the number of nodes allocated.
 prepend task number to lines of stdout/err. Normally, stdout and stderr
 from remote tasks is line-buffered directly to the stdout and stderr of
 .B srun
-. The \fB\-\-label\fR option will prepend lines of output with the remote
+The \fB\-\-label\fR option will prepend lines of output with the remote
 task id.
 .TP
+\fB-u\fR, \fB\-\-unbuffered\fR
+do not line buffer stdout from remote tasks. This option cannot be used
+with \fI\-\-label\fR. 
+.TP
 \fB\-m\fR, \fB\-\-distribution\fR=(\fIblock\fR|\fIcyclic\fR)
 Specify an alternate distribution method for remote processes.
 .RS
diff --git a/src/srun/io.c b/src/srun/io.c
index 28da70815d5..8ab0606a1ba 100644
--- a/src/srun/io.c
+++ b/src/srun/io.c
@@ -170,7 +170,7 @@ _update_task_state(job_t *job, int taskid)
 
 
 static void
-_do_output(cbuf_t buf, FILE *out, int tasknum)
+_do_output_line(cbuf_t buf, FILE *out, int tasknum)
 {
 	int  len     = 0;
 	int  tot     = 0;
@@ -198,6 +198,15 @@ _do_output(cbuf_t buf, FILE *out, int tasknum)
 	return;
 }
 
+static void
+_do_output(cbuf_t buf, FILE *out, int tasknum)
+{
+	if (opt.unbuffered)
+		cbuf_read_to_fd(buf, fileno(out), -1);
+	else
+		_do_output_line(buf, out, tasknum);
+}
+
 static void
 _flush_io(job_t *job)
 {
diff --git a/src/srun/opt.c b/src/srun/opt.c
index 76acdb466ea..19b95abfc38 100644
--- a/src/srun/opt.c
+++ b/src/srun/opt.c
@@ -155,10 +155,10 @@ struct poptOption constraintTable[] = {
 	 },
 	{"nodelist", 'w', POPT_ARG_STRING, &opt.nodelist, OPT_NODELIST,
 	 "request a specific list of hosts",
-	 "host1,host2,..."},
+	 "hosts..."},
 	{"exclude", 'x', POPT_ARG_STRING, &opt.exc_nodes, OPT_EXC_NODES,
-	 "request a specific list of hosts be excluded from the allocation",
-	 "host1,host2,..."},
+	 "exclude a specific list of hosts",
+	 "hosts..."},
 	{"no-allocate", 'Z', POPT_ARG_NONE, &opt.no_alloc, OPT_NO_ALLOC,
 	 "don't allocate nodes (must supply -w)",
 	},
@@ -195,7 +195,7 @@ struct poptOption runTable[] = {
 	 "overcommit resources",
 	 },
 	{"no-kill", 'k', POPT_ARG_NONE, &opt.no_kill, 0,
-	 "Do not kill job on node failure",
+	 "do not kill job on node failure",
 	 },
 	{"share", 's', POPT_ARG_NONE, &opt.share, 0,
 	 "share node with other jobs",
@@ -203,6 +203,9 @@ struct poptOption runTable[] = {
 	{"label", 'l', POPT_ARG_NONE, &opt.labelio, 0,
 	 "prepend task number to lines of stdout/err",
 	 },
+	{"unbuffered", 'u',  POPT_ARG_NONE, &opt.unbuffered, 0,
+	 "do not line-buffer stdout/err",
+	},
 	{"distribution", 'm', POPT_ARG_STRING, 0, OPT_DISTRIB,
 	 "distribution method for processes (type = block|cyclic)",
 	 "type"},
@@ -226,7 +229,7 @@ struct poptOption runTable[] = {
         {"slurmd-debug", 'd', POPT_ARG_INT, &opt.slurmd_debug, OPT_DEBUG,
 	 "slurmd debug level", "value"},
 	{"threads", 'T', POPT_ARG_INT, &opt.max_threads, OPT_THREADS,
-	 "number of threads in srun",
+	 "set srun launch fanout",
 	 "threads"},
 	{"wait", 'W', POPT_ARG_INT, &opt.max_wait, OPT_WAIT,
 	 "seconds to wait after first task ends before killing job",
@@ -583,6 +586,7 @@ static void _opt_default()
 	opt.core_format = "normal";
 
 	opt.labelio = false;
+	opt.unbuffered = false;
 	opt.overcommit = false;
 	opt.batch = false;
 	opt.share = false;
@@ -952,11 +956,6 @@ _opt_verify(poptContext optctx)
 		 *}
 		 */
 
-
-		/* XXX check here to see if job to attach to exists ? */
-
-		/* XXX what other args are incompatible with attach mode? */
-
 	} else { /* mode != MODE_ATTACH */
 
 		if ((remote_argc == 0) && (mode != MODE_ALLOCATE)) {
@@ -1012,11 +1011,17 @@ _opt_verify(poptContext optctx)
 		error("Thread value invalid, reset to 1");
 		opt.max_threads = 1;
 	} else if (opt.max_threads > MAX_THREADS) {
-		error("Thread value exceeds system limit, reset to %d", 
+		error("Thread value exceeds defined limit, reset to %d", 
 			MAX_THREADS);
 		opt.max_threads = MAX_THREADS;
 	}
 
+	if (opt.labelio && opt.unbuffered) {
+		error("Do not specify both -l (--label) and " 
+		      "-u (--unbuffered)");
+		exit(1);
+	}
+
 	return verified;
 }
 
@@ -1167,6 +1172,7 @@ void _opt_list()
 	info("slurmd_debug   : %d", opt.slurmd_debug);
 	info("immediate      : %s", tf_(opt.immediate));
 	info("label output   : %s", tf_(opt.labelio));
+	info("unbuffered IO  : %s", tf_(opt.unbuffered));
 	info("allocate       : %s", tf_(opt.allocate));
 	info("attach         : `%s'", opt.attach);
 	info("overcommit     : %s", tf_(opt.overcommit));
diff --git a/src/srun/opt.h b/src/srun/opt.h
index d1d20cb87f1..f400cf3ed89 100644
--- a/src/srun/opt.h
+++ b/src/srun/opt.h
@@ -127,6 +127,7 @@ typedef struct srun_options {
 	int immediate;		/* -i, --immediate      	*/
 
 	bool labelio;		/* --label-output, -l		*/
+	bool unbuffered;        /* --unbuffered,   -u           */
 	bool allocate;		/* --allocate, 	   -A		*/
 	bool overcommit;	/* --overcommit,   -O		*/
 	bool batch;		/* --batch,   -b		*/
-- 
GitLab