From dae309a5de82dc910fdd75c8021c483dd2216c6c Mon Sep 17 00:00:00 2001
From: Danny Auble <da@llnl.gov>
Date: Tue, 14 Oct 2008 23:36:24 +0000
Subject: [PATCH] svn merge -r15411:15415
 https://eris.llnl.gov/svn/slurm/branches/slurm-1.3

---
 NEWS                  |  5 +++-
 doc/man/man1/squeue.1 |  4 +--
 src/common/hostlist.c | 24 +++++++++++++++++
 src/common/hostlist.h | 18 +++++++++++++
 src/squeue/opts.c     | 63 ++++++++++++++++++++++++++++---------------
 src/squeue/print.c    | 23 +++++-----------
 src/squeue/squeue.h   |  2 +-
 7 files changed, 97 insertions(+), 42 deletions(-)

diff --git a/NEWS b/NEWS
index 6a1e94158bb..ac15efe28f6 100644
--- a/NEWS
+++ b/NEWS
@@ -78,7 +78,10 @@ documents those changes that are of interest to users and admins.
     - Add check for NULL return from hostlist_create().
     - Rewrite of hostrange_hn_within(), avoids reporting "tst0" in the hostlist 
       "tst".
-
+ -- Modify squeue to accept "--nodes=<hostlist>" rather than 
+    "--node=<node_name>" and report all jobs with any jobs on the set of nodes
+    identified. From Par Anderson, National Supercomputer Centre, Sweden.
+ 
 * Changes in SLURM 1.3.9
 ========================
  -- Fix jobs being cancelled by ctrl-C to have correct cancelled state in 
diff --git a/doc/man/man1/squeue.1 b/doc/man/man1/squeue.1
index 9941d0e60ef..28a453d12cb 100644
--- a/doc/man/man1/squeue.1
+++ b/doc/man/man1/squeue.1
@@ -50,8 +50,8 @@ Report more of the available information for the selected jobs or job steps,
 subject to any constraints specified.
 
 .TP
-\fB\-n <node_name>\fR, \fB\-\-node=<node_name>\fR
-Report only on jobs allocated to the specified node.
+\fB\-n <hostlist>\fR, \fB\-\-nodes=<hostlist>\fR
+Report only on jobs allocated to the specified node or list of nodes.
 This may either be the \fBNodeName\fR or \fBNodeHostname\fR
 as defined in \fBslurm.conf(5)\fR in the event that they differ.
 A node_name of \fBlocalhost\fR is mapped to the current host name.
diff --git a/src/common/hostlist.c b/src/common/hostlist.c
index cd8a0d11058..bc95536134d 100644
--- a/src/common/hostlist.c
+++ b/src/common/hostlist.c
@@ -2979,6 +2979,30 @@ static int hostset_find_host(hostset_t set, const char *host)
 	return retval;
 }
 
