From 31eccd3b11940fb643d811f67cce995aaa4d7cf3 Mon Sep 17 00:00:00 2001
From: Don Lipari <lipari1@llnl.gov>
Date: Fri, 10 Jul 2009 23:02:54 +0000
Subject: [PATCH] Replaced misc cpu allocation members in job_info_t with
 select_job_res_t which will only be populated when (show_flags & SHOW_DETAIL)
 Added a --detail option to "scontrol show job" to display the cpu/mem
 allocation info on a node-by-node basis.

---
 doc/man/man1/scontrol.1          |   8 +++
 slurm/slurm.h.in                 |  11 +--
 src/api/job_info.c               | 111 +++++++++++++++++++++----------
 src/common/slurm_protocol_defs.c |   7 +-
 src/common/slurm_protocol_defs.h |   1 +
 src/common/slurm_protocol_pack.c |   8 +--
 src/scontrol/info_job.c          |   8 ++-
 src/scontrol/scontrol.c          |  26 +++++++-
 src/scontrol/scontrol.h          |   1 +
 src/slurmctld/job_mgr.c          |  25 ++++---
 src/slurmctld/proc_req.c         |   5 +-
 src/slurmctld/slurmctld.h        |   7 +-
 src/squeue/print.c               |  12 ++--
 src/squeue/squeue.c              |   5 +-
 14 files changed, 157 insertions(+), 78 deletions(-)

diff --git a/doc/man/man1/scontrol.1 b/doc/man/man1/scontrol.1
index ed6edc1a7a6..459af1351f4 100644
--- a/doc/man/man1/scontrol.1
+++ b/doc/man/man1/scontrol.1
@@ -29,6 +29,9 @@ and jobs steps. This causes information to be displayed about partitions
 that are configured as hidden and partitions that are unavailable to user's 
 group.
 .TP
+\fB\-d\fR, \fB\-\-detail\fR
+Causes the \fBshow\fR command to provide additional details where available.
+.TP
 \fB\-h\fR, \fB\-\-help\fR
 Print a help message describing the usage of scontrol.
 .TP
@@ -118,6 +121,11 @@ Delete the entry with the specified \fISPECIFICATION\fP.
 The two \fISPECIFICATION\fP choices are \fIPartitionName=<name>\fP
 and \fIReservation=<name>\fP
 
+.TP
+\fBdetail\fP
+Causes the \fIshow\fP command to provide additional details where available.
+(currently only for \fIshow job\fP).
+
 .TP
 \fBexit\fP
 Terminate the execution of scontrol.
diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in
index 7c3fad1cf65..42e84ef76fc 100644
--- a/slurm/slurm.h.in
+++ b/slurm/slurm.h.in
@@ -133,7 +133,7 @@ BEGIN_C_DECLS
    typedef struct switch_jobinfo *switch_jobinfo_t;	/* opaque data type */
 #endif
 
-/* Define select_jobinfo_t, select_nodeinfo_t below 
+/* Define select_job_res_t below
  * to avoid including extraneous slurm headers */
 #ifndef __select_job_res_t_defined
 #  define  __select_job_res_t_defined	/* Opaque data for select plugins */
