From aa0082184841b3c09a31fdeff3b8f23ae6deca59 Mon Sep 17 00:00:00 2001
From: Don Lipari <lipari1@llnl.gov>
Date: Wed, 2 Sep 2009 18:52:13 +0000
Subject: [PATCH] Added to scancel the ability to select jobs by account and
 qos

---
 NEWS                   |  1 +
 doc/man/man1/salloc.1  |  5 ++-
 doc/man/man1/sbatch.1  |  5 ++-
 doc/man/man1/scancel.1 | 29 +++++++++++----
 doc/man/man1/srun.1    |  8 +++-
 src/salloc/opt.c       |  1 +
 src/sbatch/opt.c       | 11 +++---
 src/scancel/opt.c      | 84 +++++++++++++++++++++++++-----------------
 src/scancel/scancel.c  | 16 ++++----
 src/scancel/scancel.h  |  5 ++-
 src/srun/opt.c         | 55 +++++++++++++--------------
 11 files changed, 135 insertions(+), 85 deletions(-)

diff --git a/NEWS b/NEWS
index a2551cb2b7f..f56bd189b6d 100644
--- a/NEWS
+++ b/NEWS
@@ -78,6 +78,7 @@ documents those changes that are of interest to users and admins.
     SLURM_JOB_CPUS_PER_NODE now reference cnode counts instead of midplane
     counts.  SLURM_NODELIST still references midplane names.
  -- Added qos support to salloc/sbatch/srun
+ -- Added to scancel the ability to select jobs by account and qos
 
 * Changes in SLURM 2.1.0-pre2
 =============================
diff --git a/doc/man/man1/salloc.1 b/doc/man/man1/salloc.1
index 32616885bcf..e0fe6e74791 100644
--- a/doc/man/man1/salloc.1
+++ b/doc/man/man1/salloc.1
@@ -748,7 +748,7 @@ Specify a minimum amount of temporary disk space.
 
 .TP
 \fB\-U\fR, \fB\-\-account\fR=<\fIaccount\fR>
-Change resource use by this job to specified account.
+Charge resources used by this job to specified account.
 The \fIaccount\fR is an arbitrary string. The account name may
 be changed after job submission using the \fBscontrol\fR
 command.
@@ -916,6 +916,9 @@ Same as \fB\-O, \-\-overcommit\fR
 \fBSALLOC_PARTITION\fR
 Same as \fB\-p, \-\-partition\fR
 .TP
+\fBSALLOC_QOS\fR
+Same as \fB\-\-qos\fR
+.TP
 \fBSALLOC_TIMELIMIT\fR
 Same as \fB\-t, \-\-time\fR
 .TP
diff --git a/doc/man/man1/sbatch.1 b/doc/man/man1/sbatch.1
index 8d5ea0997f5..59ca487d045 100644
--- a/doc/man/man1/sbatch.1
+++ b/doc/man/man1/sbatch.1
@@ -848,7 +848,7 @@ Specify a minimum amount of temporary disk space.
 
 .TP
 \fB\-U\fR, \fB\-\-account\fR=<\fIaccount\fR>
-Change resource use by this job to specified account.
+Charge resources used by this job to specified account.
 The \fIaccount\fR is an arbitrary string. The account name may
 be changed after job submission using the \fBscontrol\fR
 command.
@@ -1032,6 +1032,9 @@ Same as \fB\-O, \-\-overcommit\fR
 \fBSBATCH_PARTITION\fR
 Same as \fB\-p, \-\-partition\fR
 .TP
+\fBSBATCH_QOS\fR
+Same as \fB\-\-qos\fR
+.TP
 \fBSBATCH_TIMELIMIT\fR
 Same as \fB\-t, \-\-time\fR
 
diff --git a/doc/man/man1/scancel.1 b/doc/man/man1/scancel.1
index a6b647517c5..ded779e8398 100644
--- a/doc/man/man1/scancel.1
+++ b/doc/man/man1/scancel.1
@@ -16,6 +16,10 @@ be printed and the job will not be signaled.
 
 .SH "OPTIONS"
 
+.TP
+\fB\-a\fR, \fB\-\-account\fR=\fIaccount\fR
+Restrict the scancel operation to jobs under this charge account.
+
 .TP
 \fB\-b\fR, \fB\-\-batch\fR
 Signal the batch job shell and its child processes.
@@ -40,11 +44,15 @@ Interactive mode. Confirm each job_id.step_id before performing the cancel opera
 
 .TP
 \fB\-n\fR, \fB\-\-name\fR=\fIjob_name\fR