+int hostset_intersects(hostset_t set, const char *hosts)
+{
+	int retval = 0;
+	hostlist_t hl;
+	char *hostname;
+
+	assert(set->hl->magic == HOSTLIST_MAGIC);
+
+	hl = hostlist_create(hosts);
+	if (!hl)    /* malloc failure */
+		return retval;
+
+	while ((hostname = hostlist_pop(hl)) != NULL) {
+		retval += hostset_find_host(set, hostname);
+		free(hostname);
+		if (retval)
+			break;
+	}
+
+	hostlist_destroy(hl);
+
+	return retval;
+}
+
 int hostset_within(hostset_t set, const char *hosts)
 {
 	int nhosts, nfound;
diff --git a/src/common/hostlist.h b/src/common/hostlist.h
index 49e2847d764..41a8501899e 100644
--- a/src/common/hostlist.h
+++ b/src/common/hostlist.h
@@ -40,6 +40,8 @@
 #ifndef _HOSTLIST_H
 #define _HOSTLIST_H
 
+#include <unistd.h>		/* load ssize_t definition */
+
 /* max size of internal hostrange buffer */
 #define MAXHOSTRANGELEN 8192
 
@@ -433,6 +435,12 @@ int hostset_insert(hostset_t set, const char *hosts);
  */
 int hostset_delete(hostset_t set, const char *hosts);
 
+/* hostset_intersects():
+ * Return 1 if any of the hosts specified by "hosts" are within the hostset "set"
+ * Return 0 if all host in "hosts" is not in the hostset "set"
+ */
+int hostset_intersects(hostset_t set, const char *hosts);
+
 /* hostset_within():
  * Return 1 if all hosts specified by "hosts" are within the hostset "set"
  * Retrun 0 if every host in "hosts" is not in the hostset "set"
@@ -444,6 +452,11 @@ int hostset_within(hostset_t set, const char *hosts);
  */
 char * hostset_shift(hostset_t set);
 
+/* hostset_pop():
+ * hostset equivalent to hostlist_pop()
+ */
+char *hostset_pop(hostset_t set);
+
 /* hostset_shift_range():
  * hostset eqivalent to hostlist_shift_range()
  */
@@ -465,4 +478,9 @@ int hostset_find(hostset_t set, const char *hostname);
 
 char * hostset_nth(hostset_t set, int n);
 
+/* hostset_ranged_string():
+ * hostset equivelent to hostlist_ranged_string();
+ */
+ssize_t hostset_ranged_string(hostset_t set, size_t n, char *buf);
+
 #endif /* !_HOSTLIST_H */
diff --git a/src/squeue/opts.c b/src/squeue/opts.c
index 8abdb3142b0..db18c23953e 100644
--- a/src/squeue/opts.c
+++ b/src/squeue/opts.c
@@ -64,7 +64,7 @@
 /* getopt_long options, integers but not characters */
 #define OPT_LONG_HELP  0x100
 #define OPT_LONG_USAGE 0x101
-#define OPT_LONG_HIDE	0x102
+#define OPT_LONG_HIDE  0x102
 
 /* FUNCTIONS */
 static List  _build_job_list( char* str );
@@ -92,7 +92,6 @@ parse_command_line( int argc, char* argv[] )
 	char *env_val = NULL;
 	int opt_char;
 	int option_index;
-	hostlist_t host_list;
 	static struct option long_options[] = {
 		{"all",        no_argument,       0, 'a'},
 		{"noheader",   no_argument,       0, 'h'},
@@ -100,6 +99,7 @@ parse_command_line( int argc, char* argv[] )
 		{"jobs",       optional_argument, 0, 'j'},
 		{"long",       no_argument,       0, 'l'},
 		{"node",       required_argument, 0, 'n'},
+		{"nodes",      required_argument, 0, 'n'},
 		{"format",     required_argument, 0, 'o'},
 		{"partitions", required_argument, 0, 'p'},
 		{"steps",      optional_argument, 0, 's'},
@@ -154,15 +154,15 @@ parse_command_line( int argc, char* argv[] )
 				params.long_list = true;
 				break;
 			case (int) 'n':
-				xfree(params.node);
-				params.node = xstrdup(optarg);
-				host_list = hostlist_create(params.node);
-				if (!host_list) {
-					error("'%s' invalid entry for --node",
-						optarg);
+				if (params.nodes)
+					hostset_destroy(params.nodes);
+
+				params.nodes = hostset_create(optarg);
+				if (params.nodes == NULL) {
+					error("'%s' invalid entry for --nodes",
+					      optarg);
 					exit(1);
 				}
-				hostlist_destroy(host_list);
 				break;
 			case (int) 'o':
 				xfree(params.format);
@@ -236,18 +236,36 @@ parse_command_line( int argc, char* argv[] )
 		exit(1);
 	}
 
-	if ( params.node ) {
+	if ( params.nodes ) {
 		char *name1 = NULL;
-		if (strcasecmp("localhost", params.node) == 0) {
-			xfree(params.node);
-			params.node = xmalloc(128);
-			gethostname_short(params.node, 128);
-		}
-		name1 = slurm_conf_get_nodename(params.node);
-		if (name1) {
-			xfree(params.node);
-			params.node = xstrdup(name1);
+		char *name2 = NULL;
+		hostset_t nodenames = hostset_create(NULL);
+		if (nodenames == NULL)
+			fatal("malloc failure");
+
+		while ( hostset_count(params.nodes) > 0 ) {
+			name1 = hostset_pop(params.nodes);
+			
+			/* localhost = use current host name */
+			if ( strcasecmp("localhost", name1) == 0 ) {
+				name2 = xmalloc(128);
+				gethostname_short(name2, 128);
+			} else {
+				/* translate NodeHostName to NodeName */
+				name2 = slurm_conf_get_nodename(name1);
+
+				/* use NodeName if translation failed */
+				if ( name2 == NULL )
+					name2 = xstrdup(name1);
+			}
+			hostset_insert(nodenames, name2);
+			free(name1);
+			xfree(name2);
 		}
+		
+		/* Replace params.nodename with the new one */
+		hostset_destroy(params.nodes);
+		params.nodes = nodenames;
 	}
 
 	if ( ( params.partitions == NULL ) && 
@@ -706,6 +724,9 @@ _print_options()
 	enum job_states *state_id;
 	squeue_job_step_t *job_step_id;
 	uint32_t *job_id;
+	char hostlist[8192];
+
+	hostset_ranged_string (params.nodes, sizeof(hostlist)-1, hostlist);
 
 	printf( "-----------------------------\n" );
 	printf( "all        = %s\n", params.all_flag ? "true" : "false");
@@ -714,7 +735,7 @@ _print_options()
 	printf( "job_flag   = %d\n", params.job_flag );
 	printf( "jobs       = %s\n", params.jobs );
 	printf( "max_procs  = %d\n", params.max_procs ) ;
-	printf( "node       = %s\n", params.node ) ;
+	printf( "nodes      = %s\n", hostlist ) ;
 	printf( "partitions = %s\n", params.partitions ) ;
 	printf( "sort       = %s\n", params.sort ) ;
 	printf( "states     = %s\n", params.states ) ;
@@ -994,7 +1015,7 @@ Usage: squeue [OPTIONS]\n\
   -j, --jobs                      comma separated list of jobs\n\
                                   to view, default is all\n\
   -l, --long                      long report\n\
-  -n, --node=node_name            name of single node to view, default is \n\
+  -n, --nodes=hostlist            list of nodes to view, default is \n\
                                   all nodes\n\
   -o, --format=format             format specification\n\
   -p, --partitions=partitions     comma separated list of partitions\n\
diff --git a/src/squeue/print.c b/src/squeue/print.c
index e26b55f9b6a..3256321ecf9 100644
--- a/src/squeue/print.c
+++ b/src/squeue/print.c
@@ -59,7 +59,6 @@ static int	_adjust_completing (job_info_t *j, node_info_msg_t **ni);
 static int	_filter_job(job_info_t * job);
 static int	_filter_step(job_step_info_t * step);
 static int	_get_node_cnt(job_info_t * job);
-static bool     _node_in_list(char *node_name, char *node_list);
 static int	_nodes_in_list(char *node_list);
 static int	_print_str(char *str, int width, bool right, bool cut_output);
 
@@ -783,18 +782,6 @@ static int _nodes_in_list(char *node_list)
 	return count;
 }
 
-static bool _node_in_list(char *node_name, char *node_list)
-{
-	bool rc;
-	hostset_t host_set = hostset_create(node_list);
-	if (hostset_within(host_set, node_name) == 0)
-		rc = false;
-	else
-		rc = true;
-	hostset_destroy(host_set);
-	return rc;
-}
-
 int _print_job_shared(job_info_t * job, int width, bool right_justify, 
 		      char* suffix)
 {
@@ -1315,8 +1302,9 @@ static int _filter_job(job_info_t * job)
 			return 4;
 	}
 
-	if ((params.node)
-	&&  (!_node_in_list(params.node, job->nodes)))
+	if ((params.nodes)
+	    && ((job->nodes == NULL)
+		|| (!hostset_intersects(params.nodes, job->nodes))))
 		return 5;
 
 	if (params.user_list) {
@@ -1389,8 +1377,9 @@ static int _filter_step(job_step_info_t * step)
 			return 3;
 	}
 
-	if ((params.node)
-	&&  (!_node_in_list(params.node, step->nodes)))
+	if ((params.nodes) 
+	    && ((step->nodes == NULL)
+		|| (!hostset_intersects(params.nodes, step->nodes))))
 		return 5;
 
 	if (params.user_list) {
diff --git a/src/squeue/squeue.h b/src/squeue/squeue.h
index 0227512ac46..0348806486a 100644
--- a/src/squeue/squeue.h
+++ b/src/squeue/squeue.h
@@ -84,7 +84,7 @@ struct squeue_parameters {
 	int  verbose;
 
 	char* jobs;
-	char* node;
+	hostset_t nodes;
 	char* partitions;
 	char* states;
 	char* steps;
-- 
GitLab