@@ -460,6 +460,7 @@ enum node_states {
 /* Used as show_flags for slurm_get_ and slurm_load_ function calls.
  * Values can be can be ORed */
 #define SHOW_ALL	1	/* Show info for "hidden" partitions */
+#define SHOW_DETAIL	0x02	/* Show detailed resource information */
 
 /* Define keys for ctx_key argument of slurm_step_ctx_get() */
 enum ctx_keys {
@@ -660,8 +661,6 @@ typedef struct job_info {
 	char *command;		/* command to be executed */
 	char *comment;		/* arbitrary comment (used by Moab scheduler) */
 	uint16_t contiguous;	/* 1 if job requires contiguous nodes */
-	uint32_t *cpu_count_reps;/* how many nodes have same cpu count */
-	uint16_t *cpus_per_node;/* cpus per node */
 	uint16_t cpus_per_task;	/* number of processors required for each task */
 	char *dependency;	/* syncrhonize job execution with other jobs */
 	time_t end_time;	/* time of termination, actual or expected */
@@ -697,7 +696,6 @@ typedef struct job_info {
 	uint16_t ntasks_per_core;/* number of tasks to invoke on each core */
 	uint16_t ntasks_per_node;/* number of tasks to invoke on each node */
 	uint16_t ntasks_per_socket;/* number of tasks to invoke on each socket */
-	uint32_t num_cpu_groups;/* elements in cpu arrays below */
 
 	uint32_t num_nodes;	/* minimum number of nodes required by job */
 	uint32_t num_procs;	/* number of processors required by job */
@@ -714,6 +712,7 @@ typedef struct job_info {
 	char *resv_name;	/* reservation name */
 	select_jobinfo_t *select_jobinfo; /* opaque data type,
 				 * process using slurm_get_select_jobinfo() */
+	select_job_res_t select_job_res; /* job resources from select plugin */
 	uint16_t shared;	/* 1 if job can share nodes with other jobs */
 	time_t start_time;	/* time execution begins, actual or expected */
 	char *state_desc;	/* optional details for state_reason */
@@ -1804,10 +1803,12 @@ void slurm_print_key_pairs PARAMS((
  * slurm_load_job - issue RPC to get job information for one job ID
  * IN job_info_msg_pptr - place to store a job configuration pointer
  * IN job_id -  ID of job we want information about 
+ * IN show_flags - job filtering options
  * RET 0 or -1 on error
  * NOTE: free the response using slurm_free_job_info_msg
  */
-extern int slurm_load_job PARAMS((job_info_msg_t **resp, uint32_t job_id));
+extern int slurm_load_job PARAMS((job_info_msg_t **resp, uint32_t job_id,
+	uint16_t show_flags));
 
 /*
  * slurm_load_jobs - issue RPC to get slurm all job configuration  
diff --git a/src/api/job_info.c b/src/api/job_info.c
index fb85cc823d3..5ad6cb4d1da 100644
--- a/src/api/job_info.c
+++ b/src/api/job_info.c
@@ -125,12 +125,19 @@ slurm_print_job_info ( FILE* out, job_info_t * job_ptr, int one_liner )
 extern char *
 slurm_sprint_job_info ( job_info_t * job_ptr, int one_liner )
 {
-	int i, j;
+	bitstr_t	*core_bitmap;
+	int abs_node_inx, rel_node_inx;
+	int bit_inx, bit_reps;
+	int i, j, last;
+	int sock_inx, sock_reps;
 	char time_str[32], select_buf[122], *group_name, *user_name;
 	char tmp1[128], tmp2[128], *tmp3_ptr;
 	char tmp_line[512];
+	char *host;
 	char *ionodes = NULL;
+	hostlist_t hl;
 	uint16_t exit_status = 0, term_sig = 0;
+	select_job_res_t select_job_res = job_ptr->select_job_res;
 	char *out = NULL;
 	
 #ifdef HAVE_BG
@@ -272,47 +279,79 @@ slurm_sprint_job_info ( job_info_t * job_ptr, int one_liner )
 	xstrcat(out, tmp_line);
 #endif
 
-	if ((job_ptr->num_cpu_groups > 0) && 
-	    (job_ptr->cpus_per_node) &&
-	    (job_ptr->cpu_count_reps)) {
-		int length = 0;
-		xstrcat(out, "AllocCPUs=");
-		length += 10;
-		for (i = 0; i < job_ptr->num_cpu_groups; i++) {
-			if (length > 70) {
-				/* skip to last CPU group entry */
-			    	if (i < job_ptr->num_cpu_groups - 1) {
-			    		continue;
-				}
-				/* add elipsis before last entry */
-			    	xstrcat(out, "...,");
-				length += 4;
-			}
+	if (!select_job_res || !select_job_res->core_bitmap)
+		goto line7;
 
-			snprintf(tmp_line, sizeof(tmp_line),
-				"%d",
-				 job_ptr->cpus_per_node[i]);
-			xstrcat(out, tmp_line);
-			length += strlen(tmp_line);
-		    	if (job_ptr->cpu_count_reps[i] > 1) {
-				snprintf(tmp_line, sizeof(tmp_line),
-					"*%d",
-					 job_ptr->cpu_count_reps[i]);
-				xstrcat(out, tmp_line);
-				length += strlen(tmp_line);
-			}
-			if (i < job_ptr->num_cpu_groups - 1) {
-				xstrcat(out, ",");
-				length++;
-			}
+	bit_inx = bit_ffs(select_job_res->core_bitmap);
+	if (bit_inx == -1)
+		goto line7;
+
+	last  = bit_fls(select_job_res->core_bitmap);
+	if (last == -1)
+		goto line7;
+
+	hl = hostlist_create(job_ptr->nodes);
+	if (!hl) {
+		error("slurm_sprint_job_info: hostlist_create");
+		return NULL;
+	}
+
+	i = sock_inx = sock_reps = 0;
+	abs_node_inx = job_ptr->node_inx[i];
+
+	for (rel_node_inx=0; rel_node_inx < select_job_res->nhosts;
+	     rel_node_inx++) {
+
+		if (sock_reps >=
+		    select_job_res->sock_core_rep_count[sock_inx]) {
+			sock_inx++;
+			sock_reps = 0;
+		}
+		sock_reps++;
+
+		bit_reps = select_job_res->sockets_per_node[sock_inx] *
+			select_job_res->cores_per_socket[sock_inx];
+
+		core_bitmap = bit_alloc(bit_reps);
+		if (core_bitmap == NULL) {
+			error("bit_alloc malloc failure");
+			return NULL;
 		}
+
+		for (j=0; j < bit_reps; j++) {
+			if (bit_test(select_job_res->core_bitmap, bit_inx))
+				bit_set(core_bitmap, j);
+			bit_inx++;
+		}
+
+		bit_fmt(tmp1, sizeof(tmp1), core_bitmap);
+		bit_free(core_bitmap);
+		host = hostlist_shift(hl);
+		snprintf(tmp_line, sizeof(tmp_line),
+			 "Node=%s CPUs=%s Mem=%d", host, tmp1,
+			 select_job_res->memory_allocated ?
+			 select_job_res->memory_allocated[rel_node_inx] : 0);
+		xstrcat(out, tmp_line);
+		free(host);
+
 		if (one_liner)
 			xstrcat(out, " ");
 		else
 			xstrcat(out, "\n   ");
+
+		if (bit_inx > last)
+			break;
+
+		if (abs_node_inx > job_ptr->node_inx[i+1]) {
+			i += 2;
+			abs_node_inx = job_ptr->node_inx[i];
+		} else {
+			abs_node_inx++;
+		}
 	}
+	hostlist_destroy(hl);
 
-	/****** Line 7 ******/
+line7:	/****** Line 7 ******/
 	convert_num_unit((float)job_ptr->num_procs, tmp1, sizeof(tmp1), 
 			 UNIT_NONE);
 #ifdef HAVE_BG
@@ -632,11 +671,12 @@ slurm_load_jobs (time_t update_time, job_info_msg_t **resp,
  * slurm_load_job - issue RPC to get job information for one job ID
  * IN job_info_msg_pptr - place to store a job configuration pointer
  * IN job_id -  ID of job we want information about 
+ * IN show_flags -  job filtering options
  * RET 0 or -1 on error
  * NOTE: free the response using slurm_free_job_info_msg
  */
 extern int
-slurm_load_job (job_info_msg_t **resp, uint32_t job_id)
+slurm_load_job (job_info_msg_t **resp, uint32_t job_id, uint16_t show_flags)
 {
 	int rc;
 	slurm_msg_t resp_msg;
@@ -647,6 +687,7 @@ slurm_load_job (job_info_msg_t **resp, uint32_t job_id)
 	slurm_msg_t_init(&resp_msg);
 
 	req.job_id = job_id;
+	req.show_flags = show_flags;
 	req_msg.msg_type = REQUEST_JOB_INFO_SINGLE;
 	req_msg.data     = &req;
 
diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c
index fe201d73129..d54156e63a0 100644
--- a/src/common/slurm_protocol_defs.c
+++ b/src/common/slurm_protocol_defs.c
@@ -391,8 +391,6 @@ void slurm_free_job_info_members(job_info_t * job)
 		xfree(job->alloc_node);
 		xfree(job->command);
 		xfree(job->comment);
-		xfree(job->cpu_count_reps);
-		xfree(job->cpus_per_node);
 		xfree(job->dependency);
 		xfree(job->exc_nodes);
 		xfree(job->exc_node_inx);
@@ -403,10 +401,11 @@ void slurm_free_job_info_members(job_info_t * job)
 		xfree(job->node_inx);
 		xfree(job->nodes);
 		xfree(job->partition);
-		xfree(job->resv_name);
-		xfree(job->req_nodes);
 		xfree(job->req_node_inx);
+		xfree(job->req_nodes);
+		xfree(job->resv_name);
 		select_g_select_jobinfo_free(job->select_jobinfo);
+		free_select_job_res(&job->select_job_res);
 		xfree(job->state_desc);
 		xfree(job->wckey);
 		xfree(job->work_dir);
diff --git a/src/common/slurm_protocol_defs.h b/src/common/slurm_protocol_defs.h
index b73feeccb20..46019f43107 100644
--- a/src/common/slurm_protocol_defs.h
+++ b/src/common/slurm_protocol_defs.h
@@ -442,6 +442,7 @@ typedef struct job_notify_msg {
 
 typedef struct job_id_msg {
 	uint32_t job_id;
+	uint16_t show_flags;
 } job_id_msg_t;
 
 typedef struct job_step_id_msg {
diff --git a/src/common/slurm_protocol_pack.c b/src/common/slurm_protocol_pack.c
index faa60fec0ca..f6077a9d96f 100644
--- a/src/common/slurm_protocol_pack.c
+++ b/src/common/slurm_protocol_pack.c
@@ -2814,11 +2814,7 @@ _unpack_job_info_members(job_info_t * job, Buf buffer)
 	safe_unpackstr_xmalloc(&job->resv_name,  &uint32_tmp, buffer);
 
 	safe_unpack32(&job->exit_code, buffer);
-	safe_unpack32(&job->num_cpu_groups, buffer);
-	if (job->num_cpu_groups) {
-		safe_unpack16_array(&job->cpus_per_node, &uint32_tmp, buffer);
-		safe_unpack32_array(&job->cpu_count_reps, &uint32_tmp, buffer);
-	}
+	unpack_select_job_res(&job->select_job_res, buffer);
 
 	safe_unpackstr_xmalloc(&job->name, &uint32_tmp, buffer);
 	safe_unpackstr_xmalloc(&job->wckey, &uint32_tmp, buffer);
@@ -4871,6 +4867,7 @@ _pack_job_ready_msg(job_id_msg_t * msg, Buf buffer)
 	xassert ( msg != NULL );
 
 	pack32((uint32_t)msg->job_id  , buffer ) ;
+	pack16((uint16_t)msg->show_flags, buffer);
 }
 
 static int
@@ -4883,6 +4880,7 @@ _unpack_job_ready_msg(job_id_msg_t ** msg_ptr, Buf buffer)
 	*msg_ptr = msg ;
 
 	safe_unpack32(&msg->job_id  , buffer ) ;
+	safe_unpack16(&msg->show_flags, buffer);
 	return SLURM_SUCCESS;
 
 unpack_error:
diff --git a/src/scontrol/info_job.c b/src/scontrol/info_job.c
index 049936cf794..15062aa2d54 100644
--- a/src/scontrol/info_job.c
+++ b/src/scontrol/info_job.c
@@ -82,11 +82,15 @@ _scontrol_load_jobs(job_info_msg_t ** job_buffer_pptr, uint32_t job_id)
 	if (all_flag)
 		show_flags |= SHOW_ALL;
 
+	if (detail_flag)
+		show_flags |= SHOW_DETAIL;
+
 	if (old_job_info_ptr) {
 		if (last_show_flags != show_flags)
 			old_job_info_ptr->last_update = (time_t) 0;
 		if (job_id) {
-			error_code = slurm_load_job(&job_info_ptr, job_id);
+			error_code = slurm_load_job(&job_info_ptr, job_id,
+						    show_flags);
 		} else {
 			error_code = slurm_load_jobs(
 					old_job_info_ptr->last_update,
@@ -101,7 +105,7 @@ _scontrol_load_jobs(job_info_msg_t ** job_buffer_pptr, uint32_t job_id)
  				printf ("slurm_load_jobs no change in data\n");
 		}
 	} else if (job_id) {
-		error_code = slurm_load_job(&job_info_ptr, job_id);
+		error_code = slurm_load_job(&job_info_ptr, job_id, show_flags);
 	} else {
 		error_code = slurm_load_jobs((time_t) NULL, &job_info_ptr,
 					     show_flags);
diff --git a/src/scontrol/scontrol.c b/src/scontrol/scontrol.c
index dacbbcb0795..4728fa79fac 100644
--- a/src/scontrol/scontrol.c
+++ b/src/scontrol/scontrol.c
@@ -45,6 +45,7 @@
 
 char *command_name;
 int all_flag;		/* display even hidden partitions */
+int detail_flag;	/* display additional details */
 int exit_code;		/* scontrol's exit code, =1 on any error at any time */
 int exit_flag;		/* program to terminate if =1 */
 int input_words;	/* number of words of input permitted */
@@ -79,6 +80,7 @@ main (int argc, char *argv[])
 	int option_index;
 	static struct option long_options[] = {
 		{"all",      0, 0, 'a'},
+		{"details",  0, 0, 'd'},
 		{"help",     0, 0, 'h'},
 		{"hide",     0, 0, OPT_LONG_HIDE},
 		{"oneliner", 0, 0, 'o'},
@@ -91,6 +93,7 @@ main (int argc, char *argv[])
 
 	command_name      = argv[0];
 	all_flag          = 0;
+	detail_flag       = 0;
 	exit_code         = 0;
 	exit_flag         = 0;
 	input_field_count = 0;
@@ -101,7 +104,7 @@ main (int argc, char *argv[])
 	if (getenv ("SCONTROL_ALL"))
 		all_flag= 1;
 
-	while((opt_char = getopt_long(argc, argv, "ahoQvV",
+	while((opt_char = getopt_long(argc, argv, "adhoQvV",
 			long_options, &option_index)) != -1) {
 		switch (opt_char) {
 		case (int)'?':
@@ -112,12 +115,16 @@ main (int argc, char *argv[])
 		case (int)'a':
 			all_flag = 1;
 			break;
+		case (int)'d':
+			detail_flag = 1;
+			break;
 		case (int)'h':
 			_usage ();
 			exit(exit_code);
 			break;
 		case OPT_LONG_HIDE:
 			all_flag = 0;
+			detail_flag = 0;
 			break;
 		case (int)'o':
 			one_liner = 1;
@@ -517,6 +524,16 @@ if (strncasecmp (tag, "abort", MAX(taglen, 5)) == 0) {
 		}		
 		_create_it ((argc - 1), &argv[1]);
 	}
+	else if (strncasecmp (tag, "details", MAX(taglen, 1)) == 0) {
+		if (argc > 1) {
+			exit_code = 1;
+			fprintf (stderr,
+				 "too many arguments for keyword:%s\n", 
+				 tag);
+			return 0;
+		}
+		detail_flag = 1;
+	}
 	else if (strncasecmp (tag, "exit", MAX(taglen, 1)) == 0) {
 		if (argc > 1) {
 			exit_code = 1;
@@ -535,8 +552,10 @@ if (strncasecmp (tag, "abort", MAX(taglen, 5)) == 0) {
 		}
 		_usage ();
 	}
-	else if (strncasecmp (tag, "hide", MAX(taglen, 2)) == 0)
+	else if (strncasecmp (tag, "hide", MAX(taglen, 2)) == 0) {
 		all_flag = 0;
+		detail_flag = 0;
+	}
 	else if (strncasecmp (tag, "oneliner", MAX(taglen, 1)) == 0) {
 		if (argc > 1) {
 			exit_code = 1;
@@ -1256,6 +1275,7 @@ _usage () {
 scontrol [<OPTION>] [<COMMAND>]                                            \n\
     Valid <OPTION> values are:                                             \n\
      -a or --all: equivalent to \"all\" command                            \n\
+     -d or --details: equivalent to \"details\" command                    \n\
      -h or --help: equivalent to \"help\" command                          \n\
      --hide: equivalent to \"hide\" command                                \n\
      -o or --oneliner: equivalent to \"oneliner\" command                  \n\
@@ -1277,6 +1297,8 @@ scontrol [<OPTION>] [<COMMAND>]                                            \n\
      completing               display jobs in completing state along with  \n\
                               their completing or down nodes               \n\
      create <SPECIFICATIONS>  create a new partition or reservation        \n\
+     details                  evokes additional details from the \"show\"  \n\
+                              command                                      \n\
      delete <SPECIFICATIONS>  delete the specified partition or reservation\n\
      exit                     terminate scontrol                           \n\
      help                     print this description of use.               \n\
diff --git a/src/scontrol/scontrol.h b/src/scontrol/scontrol.h
index dd6344cb6e8..ad5d0ec607e 100644
--- a/src/scontrol/scontrol.h
+++ b/src/scontrol/scontrol.h
@@ -93,6 +93,7 @@
 
 extern char *command_name;
 extern int all_flag;	/* display even hidden partitions */
+extern int detail_flag;	/* display additional details */
 extern int exit_code;	/* scontrol's exit code, =1 on any error at any time */
 extern int exit_flag;	/* program to terminate if =1 */
 extern int input_words;	/* number of words of input permitted */
diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c
index 4bd5df0c806..1bff9ba6f05 100644
--- a/src/slurmctld/job_mgr.c
+++ b/src/slurmctld/job_mgr.c
@@ -4006,7 +4006,7 @@ extern void pack_all_jobs(char **buffer_ptr, int *buffer_size,
 		&&  (job_ptr->user_id != uid) && !validate_super_user(uid))
 			continue;
 
-		pack_job(job_ptr, buffer);
+		pack_job(job_ptr, show_flags, buffer);
 		jobs_packed++;
 	}
 	part_filter_clear();
@@ -4028,13 +4028,14 @@ extern void pack_all_jobs(char **buffer_ptr, int *buffer_size,
  * OUT buffer_ptr - the pointer is set to the allocated buffer.
  * OUT buffer_size - set to size of the buffer in bytes
  * IN job_id - ID of job that we want info for
+ * IN show_flags - job filtering options
  * IN uid - uid of user making request (for partition filtering)
  * NOTE: the buffer at *buffer_ptr must be xfreed by the caller
  * NOTE: change _unpack_job_desc_msg() in common/slurm_protocol_pack.c 
  *	whenever the data format changes
  */
 extern int pack_one_job(char **buffer_ptr, int *buffer_size,
-			 uint32_t job_id, uid_t uid)
+			uint32_t job_id, uint16_t show_flags, uid_t uid)
 {
 	ListIterator job_iterator;
 	struct job_record *job_ptr;
@@ -4063,7 +4064,7 @@ extern int pack_one_job(char **buffer_ptr, int *buffer_size,
 	buffer = init_buf(BUF_SIZE);
 	pack32(jobs_packed, buffer);
 	pack_time(time(NULL), buffer);
-	pack_job(job_ptr, buffer);
+	pack_job(job_ptr, show_flags, buffer);
 
 	*buffer_size = get_buf_offset(buffer);
 	buffer_ptr[0] = xfer_buf_data(buffer);
@@ -4074,12 +4075,13 @@ extern int pack_one_job(char **buffer_ptr, int *buffer_size,
  * pack_job - dump all configuration information about a specific job in 
  *	machine independent form (for network transmission)
  * IN dump_job_ptr - pointer to job for which information is requested
+ * IN show_flags - job filtering options
  * IN/OUT buffer - buffer in which data is placed, pointers automatically 
  *	updated
  * NOTE: change _unpack_job_info_members() in common/slurm_protocol_pack.c
  *	  whenever the data format changes
  */
-void pack_job(struct job_record *dump_job_ptr, Buf buffer)
+void pack_job(struct job_record *dump_job_ptr, uint16_t show_flags, Buf buffer)
 {
 	struct job_details *detail_ptr;
 
@@ -4123,15 +4125,12 @@ void pack_job(struct job_record *dump_job_ptr, Buf buffer)
 
 	pack32(dump_job_ptr->exit_code, buffer);
 
-	if (dump_job_ptr->select_job && 
-	    dump_job_ptr->select_job->cpu_array_cnt) {
-		pack32(dump_job_ptr->select_job->cpu_array_cnt, buffer);
-		pack16_array(dump_job_ptr->select_job->cpu_array_value,
-			     dump_job_ptr->select_job->cpu_array_cnt, buffer);
-		pack32_array(dump_job_ptr->select_job->cpu_array_reps,
-			     dump_job_ptr->select_job->cpu_array_cnt, buffer);
-	} else
-		pack32((uint32_t) 0, buffer);
+	if (show_flags & SHOW_DETAIL) {
+		pack_select_job_res(dump_job_ptr->select_job, buffer);
+	} else {
+		uint32_t empty = NO_VAL;
+		pack32(empty, buffer);
+	}
 
 	packstr(dump_job_ptr->name, buffer);
 	packstr(dump_job_ptr->wckey, buffer);
diff --git a/src/slurmctld/proc_req.c b/src/slurmctld/proc_req.c
index d65ec089e86..7c92cc893c3 100644
--- a/src/slurmctld/proc_req.c
+++ b/src/slurmctld/proc_req.c
@@ -845,7 +845,7 @@ static void _slurm_rpc_dump_job_single(slurm_msg_t * msg)
 	char *dump = NULL;
 	int dump_size, rc;
 	slurm_msg_t response_msg;
-	job_id_msg_t *job_info_request_msg = (job_id_msg_t *) msg->data;
+	job_id_msg_t *job_id_msg = (job_id_msg_t *) msg->data;
 	/* Locks: Read config job, write node (for hiding) */
 	slurmctld_lock_t job_read_lock = { 
 		READ_LOCK, READ_LOCK, NO_LOCK, WRITE_LOCK };
@@ -856,7 +856,8 @@ static void _slurm_rpc_dump_job_single(slurm_msg_t * msg)
 		(unsigned int) uid);
 	lock_slurmctld(job_read_lock);
 
-	rc = pack_one_job(&dump, &dump_size, job_info_request_msg->job_id,
+	rc = pack_one_job(&dump, &dump_size, job_id_msg->job_id,
+			  job_id_msg->show_flags,
 			  g_slurm_auth_get_uid(msg->auth_cred, NULL));
 	unlock_slurmctld(job_read_lock);
 	END_TIMER2("_slurm_rpc_dump_job_single");
diff --git a/src/slurmctld/slurmctld.h b/src/slurmctld/slurmctld.h
index 805a84c4b28..c1c2af149be 100644
--- a/src/slurmctld/slurmctld.h
+++ b/src/slurmctld/slurmctld.h
@@ -1374,12 +1374,14 @@ extern void pack_all_part(char **buffer_ptr, int *buffer_size,
  * pack_job - dump all configuration information about a specific job in 
  *	machine independent form (for network transmission)
  * IN dump_job_ptr - pointer to job for which information is requested
+ * IN show_flags - job filtering options
  * IN/OUT buffer - buffer in which data is placed, pointers automatically 
  *	updated
  * NOTE: change _unpack_job_desc_msg() in common/slurm_protocol_pack.c
  *	  whenever the data format changes
  */
-extern void pack_job (struct job_record *dump_job_ptr, Buf buffer);
+extern void pack_job (struct job_record *dump_job_ptr, uint16_t show_flags,
+		      Buf buffer);
 
 /* 
  * pack_part - dump all configuration information about a specific partition 
@@ -1399,13 +1401,14 @@ extern void pack_part (struct part_record *part_ptr, Buf buffer);
  * OUT buffer_ptr - the pointer is set to the allocated buffer.
  * OUT buffer_size - set to size of the buffer in bytes
  * IN job_id - ID of job that we want info for
+ * IN show_flags - job filtering options
  * IN uid - uid of user making request (for partition filtering)
  * NOTE: the buffer at *buffer_ptr must be xfreed by the caller
  * NOTE: change _unpack_job_desc_msg() in common/slurm_protocol_pack.c 
  *	whenever the data format changes
  */
 extern int pack_one_job(char **buffer_ptr, int *buffer_size,
-			 uint32_t job_id, uid_t uid);
+			uint32_t job_id, uint16_t show_flags, uid_t uid);
 
 /* part_filter_clear - Clear the partition's hidden flag based upon a user's
  * group access. This must follow a call to part_filter_set() */
diff --git a/src/squeue/print.c b/src/squeue/print.c
index 490e2e65177..f70c8907946 100644
--- a/src/squeue/print.c
+++ b/src/squeue/print.c
@@ -644,13 +644,13 @@ int _print_job_num_procs(job_info_t * job, int width, bool right, char* suffix)
 	if (job == NULL)	/* Print the Header instead */
 		_print_str("CPUS", width, right, true);
 	else {
-		if ((job->num_cpu_groups > 0) &&
-		    (job->cpus_per_node) &&
-		    (job->cpu_count_reps)) {
+		if ((job->select_job_res->cpu_array_cnt > 0) &&
+		    (job->select_job_res->cpu_array_value) &&
+		    (job->select_job_res->cpu_array_reps)) {
 			uint32_t cnt = 0, i;
-			for (i=0; i<job->num_cpu_groups; i++) {
-				cnt += job->cpus_per_node[i] * 
-				       job->cpu_count_reps[i];
+			for (i=0; i<job->select_job_res->cpu_array_cnt; i++) {
+				cnt += job->select_job_res->cpu_array_value[i] *
+				       job->select_job_res->cpu_array_reps[i];
 			}
 			convert_num_unit((float)cnt, tmp_char, 
 					 sizeof(tmp_char), UNIT_NONE);
diff --git a/src/squeue/squeue.c b/src/squeue/squeue.c
index 53fce97b4f0..f6892860036 100644
--- a/src/squeue/squeue.c
+++ b/src/squeue/squeue.c
@@ -151,7 +151,8 @@ _print_job ( void )
 
 	if (old_job_ptr) {
 		if (job_id) {
-			error_code = slurm_load_job(&new_job_ptr, job_id);
+			error_code = slurm_load_job(&new_job_ptr, job_id,
+						    show_flags);
 		} else {
 			error_code = slurm_load_jobs(old_job_ptr->last_update,
 						     &new_job_ptr, show_flags);
@@ -163,7 +164,7 @@ _print_job ( void )
 			new_job_ptr = old_job_ptr;
 		}
 	} else if (job_id) {
-		error_code = slurm_load_job(&new_job_ptr, job_id);
+		error_code = slurm_load_job(&new_job_ptr, job_id, show_flags);
 	} else {
 		error_code = slurm_load_jobs((time_t) NULL, &new_job_ptr,
 				show_flags);
-- 
GitLab