-The name of jobs to be signaled.
+Restrict the scancel operation to jobs with this job name.
 
 .TP
 \fB\-p\fR, \fB\-\-partition\fR=\fIpartition_name\fR
-The name of the partition from which jobs are to be signaled.
+Restrict the scancel operation to jobs in this partition.
+
+.TP
+\fB\-p\fR, \fB\-\-qos\fR=\fIqos\fR
+Restrict the scancel operation to jobs with this quality of service.
 
 .TP
 \fB\-Q\fR, \fB\-\-quiet\fR
@@ -53,17 +61,18 @@ This option is incompatible with the \fB\-\-verbose\fR option.
 
 .TP
 \fB\-s\fR, \fB\-\-signal\fR=\fIsignal_name\fR
-The name or number of the signal to be send. 
-If no signal is specified, the specified job or step will be terminated.
+The name or number of the signal to send.  If no signal is specified,
+the specified job or step will be terminated.
 
 .TP
 \fB\-t\fR, \fB\-\-state\fR=\fIjob_state_name\fR
-The state of the jobs to be signaled. \fIjob_state_name\fR may have a value of 
-either "PENDING", "RUNNING" or "SUSPENDED".
+Restrict the scancel operation to jobs in this
+state. \fIjob_state_name\fR may have a value of either "PENDING",
+"RUNNING" or "SUSPENDED".
 
 .TP
 \fB\-u\fR, \fB\-\-user\fR=\fIuser_name\fR
-The name of the user whose jobs are to be signaled.
+Restrict the scancel operation to jobs owned by this user.
 
 .TP
 \fB\-\-usage\fR
@@ -114,6 +123,9 @@ Some \fBscancel\fR options may be set via environment variables. These
 environment variables, along with their corresponding options, are listed below.
 (Note: commandline options will always override these settings)
 .TP 20
+\fBSCANCEL_ACCOUNT\fR
+\fB\-a\fR, \fB\-\-account\fR=\fIaccount\fR
+.TP 20
 \fBSCANCEL_BATCH\fR
 \fB\-b, \-\-batch\fR
 .TP 20
@@ -129,6 +141,9 @@ environment variables, along with their corresponding options, are listed below.
 \fBSCANCEL_PARTITION\fR
 \fB\-p\fR, \fB\-\-partition\fR=\fIpartition_name\fR
 .TP 20
+\fBSCANCEL_QOS\fR
+\fB\-q\fR, \fB\-\-qos\fR=\fIqos\fR
+.TP 20
 \fBSCANCEL_STATE\fR
 \fB\-t\fR, \fB\-\-state\fR=\fIjob_state_name\fR
 .TP 20
diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1
index 777858d8393..36e8d04874a 100644
--- a/doc/man/man1/srun.1
+++ b/doc/man/man1/srun.1
@@ -976,7 +976,7 @@ Specify a minimum amount of temporary disk space.
 
 .TP
 \fB\-U\fR, \fB\-\-account\fR=<\fIaccount\fR>
-Change resource use by this job to specified account.
+Charge resources used by this job to specified account.
 The \fIaccount\fR is an arbitrary string. The account name may
 be changed after job submission using the \fBscontrol\fR
 command.
@@ -1384,6 +1384,9 @@ Same as \fB\-p, \-\-partition\fR
 \fBSLURM_PROLOG\fR
 Same as \fB\-\-prolog\fR
 .TP
+\fBSLURM_QOS\fR
+Same as \fB\-\-qos\fR
+.TP
 \fBSLURM_REMOTE_CWD\fR
 Same as \fB\-D, \-\-chdir=\fR
 .TP
@@ -1417,6 +1420,9 @@ Same as \fB\-u, \-\-unbuffered\fR
 \fBSLURM_WAIT\fR
 Same as \fB\-W, \-\-wait\fR
 .TP
+\fBSLURM_WCKEY\fR
+Same as \fB\-W, \-\-wckey\fR
+.TP
 \fBSLURM_WORKING_DIR\fR
 \fB\-D, \-\-chdir\fR
 
