From 9227daff218ea2acb54d3b98ff97f3c777e53f15 Mon Sep 17 00:00:00 2001
From: Danny Auble <da@llnl.gov>
Date: Fri, 10 Nov 2006 22:16:36 +0000
Subject: [PATCH] added configurable images for block creation (No real
 documentation yet)

---
 NEWS                                          |   3 +-
 slurm/slurm.h.in                              |  17 +-
 src/api/init_msg.c                            |   4 +
 src/api/job_info.c                            |  57 ++++-
 src/api/node_select_info.h                    |   4 +
 src/common/node_select.c                      | 232 +++++++++++++-----
 src/common/slurm_protocol_defs.c              |   4 +
 src/common/slurm_protocol_pack.c              |  20 ++
 .../block_allocator/block_allocator.c         | 110 ++++++++-
 .../block_allocator/block_allocator.h         |  26 +-
 .../select/bluegene/plugin/bg_block_info.c    |   4 +
 .../select/bluegene/plugin/bg_job_place.c     |  80 +++++-
 .../select/bluegene/plugin/block_sys.c        |   8 +-
 src/plugins/select/bluegene/plugin/bluegene.c | 164 +++++++++++--
 src/plugins/select/bluegene/plugin/bluegene.h |   8 +
 src/sbatch/opt.c                              |  64 ++++-
 src/sbatch/opt.h                              |   9 +-
 src/sbatch/sbatch.c                           |  11 +-
 src/slurmctld/job_mgr.c                       |   8 +
 src/srun/allocate.c                           |  11 +-
 src/srun/opt.c                                |  60 ++++-
 src/srun/opt.h                                |  12 +-
 22 files changed, 794 insertions(+), 122 deletions(-)

diff --git a/NEWS b/NEWS
index 1214df39a4f..6397e03dbe8 100644
--- a/NEWS
+++ b/NEWS
@@ -3,7 +3,8 @@ documents those changes that are of interest to users and admins.
 
 * Changes in SLURM 1.2.0-pre7
 =============================
-
+ -- BLUEGENE - added configurable images for bluegene block creation.
+    (No documentation out side of srun and sbatch just yet)
 
 * Changes in SLURM 1.2.0-pre6
 =============================
diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in
index 10ec82cbb5c..e4016689f7f 100644
--- a/slurm/slurm.h.in
+++ b/slurm/slurm.h.in
@@ -223,7 +223,11 @@ enum select_data_type {
 	SELECT_DATA_NODECARD,	/* data-> uint16_t nodecard */
 	SELECT_DATA_NODE_CNT,	/* data-> uint32_t node_cnt */
 	SELECT_DATA_ALTERED,    /* data-> uint16_t altered */
-	SELECT_DATA_MAX_PROCS	/* data-> uint32_t max_procs */
+	SELECT_DATA_MAX_PROCS,	/* data-> uint32_t max_procs */
+	SELECT_DATA_BLRTS_IMAGE,/* data-> char blrtsimage */
+	SELECT_DATA_LINUX_IMAGE,/* data-> char linuximage */
+	SELECT_DATA_MLOADER_IMAGE,/* data-> char mloaderimage */
+	SELECT_DATA_RAMDISK_IMAGE/* data-> char ramdiskimage */
 };
 
 enum select_print_mode {
@@ -235,7 +239,11 @@ enum select_print_mode {
 	SELECT_PRINT_ROTATE,    /* Print just the ROTATE */
 	SELECT_PRINT_GEOMETRY,	/* Print just the GEO */
 	SELECT_PRINT_START,	/* Print just the START location */
-	SELECT_PRINT_MAX_PROCS  /* Print just the MAX PROCS */
+	SELECT_PRINT_MAX_PROCS,  /* Print just the MAX PROCS */
+	SELECT_PRINT_BLRTS_IMAGE,/* Print just the BLRTS IMAGE */
+	SELECT_PRINT_LINUX_IMAGE,/* Print just the LINUX IMAGE */
+	SELECT_PRINT_MLOADER_IMAGE,/* Print just the MLOADER IMAGE */
+	SELECT_PRINT_RAMDISK_IMAGE/* Print just the RAMDISK IMAGE */
 };
 
 enum select_node_cnt {
@@ -491,6 +499,11 @@ typedef struct job_descriptor {	/* For submit, allocate, and update requests */
 #endif
 	uint16_t conn_type;	/* see enum connection_type */
 	uint16_t rotate;	/* permit geometry rotation if set */
+	char *blrtsimage;       /* BlrtsImage for block */
+	char *linuximage;       /* LinuxImage for block */
+	char *mloaderimage;     /* mloaderImage for block */
+	char *ramdiskimage;     /* RamDiskImage for block */
+
 /* End of Blue Gene specific values */
 
 	select_jobinfo_t select_jobinfo; /* opaque data type,
diff --git a/src/api/init_msg.c b/src/api/init_msg.c
index beaf6928ced..9057c9b2376 100644
--- a/src/api/init_msg.c
+++ b/src/api/init_msg.c
@@ -129,6 +129,10 @@ void slurm_init_job_desc_msg(job_desc_msg_t * job_desc_msg)
 #endif
 	job_desc_msg->conn_type   = (uint16_t) NO_VAL;
 	job_desc_msg->rotate      = (uint16_t) NO_VAL;
+	job_desc_msg->blrtsimage = NULL;
+	job_desc_msg->linuximage = NULL;
+	job_desc_msg->mloaderimage = NULL;
+	job_desc_msg->ramdiskimage = NULL;
 	job_desc_msg->select_jobinfo = NULL;
 }
 
diff --git a/src/api/job_info.c b/src/api/job_info.c
index e9fb4d1d7cd..e2074b87ab4 100644
--- a/src/api/job_info.c
+++ b/src/api/job_info.c
@@ -123,7 +123,7 @@ extern char *
 slurm_sprint_job_info ( job_info_t * job_ptr, int one_liner )
 {
 	int i, j;
-	char time_str[32], select_buf[128];
+	char time_str[32], select_buf[122];
 	struct group *group_info = NULL;
 	char tmp1[128], tmp2[128];
 	char tmp_line[128];
@@ -444,7 +444,8 @@ slurm_sprint_job_info ( job_info_t * job_ptr, int one_liner )
 
 	/****** Line 16 (optional) ******/
 	select_g_sprint_jobinfo(job_ptr->select_jobinfo,
-		select_buf, sizeof(select_buf), SELECT_PRINT_MIXED);
+				select_buf, sizeof(select_buf),
+				SELECT_PRINT_MIXED);
 	if (select_buf[0] != '\0') {
 		if (one_liner)
 			xstrcat(out, " ");
@@ -452,6 +453,58 @@ slurm_sprint_job_info ( job_info_t * job_ptr, int one_liner )
 			xstrcat(out, "\n   ");
 		xstrcat(out, select_buf);
 	}
+	/****** Line 17 (optional) ******/
+	select_g_sprint_jobinfo(job_ptr->select_jobinfo,
+				select_buf, sizeof(select_buf),
+				SELECT_PRINT_BLRTS_IMAGE);
+	if (select_buf[0] != '\0') {
+		if (one_liner)
+			xstrcat(out, " ");
+		else
+			xstrcat(out, "\n   ");
+		snprintf(tmp_line, sizeof(tmp_line),
+			 "BlrtsImage=%s", select_buf);
+		xstrcat(out, tmp_line);
+	}
+	/****** Line 18 (optional) ******/
+	select_g_sprint_jobinfo(job_ptr->select_jobinfo,
+				select_buf, sizeof(select_buf),
+				SELECT_PRINT_LINUX_IMAGE);
+	if (select_buf[0] != '\0') {
+		if (one_liner)
+			xstrcat(out, " ");
+		else
+			xstrcat(out, "\n   ");
+		snprintf(tmp_line, sizeof(tmp_line),
+			 "LinuxImage=%s", select_buf);
+		xstrcat(out, tmp_line);
+	}
+	/****** Line 19 (optional) ******/
+	select_g_sprint_jobinfo(job_ptr->select_jobinfo,
+				select_buf, sizeof(select_buf),
+				SELECT_PRINT_MLOADER_IMAGE);
+	if (select_buf[0] != '\0') {
+		if (one_liner)
+			xstrcat(out, " ");
+		else
+			xstrcat(out, "\n   ");
+		snprintf(tmp_line, sizeof(tmp_line),
+			 "MloaderImage=%s", select_buf);
+		xstrcat(out, tmp_line);
+	}
+	/****** Line 20 (optional) ******/
+	select_g_sprint_jobinfo(job_ptr->select_jobinfo,
+				select_buf, sizeof(select_buf),
+				SELECT_PRINT_RAMDISK_IMAGE);
+	if (select_buf[0] != '\0') {
+		if (one_liner)
+			xstrcat(out, " ");
+		else
+			xstrcat(out, "\n   ");
+		snprintf(tmp_line, sizeof(tmp_line),
+			 "RamDiskImage=%s", select_buf);
+		xstrcat(out, tmp_line);
+	}
 	xstrcat(out, "\n\n");
 
 	return out;
diff --git a/src/api/node_select_info.h b/src/api/node_select_info.h
index 61d5b5df806..4306f9949a7 100644
--- a/src/api/node_select_info.h
+++ b/src/api/node_select_info.h
@@ -60,6 +60,10 @@ typedef struct {
 	int *bp_inx;            /* list index pairs into node_table for *nodes:
 				 * start_range_1, end_range_1,
 				 * start_range_2, .., -1  */
+	char *blrtsimage;       /* BlrtsImage for this block */
+	char *linuximage;       /* LinuxImage for this block */
+	char *mloaderimage;     /* mloaderImage for this block */
+	char *ramdiskimage;     /* RamDiskImage for this block */
 } bg_info_record_t;
 
 typedef struct {
diff --git a/src/common/node_select.c b/src/common/node_select.c
index 38fb3ac2880..13b875d1c05 100644
--- a/src/common/node_select.c
+++ b/src/common/node_select.c
@@ -138,15 +138,19 @@ struct select_jobinfo {
 	uint16_t altered;       /* see if we have altered this job 
 				 * or not yet */
 	uint32_t max_procs;	/* maximum processors to use */
+	char *blrtsimage;       /* BlrtsImage for this block */
+	char *linuximage;       /* LinuxImage for this block */
+	char *mloaderimage;     /* mloaderImage for this block */
+	char *ramdiskimage;     /* RamDiskImage for this block */
 };
 #endif
 
 /*
  * Local functions
  */
+static slurm_select_ops_t *_select_get_ops(slurm_select_context_t *c);
 static slurm_select_context_t *_select_context_create(const char *select_type);
 static int _select_context_destroy(slurm_select_context_t *c);
-static slurm_select_ops_t *_select_get_ops(slurm_select_context_t *c);
 
 /*
  * Locate and load the appropriate plugin
@@ -392,7 +396,8 @@ extern int select_g_get_extra_jobinfo (struct node_record *node_ptr,
 /* 
  * Get select data from a specific node record
  * IN node_pts  - current node record
- * IN cr_info   - type of data to get from the node record (see enum select_data_info)
+ * IN cr_info   - type of data to get from the node record 
+ *                (see enum select_data_info)
  * IN/OUT data  - the data to get from node record
  */
 extern int select_g_get_select_nodeinfo (struct node_record *node_ptr, 
@@ -579,6 +584,69 @@ extern int select_g_pack_node_info(time_t last_query_time, Buf *buffer)
 }
 
 #ifdef HAVE_BG		/* node selection specific logic */
+static void _free_node_info(bg_info_record_t *bg_info_record)
+{
+	xfree(bg_info_record->nodes);
+	xfree(bg_info_record->owner_name);
+	xfree(bg_info_record->bg_block_id);
+	xfree(bg_info_record->bp_inx);
+	xfree(bg_info_record->blrtsimage);
+	xfree(bg_info_record->linuximage);
+	xfree(bg_info_record->mloaderimage);
+	xfree(bg_info_record->ramdiskimage);
+}
+
+/* NOTE: The matching pack functions are directly in the select/bluegene 
+ * plugin. The unpack functions can not be there since the plugin is 
+ * dependent upon libraries which do not exist on the BlueGene front-end 
+ * nodes. */
+static int _unpack_node_info(bg_info_record_t *bg_info_record, Buf buffer)
+{
+	uint16_t uint16_tmp;
+	uint32_t uint32_tmp;
+	char *bp_inx_str;
+	
+	safe_unpackstr_xmalloc(&(bg_info_record->nodes), &uint16_tmp, buffer);
+	safe_unpackstr_xmalloc(&bg_info_record->owner_name, &uint16_tmp, 
+			       buffer);
+	safe_unpackstr_xmalloc(&bg_info_record->bg_block_id, &uint16_tmp, 
+			       buffer);
+
+	safe_unpack16(&uint16_tmp, buffer);
+	bg_info_record->state     = (int) uint16_tmp;
+	safe_unpack16(&uint16_tmp, buffer);
+	bg_info_record->conn_type = (int) uint16_tmp;
+	safe_unpack16(&uint16_tmp, buffer);
+	bg_info_record->node_use = (int) uint16_tmp;
+	safe_unpack16(&uint16_tmp, buffer);
+	bg_info_record->quarter = (int) uint16_tmp;
+	safe_unpack16(&uint16_tmp, buffer);
+	bg_info_record->nodecard = (int) uint16_tmp;
+	safe_unpack32(&uint32_tmp, buffer);
+	bg_info_record->node_cnt = (int) uint32_tmp;
+	safe_unpackstr_xmalloc(&bp_inx_str, &uint16_tmp, buffer);
+	if (bp_inx_str == NULL) {
+		bg_info_record->bp_inx = bitfmt2int("");
+	} else {
+		bg_info_record->bp_inx = bitfmt2int(bp_inx_str);
+		xfree(bp_inx_str);
+	}
+	safe_unpackstr_xmalloc(&bg_info_record->blrtsimage, &uint16_tmp, 
+			       buffer);
+	safe_unpackstr_xmalloc(&bg_info_record->linuximage, &uint16_tmp, 
+			       buffer);
+	safe_unpackstr_xmalloc(&bg_info_record->mloaderimage, &uint16_tmp, 
+			       buffer);
+	safe_unpackstr_xmalloc(&bg_info_record->ramdiskimage, &uint16_tmp, 
+			       buffer);
+
+	return SLURM_SUCCESS;
+
+unpack_error:
+	_free_node_info(bg_info_record);
+	return SLURM_ERROR;
+}
+
 static char *_job_conn_type_string(uint16_t inx)
 {
 	if (inx == SELECT_TORUS)
@@ -625,7 +693,11 @@ extern int select_g_alloc_jobinfo (select_jobinfo_t *jobinfo)
 	(*jobinfo)->nodecard = (uint16_t) NO_VAL;
 	(*jobinfo)->node_cnt = NO_VAL;
 	(*jobinfo)->max_procs =  NO_VAL;
-	
+	(*jobinfo)->blrtsimage = NULL;
+	(*jobinfo)->linuximage = NULL;
+	(*jobinfo)->mloaderimage = NULL;
+	(*jobinfo)->ramdiskimage = NULL;
+
 	return SLURM_SUCCESS;
 }
 
@@ -689,6 +761,26 @@ extern int select_g_set_jobinfo (select_jobinfo_t jobinfo,
 	case SELECT_DATA_MAX_PROCS:
 		jobinfo->max_procs = *uint32;
 		break;
+	case SELECT_DATA_BLRTS_IMAGE:
+		/* we xfree() any preset value to avoid a memory leak */
+		xfree(jobinfo->blrtsimage);
+		jobinfo->blrtsimage = xstrdup(tmp_char);
+		break;
+	case SELECT_DATA_LINUX_IMAGE:
+		/* we xfree() any preset value to avoid a memory leak */
+		xfree(jobinfo->linuximage);
+		jobinfo->linuximage = xstrdup(tmp_char);
+		break;
+	case SELECT_DATA_MLOADER_IMAGE:
+		/* we xfree() any preset value to avoid a memory leak */
+		xfree(jobinfo->mloaderimage);
+		jobinfo->mloaderimage = xstrdup(tmp_char);
+		break;
+	case SELECT_DATA_RAMDISK_IMAGE:
+		/* we xfree() any preset value to avoid a memory leak */
+		xfree(jobinfo->ramdiskimage);
+		jobinfo->ramdiskimage = xstrdup(tmp_char);
+		break;	
 	default:
 		debug("select_g_set_jobinfo data_type %d invalid", 
 		      data_type);
@@ -762,6 +854,34 @@ extern int select_g_get_jobinfo (select_jobinfo_t jobinfo,
 	case SELECT_DATA_MAX_PROCS:
 		*uint32 = jobinfo->max_procs;
 		break;
+	case SELECT_DATA_BLRTS_IMAGE:
+		if ((jobinfo->blrtsimage == NULL)
+		    ||  (jobinfo->blrtsimage[0] == '\0'))
+			*tmp_char = NULL;
+		else
+			*tmp_char = xstrdup(jobinfo->blrtsimage);
+		break;
+	case SELECT_DATA_LINUX_IMAGE:
+		if ((jobinfo->linuximage == NULL)
+		    ||  (jobinfo->linuximage[0] == '\0'))
+			*tmp_char = NULL;
+		else
+			*tmp_char = xstrdup(jobinfo->linuximage);
+		break;
+	case SELECT_DATA_MLOADER_IMAGE:
+		if ((jobinfo->mloaderimage == NULL)
+		    ||  (jobinfo->mloaderimage[0] == '\0'))
+			*tmp_char = NULL;
+		else
+			*tmp_char = xstrdup(jobinfo->mloaderimage);
+		break;
+	case SELECT_DATA_RAMDISK_IMAGE:
+		if ((jobinfo->ramdiskimage == NULL)
+		    ||  (jobinfo->ramdiskimage[0] == '\0'))
+			*tmp_char = NULL;
+		else
+			*tmp_char = xstrdup(jobinfo->ramdiskimage);
+		break;
 	default:
 		debug("select_g_get_jobinfo data_type %d invalid", 
 		      data_type);
@@ -802,6 +922,11 @@ extern select_jobinfo_t select_g_copy_jobinfo(select_jobinfo_t jobinfo)
 		rc->node_cnt = jobinfo->node_cnt;
 		rc->altered = jobinfo->altered;
 		rc->max_procs = jobinfo->max_procs;
+		rc->blrtsimage = xstrdup(jobinfo->blrtsimage);
+		rc->linuximage = xstrdup(jobinfo->linuximage);
+		rc->mloaderimage = xstrdup(jobinfo->mloaderimage);
+		rc->ramdiskimage = xstrdup(jobinfo->ramdiskimage);
+		
 	}
 
 	return rc;
@@ -823,6 +948,10 @@ extern int select_g_free_jobinfo  (select_jobinfo_t *jobinfo)
 	} else {
 		(*jobinfo)->magic = 0;
 		xfree((*jobinfo)->bg_block_id);
+		xfree((*jobinfo)->blrtsimage);
+		xfree((*jobinfo)->linuximage);
+		xfree((*jobinfo)->mloaderimage);
+		xfree((*jobinfo)->ramdiskimage);
 		xfree(*jobinfo);
 	}
 	return rc;
@@ -851,12 +980,20 @@ extern int  select_g_pack_jobinfo  (select_jobinfo_t jobinfo, Buf buffer)
 		pack32((uint32_t)jobinfo->node_cnt, buffer);
 		pack32((uint32_t)jobinfo->max_procs, buffer);
 		packstr(jobinfo->bg_block_id, buffer);
+		packstr(jobinfo->blrtsimage, buffer);
+		packstr(jobinfo->linuximage, buffer);
+		packstr(jobinfo->mloaderimage, buffer);
+		packstr(jobinfo->ramdiskimage, buffer);
 	} else {
 		for (i=0; i<((SYSTEM_DIMENSIONS*2)+4); i++)
 			pack16((uint16_t) 0, buffer);
 		pack32((uint32_t) 0, buffer);
 		pack32((uint32_t) 0, buffer);
 		packstr("", buffer);
+		packstr("", buffer);
+		packstr("", buffer);
+		packstr("", buffer);
+		packstr("", buffer);
 	}
 
 	return SLURM_SUCCESS;
@@ -884,6 +1021,11 @@ extern int  select_g_unpack_jobinfo(select_jobinfo_t jobinfo, Buf buffer)
 	safe_unpack32(&(jobinfo->node_cnt), buffer);
 	safe_unpack32(&(jobinfo->max_procs), buffer);
 	safe_unpackstr_xmalloc(&(jobinfo->bg_block_id), &uint16_tmp, buffer);
+	safe_unpackstr_xmalloc(&(jobinfo->blrtsimage), &uint16_tmp, buffer);
+	safe_unpackstr_xmalloc(&(jobinfo->linuximage), &uint16_tmp, buffer);
+	safe_unpackstr_xmalloc(&(jobinfo->mloaderimage), &uint16_tmp, buffer);
+	safe_unpackstr_xmalloc(&(jobinfo->ramdiskimage), &uint16_tmp, buffer);
+
 	return SLURM_SUCCESS;
 
       unpack_error:
@@ -898,12 +1040,13 @@ extern int  select_g_unpack_jobinfo(select_jobinfo_t jobinfo, Buf buffer)
  * RET        - the string, same as buf
  */
 extern char *select_g_sprint_jobinfo(select_jobinfo_t jobinfo,
-		char *buf, size_t size, int mode)
+				     char *buf, size_t size, int mode)
 {
 	uint16_t geometry[SYSTEM_DIMENSIONS];
 	int i;
 	char max_procs_char[7], start_char[32];
-
+	char *tmp_image = "default";
+		
 	if (buf == NULL) {
 		error("select_g_sprint_jobinfo: buf is null");
 		return NULL;
@@ -967,6 +1110,7 @@ extern char *select_g_sprint_jobinfo(select_jobinfo_t jobinfo,
 				"%1ux%1ux%1u", jobinfo->start[0],
 				jobinfo->start[1], jobinfo->start[2]);
 		}
+		
 		snprintf(buf, size, 
 			 "Connection=%s Rotate=%s MaxProcs=%s "
 			 "Geometry=%1ux%1ux%1u Start=%s Block_ID=%s",
@@ -993,9 +1137,9 @@ extern char *select_g_sprint_jobinfo(select_jobinfo_t jobinfo,
 		break;
 	case SELECT_PRINT_START:
 		if (jobinfo->start[0] == (uint16_t) NO_VAL)
-			sprintf(start_char, "None");
+			sprintf(buf, "None");
 		else {
-			snprintf(start_char, sizeof(start_char), 
+			snprintf(buf, size, 
 				 "%1ux%1ux%1u", jobinfo->start[0],
 				 jobinfo->start[1], jobinfo->start[2]);
 		} 
@@ -1008,7 +1152,26 @@ extern char *select_g_sprint_jobinfo(select_jobinfo_t jobinfo,
 		
 		snprintf(buf, size, "%s", max_procs_char);
 		break;
-		
+	case SELECT_PRINT_BLRTS_IMAGE:
+		if(jobinfo->blrtsimage)
+			tmp_image = jobinfo->blrtsimage;
+		snprintf(buf, size, "%s", tmp_image);		
+		break;
+	case SELECT_PRINT_LINUX_IMAGE:
+		if(jobinfo->linuximage)
+			tmp_image = jobinfo->linuximage;
+		snprintf(buf, size, "%s", tmp_image);		
+		break;
+	case SELECT_PRINT_MLOADER_IMAGE:
+		if(jobinfo->mloaderimage)
+			tmp_image = jobinfo->mloaderimage;
+		snprintf(buf, size, "%s", tmp_image);		
+		break;
+	case SELECT_PRINT_RAMDISK_IMAGE:
+		if(jobinfo->ramdiskimage)
+			tmp_image = jobinfo->ramdiskimage;
+		snprintf(buf, size, "%s", tmp_image);		
+		break;		
 	default:
 		error("select_g_sprint_jobinfo: bad mode %d", mode);
 		if (size > 0)
@@ -1018,59 +1181,6 @@ extern char *select_g_sprint_jobinfo(select_jobinfo_t jobinfo,
 	return buf;
 }
 
-/* NOTE: The matching pack functions are directly in the select/bluegene 
- * plugin. The unpack functions can not be there since the plugin is 
- * dependent upon libraries which do not exist on the BlueGene front-end 
- * nodes. */
-static int _unpack_node_info(bg_info_record_t *bg_info_record, Buf buffer)
-{
-	uint16_t uint16_tmp;
-	uint32_t uint32_tmp;
-	char *bp_inx_str;
-	
-	safe_unpackstr_xmalloc(&(bg_info_record->nodes), &uint16_tmp, buffer);
-	safe_unpackstr_xmalloc(&bg_info_record->owner_name, &uint16_tmp, 
-		buffer);
-	safe_unpackstr_xmalloc(&bg_info_record->bg_block_id, &uint16_tmp, 
-		buffer);
-
-	safe_unpack16(&uint16_tmp, buffer);
-	bg_info_record->state     = (int) uint16_tmp;
-	safe_unpack16(&uint16_tmp, buffer);
-	bg_info_record->conn_type = (int) uint16_tmp;
-	safe_unpack16(&uint16_tmp, buffer);
-	bg_info_record->node_use = (int) uint16_tmp;
-	safe_unpack16(&uint16_tmp, buffer);
-	bg_info_record->quarter = (int) uint16_tmp;
-	safe_unpack16(&uint16_tmp, buffer);
-	bg_info_record->nodecard = (int) uint16_tmp;
-	safe_unpack32(&uint32_tmp, buffer);
-	bg_info_record->node_cnt = (int) uint32_tmp;
-	safe_unpackstr_xmalloc(&bp_inx_str, &uint16_tmp, buffer);
-	if (bp_inx_str == NULL) {
-		bg_info_record->bp_inx = bitfmt2int("");
-	} else {
-		bg_info_record->bp_inx = bitfmt2int(bp_inx_str);
-		xfree(bp_inx_str);
-	}
-		
-	return SLURM_SUCCESS;
-
-unpack_error:
-	xfree(bg_info_record->nodes);
-	xfree(bg_info_record->owner_name);
-	xfree(bg_info_record->bg_block_id);
-	xfree(bg_info_record->bp_inx);
-	return SLURM_ERROR;
-}
-
-static void _free_node_info(bg_info_record_t *bg_info_record)
-{
-	xfree(bg_info_record->nodes);
-	xfree(bg_info_record->owner_name);
-	xfree(bg_info_record->bg_block_id);
-}
-
 /* Unpack node select info from a buffer */
 extern int select_g_unpack_node_info(node_select_info_msg_t **
 		node_select_info_msg_pptr, Buf buffer)
diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c
index b20374561e7..360df64d6a7 100644
--- a/src/common/slurm_protocol_defs.c
+++ b/src/common/slurm_protocol_defs.c
@@ -202,6 +202,10 @@ void slurm_free_job_desc_msg(job_desc_msg_t * msg)
 		xfree(msg->account);
 		xfree(msg->network);
 		xfree(msg->comment);
+		xfree(msg->blrtsimage);
+		xfree(msg->linuximage);
+		xfree(msg->mloaderimage);
+		xfree(msg->ramdiskimage);
 		xfree(msg);
 	}
 }
diff --git a/src/common/slurm_protocol_pack.c b/src/common/slurm_protocol_pack.c
index 8806e563167..ed22c3016d6 100644
--- a/src/common/slurm_protocol_pack.c
+++ b/src/common/slurm_protocol_pack.c
@@ -2363,6 +2363,22 @@ _pack_job_desc_msg(job_desc_msg_t * job_desc_ptr, Buf buffer)
 			select_g_set_jobinfo(job_desc_ptr->select_jobinfo, 
 					     SELECT_DATA_ROTATE, 
 					     &(job_desc_ptr->rotate));
+		if (job_desc_ptr->blrtsimage)
+			select_g_set_jobinfo(job_desc_ptr->select_jobinfo, 
+					     SELECT_DATA_BLRTS_IMAGE, 
+					     &(job_desc_ptr->blrtsimage));
+		if (job_desc_ptr->linuximage)
+			select_g_set_jobinfo(job_desc_ptr->select_jobinfo, 
+					     SELECT_DATA_BLRTS_IMAGE, 
+					     &(job_desc_ptr->linuximage));
+		if (job_desc_ptr->mloaderimage)
+			select_g_set_jobinfo(job_desc_ptr->select_jobinfo, 
+					     SELECT_DATA_BLRTS_IMAGE, 
+					     &(job_desc_ptr->mloaderimage));
+		if (job_desc_ptr->ramdiskimage)
+			select_g_set_jobinfo(job_desc_ptr->select_jobinfo, 
+					     SELECT_DATA_BLRTS_IMAGE, 
+					     &(job_desc_ptr->ramdiskimage));
 		select_g_pack_jobinfo(job_desc_ptr->select_jobinfo, buffer);
 		select_g_free_jobinfo(&job_desc_ptr->select_jobinfo);
 	}
@@ -2465,6 +2481,10 @@ _unpack_job_desc_msg(job_desc_msg_t ** job_desc_buffer_ptr, Buf buffer)
 #endif
 	job_desc_ptr->conn_type = (uint16_t)NO_VAL;
 	job_desc_ptr->rotate = (uint16_t)NO_VAL;
+	job_desc_ptr->blrtsimage = NULL;
+	job_desc_ptr->linuximage = NULL;
+	job_desc_ptr->mloaderimage = NULL;
+	job_desc_ptr->ramdiskimage = NULL;
 	return SLURM_SUCCESS;
 
 unpack_error:
diff --git a/src/plugins/select/bluegene/block_allocator/block_allocator.c b/src/plugins/select/bluegene/block_allocator/block_allocator.c
index 0187a22e2b2..8f5e06493e7 100644
--- a/src/plugins/select/bluegene/block_allocator/block_allocator.c
+++ b/src/plugins/select/bluegene/block_allocator/block_allocator.c
@@ -44,6 +44,7 @@
 #include <stdlib.h>
 #include <math.h>
 #include "block_allocator.h"
+#include "src/common/uid.h"
 
 #define DEBUG_PA
 #define BEST_COUNT_INIT 20
@@ -73,10 +74,10 @@ int DIM_SIZE[BA_SYSTEM_DIMENSIONS] = {0};
 #endif
 
 s_p_options_t bg_conf_file_options[] = {
-	{"BlrtsImage", S_P_STRING}, 
-	{"LinuxImage", S_P_STRING},
-	{"MloaderImage", S_P_STRING},
-	{"LinuxImage", S_P_STRING},
+	{"DefaultBlrtsImage", S_P_STRING}, 
+	{"DefaultLinuxImage", S_P_STRING},
+	{"DefaultMloaderImage", S_P_STRING},
+	{"DefaultRamDiskImage", S_P_STRING},
 	{"BridgeAPILogFile", S_P_STRING},
 	{"RamDiskImage", S_P_STRING},
 	{"LayoutMode", S_P_STRING},
@@ -85,6 +86,12 @@ s_p_options_t bg_conf_file_options[] = {
 	{"NodeCardNodeCnt", S_P_UINT16},
 	{"Numpsets", S_P_UINT16},
 	{"BPs", S_P_ARRAY, parse_blockreq, destroy_blockreq},
+	/* these are just going to be put into a list that will be
+	   freed later don't free them after reading them */
+	{"BlrtsImage", S_P_ARRAY, parse_image, NULL}, 
+	{"LinuxImage", S_P_ARRAY, parse_image, NULL},
+	{"MloaderImage", S_P_ARRAY, parse_image, NULL},
+	{"RamDiskImage", S_P_ARRAY, parse_image, NULL},
 	{NULL}
 };
 
@@ -213,6 +220,10 @@ extern int parse_blockreq(void **dest, slurm_parser_enum_t type,
 		{"Type", S_P_STRING},
 		{"Nodecards", S_P_UINT16},
 		{"Quarters", S_P_UINT16},
+		{"BlrtsImage", S_P_STRING},
+		{"LinuxImage", S_P_STRING},
+		{"MloaderImage", S_P_STRING},
+		{"RamDiskImage", S_P_STRING},
 		{NULL}
 	};
 	s_p_hashtbl_t *tbl;
@@ -224,7 +235,11 @@ extern int parse_blockreq(void **dest, slurm_parser_enum_t type,
 	
 	n = xmalloc(sizeof(blockreq_t));
 	n->block = xstrdup(value);
-
+	s_p_get_string(&n->blrtsimage, "BlrtsImage", tbl);
+	s_p_get_string(&n->linuximage, "LinuxImage", tbl);
+	s_p_get_string(&n->mloaderimage, "MloaderImage", tbl);
+	s_p_get_string(&n->ramdiskimage, "RamDiskImage", tbl);
+	
 	s_p_get_string(&tmp, "Type", tbl);
 	if (!tmp || !strcasecmp(tmp,"TORUS"))
 		n->conn_type = SELECT_TORUS;
@@ -250,6 +265,87 @@ extern void destroy_blockreq(void *ptr)
 	blockreq_t *n = (blockreq_t *)ptr;
 	if(n) {
 		xfree(n->block);
+		xfree(n->blrtsimage);
+		xfree(n->linuximage);
+		xfree(n->mloaderimage);
+		xfree(n->ramdiskimage);
+		xfree(n);
+	}
+}
+
+extern int parse_image(void **dest, slurm_parser_enum_t type,
+		       const char *key, const char *value, 
+		       const char *line, char **leftover)
+{
+	s_p_options_t image_options[] = {
+		{"GROUPS", S_P_STRING},
+		{NULL}
+	};
+	s_p_hashtbl_t *tbl = NULL;
+	char *tmp = NULL;
+	image_t *n = NULL;
+	image_group_t *image_group = NULL;
+	int i = 0, j = 0;
+
+	tbl = s_p_hashtbl_create(image_options);
+	s_p_parse_line(tbl, *leftover, leftover);
+	
+	n = xmalloc(sizeof(image_t));
+	n->name = xstrdup(value);
+	n->def = false;
+	debug3("image %s", n->name);
+	n->groups = list_create(destroy_image_group_list);
+	s_p_get_string(&tmp, "Groups", tbl);
+	if(tmp) {
+		for(i=0; i<strlen(tmp); i++) {
+			if(tmp[i] == ':') {
+				image_group = xmalloc(sizeof(image_group));
+				image_group->name = xmalloc(i-j+2);
+				snprintf(image_group->name,
+					 (i-j)+1, "%s", tmp+j);
+				image_group->gid =
+					gid_from_string(image_group->name);
+				debug3("adding group %s %d", image_group->name,
+				       image_group->gid);
+				list_append(n->groups, image_group);
+				j=i;
+				j++;
+			} 		
+		}
+		if(j != i) {
+			image_group = xmalloc(sizeof(image_group));
+			image_group->name = xmalloc(i-j+2);
+			snprintf(image_group->name, (i-j)+1, "%s", tmp+j);
+			image_group->gid = gid_from_string(image_group->name);
+			debug3("adding group %s %d", image_group->name,
+			       image_group->gid);
+			list_append(n->groups, image_group);
+		}
+	}
+	s_p_hashtbl_destroy(tbl);
+
+	*dest = (void *)n;
+	return 1;
+}
+
+extern void destroy_image_group_list(void *ptr)
+{
+	image_group_t *image_group = (image_group_t *)ptr;
+	if(image_group) {
+		xfree(image_group->name);
+		xfree(image_group);
+	}
+}
+
+extern void destroy_image(void *ptr)
+{
+	image_t *n = (image_t *)ptr;
+	if(n) {
+		xfree(n->name);
+		if(n->groups) {
+			list_destroy(n->groups);
+			n->groups = NULL;
+		}
 		xfree(n);
 	}
 }
@@ -593,6 +689,10 @@ extern void delete_ba_request(void *arg)
 		xfree(ba_request->save_name);
 		if(ba_request->elongate_geos)
 			list_destroy(ba_request->elongate_geos);
+		xfree(ba_request->blrtsimage);
+		xfree(ba_request->linuximage);
+		xfree(ba_request->mloaderimage);
+		xfree(ba_request->ramdiskimage);
 		
 		xfree(ba_request);
 	}
diff --git a/src/plugins/select/bluegene/block_allocator/block_allocator.h b/src/plugins/select/bluegene/block_allocator/block_allocator.h
index fc923160a7e..73680b7e030 100644
--- a/src/plugins/select/bluegene/block_allocator/block_allocator.h
+++ b/src/plugins/select/bluegene/block_allocator/block_allocator.h
@@ -91,6 +91,10 @@ typedef struct {
  */
 typedef struct {
 	char *save_name;
+	char *blrtsimage;              /* BlrtsImage for this block */
+	char *linuximage;              /* LinuxImage for this block */
+	char *mloaderimage;            /* mloaderImage for this block */
+	char *ramdiskimage;            /* RamDiskImage for this block */
 	int geometry[BA_SYSTEM_DIMENSIONS];
 	int start[BA_SYSTEM_DIMENSIONS];
 	int start_req;
@@ -107,13 +111,27 @@ typedef struct {
 	List elongate_geos;
 } ba_request_t; 
 
-typedef struct blockreq {
+typedef struct {
 	char *block;
+	char *blrtsimage;              /* BlrtsImage for this block */
+	char *linuximage;              /* LinuxImage for this block */
+	char *mloaderimage;            /* mloaderImage for this block */
+	char *ramdiskimage;            /* RamDiskImage for this block */
 	int conn_type;
 	uint16_t quarters;
 	uint16_t nodecards;
 } blockreq_t;
 
+typedef struct {
+	char *name;
+	bool def;
+	List groups;
+} image_t;
+
+typedef struct {
+	char *name;
+	gid_t gid;
+} image_group_t;
 /** 
  * structure that holds the configuration settings for each connection
  * 
@@ -210,6 +228,12 @@ extern int parse_blockreq(void **dest, slurm_parser_enum_t type,
 			  const char *line, char **leftover);
 
 extern void destroy_blockreq(void *ptr);
+extern int parse_image(void **dest, slurm_parser_enum_t type,
+		       const char *key, const char *value, 
+		       const char *line, char **leftover);
+
+extern void destroy_image_group_list(void *ptr);
+extern void destroy_image(void *ptr);
 extern void destroy_ba_node(void *ptr);
 
 /**
diff --git a/src/plugins/select/bluegene/plugin/bg_block_info.c b/src/plugins/select/bluegene/plugin/bg_block_info.c
index f2103a91b9a..69ef0c80b03 100644
--- a/src/plugins/select/bluegene/plugin/bg_block_info.c
+++ b/src/plugins/select/bluegene/plugin/bg_block_info.c
@@ -217,6 +217,10 @@ extern void pack_block(bg_record_t *bg_record, Buf buffer)
 	pack16((uint16_t)bg_record->nodecard, buffer);	
 	pack32((uint32_t)bg_record->node_cnt, buffer);
 	pack_bit_fmt(bg_record->bitmap, buffer);
+	packstr(bg_record->blrtsimage, buffer);
+	packstr(bg_record->linuximage, buffer);
+	packstr(bg_record->mloaderimage, buffer);
+	packstr(bg_record->ramdiskimage, buffer);
 }
 
 extern int update_block_list()
diff --git a/src/plugins/select/bluegene/plugin/bg_job_place.c b/src/plugins/select/bluegene/plugin/bg_job_place.c
index e8d2817b781..cd6990aaeda 100644
--- a/src/plugins/select/bluegene/plugin/bg_job_place.c
+++ b/src/plugins/select/bluegene/plugin/bg_job_place.c
@@ -89,9 +89,10 @@ pthread_mutex_t create_dynamic_mutex = PTHREAD_MUTEX_INITIALIZER;
  * 
  */
 static int _find_best_block_match(struct job_record* job_ptr, 
-				  bitstr_t* slurm_block_bitmap, uint32_t min_nodes,
-				  uint32_t max_nodes, uint32_t req_nodes,
-				  int spec, bg_record_t** found_bg_record, 
+				  bitstr_t* slurm_block_bitmap,
+				  uint32_t min_nodes, uint32_t max_nodes,
+				  uint32_t req_nodes, int spec,
+				  bg_record_t** found_bg_record, 
 				  bool test_only)
 {
 	ListIterator itr;
@@ -116,7 +117,11 @@ static int _find_best_block_match(struct job_record* job_ptr,
 	bitstr_t* tmp_bitmap = NULL;
 	int start_req = 0;
 	static int total_cpus = 0;
-
+	char *blrtsimage;              /* BlrtsImage for this request */
+	char *linuximage;              /* LinuxImage for this request */
+	char *mloaderimage;            /* mloaderImage for this request */
+	char *ramdiskimage;            /* RamDiskImage for this request */
+	int rc = SLURM_SUCCESS;
 	if(!total_cpus)
 		total_cpus = DIM_SIZE[X] * DIM_SIZE[Y] * DIM_SIZE[Z] 
 			* procs_per_node;
@@ -197,6 +202,14 @@ static int _find_best_block_match(struct job_record* job_ptr,
 			     SELECT_DATA_ROTATE, &rotate);
 	select_g_get_jobinfo(job_ptr->select_jobinfo,
 			     SELECT_DATA_MAX_PROCS, &max_procs);
+	select_g_get_jobinfo(job_ptr->select_jobinfo,
+			     SELECT_DATA_BLRTS_IMAGE, &blrtsimage);
+	select_g_get_jobinfo(job_ptr->select_jobinfo,
+			     SELECT_DATA_LINUX_IMAGE, &linuximage);
+	select_g_get_jobinfo(job_ptr->select_jobinfo,
+			     SELECT_DATA_MLOADER_IMAGE, &mloaderimage);
+	select_g_get_jobinfo(job_ptr->select_jobinfo,
+			     SELECT_DATA_RAMDISK_IMAGE, &ramdiskimage);
 	
 	if(req_geometry[X] != 0 && req_geometry[X] != (uint16_t)NO_VAL) {
 		target_size = 1;
@@ -478,7 +491,8 @@ try_again:
 			tmp_char);
 		bit_and(slurm_block_bitmap, (*found_bg_record)->bitmap);
 		slurm_mutex_unlock(&block_state_mutex);
-		return SLURM_SUCCESS;
+		rc = SLURM_SUCCESS;
+		goto end_it;
 	}
 
 	/* all these assume that the *found_bg_record is NULL */
@@ -507,17 +521,24 @@ try_again:
 		request.rotate = rotate;
 		request.elongate = true;
 		request.start_req = start_req;
+		request.blrtsimage = blrtsimage;
+		request.linuximage = linuximage;
+		request.mloaderimage = mloaderimage;
+		request.ramdiskimage = ramdiskimage;
+	
 		debug("trying with all free blocks");
 		if(create_dynamic_block(&request, NULL) == SLURM_ERROR) {
 			error("this job will never run on "
 			      "this system");
 			xfree(request.save_name);
-			return SLURM_ERROR;
+			rc = SLURM_ERROR;
+			goto end_it;
 		} else {
 			if(!request.save_name) {
 				error("no name returned from "
 				      "create_dynamic_block");
-				return SLURM_ERROR;
+				rc = SLURM_ERROR;
+				goto end_it;
 			} 
 
 			/* 
@@ -553,7 +574,8 @@ try_again:
 			bit_and(slurm_block_bitmap, tmp_bitmap);
 			bit_free(tmp_bitmap);
 			xfree(request.save_name);
-			return SLURM_SUCCESS;
+			rc = SLURM_SUCCESS;
+			goto end_it;
 		}
 	} else if(!created) {
 		debug2("going to create %d", target_size);
@@ -592,6 +614,10 @@ try_again:
 			request.rotate = rotate;
 			request.elongate = true;
 			request.start_req = start_req;
+			request.blrtsimage = blrtsimage;
+			request.linuximage = linuximage;
+			request.mloaderimage = mloaderimage;
+			request.ramdiskimage = ramdiskimage;
 			/* 1- try empty space
 			   2- we see if we can create one in the 
 			   unused bps
@@ -613,7 +639,15 @@ try_again:
 	}
 not_dynamic:
 	debug("_find_best_block_match none found");
-	return SLURM_ERROR;
+	rc = SLURM_ERROR;
+
+end_it:
+	xfree(blrtsimage);
+	xfree(linuximage);
+	xfree(mloaderimage);
+	xfree(ramdiskimage);
+		
+	return rc;
 }
 
 /*
@@ -642,6 +676,19 @@ extern int submit_job(struct job_record *job_ptr, bitstr_t *slurm_block_bitmap,
 				SELECT_PRINT_MIXED);
 	debug("bluegene:submit_job: %s nodes=%u-%u-%u", 
 	      buf, min_nodes, req_nodes, max_nodes);
+	select_g_sprint_jobinfo(job_ptr->select_jobinfo, buf, sizeof(buf), 
+				SELECT_PRINT_BLRTS_IMAGE);
+	debug2("BlrtsImage=%s", buf);
+	select_g_sprint_jobinfo(job_ptr->select_jobinfo, buf, sizeof(buf), 
+				SELECT_PRINT_LINUX_IMAGE);
+	debug2("LinuxImage=%s", buf);
+	select_g_sprint_jobinfo(job_ptr->select_jobinfo, buf, sizeof(buf), 
+				SELECT_PRINT_MLOADER_IMAGE);
+	debug2("MloaderImage=%s", buf);
+	select_g_sprint_jobinfo(job_ptr->select_jobinfo, buf, sizeof(buf), 
+				SELECT_PRINT_RAMDISK_IMAGE);
+	debug2("RamDiskImage=%s", buf);
+	
 	if(bluegene_layout_mode == LAYOUT_DYNAMIC)
 		slurm_mutex_lock(&create_dynamic_mutex);
 	
@@ -698,6 +745,21 @@ extern int submit_job(struct job_record *job_ptr, bitstr_t *slurm_block_bitmap,
 			select_g_set_jobinfo(job_ptr->select_jobinfo,
 					     SELECT_DATA_CONN_TYPE, 
 					     &tmp16);
+
+			select_g_set_jobinfo(job_ptr->select_jobinfo,
+					     SELECT_DATA_BLRTS_IMAGE,
+					     record->blrtsimage);
+			select_g_set_jobinfo(job_ptr->select_jobinfo,
+					     SELECT_DATA_LINUX_IMAGE,
+					     record->linuximage);
+			select_g_set_jobinfo(job_ptr->select_jobinfo,
+					     SELECT_DATA_MLOADER_IMAGE,
+					     record->mloaderimage);
+			select_g_set_jobinfo(job_ptr->select_jobinfo,
+					     SELECT_DATA_RAMDISK_IMAGE,
+					     record->ramdiskimage);
+
+			
 			slurm_mutex_unlock(&block_state_mutex);
 		}
 		if(test_only) {
diff --git a/src/plugins/select/bluegene/plugin/block_sys.c b/src/plugins/select/bluegene/plugin/block_sys.c
index 9c8bc959a94..d579bc3d98b 100755
--- a/src/plugins/select/bluegene/plugin/block_sys.c
+++ b/src/plugins/select/bluegene/plugin/block_sys.c
@@ -104,20 +104,20 @@ static void _pre_allocate(bg_record_t *bg_record)
 	int send_psets=bluegene_numpsets;
 
 	if ((rc = bridge_set_data(bg_record->bg_block, RM_PartitionBlrtsImg,   
-				  bluegene_blrts)) != STATUS_OK)
+				  bg_record->blrtsimage)) != STATUS_OK)
 		error("bridge_set_data(RM_PartitionBlrtsImg)", bg_err_str(rc));
 
 	if ((rc = bridge_set_data(bg_record->bg_block, RM_PartitionLinuxImg,   
-				  bluegene_linux)) != STATUS_OK) 
+				  bg_record->linuximage)) != STATUS_OK) 
 		error("bridge_set_data(RM_PartitionLinuxImg)", bg_err_str(rc));
 
 	if ((rc = bridge_set_data(bg_record->bg_block, RM_PartitionMloaderImg, 
-				  bluegene_mloader)) != STATUS_OK)
+				  bg_record->mloaderimage)) != STATUS_OK)
 		error("bridge_set_data(RM_PartitionMloaderImg)", 
 		      bg_err_str(rc));
 
 	if ((rc = bridge_set_data(bg_record->bg_block, RM_PartitionRamdiskImg, 
-				  bluegene_ramdisk)) != STATUS_OK)
+				  bg_record->ramdiskimage)) != STATUS_OK)
 		error("bridge_set_data(RM_PartitionRamdiskImg)", 
 		      bg_err_str(rc));
 
diff --git a/src/plugins/select/bluegene/plugin/bluegene.c b/src/plugins/select/bluegene/plugin/bluegene.c
index 2773f682769..addad59e73a 100644
--- a/src/plugins/select/bluegene/plugin/bluegene.c
+++ b/src/plugins/select/bluegene/plugin/bluegene.c
@@ -61,8 +61,13 @@ List bg_freeing_list = NULL;  	        /* blocks that being freed */
 List bg_request_list = NULL;  	        /* list of request that can't 
 					   be made just yet */
 
-char *bluegene_blrts = NULL, *bluegene_linux = NULL, *bluegene_mloader = NULL;
-char *bluegene_ramdisk = NULL, *bridge_api_file = NULL; 
+List bg_blrtsimage_list = NULL;
+List bg_linuximage_list = NULL;
+List bg_mloaderimage_list = NULL;
+List bg_ramdiskimage_list = NULL;
+char *default_blrtsimage = NULL, *default_linuximage = NULL;
+char *default_mloaderimage = NULL, *default_ramdiskimage = NULL;
+char *bridge_api_file = NULL; 
 bg_layout_t bluegene_layout_mode = NO_VAL;
 uint16_t bluegene_numpsets = 0;
 uint16_t bluegene_bp_node_cnt = 0;
@@ -178,10 +183,30 @@ extern void fini_bg(void)
 	}
 	slurm_mutex_unlock(&request_list_mutex);
 		
-	xfree(bluegene_blrts);
-	xfree(bluegene_linux);
-	xfree(bluegene_mloader);
-	xfree(bluegene_ramdisk);
+	if(bg_blrtsimage_list) {
+		list_destroy(bg_blrtsimage_list);
+		bg_blrtsimage_list = NULL;
+	}
+	
+	if(bg_linuximage_list) {
+		list_destroy(bg_linuximage_list);
+		bg_linuximage_list = NULL;
+	}
+	
+	if(bg_mloaderimage_list) {
+		list_destroy(bg_mloaderimage_list);
+		bg_mloaderimage_list = NULL;
+	}
+
+	if(bg_ramdiskimage_list) {
+		list_destroy(bg_ramdiskimage_list);
+		bg_ramdiskimage_list = NULL;
+	}
+
+	xfree(default_blrtsimage);
+	xfree(default_linuximage);
+	xfree(default_mloaderimage);
+	xfree(default_ramdiskimage);
 	xfree(bridge_api_file);
 	xfree(bg_conf);
 	
@@ -245,7 +270,12 @@ extern void destroy_bg_record(void *object)
 		}
 		if(bg_record->bitmap)
 			bit_free(bg_record->bitmap);
-		
+
+		xfree(bg_record->blrtsimage);
+		xfree(bg_record->linuximage);
+		xfree(bg_record->mloaderimage);
+		xfree(bg_record->ramdiskimage);
+
 		xfree(bg_record);
 		bg_record = NULL;
 	}
@@ -427,6 +457,16 @@ extern void copy_bg_record(bg_record_t *fir_record, bg_record_t *sec_record)
 	sec_record->user_name = xstrdup(fir_record->user_name);
 	xfree(sec_record->target_name);
 	sec_record->target_name = xstrdup(fir_record->target_name);
+
+	xfree(sec_record->blrtsimage);
+	sec_record->blrtsimage = xstrdup(fir_record->blrtsimage);
+	xfree(sec_record->linuximage);
+	sec_record->linuximage = xstrdup(fir_record->linuximage);
+	xfree(sec_record->mloaderimage);
+	sec_record->mloaderimage = xstrdup(fir_record->mloaderimage);
+	xfree(sec_record->ramdiskimage);
+	sec_record->ramdiskimage = xstrdup(fir_record->ramdiskimage);
+
 	sec_record->user_uid = fir_record->user_uid;
 	sec_record->block_lifecycle = fir_record->block_lifecycle;
 	sec_record->state = fir_record->state;
@@ -1263,6 +1303,10 @@ no_list:
 	requests = list_create(destroy_bg_record);
 	
 	blockreq.block = request->save_name;
+	blockreq.blrtsimage = request->blrtsimage;
+	blockreq.linuximage = request->linuximage;
+	blockreq.mloaderimage = request->mloaderimage;
+	blockreq.ramdiskimage = request->ramdiskimage;
 	blockreq.conn_type = request->conn_type;
 	blockreq.nodecards = num_nodecard;
 	blockreq.quarters = num_quarter;
@@ -1370,6 +1414,10 @@ extern int create_full_system_block(int *block_inx)
 
 	records = list_create(destroy_bg_record);
 	blockreq.block = name;
+	blockreq.blrtsimage = NULL;
+	blockreq.linuximage = NULL;
+	blockreq.mloaderimage = NULL;
+	blockreq.ramdiskimage = NULL;
 	blockreq.conn_type = SELECT_TORUS;
 	blockreq.nodecards = 0;
 	blockreq.quarters = 0;
@@ -1784,6 +1832,7 @@ extern int read_bg_conf(void)
 	s_p_hashtbl_t *tbl = NULL;
 	char *layout = NULL;
 	blockreq_t **blockreq_array = NULL;
+	image_t **image_array = NULL;
 	static time_t last_config_update = (time_t) 0;
 	struct stat config_stat;
 		
@@ -1813,14 +1862,51 @@ extern int read_bg_conf(void)
 		fatal("something wrong with opening/reading bluegene "
 		      "conf file");
 	
-	if (!s_p_get_string(&bluegene_blrts, "BlrtsImage", tbl)) 
+	_set_bg_lists();	
+	if (s_p_get_array((void ***)&image_array, 
+			  &count, "BlrtsImage", tbl)) {
+		for (i = 0; i < count; i++) {
+			list_append(bg_blrtsimage_list, image_array[i]);
+		}
+	}
+	if (!s_p_get_string(&default_blrtsimage, "DefaultBlrtsImage", tbl)) {
 		fatal("BlrtsImage not configured in bluegene.conf");
-	if (!s_p_get_string(&bluegene_linux, "LinuxImage", tbl)) 
+	}
+
+	if (s_p_get_array((void ***)&image_array, 
+			  &count, "LinuxImage", tbl)) {
+		for (i = 0; i < count; i++) {
+			list_append(bg_linuximage_list, image_array[i]);
+		}
+	}
+	if (!s_p_get_string(&default_linuximage, "DefaultLinuxImage", tbl)) {
 		fatal("LinuxImage not configured in bluegene.conf");
-	if (!s_p_get_string(&bluegene_mloader, "MloaderImage", tbl)) 
+	}
+
+	if (s_p_get_array((void ***)&image_array, 
+			  &count, "MloaderImage", tbl)) {
+		for (i = 0; i < count; i++) {
+			list_append(bg_mloaderimage_list, image_array[i]);
+		}
+	}
+	if (!s_p_get_string(&default_mloaderimage,
+			    "DefaultMloaderImage", tbl)) {
 		fatal("MloaderImage not configured in bluegene.conf");
-	if (!s_p_get_string(&bluegene_ramdisk, "RamDiskImage", tbl)) 
+	}
+
+	if (s_p_get_array((void ***)&image_array, 
+			  &count, "RamDiskImage", tbl)) {
+		for (i = 0; i < count; i++) {
+			list_append(bg_ramdiskimage_list, image_array[i]);
+		}
+	}
+	if (!s_p_get_string(&default_ramdiskimage,
+			    "DefaultRamDiskImage", tbl)) {
 		fatal("RamDiskImage not configured in bluegene.conf");
+	} else {
+		
+	}
+
 	if (!s_p_get_uint16(&bluegene_numpsets, "Numpsets", tbl))
 		fatal("Warning: Numpsets not configured in bluegene.conf");
 	if (!s_p_get_uint16(&bridge_api_verb, "BridgeAPIVerbose", tbl))
@@ -1872,7 +1958,6 @@ extern int read_bg_conf(void)
 	if(bluegene_nodecard_node_cnt<=0)
 		fatal("You should have more than 0 nodes per nodecard");
 
-	_set_bg_lists();	
 	/* add blocks defined in file */
 	if(bluegene_layout_mode != LAYOUT_DYNAMIC) {
 		if (!s_p_get_array((void ***)&blockreq_array, 
@@ -1996,33 +2081,47 @@ static int _ba_node_cmpf_inc(ba_node_t *node_a, ba_node_t *node_b)
 static void _set_bg_lists()
 {
 	slurm_mutex_lock(&block_state_mutex);
-	if (bg_found_block_list)
+	if(bg_found_block_list)
 		list_destroy(bg_found_block_list);
 	bg_found_block_list = list_create(NULL);
-	if (bg_booted_block_list) 
+	if(bg_booted_block_list) 
 		list_destroy(bg_booted_block_list);
 	bg_booted_block_list = list_create(NULL);
-	if (bg_job_block_list) 
+	if(bg_job_block_list) 
 		list_destroy(bg_job_block_list);
 	bg_job_block_list = list_create(NULL);	
 	num_unused_cpus = 
 		DIM_SIZE[X] * DIM_SIZE[Y] * DIM_SIZE[Z] * procs_per_node;
-	if (bg_curr_block_list)
+	if(bg_curr_block_list)
 		list_destroy(bg_curr_block_list);	
 	bg_curr_block_list = list_create(destroy_bg_record);
 	
 	
-	if (bg_list) 
+	if(bg_list) 
 		list_destroy(bg_list);
 	bg_list = list_create(destroy_bg_record);
 
 	slurm_mutex_lock(&request_list_mutex);
-	if (bg_request_list) 
+	if(bg_request_list) 
 		list_destroy(bg_request_list);
 	bg_request_list = list_create(delete_ba_request);
 	slurm_mutex_unlock(&request_list_mutex);
-		
-	slurm_mutex_unlock(&block_state_mutex);		
+	
+	slurm_mutex_unlock(&block_state_mutex);	
+	
+	if(bg_blrtsimage_list)
+		list_destroy(bg_blrtsimage_list);
+	bg_blrtsimage_list = list_create(destroy_image);
+	if(bg_linuximage_list)
+		list_destroy(bg_linuximage_list);
+	bg_linuximage_list = list_create(destroy_image);
+	if(bg_mloaderimage_list)
+		list_destroy(bg_mloaderimage_list);
+	bg_mloaderimage_list = list_create(destroy_image);
+	if(bg_ramdiskimage_list)
+		list_destroy(bg_ramdiskimage_list);
+	bg_ramdiskimage_list = list_create(destroy_image);
+	
 }
 
 /*
@@ -2645,6 +2744,10 @@ static bg_record_t *_create_small_record(bg_record_t *bg_record,
 	found_record->user_uid = bg_record->user_uid;
 	found_record->bg_block_list = list_create(destroy_ba_node);
 	found_record->nodes = xstrdup(bg_record->nodes);
+	found_record->blrtsimage = xstrdup(bg_record->blrtsimage);
+	found_record->linuximage = xstrdup(bg_record->linuximage);
+	found_record->mloaderimage = xstrdup(bg_record->mloaderimage);
+	found_record->ramdiskimage = xstrdup(bg_record->ramdiskimage);
 
 	process_nodes(found_record);
 				
@@ -2729,6 +2832,27 @@ static int _add_bg_record(List records, List used_nodes, blockreq_t *blockreq)
 	bg_record->cpus_per_bp = procs_per_node;
 	bg_record->node_cnt = bluegene_bp_node_cnt * bg_record->bp_count;
 	bg_record->job_running = NO_JOB_RUNNING;
+
+	if(blockreq->blrtsimage)
+		bg_record->blrtsimage = xstrdup(blockreq->blrtsimage);
+	else
+		bg_record->blrtsimage = xstrdup(default_blrtsimage);
+
+	if(blockreq->linuximage)
+		bg_record->linuximage = xstrdup(blockreq->linuximage);
+	else
+		bg_record->linuximage = xstrdup(default_linuximage);
+
+	if(blockreq->mloaderimage)
+		bg_record->mloaderimage = xstrdup(blockreq->mloaderimage);
+	else
+		bg_record->mloaderimage = xstrdup(default_mloaderimage);
+
+	if(blockreq->ramdiskimage)
+		bg_record->ramdiskimage = xstrdup(blockreq->ramdiskimage);
+	else
+		bg_record->ramdiskimage = xstrdup(default_ramdiskimage);
+	info("default is %s", bg_record->blrtsimage);
 	
 	if(bg_record->conn_type != SELECT_SMALL) {
 		/* this needs to be an append so we keep things in the
diff --git a/src/plugins/select/bluegene/plugin/bluegene.h b/src/plugins/select/bluegene/plugin/bluegene.h
index bbc5964080a..674ca2ece49 100644
--- a/src/plugins/select/bluegene/plugin/bluegene.h
+++ b/src/plugins/select/bluegene/plugin/bluegene.h
@@ -103,6 +103,10 @@ typedef struct bg_record {
 					   determine quarter of BP */
 	uint16_t nodecard;             /* used for small blocks 
 					  determine nodecard of quarter */
+	char *blrtsimage;              /* BlrtsImage for this block */
+	char *linuximage;              /* LinuxImage for this block */
+	char *mloaderimage;            /* mloaderImage for this block */
+	char *ramdiskimage;            /* RamDiskImage for this block */
 } bg_record_t;
 
 typedef struct {
@@ -144,6 +148,10 @@ extern List bg_booted_block_list;  	/* blocks that are booted */
 extern List bg_freeing_list;  	        /* blocks that being freed */
 extern List bg_request_list;  	        /* list of request that can't 
 					   be made just yet */
+extern List bg_blrtsimage_list;
+extern List bg_linuximage_list;
+extern List bg_mloaderimage_list;
+extern List bg_ramdiskimage_list;
 
 extern bool agent_fini;
 extern pthread_mutex_t block_state_mutex;
diff --git a/src/sbatch/opt.c b/src/sbatch/opt.c
index 774080b78eb..ed0b3f5b605 100644
--- a/src/sbatch/opt.c
+++ b/src/sbatch/opt.c
@@ -102,6 +102,10 @@
 #define LONG_OPT_NICE        0x115
 #define LONG_OPT_NO_REQUEUE  0x116
 #define LONG_OPT_COMMENT     0x117
+#define LONG_OPT_BLRTS_IMAGE     0x140
+#define LONG_OPT_LINUX_IMAGE     0x141
+#define LONG_OPT_MLOADER_IMAGE   0x142
+#define LONG_OPT_RAMDISK_IMAGE   0x143
 
 /*---- global variables, defined in opt.h ----*/
 opt_t opt;
@@ -419,7 +423,7 @@ static void _opt_default()
 	for (i=0; i<SYSTEM_DIMENSIONS; i++)
 		opt.geometry[i]	    = (uint16_t) NO_VAL;
 	opt.no_rotate	    = false;
-	opt.conn_type	    = -1;
+	opt.conn_type	    = (uint16_t) NO_VAL;
 
 	opt.euid	    = (uid_t) -1;
 	opt.egid	    = (gid_t) -1;
@@ -449,15 +453,19 @@ struct env_vars {
 
 env_vars_t env_vars[] = {
   {"SBATCH_ACCOUNT",       OPT_STRING,     &opt.account,       NULL           },
+  {"SBATCH_BLRTS_IMAGE",   OPT_STRING,     &opt.blrtsimage,    NULL           },
   {"SBATCH_CONN_TYPE",     OPT_CONN_TYPE,  NULL,               NULL           },
   {"SBATCH_DEBUG",         OPT_DEBUG,      NULL,               NULL           },
   {"SBATCH_GEOMETRY",      OPT_GEOMETRY,   NULL,               NULL           },
   {"SBATCH_IMMEDIATE",     OPT_BOOL,       &opt.immediate,     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_MLOADER_IMAGE", OPT_STRING,     &opt.mloaderimage,  NULL           },
   {"SBATCH_NO_REQUEUE",    OPT_BOOL,       &opt.no_requeue,    NULL           },
-  {"SBATCH_NO_ROTATE",     OPT_NO_ROTATE,  NULL,               NULL           },
+  {"SBATCH_NO_ROTATE",     OPT_BOOL,       &opt.no_rotate,     NULL           },
   {"SBATCH_PARTITION",     OPT_STRING,     &opt.partition,     NULL           },
+  {"SBATCH_RAMDISK_IMAGE", OPT_STRING,     &opt.ramdiskimage,  NULL           },
   {"SBATCH_TIMELIMIT",     OPT_INT,        &opt.time_limit,    NULL           },
   {NULL, 0, NULL, NULL}
 };
@@ -609,6 +617,10 @@ static struct option long_options[] = {
 	{"nice",          optional_argument, 0, LONG_OPT_NICE},
 	{"no-requeue",    no_argument,       0, LONG_OPT_NO_REQUEUE},
 	{"comment",       required_argument, 0, LONG_OPT_COMMENT},
+	{"blrts-image",   required_argument, 0, LONG_OPT_BLRTS_IMAGE},
+	{"linux-image",   required_argument, 0, LONG_OPT_LINUX_IMAGE},
+	{"mloader-image", required_argument, 0, LONG_OPT_MLOADER_IMAGE},
+	{"ramdisk-image", required_argument, 0, LONG_OPT_RAMDISK_IMAGE},
 	{NULL,            0,                 0, 0}
 };
 
@@ -1114,7 +1126,7 @@ static void _set_options(int argc, char **argv)
 				opt.nice = 100;
 			if (abs(opt.nice) > NICE_OFFSET) {
 				error("Invalid nice value, must be between "
-					"-%d and %d", NICE_OFFSET, NICE_OFFSET);
+				      "-%d and %d", NICE_OFFSET, NICE_OFFSET);
 				exit(1);
 			}
 			break;
@@ -1125,6 +1137,22 @@ static void _set_options(int argc, char **argv)
 			xfree(opt.comment);
 			opt.comment = xstrdup(optarg);
 			break;
+		case LONG_OPT_BLRTS_IMAGE:
+			xfree(opt.blrtsimage);
+			opt.blrtsimage = xstrdup(optarg);
+			break;
+		case LONG_OPT_LINUX_IMAGE:
+			xfree(opt.linuximage);
+			opt.linuximage = xstrdup(optarg);
+			break;
+		case LONG_OPT_MLOADER_IMAGE:
+			xfree(opt.mloaderimage);
+			opt.mloaderimage = xstrdup(optarg);
+			break;
+		case LONG_OPT_RAMDISK_IMAGE:
+			xfree(opt.ramdiskimage);
+			opt.ramdiskimage = xstrdup(optarg);
+			break;
 		default:
 			fatal("Unrecognized command line parameter %c",
 			      opt_char);
@@ -1481,12 +1509,22 @@ static void _opt_list()
 	str = print_constraints();
 	info("constraints    : %s", str);
 	xfree(str);
-	if (opt.conn_type >= 0)
+	if (opt.conn_type != (uint16_t) NO_VAL)
 		info("conn_type      : %u", opt.conn_type);
 	str = print_geometry();
 	info("geometry       : %s", str);
 	xfree(str);
 	info("rotate         : %s", opt.no_rotate ? "yes" : "no");
+
+	if (opt.blrtsimage)
+		info("BlrtsImage     : %s", opt.blrtsimage);
+	if (opt.linuximage)
+		info("LinuxImage     : %s", opt.linuximage);
+	if (opt.mloaderimage)
+		info("MloaderImage   : %s", opt.mloaderimage);
+	if (opt.ramdiskimage)
+		info("RamDiskImage   : %s", opt.ramdiskimage);
+
 	if (opt.begin) {
 		char time_str[32];
 		slurm_make_time_str(&opt.begin, time_str, sizeof(time_str));
@@ -1514,6 +1552,8 @@ static void _usage(void)
 "              [--account=name] [--dependency=jobid] [--comment=name]\n"
 #ifdef HAVE_BG		/* Blue gene specific options */
 "              [--geometry=XxYxZ] [--conn-type=type] [--no-rotate]\n"
+"              [--blrts-image=path] [--linux-image=path]\n"
+"              [--mloader-image=path] [--ramdisk-image=path]\n"
 #endif
 "              [--mail-type=type] [--mail-user=user][--nice[=value]]\n"
 "              [--no-requeue]\n"
@@ -1569,12 +1609,16 @@ static void _help(void)
 "                              cpu consumable resource is enabled\n"
 "\n"
 #ifdef HAVE_BG				/* Blue gene specific options */
-  "Blue Gene related options:\n"
-  "  -g, --geometry=XxYxZ        geometry constraints of the job\n"
-  "  -R, --no-rotate             disable geometry rotation\n"
-  "      --conn-type=type        constraint on type of connection, MESH or TORUS\n"
-  "                              if not set, then tries to fit TORUS else MESH\n"
-  "\n"
+"Blue Gene related options:\n"
+"  -g, --geometry=XxYxZ        geometry constraints of the job\n"
+"  -R, --no-rotate             disable geometry rotation\n"
+"      --conn-type=type        constraint on type of connection, MESH or TORUS\n"
+"                              if not set, then tries to fit TORUS else MESH\n"
+"      --blrts-image=path      path to blrts image for bluegene block.  Default if not set\n"
+"      --linux-image=path      path to linux image for bluegene block.  Default if not set\n"
+"      --mloader-image=path    path to mloader image for bluegene block.  Default if not set\n"
+"      --ramdisk-image=path    path to ramdisk image for bluegene block.  Default if not set\n"
+"\n"
 #endif
 "Help options:\n"
 "  -h, --help                  show this help message\n"
diff --git a/src/sbatch/opt.h b/src/sbatch/opt.h
index 8c64d43c816..0cecd0f0e07 100644
--- a/src/sbatch/opt.h
+++ b/src/sbatch/opt.h
@@ -95,9 +95,16 @@ typedef struct sbatch_options {
 	char *nodelist;		/* --nodelist=node1,node2,...	*/
 	char *exc_nodes;	/* --exclude=node1,node2,... -x	*/
 
+	/* BLUEGENE SPECIFIC */
 	uint16_t geometry[SYSTEM_DIMENSIONS]; /* --geometry, -g	*/
 	bool no_rotate;		/* --no_rotate, -R		*/
-	int16_t conn_type;	/* --conn-type 			*/
+	uint16_t conn_type;	/* --conn-type 			*/
+	char *blrtsimage;       /* --blrtsimage BlrtsImage for block */
+	char *linuximage;       /* --linuximage LinuxImage for block */
+	char *mloaderimage;     /* --mloaderimage mloaderImage for block */
+	char *ramdiskimage;     /* --ramdiskimage RamDiskImage for block */
+	/*********************/
+
 	time_t begin;		/* --begin			*/
 	uint16_t mail_type;	/* --mail-type			*/
 	char *mail_user;	/* --mail-user			*/
diff --git a/src/sbatch/sbatch.c b/src/sbatch/sbatch.c
index ccd7c681ad1..fd5bef9ddb5 100644
--- a/src/sbatch/sbatch.c
+++ b/src/sbatch/sbatch.c
@@ -141,10 +141,19 @@ static int fill_job_desc_from_opts(job_desc_msg_t *desc)
 			desc->geometry[i] = opt.geometry[i];
 	}
 #endif
-	if (opt.conn_type != -1)
+	if (opt.conn_type != (uint16_t) NO_VAL)
 		desc->conn_type = opt.conn_type;
 	if (opt.no_rotate)
 		desc->rotate = 0;
+	if (opt.blrtsimage)
+		desc->blrtsimage = xstrdup(opt.blrtsimage);
+	if (opt.linuximage)
+		desc->linuximage = xstrdup(opt.linuximage);
+	if (opt.mloaderimage)
+		desc->mloaderimage = xstrdup(opt.mloaderimage);
+	if (opt.ramdiskimage)
+		desc->ramdiskimage = xstrdup(opt.ramdiskimage);
+
 	if (opt.mincpus > -1)
 		desc->job_min_procs = opt.mincpus;
 	if (opt.minsockets > -1)
diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c
index 019476c9be1..952f202208b 100644
--- a/src/slurmctld/job_mgr.c
+++ b/src/slurmctld/job_mgr.c
@@ -1664,6 +1664,7 @@ static int _job_create(job_desc_msg_t * job_desc, int allocate, int will_run,
 #if SYSTEM_DIMENSIONS
 	uint16_t geo[SYSTEM_DIMENSIONS];
 	uint16_t rotate;
+	uint16_t conn_type;
 #endif
 
 	debug2("before alteration asking for nodes %u-%u procs %u", 
@@ -1797,6 +1798,13 @@ static int _job_create(job_desc_msg_t * job_desc, int allocate, int will_run,
 		select_g_set_jobinfo(job_desc->select_jobinfo,
 				     SELECT_DATA_ROTATE, &rotate);
 	}
+	select_g_get_jobinfo(job_desc->select_jobinfo,
+			     SELECT_DATA_CONN_TYPE, &conn_type);
+	if (conn_type == (uint16_t) NO_VAL) {
+		conn_type = (uint16_t) SELECT_TORUS;
+		select_g_set_jobinfo(job_desc->select_jobinfo,
+				     SELECT_DATA_CONN_TYPE, &conn_type);
+	}
 #endif
 
 	if (job_desc->max_nodes == NO_VAL)
diff --git a/src/srun/allocate.c b/src/srun/allocate.c
index 38ccaa29bee..c45352bca9b 100644
--- a/src/srun/allocate.c
+++ b/src/srun/allocate.c
@@ -489,12 +489,21 @@ job_desc_msg_create_from_opts (char *script)
 	}
 #endif
 
-	if (opt.conn_type != (int16_t) NO_VAL)
+	if (opt.conn_type != (uint16_t) NO_VAL)
 		j->conn_type = opt.conn_type;
 			
 	if (opt.no_rotate)
 		j->rotate = 0;
 
+	if (opt.blrtsimage)
+		j->blrtsimage = xstrdup(opt.blrtsimage);
+	if (opt.linuximage)
+		j->linuximage = xstrdup(opt.linuximage);
+	if (opt.mloaderimage)
+		j->mloaderimage = xstrdup(opt.mloaderimage);
+	if (opt.ramdiskimage)
+		j->ramdiskimage = xstrdup(opt.ramdiskimage);
+
 	if (opt.max_nodes)
 		j->max_nodes    = opt.max_nodes;
 	if (opt.max_sockets_per_node)
diff --git a/src/srun/opt.c b/src/srun/opt.c
index 393c279e97b..9b359e916be 100644
--- a/src/srun/opt.c
+++ b/src/srun/opt.c
@@ -153,6 +153,10 @@
 #define LONG_OPT_NTASKSPERCORE	 0x138
 #define LONG_OPT_JOBMEM	         0x13a
 #define LONG_OPT_HINT	         0x13b
+#define LONG_OPT_BLRTS_IMAGE     0x140
+#define LONG_OPT_LINUX_IMAGE     0x141
+#define LONG_OPT_MLOADER_IMAGE   0x142
+#define LONG_OPT_RAMDISK_IMAGE   0x143
 
 /*---- global variables, defined in opt.h ----*/
 char **remote_argv;
@@ -986,6 +990,10 @@ static void _opt_default()
 		opt.geometry[i]	    = (uint16_t) NO_VAL;
 	opt.no_rotate	    = false;
 	opt.conn_type	    = (uint16_t) NO_VAL;
+	opt.blrtsimage = NULL;
+	opt.linuximage = NULL;
+	opt.mloaderimage = NULL;
+	opt.ramdiskimage = NULL;
 
 	opt.euid	    = (uid_t) -1;
 	opt.egid	    = (gid_t) -1;
@@ -1036,6 +1044,7 @@ struct env_vars {
 env_vars_t env_vars[] = {
 	{"SLURM_ACCOUNT",       OPT_STRING,     &opt.account,       NULL           },
 	{"SLURMD_DEBUG",        OPT_INT,        &opt.slurmd_debug,  NULL           },
+	{"SLURM_BLRTS_IMAGE",   OPT_STRING,     &opt.blrtsimage,    NULL           },
 	{"SLURM_CPUS_PER_TASK", OPT_INT,        &opt.cpus_per_task, &opt.cpus_set  },
 	{"SLURM_CONN_TYPE",     OPT_CONN_TYPE,  NULL,               NULL           },
 	{"SLURM_CORE_FORMAT",   OPT_CORE,       NULL,               NULL           },
@@ -1048,6 +1057,8 @@ env_vars_t env_vars[] = {
 	{"SLURM_JOBID",         OPT_INT,        &opt.jobid,         NULL           },
 	{"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_MLOADER_IMAGE", OPT_STRING,     &opt.mloaderimage,  NULL           },
 	{"SLURM_NNODES",        OPT_NODES,      NULL,               NULL           },
 	{"SLURM_NSOCKETS_PER_NODE",OPT_NSOCKETS,NULL,               NULL           },
 	{"SLURM_NCORES_PER_SOCKET",OPT_NCORES,  NULL,               NULL           },
@@ -1057,6 +1068,7 @@ env_vars_t env_vars[] = {
 	{"SLURM_NPROCS",        OPT_INT,        &opt.nprocs,        &opt.nprocs_set},
 	{"SLURM_OVERCOMMIT",    OPT_OVERCOMMIT, NULL,               NULL           },
 	{"SLURM_PARTITION",     OPT_STRING,     &opt.partition,     NULL           },
+	{"SLURM_RAMDISK_IMAGE", OPT_STRING,     &opt.ramdiskimage,  NULL           },
 	{"SLURM_REMOTE_CWD",    OPT_STRING,     &opt.cwd,           NULL           },
 	{"SLURM_STDERRMODE",    OPT_STRING,     &opt.efname,        NULL           },
 	{"SLURM_STDINMODE",     OPT_STRING,     &opt.ifname,        NULL           },
@@ -1374,6 +1386,10 @@ void set_options(const int argc, char **argv, int first)
 		{"ntasks-per-node",  required_argument, 0, LONG_OPT_NTASKSPERNODE},
 		{"ntasks-per-socket",required_argument, 0, LONG_OPT_NTASKSPERSOCKET},
 		{"ntasks-per-core",  required_argument, 0, LONG_OPT_NTASKSPERCORE},
+		{"blrts-image",      required_argument, 0, LONG_OPT_BLRTS_IMAGE},
+		{"linux-image",      required_argument, 0, LONG_OPT_LINUX_IMAGE},
+		{"mloader-image",      required_argument, 0, LONG_OPT_MLOADER_IMAGE},
+		{"ramdisk-image",      required_argument, 0, LONG_OPT_RAMDISK_IMAGE},
 		{NULL,               0,                 0, 0}
 	};
 	char *opt_string = "+a:AbB:c:C:d:D:e:g:Hi:IjJ:kKlm:n:N:"
@@ -1921,6 +1937,30 @@ void set_options(const int argc, char **argv, int first)
 			opt.ntasks_per_core = _get_int(optarg, "ntasks-per-core",
 				true);
 			break;
+		case LONG_OPT_BLRTS_IMAGE:
+			if(!first && opt.blrtsimage)
+				break;			
+			xfree(opt.blrtsimage);
+			opt.blrtsimage = xstrdup(optarg);
+			break;
+		case LONG_OPT_LINUX_IMAGE:
+			if(!first && opt.linuximage)
+				break;			
+			xfree(opt.linuximage);
+			opt.linuximage = xstrdup(optarg);
+			break;
+		case LONG_OPT_MLOADER_IMAGE:
+			if(!first && opt.mloaderimage)
+				break;			
+			xfree(opt.mloaderimage);
+			opt.mloaderimage = xstrdup(optarg);
+			break;
+		case LONG_OPT_RAMDISK_IMAGE:
+			if(!first && opt.ramdiskimage)
+				break;			
+			xfree(opt.ramdiskimage);
+			opt.ramdiskimage = xstrdup(optarg);
+			break;
 		default:
 			if (spank_process_option (opt_char, optarg) < 0) {
 				exit (1);
@@ -2545,12 +2585,22 @@ static void _opt_list()
 	str = print_constraints();
 	info("constraints    : %s", str);
 	xfree(str);
-	if (opt.conn_type >= 0)
+	if (opt.conn_type != (uint16_t) NO_VAL)
 		info("conn_type      : %u", opt.conn_type);
 	str = print_geometry();
 	info("geometry       : %s", str);
 	xfree(str);
 	info("rotate         : %s", opt.no_rotate ? "yes" : "no");
+	
+	if (opt.blrtsimage)
+		info("BlrtsImage     : %s", opt.blrtsimage);
+	if (opt.linuximage)
+		info("LinuxImage     : %s", opt.linuximage);
+	if (opt.mloaderimage)
+		info("MloaderImage   : %s", opt.mloaderimage);
+	if (opt.ramdiskimage)
+		info("RamDiskImage   : %s", opt.ramdiskimage);
+
 	info("network        : %s", opt.network);
 	info("propagate      : %s",
 	     opt.propagate == NULL ? "NONE" : opt.propagate);
@@ -2599,7 +2649,9 @@ static void _usage(void)
 "            [--ntasks-per-node=n] [--ntasks-per-socket=n]\n"
 "            [--ntasks-per-core=n]\n"
 #ifdef HAVE_BG		/* Blue gene specific options */
-		"            [--geometry=XxYxZ] [--conn-type=type] [--no-rotate]\n"
+"            [--geometry=XxYxZ] [--conn-type=type] [--no-rotate]\n"
+"            [--blrts-image=path] [--linux-image=path]\n"
+"            [--mloader-image=path] [--ramdisk-image=path]\n"
 #endif
 		"            [--mail-type=type] [--mail-user=user] [--nice[=value]]\n"
 		"            [--prolog=fname] [--epilog=fname]\n"
@@ -2739,6 +2791,10 @@ static void _help(void)
 		"  -R, --no-rotate             disable geometry rotation\n"
 		"      --conn-type=type        constraint on type of connection, MESH or TORUS\n"
 		"                              if not set, then tries to fit TORUS else MESH\n"
+		"      --blrts-image=path      path to blrts image for bluegene block.  Default if not set\n"
+		"      --linux-image=path      path to linux image for bluegene block.  Default if not set\n"
+		"      --mloader-image=path    path to mloader image for bluegene block.  Default if not set\n"
+		"      --ramdisk-image=path    path to ramdisk image for bluegene block.  Default if not set\n"
 		"\n"
 #endif
 		"Help options:\n"
diff --git a/src/srun/opt.h b/src/srun/opt.h
index 3ff585d6cac..b6da3831adb 100644
--- a/src/srun/opt.h
+++ b/src/srun/opt.h
@@ -16,7 +16,7 @@
  *  any later version.
  *
  *  In addition, as a special exception, the copyright holders give permission 
- *  to link the code of portions of this program with the OpenSSL library under 
+ *  to link the code of portions of this program with the OpenSSL library under
  *  certain conditions as described in each individual source file, and 
  *  distribute linked combinations including the two. You must obey the GNU 
  *  General Public License in all respects for all of the code used other than 
@@ -192,15 +192,23 @@ typedef struct srun_options {
 	int  msg_timeout;       /* Undocumented                 */
 	char *network;		/* --network=			*/
 
+	/* BLUEGENE SPECIFIC */
 	uint16_t geometry[SYSTEM_DIMENSIONS]; /* --geometry, -g	*/
 	bool no_rotate;		/* --no_rotate, -R		*/
-	int16_t conn_type;	/* --conn-type 			*/
+	uint16_t conn_type;	/* --conn-type 			*/
+	char *blrtsimage;       /* --blrtsimage BlrtsImage for block */
+	char *linuximage;       /* --linuximage LinuxImage for block */
+	char *mloaderimage;     /* --mloaderimage mloaderImage for block */
+	char *ramdiskimage;     /* --ramdiskimage RamDiskImage for block */
+	/*********************/
+
 	char *prolog;           /* --prolog                     */
 	char *epilog;           /* --epilog                     */
 	time_t begin;		/* --begin			*/
 	uint16_t mail_type;	/* --mail-type			*/
 	char *mail_user;	/* --mail-user			*/
 	char *ctrl_comm_ifhn;	/* --ctrl-comm-ifhn		*/
+	
 } opt_t;
 
 extern opt_t opt;
-- 
GitLab