diff --git a/src/common/node_conf.c b/src/common/node_conf.c
index 4aff65daad0bd03d632b0eec5f5f629de6779060..e4c1c66947d577b1f22c604b3df6af8e7d132d8e 100644
--- a/src/common/node_conf.c
+++ b/src/common/node_conf.c
@@ -78,8 +78,9 @@
 #define _DEBUG 0
 
 /* Global variables */
-List config_list  = NULL;		/* list of config_record entries */
-List feature_list = NULL;		/* list of features_record entries */
+List config_list  = NULL;	/* list of config_record entries */
+List feature_list = NULL;	/* list of features_record entries */
+List front_end_list = NULL;	/* list of slurm_conf_frontend_t entries */
 time_t last_node_update = (time_t) 0;	/* time of last update */
 struct node_record *node_record_table_ptr = NULL;	/* node records */
 struct node_record **node_hash_table = NULL;	/* node_record hash table */
@@ -100,7 +101,6 @@ static int	_list_find_config (void *config_entry, void *key);
 static int	_list_find_feature (void *feature_entry, void *key);
 
 
-
 static void _add_config_feature(char *feature, bitstr_t *node_bitmap)
 {
 	struct features_record *feature_ptr;
@@ -152,7 +152,7 @@ static int _build_single_nodeline_info(slurm_conf_node_t *node_ptr,
 	int state_val = NODE_STATE_UNKNOWN;
 
 	if (node_ptr->state != NULL) {
-		state_val = state_str2int(node_ptr->state);
+		state_val = state_str2int(node_ptr->state, node_ptr->nodenames);
 		if (state_val == NO_VAL)
 			goto cleanup;
 	}
@@ -178,9 +178,9 @@ static int _build_single_nodeline_info(slurm_conf_node_t *node_ptr,
 
 	/* some sanity checks */
 #ifdef HAVE_FRONT_END
-	if ((hostlist_count(hostname_list) != 1) ||
-	    (hostlist_count(address_list)  != 1)) {
-		error("Only one hostname and address allowed "
+	if ((hostlist_count(hostname_list) > 1) ||
+	    (hostlist_count(address_list)  > 1)) {
+		error("Only one NodeHostName and NodeAddr are allowed "
 		      "in FRONT_END mode");
 		goto cleanup;
 	}
@@ -249,8 +249,9 @@ cleanup:
 static int _delete_config_record (void)
 {
 	last_node_update = time (NULL);
-	(void) list_delete_all (config_list,  &_list_find_config,  NULL);
-	(void) list_delete_all (feature_list, &_list_find_feature, NULL);
+	(void) list_delete_all (config_list,    &_list_find_config,  NULL);
+	(void) list_delete_all (feature_list,   &_list_find_feature, NULL);
+	(void) list_delete_all (front_end_list, &list_find_frontend, NULL);
 	return SLURM_SUCCESS;
 }
 
@@ -463,6 +464,91 @@ static int _list_find_feature (void *feature_entry, void *key)
 	return 0;
 }
 
+/* Log the contents of a frontend record */
+static void _dump_front_end(slurm_conf_frontend_t *fe_ptr)
+{
+	debug("fe name:%s addr:%s port:%u state:%u reason:%s",
+	      fe_ptr->frontends, fe_ptr->addresses,
+	      fe_ptr->port, fe_ptr->node_state, fe_ptr->reason);
+}
+
+/*
+ * build_all_frontend_info - get a array of slurm_conf_frontend_t structures
+ *	from the slurm.conf reader, build table, and set values
+ * RET 0 if no error, error code otherwise
+ */
+extern int build_all_frontend_info (void)
+{
+	slurm_conf_frontend_t **ptr_array;
+	slurm_conf_frontend_t *fe_single, *fe_line;
+	int i, count, max_rc = SLURM_SUCCESS;
+
+	count = slurm_conf_frontend_array(&ptr_array);
+#ifdef HAVE_FRONT_END
+	if (count == 0) {
+		verbose("No FrontendName information available!");
+		if (node_record_count == 0)
+			fatal("No nodes configured");
+		fe_single = xmalloc(sizeof(slurm_conf_frontend_t));
+		if (list_append(front_end_list, fe_single) == NULL)
+			fatal("list_append: malloc failure");
+		if (node_record_table_ptr->comm_name) {
+			fe_single->frontends = xstrdup(node_record_table_ptr->
+						       comm_name);
+			fe_single->addresses = xstrdup(node_record_table_ptr->
+						       comm_name);
+		} else {
+			fe_single->frontends = xstrdup(node_record_table_ptr->
+						       name);
+			fe_single->addresses = xstrdup(node_record_table_ptr->
+						       name);
+		}
+		fe_single->port = node_record_table_ptr->port;
+		fe_single->node_state = NODE_STATE_IDLE;
+		_dump_front_end(fe_single);
+	}
+
+	for (i = 0; i < count; i++) {
+		hostlist_t hl_name, hl_addr;
+		char *fe_name, *fe_addr;
+
+		fe_line = ptr_array[i];
+		hl_name = hostlist_create(fe_line->frontends);
+		if (hl_name == NULL)
+			fatal("Invalid FrontendName:%s", fe_line->frontends);
+		hl_addr = hostlist_create(fe_line->addresses);
+		if (hl_addr == NULL)
+			fatal("Invalid FrontendAddr:%s", fe_line->addresses);
+		if (hostlist_count(hl_name) != hostlist_count(hl_addr)) {
+			fatal("Inconsistent node count between "
+			      "FrontendName(%s) and FrontendAddr(%s)",
+			      fe_line->frontends, fe_line->addresses);
+		}
+		while ((fe_name = hostlist_shift(hl_name))) {
+			fe_addr = hostlist_shift(hl_addr);
+			fe_single = xmalloc(sizeof(slurm_conf_frontend_t));
+			if (list_append(front_end_list, fe_single) == NULL)
+				fatal("list_append: malloc failure");
+			fe_single->frontends = xstrdup(fe_name);
+			fe_single->addresses = xstrdup(fe_addr);
+			free(fe_name);
+			free(fe_addr);
+			fe_single->port = fe_line->port;
+			if (fe_line->reason && fe_line->reason[0])
+				fe_single->reason = xstrdup(fe_line->reason);
+			fe_single->node_state = fe_line->node_state;
+			_dump_front_end(fe_single);
+		}
+		hostlist_destroy(hl_addr);
+		hostlist_destroy(hl_name);
+	}
+#else
+	if (count != 0)
+		fatal("FrontendName information configured!");
+#endif
+	return max_rc;
+}
+
 /*
  * build_all_nodeline_info - get a array of slurm_conf_node_t structures
  *	from the slurm.conf reader, build table, and set values
@@ -704,9 +790,11 @@ extern int init_node_conf (void)
 	if (config_list)	/* delete defunct configuration entries */
 		(void) _delete_config_record ();
 	else {
-		config_list  = list_create (_list_delete_config);
-		feature_list = list_create (_list_delete_feature);
-		if ((config_list == NULL) || (feature_list == NULL))
+		config_list    = list_create (_list_delete_config);
+		feature_list   = list_create (_list_delete_feature);
+		front_end_list = list_create (destroy_frontend);
+		if ((config_list == NULL) || (feature_list == NULL) ||
+		    (front_end_list == NULL))
 			fatal("list_create malloc failure");
 	}
 
@@ -725,6 +813,8 @@ extern void node_fini2 (void)
 		config_list = NULL;
 		list_destroy(feature_list);
 		feature_list = NULL;
+		list_destroy(front_end_list);
+		front_end_list = NULL;
 	}
 
 	node_ptr = node_record_table_ptr;
@@ -838,7 +928,7 @@ extern void rehash_node (void)
 }
 
 /* Convert a node state string to it's equivalent enum value */
-extern int state_str2int(const char *state_str)
+extern int state_str2int(const char *state_str, char *node_name)
 {
 	int state_val = NO_VAL;
 	int i;
@@ -858,7 +948,7 @@ extern int state_str2int(const char *state_str)
 			state_val = NODE_STATE_IDLE | NODE_STATE_FAIL;
 	}
 	if (state_val == NO_VAL) {
-		error("invalid node state %s", state_str);
+		error("node %s has invalid state %s", node_name, state_str);
 		errno = EINVAL;
 	}
 	return state_val;
diff --git a/src/common/node_conf.h b/src/common/node_conf.h
index 7807359061b087ef7fc92b66717c4f5f1aecc38b..325823851e313ea28f37b48c14dfbedf0000cdd4 100644
--- a/src/common/node_conf.h
+++ b/src/common/node_conf.h
@@ -81,6 +81,8 @@ struct config_record {
 };
 extern List config_list;	/* list of config_record entries */
 
+extern List front_end_list;	/* list of slurm_conf_frontend_t entries */
+
 struct features_record {
 	uint32_t magic;		/* magic cookie to test data integrity */
 	char *name;		/* name of a feature */
@@ -167,8 +169,10 @@ extern time_t last_node_update;		/* time of last node record update */
  */
 char * bitmap2node_name (bitstr_t *bitmap);
 
+extern int build_all_frontend_info (void);
+
 /*
- * _build_all_nodeline_info - get a array of slurm_conf_node_t structures
+ * build_all_nodeline_info - get a array of slurm_conf_node_t structures
  *	from the slurm.conf reader, build table, and set values
  * IN set_bitmap - if true, set node_bitmap in config record (used by slurmd)
  * RET 0 if no error, error code otherwise
@@ -241,6 +245,6 @@ extern void purge_node_rec (struct node_record *node_ptr);
 extern void rehash_node (void);
 
 /* Convert a node state string to it's equivalent enum value */
-extern int state_str2int(const char *state_str);
+extern int state_str2int(const char *state_str, char *node_name);
 
 #endif /* !_HAVE_NODE_CONF_H */
diff --git a/src/common/read_config.c b/src/common/read_config.c
index f37bb3e461a89fc28d692f1489e0b31b2c869875..50025f2e09f9d0da0a889b4a07321bd7e282f70d 100644
--- a/src/common/read_config.c
+++ b/src/common/read_config.c
@@ -61,21 +61,23 @@
 #include <slurm/slurm.h>
 
 #include "src/common/hostlist.h"
-#include "src/common/slurm_protocol_defs.h"
-#include "src/common/slurm_protocol_api.h"
 #include "src/common/log.h"
 #include "src/common/macros.h"
+#include "src/common/node_conf.h"
+#include "src/common/parse_config.h"
 #include "src/common/parse_spec.h"
+#include "src/common/parse_time.h"
 #include "src/common/read_config.h"
-#include "src/common/xmalloc.h"
-#include "src/common/xstring.h"
+#include "src/common/slurm_protocol_api.h"
+#include "src/common/slurm_protocol_defs.h"
 #include "src/common/slurm_rlimits_info.h"
-#include "src/common/parse_config.h"
-#include "src/common/parse_time.h"
 #include "src/common/slurm_selecttype_info.h"
-#include "src/common/util-net.h"
-#include "src/common/uid.h"
 #include "src/common/strlcpy.h"
+#include "src/common/uid.h"
+#include "src/common/util-net.h"
+#include "src/common/xmalloc.h"
+#include "src/common/xstring.h"
+
 
 /*
 ** Define slurm-specific aliases for use by plugins, see slurm_xlator.h
@@ -93,6 +95,7 @@ static s_p_hashtbl_t *conf_hashtbl = NULL;
 static slurm_ctl_conf_t *conf_ptr = &slurmctld_conf;
 static bool conf_initialized = false;
 
+static s_p_hashtbl_t *default_frontend_tbl;
 static s_p_hashtbl_t *default_nodename_tbl;
 static s_p_hashtbl_t *default_partition_tbl;
 
@@ -118,10 +121,13 @@ bool nodehash_initialized = false;
 static names_ll_t *host_to_node_hashtbl[NAME_HASH_LEN] = {NULL};
 static names_ll_t *node_to_host_hashtbl[NAME_HASH_LEN] = {NULL};
 
+static void _destroy_nodename(void *ptr);
+static int _parse_frontend(void **dest, slurm_parser_enum_t type,
+			   const char *key, const char *value,
+			   const char *line, char **leftover);
 static int _parse_nodename(void **dest, slurm_parser_enum_t type,
 			   const char *key, const char *value,
 			   const char *line, char **leftover);
-static void _destroy_nodename(void *ptr);
 static bool _is_valid_path(char *path, char *msg);
 static int _parse_partitionname(void **dest, slurm_parser_enum_t type,
 				const char *key, const char *value,
@@ -282,6 +288,7 @@ s_p_options_t slurm_conf_options[] = {
 	{"VSizeFactor", S_P_UINT16},
 	{"WaitTime", S_P_UINT16},
 
+	{"FrontendName", S_P_ARRAY, _parse_frontend, destroy_frontend},
 	{"NodeName", S_P_ARRAY, _parse_nodename, _destroy_nodename},
 	{"PartitionName", S_P_ARRAY, _parse_partitionname,
 	 _destroy_partitionname},
@@ -393,6 +400,80 @@ static void _set_node_prefix(const char *nodenames)
 }
 #endif /* SYSTEM_DIMENSIONS > 1 */
 
+static int _parse_frontend(void **dest, slurm_parser_enum_t type,
+			   const char *key, const char *value,
+			   const char *line, char **leftover)
+{
+	s_p_hashtbl_t *tbl, *dflt;
+	slurm_conf_frontend_t *n;
+	char *node_state = NULL;
+	static s_p_options_t _frontend_options[] = {
+		{"FrontendAddr", S_P_STRING},
+		{"Port", S_P_UINT16},
+		{"Reason", S_P_STRING},
+		{"State", S_P_STRING},
+		{NULL}
+	};
+
+#ifndef HAVE_FRONT_END
+	fatal("Use of FrontendName in slurm.conf without SLURM being "
+	      "configured/built with the --have-front-end option");
+#endif
+
+	tbl = s_p_hashtbl_create(_frontend_options);
+	s_p_parse_line(tbl, *leftover, leftover);
+	/* s_p_dump_values(tbl, _frontend_options); */
+
+	if (strcasecmp(value, "DEFAULT") == 0) {
+		char *tmp;
+		if (s_p_get_string(&tmp, "FrontendAddr", tbl)) {
+			error("FrontendAddr not allowed with "
+			      "FrontendName=DEFAULT");
+			xfree(tmp);
+			s_p_hashtbl_destroy(tbl);
+			return -1;
+		}
+
+		if (default_frontend_tbl != NULL)
+			s_p_hashtbl_destroy(default_frontend_tbl);
+		default_frontend_tbl = tbl;
+
+		return 0;
+	} else {
+		n = xmalloc(sizeof(slurm_conf_frontend_t));
+		dflt = default_frontend_tbl;
+
+		n->frontends = xstrdup(value);
+
+		if (!s_p_get_string(&n->addresses, "FrontendAddr", tbl))
+			n->addresses = xstrdup(n->frontends);
+
+		if (!s_p_get_uint16(&n->port, "Port", tbl) &&
+		    !s_p_get_uint16(&n->port, "Port", dflt)) {
+			/* This gets resolved in slurm_conf_get_port()
+			 * and slurm_conf_get_addr(). For now just
+			 * leave with a value of zero */
+			n->port = 0;
+		}
+
+		if (!s_p_get_string(&n->reason, "Reason", tbl))
+			s_p_get_string(&n->reason, "Reason", dflt);
+
+		if (!s_p_get_string(&node_state, "State", tbl) &&
+		    !s_p_get_string(&node_state, "State", dflt))
+			n->node_state = NODE_STATE_UNKNOWN;
+		else {
+			n->node_state = state_str2int(node_state, value);
+			xfree(node_state);
+		}
+
+		*dest = (void *)n;
+
+		return 1;
+	}
+
+	/* should not get here */
+}
 
 static int _parse_nodename(void **dest, slurm_parser_enum_t type,
 			   const char *key, const char *value,
@@ -459,10 +540,21 @@ static int _parse_nodename(void **dest, slurm_parser_enum_t type,
 			_set_node_prefix(n->nodenames);
 #endif
 
+#ifdef HAVE_FRONT_END
+		if (!s_p_get_string(&n->hostnames, "NodeHostname", tbl))
+			xfree(n->hostnames);
+		if (!s_p_get_string(&n->addresses, "NodeAddr", tbl))
+			xfree(n->addresses);
+		else {
+			verbose("Use FrontendNode/FrondendAddr configuration "
+				"options instead of NodeAddr");
+		}
+#else
 		if (!s_p_get_string(&n->hostnames, "NodeHostname", tbl))
 			n->hostnames = xstrdup(n->nodenames);
 		if (!s_p_get_string(&n->addresses, "NodeAddr", tbl))
 			n->addresses = xstrdup(n->hostnames);
+#endif
 
 		if (!s_p_get_uint16(&n->cores, "CoresPerSocket", tbl)
 		    && !s_p_get_uint16(&n->cores, "CoresPerSocket", dflt)) {
@@ -581,6 +673,35 @@ static int _parse_nodename(void **dest, slurm_parser_enum_t type,
 	/* should not get here */
 }
 
+/* Destroy a front_end record built by slurm_conf_frontend_array() */
+extern void destroy_frontend(void *ptr)
+{
+	slurm_conf_frontend_t *n = (slurm_conf_frontend_t *) ptr;
+	xfree(n->frontends);
+	xfree(n->addresses);
+	xfree(n->reason);
+	xfree(ptr);
+}
+
+/*
+ * list_find_frontend - find an entry in the front_end list, see list.h for
+ *	documentation
+ * IN key - is feature name or NULL for all features
+ * RET 1 if found, 0 otherwise
+ */
+extern int list_find_frontend (void *front_end_entry, void *key)
+{
+	slurm_conf_frontend_t *front_end_ptr;
+
+	if (key == NULL)
+		return 1;
+
+	front_end_ptr = (slurm_conf_frontend_t *) front_end_entry;
+	if (strcmp(front_end_ptr->frontends, (char *) key) == 0)
+		return 1;
+	return 0;
+}
+
 static void _destroy_nodename(void *ptr)
 {
 	slurm_conf_node_t *n = (slurm_conf_node_t *)ptr;
@@ -594,6 +715,22 @@ static void _destroy_nodename(void *ptr)
 	xfree(ptr);
 }
 
+int slurm_conf_frontend_array(slurm_conf_frontend_t **ptr_array[])
+{
+	int count;
+	slurm_conf_frontend_t **ptr;
+
+	if (s_p_get_array((void ***)&ptr, &count, "FrontendName",
+			  conf_hashtbl)) {
+		*ptr_array = ptr;
+		return count;
+	} else {
+		*ptr_array = NULL;
+		return 0;
+	}
+}
+
+
 int slurm_conf_nodename_array(slurm_conf_node_t **ptr_array[])
 {
 	int count;
@@ -608,7 +745,6 @@ int slurm_conf_nodename_array(slurm_conf_node_t **ptr_array[])
 	}
 }
 
-
 static int _parse_partitionname(void **dest, slurm_parser_enum_t type,
 			       const char *key, const char *value,
 			       const char *line, char **leftover)
@@ -939,10 +1075,14 @@ static void _init_name_hashtbl()
 
 static int _get_hash_idx(const char *s)
 {
-	int i;
+	int i = 0;
+
+	if (s) {
+		while (*s) {
+			i += (int)*s++;
+		}
+	}
 
-	i = 0;
-	while (*s) i += (int)*s++;
 	return i % NAME_HASH_LEN;
 }
 
@@ -961,8 +1101,8 @@ static void _push_to_hashtbls(char *alias, char *hostname,
 	/* Ensure only one slurmd configured on each host */
 	p = host_to_node_hashtbl[hostname_idx];
 	while (p) {
-		if (strcmp(p->hostname, hostname)==0) {
-			error("Duplicated NodeHostname %s in the config file",
+		if (strcmp(p->hostname, hostname) == 0) {
+			error("Duplicated NodeHostName %s in the config file",
 			      hostname);
 			return;
 		}
@@ -1029,7 +1169,7 @@ static int _register_conf_node_aliases(slurm_conf_node_t *node_ptr)
 	char *address = NULL;
 	int error_code = SLURM_SUCCESS;
 
-	if (node_ptr->nodenames == NULL || *node_ptr->nodenames == '\0')
+	if ((node_ptr->nodenames == NULL) || (node_ptr->nodenames[0] == '\0'))
 		return -1;
 
 	if ((alias_list = hostlist_create(node_ptr->nodenames)) == NULL) {
@@ -1058,10 +1198,11 @@ static int _register_conf_node_aliases(slurm_conf_node_t *node_ptr)
 
 	/* some sanity checks */
 #ifdef HAVE_FRONT_END
-	if (hostlist_count(hostname_list) != 1
-	    || hostlist_count(address_list) != 1) {
-		error("Only one hostname and address allowed "
+	if ((hostlist_count(hostname_list) > 1) ||
+	    (hostlist_count(address_list)  > 1)) {
+		error("Only one NodeHostName and NodeAddr allowed "
 		      "in FRONT_END mode");
+		error("Use FrontendNode/FrondendAddr configuration options");
 		goto cleanup;
 	}
 
@@ -1120,15 +1261,14 @@ static void _init_slurmd_nodehash(void)
 	else
 		nodehash_initialized = true;
 
-	if(!conf_initialized) {
+	if (!conf_initialized) {
 		_init_slurm_conf(NULL);
 		conf_initialized = true;
 	}
 
 	count = slurm_conf_nodename_array(&ptr_array);
-	if (count == 0) {
+	if (count == 0)
 		return;
-	}
 
 	for (i = 0; i < count; i++) {
 		_register_conf_node_aliases(ptr_array[i]);
@@ -1179,6 +1319,30 @@ extern char *slurm_conf_get_hostname(const char *node_name)
  */
 extern char *slurm_conf_get_nodename(const char *node_hostname)
 {
+	names_ll_t *p;
+	char *alias = NULL;
+#ifdef HAVE_FRONT_END
+	slurm_conf_frontend_t *front_end_ptr = NULL;
+
+	slurm_conf_lock();
+	_init_slurmd_nodehash();
+
+	if (!front_end_list) {
+		error("front_end_list is NULL");
+	} else {
+		front_end_ptr = list_find_first(front_end_list,
+						list_find_frontend,
+						(char *) node_hostname);
+	}
+	if (front_end_ptr) {
+		p = host_to_node_hashtbl[0];
+		if (p)
+			alias = xstrdup(p->alias);
+	}
+	slurm_conf_unlock();
+
+	return alias;
+#else
 	int idx;
 	names_ll_t *p;
 
@@ -1189,15 +1353,15 @@ extern char *slurm_conf_get_nodename(const char *node_hostname)
 	p = host_to_node_hashtbl[idx];
 	while (p) {
 		if (strcmp(p->hostname, node_hostname) == 0) {
-			char *alias = xstrdup(p->alias);
-			slurm_conf_unlock();
-			return alias;
+			alias = xstrdup(p->alias);
+			break
 		}
 		p = p->next_hostname;
 	}
 	slurm_conf_unlock();
 
-	return NULL;
+	return alias
+#endif
 }
 
 /*
@@ -1677,6 +1841,10 @@ static void
 _destroy_slurm_conf(void)
 {
 	s_p_hashtbl_destroy(conf_hashtbl);
+	if (default_frontend_tbl != NULL) {
+		s_p_hashtbl_destroy(default_frontend_tbl);
+		default_frontend_tbl = NULL;
+	}
 	if (default_nodename_tbl != NULL) {
 		s_p_hashtbl_destroy(default_nodename_tbl);
 		default_nodename_tbl = NULL;
diff --git a/src/common/read_config.h b/src/common/read_config.h
index ffe660bccf3266e1a663690bb4985e77aa5a7149..7c2f600b3d06c6ed1dc826661555dda2fadab4d5 100644
--- a/src/common/read_config.h
+++ b/src/common/read_config.h
@@ -43,6 +43,7 @@
 #ifndef _READ_CONFIG_H
 #define _READ_CONFIG_H
 
+#include "src/common/list.h"
 #include "src/common/slurm_protocol_defs.h"
 #include "src/common/slurm_protocol_socket_common.h"
 #include "src/common/parse_config.h"
@@ -151,6 +152,16 @@ extern char *default_plugstack;
 #define DEFAULT_UNKILLABLE_TIMEOUT  60 /* seconds */
 #define DEFAULT_MAX_TASKS_PER_NODE  128
 
+typedef struct slurm_conf_frontend {
+	char *frontends;		/* frontend node name */
+	char *addresses;		/* frontend node address */
+	uint16_t port;			/* frontend specific port */
+	char *reason;			/* reason for down frontend node */
+	uint16_t node_state;		/* enum node_states, ORed with
+					 * NODE_STATE_NO_RESPOND if not
+					 * responding */
+} slurm_conf_frontend_t;
+
 typedef struct slurm_conf_node {
 	char *nodenames;
 	char *hostnames;
@@ -210,6 +221,17 @@ typedef struct {
 	char *value;
 } config_key_pair_t;
 
+/* Destroy a front_end record built by slurm_conf_frontend_array() */
+extern void destroy_frontend(void *ptr);
+
+/*
+ * list_find_frontend - find an entry in the front_end list, see list.h for
+ *	documentation
+ * IN key - is feature name or NULL for all features
+ * RET 1 if found, 0 otherwise
+ */
+extern int list_find_frontend (void *front_end_entry, void *key);
+
 /*
  * slurm_conf_init - load the slurm configuration from the a file.
  * IN file_name - name of the slurm configuration file to be read
@@ -257,6 +279,15 @@ extern slurm_ctl_conf_t *slurm_conf_lock(void);
 
 extern void slurm_conf_unlock(void);
 
+
+/*
+ * Set "ptr_array" with the pointer to an array of pointers to
+ * slurm_conf_frontend_t structures.
+ *
+ * Return value is the length of the array.
+ */
+extern int slurm_conf_frontend_array(slurm_conf_frontend_t **ptr_array[]);
+
 /*
  * Set "ptr_array" with the pointer to an array of pointers to
  * slurm_conf_node_t structures.
diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c
index 5379b35615c7c286ccd05fcf0e100e8fdcbc9572..faf49f9cf4e179a79d60459eb06b86d7670b7376 100644
--- a/src/slurmctld/node_mgr.c
+++ b/src/slurmctld/node_mgr.c
@@ -724,6 +724,7 @@ static void _pack_node (struct node_record *dump_node_ptr, Buf buffer,
  */
 void set_slurmd_addr (void)
 {
+#ifndef HAVE_FRONT_END
 	int i;
 	struct node_record *node_ptr = node_record_table_ptr;
 	DEF_TIMERS;
@@ -747,7 +748,7 @@ void set_slurmd_addr (void)
 	}
 
 	END_TIMER2("set_slurmd_addr");
-	return;
+#endif
 }
 
 /*
diff --git a/src/slurmctld/read_config.c b/src/slurmctld/read_config.c
index cce432765c93058fd5157fb89207faa7ce5655b8..2276e3f17cec42258d9ca6ce964b8579fc944d5b 100644
--- a/src/slurmctld/read_config.c
+++ b/src/slurmctld/read_config.c
@@ -326,7 +326,7 @@ static int _handle_downnodes_line(slurm_conf_downnodes_t *down)
 	int state_val = NODE_STATE_DOWN;
 
 	if (down->state != NULL) {
-		state_val = state_str2int(down->state);
+		state_val = state_str2int(down->state, down->nodenames);
 		if (state_val == NO_VAL) {
 			error("Invalid State \"%s\"", down->state);
 			goto cleanup;
@@ -398,6 +398,7 @@ static int _build_all_nodeline_info(void)
 
 	/* Load the node table here */
 	rc = build_all_nodeline_info(false);
+	rc = MAX(build_all_frontend_info(), rc);
 
 	/* Now perform operations on the node table as needed by slurmctld */
 #ifdef HAVE_BG
diff --git a/src/slurmd/slurmd/slurmd.c b/src/slurmd/slurmd/slurmd.c
index 89378901b4e689a493e19f1b525e621c481e0e3f..8e36dd61fcc5677c93bf3f7c74cf3cea2781e5d5 100644
--- a/src/slurmd/slurmd/slurmd.c
+++ b/src/slurmd/slurmd/slurmd.c
@@ -203,7 +203,7 @@ main (int argc, char *argv[])
 	conf->argc = &argc;
 	slurmd_uid = slurm_get_slurmd_user_id();
 	curr_uid = getuid();
-	if(curr_uid != slurmd_uid) {
+	if (curr_uid != slurmd_uid) {
 		struct passwd *pw = NULL;
 		char *slurmd_user = NULL;
 		char *curr_user = NULL;
@@ -761,7 +761,6 @@ _read_config(void)
 
 	conf->block_map_size = 0;
 
-	_update_logging();
 	_update_nice();
 		
 	get_procs(&conf->actual_cpus);
@@ -785,11 +784,11 @@ _read_config(void)
 		conf->threads = conf->conf_threads;
 	}
 
-	if(cf->fast_schedule &&
-	   ((conf->cpus    != conf->actual_cpus)    ||
-	    (conf->sockets != conf->actual_sockets) ||
-	    (conf->cores   != conf->actual_cores)   ||
-	    (conf->threads != conf->actual_threads))) {
+	if (cf->fast_schedule &&
+	    ((conf->cpus    != conf->actual_cpus)    ||
+	     (conf->sockets != conf->actual_sockets) ||
+	     (conf->cores   != conf->actual_cores)   ||
+	     (conf->threads != conf->actual_threads))) {
 		info("Node configuration differs from hardware\n"
 		     "   Procs=%u:%u(hw) Sockets=%u:%u(hw)\n"
 		     "   CoresPerSocket=%u:%u(hw) ThreadsPerCore=%u:%u(hw)",
@@ -847,6 +846,7 @@ _reconfigure(void)
 	bool did_change;
 
 	_reconfig = 0;
+	_update_logging();
 	_read_config();
 
 	/*
@@ -855,7 +855,6 @@ _reconfigure(void)
 	slurm_topo_build_config();
 	_set_topo_info();
 
-	/* _update_logging(); */
 	_print_conf();
 
 	/*
@@ -1181,13 +1180,21 @@ _slurmd_init(void)
 	 * an alternate location for the slurm config file.
 	 */
 	_process_cmdline(*conf->argc, *conf->argv);
+	_update_logging();
+
+	/*
+	 * Build nodes table like in slurmctld
+	 * This is required by the topology stack
+	 */
+	init_node_conf();
+	build_all_nodeline_info(true);
+	build_all_frontend_info();
 
 	/*
 	 * Read global slurm config file, ovverride necessary values from
 	 * defaults and command line.
-	 *
 	 */
-	_read_config();
+	_read_config();		// SETUP LOGGING EARLIER
 	cpu_cnt = MAX(conf->conf_cpus, conf->block_map_size);
 	if ((gres_plugin_init() != SLURM_SUCCESS) ||
 	    (gres_plugin_node_config_load(cpu_cnt) != SLURM_SUCCESS))
@@ -1195,25 +1202,12 @@ _slurmd_init(void)
 	if (slurm_topo_init() != SLURM_SUCCESS)
 		return SLURM_FAILURE;
 
-	/*
-	 * Build nodes table like in slurmctld
-	 * This is required by the topology stack
-	 */
-	init_node_conf();
-	build_all_nodeline_info(true);
-
 	/*
 	 * Get and set slurmd topology information
 	 */
 	slurm_topo_build_config();
 	_set_topo_info();
 
-	/*
-	 * Update location of log messages (syslog, stderr, logfile, etc.),
-	 * print current configuration (if in debug mode), and
-	 * load appropriate plugin(s).
-	 */
-	/* _update_logging(); */
 	_print_conf();
 	if (slurm_proctrack_init() != SLURM_SUCCESS)
 		return SLURM_FAILURE;