diff --git a/src/salloc/opt.c b/src/salloc/opt.c
index b66be57d7e1..ff064328874 100644
--- a/src/salloc/opt.c
+++ b/src/salloc/opt.c
@@ -374,6 +374,7 @@ env_vars_t env_vars[] = {
   {"SALLOC_NO_ROTATE",     OPT_NO_ROTATE,  NULL,               NULL          },
   {"SALLOC_OVERCOMMIT",    OPT_OVERCOMMIT, NULL,               NULL          },
   {"SALLOC_PARTITION",     OPT_STRING,     &opt.partition,     NULL          },
+  {"SALLOC_QOS",           OPT_STRING,     &opt.qos,           NULL          },
   {"SALLOC_TIMELIMIT",     OPT_STRING,     &opt.time_limit_str,NULL          },
   {"SALLOC_WAIT",          OPT_IMMEDIATE,  NULL,               NULL          },
   {"SALLOC_WCKEY",         OPT_STRING,     &opt.wckey,         NULL          },
diff --git a/src/sbatch/opt.c b/src/sbatch/opt.c
index 1c41271c284..60b4cc04366 100644
--- a/src/sbatch/opt.c
+++ b/src/sbatch/opt.c
@@ -415,6 +415,9 @@ env_vars_t env_vars[] = {
   {"SBATCH_ACCOUNT",       OPT_STRING,     &opt.account,       NULL           },
   {"SBATCH_ACCTG_FREQ",    OPT_INT,        &opt.acctg_freq,    NULL           },
   {"SBATCH_BLRTS_IMAGE",   OPT_STRING,     &opt.blrtsimage,    NULL           },
+  {"SBATCH_CHECKPOINT",    OPT_STRING,     &opt.ckpt_interval_str, NULL       },
+  {"SBATCH_CHECKPOINT_DIR",OPT_STRING,     &opt.ckpt_dir,      NULL           },
+  {"SBATCH_CNLOAD_IMAGE",  OPT_STRING,     &opt.linuximage,    NULL           },
   {"SBATCH_CONN_TYPE",     OPT_CONN_TYPE,  NULL,               NULL           },
   {"SBATCH_CPU_BIND",      OPT_CPU_BIND,   NULL,               NULL           },
   {"SBATCH_DEBUG",         OPT_DEBUG,      NULL,               NULL           },
@@ -422,10 +425,10 @@ env_vars_t env_vars[] = {
   {"SBATCH_EXCLUSIVE",     OPT_EXCLUSIVE,  NULL,               NULL           },
   {"SBATCH_GEOMETRY",      OPT_GEOMETRY,   NULL,               NULL           },
   {"SBATCH_IMMEDIATE",     OPT_BOOL,       &opt.immediate,     NULL           },
+  {"SBATCH_IOLOAD_IMAGE",  OPT_STRING,     &opt.ramdiskimage,  NULL           },
   {"SBATCH_JOBID",         OPT_INT,        &opt.jobid,         NULL           },
   {"SBATCH_JOB_NAME",      OPT_STRING,     &opt.job_name,      NULL           },
   {"SBATCH_LINUX_IMAGE",   OPT_STRING,     &opt.linuximage,    NULL           },
-  {"SBATCH_CNLOAD_IMAGE",  OPT_STRING,     &opt.linuximage,    NULL           },
   {"SBATCH_MEM_BIND",      OPT_MEM_BIND,   NULL,               NULL           },
   {"SBATCH_MLOADER_IMAGE", OPT_STRING,     &opt.mloaderimage,  NULL           },
   {"SBATCH_NETWORK",       OPT_STRING,     &opt.network,       NULL           },
@@ -434,13 +437,11 @@ env_vars_t env_vars[] = {
   {"SBATCH_OPEN_MODE",     OPT_OPEN_MODE,  NULL,               NULL           },
   {"SBATCH_OVERCOMMIT",    OPT_OVERCOMMIT, NULL,               NULL           },
   {"SBATCH_PARTITION",     OPT_STRING,     &opt.partition,     NULL           },
+  {"SBATCH_QOS",           OPT_STRING,     &opt.qos,           NULL           },
   {"SBATCH_RAMDISK_IMAGE", OPT_STRING,     &opt.ramdiskimage,  NULL           },
-  {"SBATCH_IOLOAD_IMAGE",  OPT_STRING,     &opt.ramdiskimage,  NULL           },
-  {"SBATCH_TIMELIMIT",     OPT_STRING,     &opt.time_limit_str,NULL           },
   {"SBATCH_REQUEUE",       OPT_REQUEUE,    NULL,               NULL           },
+  {"SBATCH_TIMELIMIT",     OPT_STRING,     &opt.time_limit_str,NULL           },
   {"SBATCH_WCKEY",         OPT_STRING,     &opt.wckey,         NULL           },
-  {"SBATCH_CHECKPOINT",    OPT_STRING,     &opt.ckpt_interval_str, NULL       },
-  {"SBATCH_CHECKPOINT_DIR",OPT_STRING,     &opt.ckpt_dir,      NULL           },
   {NULL, 0, NULL, NULL}
 };
 
diff --git a/src/scancel/opt.c b/src/scancel/opt.c
index c068e907225..88b4cc323fe 100644
--- a/src/scancel/opt.c
+++ b/src/scancel/opt.c
@@ -154,7 +154,6 @@ static uint16_t
 _xlate_state_name(const char *state_name, bool env_var)
 {
 	enum job_states i;
-	char *state_names;
 
 	for (i=0; i<JOB_END; i++) {
 		if ((strcasecmp(state_name,job_state_string(i)) == 0) ||
@@ -181,17 +180,8 @@ _xlate_state_name(const char *state_name, bool env_var)
 	else
 		fprintf(stderr, "Invalid job state specified: %s\n",
 			state_name);
-	state_names = xstrdup(job_state_string(0));
-	for (i=1; i<JOB_END; i++) {
-		xstrcat(state_names, ",");
-		xstrcat(state_names, job_state_string(i));
-	}
-	xstrcat(state_names, ",");
-	xstrcat(state_names, job_state_string(JOB_COMPLETING));
-	xstrcat(state_names, ",");
-	xstrcat(state_names, job_state_string(JOB_CONFIGURING));
-	fprintf (stderr, "Valid job states include: %s\n", state_names);
-	xfree (state_names);
+
+	fprintf (stderr, "Valid job states are PENDING, RUNNING, and SUSPENDED\n");
 	exit (1);
 }
 
@@ -234,19 +224,21 @@ static void _print_version (void)
  */
 static void _opt_default()
 {
+	opt.account	= NULL;
 	opt.batch	= false;
 	opt.ctld	= false;
 	opt.interactive	= false;
 	opt.job_cnt	= 0;
 	opt.job_name	= NULL;
+	opt.nodelist	= NULL;
 	opt.partition	= NULL;
+	opt.qos		= NULL;
 	opt.signal	= (uint16_t)-1; /* no signal specified */
 	opt.state	= JOB_END;
-	opt.user_name	= NULL;
 	opt.user_id	= 0;
+	opt.user_name	= NULL;
 	opt.verbose	= 0;
 	opt.wckey	= NULL;
-	opt.nodelist	= NULL;
 }
 
 /*
@@ -258,6 +250,10 @@ static void _opt_env()
 {
 	char *val;
 
+	if ( (val=getenv("SCANCEL_ACCOUNT")) ) {
+		opt.account = xstrdup(val);
+	}
+
 	if ( (val=getenv("SCANCEL_BATCH")) ) {
 		if (strcasecmp(val, "true") == 0)
 			opt.batch       = true;
@@ -297,6 +293,10 @@ static void _opt_env()
 		opt.partition = xstrdup(val);
 	}
 
+	if ( (val=getenv("SCANCEL_QOS")) ) {
+		opt.qos = xstrdup(val);
+	}
+
 	if ( (val=getenv("SCANCEL_STATE")) ) {
 		opt.state = _xlate_state_name(val, true);
 	}
@@ -332,25 +332,27 @@ static void _opt_args(int argc, char **argv)
 	int opt_char;
 	int option_index;
 	static struct option long_options[] = { 
+		{"account",	required_argument, 0, 'a'},
 		{"batch",	no_argument,       0, 'b'},
 		{"ctld",	no_argument,	   0, OPT_LONG_CTLD},
+		{"help",        no_argument,       0, OPT_LONG_HELP},
 		{"interactive", no_argument,       0, 'i'},
 		{"name",        required_argument, 0, 'n'},
+		{"nodelist",    required_argument, 0, 'w'},
 		{"partition",   required_argument, 0, 'p'},
+		{"qos",         required_argument, 0, 'q'},
 		{"quiet",       no_argument,       0, 'Q'},
 		{"signal",      required_argument, 0, 's'},
 		{"state",       required_argument, 0, 't'},
+		{"usage",       no_argument,       0, OPT_LONG_USAGE},
 		{"user",        required_argument, 0, 'u'},
 		{"verbose",     no_argument,       0, 'v'},
 		{"version",     no_argument,       0, 'V'},
-		{"nodelist",    required_argument, 0, 'w'},
 		{"wckey",       required_argument, 0, OPT_LONG_WCKEY},
-		{"help",        no_argument,       0, OPT_LONG_HELP},
-		{"usage",       no_argument,       0, OPT_LONG_USAGE},
 		{NULL,          0,                 0, 0}
 	};
 
-	while((opt_char = getopt_long(argc, argv, "bin:p:Qs:t:u:vVw:",
+	while((opt_char = getopt_long(argc, argv, "a:bin:p:Qq:s:t:u:vVw:",
 			long_options, &option_index)) != -1) {
 		switch (opt_char) {
 			case (int)'?':
@@ -359,6 +361,9 @@ static void _opt_args(int argc, char **argv)
 					"information\n");
 				exit(1);
 				break;
+			case (int)'a':
+				opt.account = xstrdup(optarg);
+				break;
 			case (int)'b':
 				opt.batch = true;
 				break;
@@ -377,6 +382,9 @@ static void _opt_args(int argc, char **argv)
 			case (int)'Q':
 				opt.verbose = -1;
 				break;
+			case (int)'q':
+				opt.qos = xstrdup(optarg);
+				break;
 			case (int)'s':
 				opt.signal = _xlate_signal_name(optarg);
 				break;
@@ -479,13 +487,15 @@ _opt_verify(void)
 		}
 	}
 
-	if ((opt.job_name == NULL) &&
+	if ((opt.account == 0) &&
+	    (opt.job_cnt == 0) &&
+	    (opt.job_name == NULL) &&
+	    (opt.nodelist == NULL) &&
 	    (opt.partition == NULL) &&
+	    (opt.qos == NULL) &&
 	    (opt.state == JOB_END) &&
 	    (opt.user_name == NULL) &&
-	    (opt.wckey == NULL) &&
-	    (opt.job_cnt == 0) &&
-	    (opt.nodelist == NULL)) {
+	    (opt.wckey == NULL)) {
 		error("No job identification provided");
 		verified = false;	/* no job specification */
 	}
@@ -499,18 +509,20 @@ static void _opt_list(void)
 {
 	int i;
 
+	info("account        : %s", opt.account);
 	info("batch          : %s", tf_(opt.batch));
 	info("ctld           : %s", tf_(opt.ctld));
 	info("interactive    : %s", tf_(opt.interactive));
 	info("job_name       : %s", opt.job_name);
+	info("nodelist       : %s", opt.nodelist);
 	info("partition      : %s", opt.partition);
+	info("qos            : %s", opt.qos);
 	info("signal         : %u", opt.signal);
 	info("state          : %s", job_state_string(opt.state));
 	info("user_id        : %u", opt.user_id);
 	info("user_name      : %s", opt.user_name);
 	info("verbose        : %d", opt.verbose);
 	info("wckey          : %s", opt.wckey);
-	info("nodelist       : %s", opt.nodelist);
 
 	for (i=0; i<opt.job_cnt; i++) {
 		info("job_steps      : %u.%u ", opt.job_id[i], opt.step_id[i]);
@@ -519,28 +531,32 @@ static void _opt_list(void)
 
 static void _usage(void)
 {
-	printf("Usage: scancel [-n job_name] [-u user] [-p partition] [-Q] [-s name | integer]\n");
-	printf("               [--batch] [-t PENDING | RUNNING | SUSPENDED] [--usage] [-v] [-V]\n");
-	printf("               [-w hosts...] [job_id[.step_id]]\n");
+	printf("Usage: scancel [-a account] [--batch] [--interactive] [-n job_name]\n");
+	printf("               [-p partition] [-Q] [-q qos] [-s signal | integer]\n");
+	printf("               [-t PENDING | RUNNING | SUSPENDED] [--usage] [-u user_name]\n");
+	printf("               [-V] [-v] [-w hosts...] [--wckey=wckey] [job_id[.step_id]]\n");
 }
 
 static void _help(void)
 {
 	printf("Usage: scancel [OPTIONS] [job_id[.step_id]]\n");
+	printf("  -a, --account=account           act only on jobs charging this account\n");
 	printf("  -b, --batch                     signal batch shell for specified job\n");
 /*	printf("      --ctld                      route request through slurmctld\n"); */
 	printf("  -i, --interactive               require response from user for each job\n");
-	printf("  -n, --name=job_name             name of job to be signaled\n");
-	printf("  -p, --partition=partition       name of job's partition\n");
+	printf("  -n, --name=job_name             act only on jobs with this name\n");
+	printf("  -p, --partition=partition       act only on jobs in this partition\n");
 	printf("  -Q, --quiet                     disable warnings\n");
+	printf("  -q, --qos=qos                   act only on jobs with this quality of service\n");
 	printf("  -s, --signal=name | integer     signal to send to job, default is SIGKILL\n");
-	printf("  -t, --state=states              states of jobs to be signaled,\n");
-	printf("                                  default is pending, running, and\n");
-	printf("                                  suspended\n");
-	printf("  -u, --user=user                 name or id of user to have jobs cancelled\n");
-	printf("  -v, --verbose                   verbosity level\n");
+	printf("  -t, --state=states              act only on jobs in this state.  Valid job\n");
+	printf("                                  states are PENDING, RUNNING and SUSPENDED\n");
+	printf("  -u, --user=user_name            act only on jobs of this user\n");
 	printf("  -V, --version                   output version information and exit\n");
-	printf("  -w, --nodelist                  cancel jobs using any of these nodes\n");
+	printf("  -v, --verbose                   verbosity level\n");
+	printf("  -w, --nodelist                  act only on jobs on these nodes\n");
+	printf("      --wckey=wckey               act only on jobs with this workload\n");
+	printf("                                  charactization key\n");
 	printf("\nHelp options:\n");
 	printf("  --help                          show this help message\n");
 	printf("  --usage                         display brief usage message\n");
diff --git a/src/scancel/scancel.c b/src/scancel/scancel.c
index b571b9ffec5..b7946f8e2b5 100644
--- a/src/scancel/scancel.c
+++ b/src/scancel/scancel.c
@@ -109,12 +109,14 @@ main (int argc, char *argv[])
 	_load_job_records();
 	_verify_job_ids();
 
-	if ((opt.interactive) ||
+	if ((opt.account) ||
+	    (opt.interactive) ||
 	    (opt.job_name) ||
+	    (opt.nodelist) ||
 	    (opt.partition) ||
+	    (opt.qos) ||
 	    (opt.state != JOB_END) ||
-	    (opt.user_name) ||
-	    (opt.nodelist)) {
+	    (opt.user_name)) {
 		_filter_job_records ();
 	}
 	_cancel_jobs ();
@@ -200,14 +202,14 @@ _filter_job_records (void)
 			continue;
 		}
 
-		if (opt.wckey != NULL &&
-		    (strcmp(job_ptr[i].wckey, opt.wckey) != 0)) {
+		if ((opt.partition != NULL) &&
+		    (strcmp(job_ptr[i].partition,opt.partition) != 0)) {
 			job_ptr[i].job_id = 0;
 			continue;
 		}
 
-		if ((opt.partition != NULL) &&
-		    (strcmp(job_ptr[i].partition,opt.partition) != 0)) {
+		if ((opt.qos != NULL) &&
+		    (strcmp(job_ptr[i].qos,opt.qos) != 0)) {
 			job_ptr[i].job_id = 0;
 			continue;
 		}
diff --git a/src/scancel/scancel.h b/src/scancel/scancel.h
index e9301c00566..fa5f2c4e0e7 100644
--- a/src/scancel/scancel.h
+++ b/src/scancel/scancel.h
@@ -44,15 +44,16 @@
 #endif
 
 typedef struct scancel_options {
-	char *account;		/* --account=			*/
+	char *account;		/* --account=n, -a		*/
 	bool batch;		/* --batch, -b			*/
 	bool ctld;		/* --ctld			*/
 	bool interactive;	/* --interactive, -i		*/
 	char *job_name;		/* --name=n, -nn		*/
 	char *partition;	/* --partition=n, -pn		*/
+	char *qos;		/* --qos=n, -qn			*/
 	uint16_t signal;	/* --signal=n, -sn		*/
 	uint16_t state;		/* --state=n, -tn		*/
-	uid_t user_id;		/* --user=n, -un		*/
+	uid_t user_id;		/* derived from user_name	*/
 	char *user_name;	/* --user=n, -un		*/
 	int verbose;		/* --verbose, -v		*/
 
diff --git a/src/srun/opt.c b/src/srun/opt.c
index 0ffdc7f130b..c8738f1092b 100644
--- a/src/srun/opt.c
+++ b/src/srun/opt.c
@@ -461,64 +461,65 @@ struct env_vars {
 };
 
 env_vars_t env_vars[] = {
-{"SLURM_ACCOUNT",       OPT_STRING,     &opt.account,       NULL             },
 {"SLURMD_DEBUG",        OPT_INT,        &opt.slurmd_debug,  NULL             },
+{"SLURM_ACCOUNT",       OPT_STRING,     &opt.account,       NULL             },
+{"SLURM_ACCTG_FREQ",    OPT_INT,        &opt.acctg_freq,    NULL             },
 {"SLURM_BLRTS_IMAGE",   OPT_STRING,     &opt.blrtsimage,    NULL             },
-{"SLURM_CPUS_PER_TASK", OPT_INT,        &opt.cpus_per_task, &opt.cpus_set    },
+{"SLURM_CHECKPOINT",    OPT_STRING,     &opt.ckpt_interval_str, NULL         },
+{"SLURM_CHECKPOINT_DIR",OPT_STRING,     &opt.ckpt_dir,      NULL             },
+{"SLURM_CNLOAD_IMAGE",  OPT_STRING,     &opt.linuximage,    NULL             },
 {"SLURM_CONN_TYPE",     OPT_CONN_TYPE,  NULL,               NULL             },
 {"SLURM_CORE_FORMAT",   OPT_CORE,       NULL,               NULL             },
+{"SLURM_CPUS_PER_TASK", OPT_INT,        &opt.cpus_per_task, &opt.cpus_set    },
 {"SLURM_CPU_BIND",      OPT_CPU_BIND,   NULL,               NULL             },
-{"SLURM_MEM_BIND",      OPT_MEM_BIND,   NULL,               NULL             },
 {"SLURM_DEPENDENCY",    OPT_STRING,     &opt.dependency,    NULL             },
+{"SLURM_DISABLE_STATUS",OPT_INT,        &opt.disable_status,NULL             },
 {"SLURM_DISTRIBUTION",  OPT_DISTRIB,    NULL,               NULL             },
+{"SLURM_EPILOG",        OPT_STRING,     &opt.epilog,        NULL             },
+{"SLURM_EXCLUSIVE",     OPT_EXCLUSIVE,  NULL,               NULL             },
 {"SLURM_GEOMETRY",      OPT_GEOMETRY,   NULL,               NULL             },
 {"SLURM_IMMEDIATE",     OPT_IMMEDIATE,  NULL,               NULL             },
-{"SLURM_JOB_NAME",      OPT_STRING,     &opt.job_name,  &opt.job_name_set_env},
+{"SLURM_IOLOAD_IMAGE",  OPT_STRING,     &opt.ramdiskimage,  NULL             },
 /* SLURM_JOBID was used in slurm version 1.3 and below, it is now vestigial */
 {"SLURM_JOBID",         OPT_INT,        &opt.jobid,         NULL             },
 {"SLURM_JOB_ID",        OPT_INT,        &opt.jobid,         NULL             },
+{"SLURM_JOB_NAME",      OPT_STRING,     &opt.job_name,  &opt.job_name_set_env},
 {"SLURM_KILL_BAD_EXIT", OPT_INT,        &opt.kill_bad_exit, NULL             },
 {"SLURM_LABELIO",       OPT_INT,        &opt.labelio,       NULL             },
 {"SLURM_LINUX_IMAGE",   OPT_STRING,     &opt.linuximage,    NULL             },
-{"SLURM_CNLOAD_IMAGE",  OPT_STRING,     &opt.linuximage,    NULL             },
+{"SLURM_MEM_BIND",      OPT_MEM_BIND,   NULL,               NULL             },
 {"SLURM_MLOADER_IMAGE", OPT_STRING,     &opt.mloaderimage,  NULL             },
-{"SLURM_NNODES",        OPT_NODES,      NULL,               NULL             },
-{"SLURM_NSOCKETS_PER_NODE",OPT_NSOCKETS,NULL,               NULL             },
+{"SLURM_MPI_TYPE",      OPT_MPI,        NULL,               NULL             },
 {"SLURM_NCORES_PER_SOCKET",OPT_NCORES,  NULL,               NULL             },
-{"SLURM_NTHREADS_PER_CORE",OPT_NTHREADS,NULL,               NULL             },
-{"SLURM_NTASKS_PER_NODE", OPT_INT,      &opt.ntasks_per_node, NULL           },
+{"SLURM_NETWORK",       OPT_STRING,     &opt.network,       NULL             },
+{"SLURM_NNODES",        OPT_NODES,      NULL,               NULL             },
+{"SLURM_NODELIST",      OPT_STRING,     &opt.alloc_nodelist,NULL             },
 {"SLURM_NO_ROTATE",     OPT_NO_ROTATE,  NULL,               NULL             },
 {"SLURM_NPROCS",        OPT_INT,        &opt.nprocs,        &opt.nprocs_set  },
+{"SLURM_NSOCKETS_PER_NODE",OPT_NSOCKETS,NULL,               NULL             },
+{"SLURM_NTASKS_PER_NODE", OPT_INT,      &opt.ntasks_per_node, NULL           },
+{"SLURM_NTHREADS_PER_CORE",OPT_NTHREADS,NULL,               NULL             },
+{"SLURM_OPEN_MODE",     OPT_OPEN_MODE,  NULL,               NULL             },
 {"SLURM_OVERCOMMIT",    OPT_OVERCOMMIT, NULL,               NULL             },
 {"SLURM_PARTITION",     OPT_STRING,     &opt.partition,     NULL             },
+{"SLURM_PROLOG",        OPT_STRING,     &opt.prolog,        NULL             },
+{"SLURM_QOS",           OPT_STRING,     &opt.qos,           NULL             },
 {"SLURM_RAMDISK_IMAGE", OPT_STRING,     &opt.ramdiskimage,  NULL             },
-{"SLURM_IOLOAD_IMAGE",  OPT_STRING,     &opt.ramdiskimage,  NULL             },
 {"SLURM_REMOTE_CWD",    OPT_STRING,     &opt.cwd,           NULL             },
+{"SLURM_RESTART_DIR",   OPT_STRING,     &opt.restart_dir ,  NULL             },
 {"SLURM_RESV_PORTS",    OPT_RESV_PORTS, NULL,               NULL             },
+{"SLURM_SRUN_MULTI",    OPT_MULTI,      NULL,               NULL             },
 {"SLURM_STDERRMODE",    OPT_STRING,     &opt.efname,        NULL             },
 {"SLURM_STDINMODE",     OPT_STRING,     &opt.ifname,        NULL             },
 {"SLURM_STDOUTMODE",    OPT_STRING,     &opt.ofname,        NULL             },
+{"SLURM_TASK_EPILOG",   OPT_STRING,     &opt.task_epilog,   NULL             },
+{"SLURM_TASK_PROLOG",   OPT_STRING,     &opt.task_prolog,   NULL             },
 {"SLURM_THREADS",       OPT_INT,        &opt.max_threads,   NULL             },
 {"SLURM_TIMELIMIT",     OPT_STRING,     &opt.time_limit_str,NULL             },
-{"SLURM_CHECKPOINT",    OPT_STRING,     &opt.ckpt_interval_str, NULL         },
-{"SLURM_CHECKPOINT_DIR",OPT_STRING,     &opt.ckpt_dir,      NULL             },
-{"SLURM_RESTART_DIR",   OPT_STRING,     &opt.restart_dir ,  NULL             },
-{"SLURM_WAIT",          OPT_INT,        &opt.max_wait,      NULL             },
-{"SLURM_DISABLE_STATUS",OPT_INT,        &opt.disable_status,NULL             },
-{"SLURM_MPI_TYPE",      OPT_MPI,        NULL,               NULL             },
-{"SLURM_SRUN_MULTI",    OPT_MULTI,      NULL,               NULL             },
 {"SLURM_UNBUFFEREDIO",  OPT_INT,        &opt.unbuffered,    NULL             },
-{"SLURM_NODELIST",      OPT_STRING,     &opt.alloc_nodelist,NULL             },
-{"SLURM_PROLOG",        OPT_STRING,     &opt.prolog,        NULL             },
-{"SLURM_EPILOG",        OPT_STRING,     &opt.epilog,        NULL             },
-{"SLURM_TASK_PROLOG",   OPT_STRING,     &opt.task_prolog,   NULL             },
-{"SLURM_TASK_EPILOG",   OPT_STRING,     &opt.task_epilog,   NULL             },
-{"SLURM_WORKING_DIR",   OPT_STRING,     &opt.cwd,           &opt.cwd_set     },
-{"SLURM_EXCLUSIVE",     OPT_EXCLUSIVE,  NULL,               NULL             },
-{"SLURM_OPEN_MODE",     OPT_OPEN_MODE,  NULL,               NULL             },
-{"SLURM_ACCTG_FREQ",    OPT_INT,        &opt.acctg_freq,    NULL             },
-{"SLURM_NETWORK",       OPT_STRING,     &opt.network,       NULL             },
+{"SLURM_WAIT",          OPT_INT,        &opt.max_wait,      NULL             },
 {"SLURM_WCKEY",         OPT_STRING,     &opt.wckey,         NULL             },
+{"SLURM_WORKING_DIR",   OPT_STRING,     &opt.cwd,           &opt.cwd_set     },
 {NULL, 0, NULL, NULL}
 };
 
-- 
GitLab