diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c
index 0bcffab0df0a66c9771011e7ea3dedfbbc76f609..362b75078c19ac28021fc6cdf02bff213239ae4c 100644
--- a/src/slurmctld/node_mgr.c
+++ b/src/slurmctld/node_mgr.c
@@ -1094,8 +1094,7 @@ int update_node ( update_node_msg_t * update_node_msg )
 	}
 	hostlist_destroy (host_list);
 
-	if ((error_code == 0) && (update_node_msg->features) &&
-	    (update_node_msg->features[0])) {
+	if ((error_code == 0) && (update_node_msg->features)) {
 		error_code = _update_node_features(
 			update_node_msg->node_names, 
 			update_node_msg->features);
diff --git a/src/sview/node_info.c b/src/sview/node_info.c
index 9d1da3d2f2e0f6614d748445ecd4b2bef05fb7a9..9dde59206d808de058528b2889f312ac98fb9fab 100644
--- a/src/sview/node_info.c
+++ b/src/sview/node_info.c
@@ -63,7 +63,7 @@ static display_data_t display_data_node[] = {
 	 create_model_node, admin_edit_node},
 	{G_TYPE_INT, SORTID_WEIGHT,"Weight", FALSE, -1, refresh_node,
 	 create_model_node, admin_edit_node},
-	{G_TYPE_STRING, SORTID_FEATURES, "Features", FALSE, -1, refresh_node,
+	{G_TYPE_STRING, SORTID_FEATURES, "Features", FALSE, 1, refresh_node,
 	 create_model_node, admin_edit_node},
 	{G_TYPE_STRING, SORTID_REASON, "Reason", FALSE, -1, refresh_node,
 	 create_model_node, admin_edit_node},
@@ -88,6 +88,7 @@ static display_data_t options_data_node[] = {
 	{G_TYPE_STRING, NODE_PAGE, "Put Node Down", TRUE, ADMIN_PAGE},
 	{G_TYPE_STRING, NODE_PAGE, "Make Node Idle", TRUE, ADMIN_PAGE},
 #endif
+	{G_TYPE_STRING, NODE_PAGE, "Update Features", TRUE, ADMIN_PAGE},
 	{G_TYPE_STRING, JOB_PAGE, "Jobs", TRUE, NODE_PAGE},
 #ifdef HAVE_BG
 	{G_TYPE_STRING, BLOCK_PAGE, "Blocks", TRUE, NODE_PAGE},
@@ -436,9 +437,95 @@ extern int get_new_info_node(node_info_msg_t **info_ptr, int force)
 	*info_ptr = new_node_ptr;
 	return error_code;
 }
+
+extern int update_features_node(GtkDialog *dialog, const char *nodelist,
+				const char *old_features)
+{
+	char tmp_char[100];
+	char *edit = NULL;
+	GtkWidget *entry = NULL;
+	GtkWidget *label = NULL;
+	update_node_msg_t *node_msg = xmalloc(sizeof(update_node_msg_t));
+	int response = 0;
+	int no_dialog = 0;
+	int rc = SLURM_SUCCESS;
+	
+	if(!dialog) {
+		snprintf(tmp_char, sizeof(tmp_char),
+			 "Update Features for Node(s) %s?", nodelist);
+	
+		dialog = GTK_DIALOG(
+			gtk_dialog_new_with_buttons(
+				tmp_char,
+				GTK_WINDOW(main_window),
+				GTK_DIALOG_MODAL
+				| GTK_DIALOG_DESTROY_WITH_PARENT,
+				NULL));	
+		no_dialog = 1;
+	}
+	label = gtk_dialog_add_button(dialog,
+				      GTK_STOCK_YES, GTK_RESPONSE_OK);
+	gtk_window_set_default(GTK_WINDOW(dialog), label);
+	gtk_dialog_add_button(dialog,
+			      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+	node_msg->node_names = xstrdup(nodelist);
+	node_msg->features = NULL;
+	node_msg->reason = NULL;
+	node_msg->node_state = (uint16_t) NO_VAL;
+	
+	snprintf(tmp_char, sizeof(tmp_char),
+		 "Features for Node(s) %s?", nodelist);
+	label = gtk_label_new(tmp_char);		
+	gtk_box_pack_start(GTK_BOX(dialog->vbox), 
+			   label, FALSE, FALSE, 0);
+	
+	entry = create_entry();
+	if(!entry)
+		goto end_it;
+
+	if(old_features) 
+		gtk_entry_set_text(GTK_ENTRY(entry), old_features);
+	
+	gtk_box_pack_start(GTK_BOX(dialog->vbox), entry, TRUE, TRUE, 0);
+	gtk_widget_show_all(GTK_WIDGET(dialog));
+	
+	response = gtk_dialog_run(dialog);
+	if (response == GTK_RESPONSE_OK) {				
+		node_msg->features =
+			xstrdup(gtk_entry_get_text(GTK_ENTRY(entry)));
+		if(!node_msg->features) {
+			edit = g_strdup_printf("No features given.");
+			display_edit_note(edit);
+			g_free(edit);
+			goto end_it;
+		}
+		if(slurm_update_node(node_msg) == SLURM_SUCCESS) {
+			edit = g_strdup_printf(
+				"Nodes %s updated successfully.",
+				nodelist);
+			display_edit_note(edit);
+			g_free(edit);
+			
+		} else {
+			edit = g_strdup_printf(
+				"Problem updating nodes %s.",
+				nodelist);
+			display_edit_note(edit);
+			g_free(edit);
+		}
+	}
+
+end_it:
+	slurm_free_update_node_msg(node_msg);
+	if(no_dialog)
+		gtk_widget_destroy(GTK_WIDGET(dialog));
 		
-extern int update_state_node2(GtkDialog *dialog,
-			      const char *nodelist, const char *type)
+	return rc;
+}
+		
+extern int update_state_node(GtkDialog *dialog,
+			     const char *nodelist, const char *type)
 {
 	uint16_t state = (uint16_t) NO_VAL;
 	char *upper = NULL, *lower = NULL;		     
@@ -505,6 +592,8 @@ extern int update_state_node2(GtkDialog *dialog,
 			xfree(lower);
 		}
 	}
+	if(!label)
+		goto end_it;
 	node_msg->node_state = (uint16_t)state;
 	gtk_box_pack_start(GTK_BOX(dialog->vbox), label, FALSE, FALSE, 0);
 	if(entry)
@@ -612,10 +701,7 @@ extern void admin_edit_node(GtkCellRendererText *cell,
 				   SORTID_NAME, 
 				   &nodelist, -1);
 		
-/* 		update_state_node(treestore, &iter,  */
-/* 				  SORTID_STATE, SORTID_STATE_NUM, */
-/* 				  new_text, &node_msg); */
-		update_state_node2(NULL, nodelist, new_text); 
+		update_state_node(NULL, nodelist, new_text); 
 				  
 		g_free(nodelist);
 	default:
@@ -1000,7 +1086,6 @@ extern void popup_all_node(GtkTreeModel *model, GtkTreeIter *iter, int id)
 extern void admin_node(GtkTreeModel *model, GtkTreeIter *iter, char *type)
 {
 	char *name = NULL;
-						
 	GtkWidget *popup = gtk_dialog_new_with_buttons(
 		type,
 		GTK_WINDOW(main_window),
@@ -1010,9 +1095,15 @@ extern void admin_node(GtkTreeModel *model, GtkTreeIter *iter, char *type)
 
 	gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1);
 		
-	/* something that has to deal with a node state change */
-	update_state_node2(GTK_DIALOG(popup), name, type);
-	
+	if(!strcasecmp("Update Features", type)) { /* update features */
+		char *old_features = NULL;
+		gtk_tree_model_get(model, iter, SORTID_FEATURES,
+				   &old_features, -1);
+		update_features_node(GTK_DIALOG(popup), name, old_features);
+		g_free(old_features);
+
+	} else /* something that has to deal with a node state change */
+		update_state_node(GTK_DIALOG(popup), name, type);
 	g_free(name);
 	gtk_widget_destroy(popup);
 		
diff --git a/src/sview/part_info.c b/src/sview/part_info.c
index 3c78593baf08eea5e8470c5c72948a54c1a44ae6..a4ea7b789ee9be764cbe1551e92226af7229cc46 100644
--- a/src/sview/part_info.c
+++ b/src/sview/part_info.c
@@ -74,6 +74,7 @@ enum {
 #endif
 	SORTID_CPUS, 
 	SORTID_DEFAULT,
+	SORTID_FEATURES, 
 	SORTID_GROUPS,
 	SORTID_HIDDEN,
 	SORTID_JOB_SIZE,
@@ -86,6 +87,7 @@ enum {
 #endif
 	SORTID_NODES, 
 	SORTID_ONLY_LINE, 
+	SORTID_REASON,
 	SORTID_ROOT, 
 	SORTID_SHARE, 
 	SORTID_STATE,
@@ -140,6 +142,10 @@ static display_data_t display_data_part[] = {
 	 create_model_part, admin_edit_part},
 	{G_TYPE_STRING, SORTID_WEIGHT, "Weight", FALSE, -1, refresh_part,
 	 create_model_part, admin_edit_part},
+	{G_TYPE_STRING, SORTID_FEATURES, "Features", FALSE, 1, refresh_part,
+	 create_model_part, admin_edit_part},
+	{G_TYPE_STRING, SORTID_REASON, "Reason", FALSE, -1, refresh_part,
+	 create_model_part, admin_edit_part},
 	{G_TYPE_INT, SORTID_STATE_NUM, NULL, FALSE, -1, refresh_part,
 	 create_model_part, admin_edit_part},
 	{G_TYPE_INT, SORTID_ONLY_LINE, NULL, FALSE, -1, refresh_part,
@@ -160,11 +166,14 @@ static display_data_t options_data_part[] = {
 	 TRUE, ADMIN_PAGE},
 	{G_TYPE_STRING, PART_PAGE, "Make Base Partitions Idle",
 	 TRUE, ADMIN_PAGE},
+	{G_TYPE_STRING, PART_PAGE, "Update Base Partition Features",
+	 TRUE, ADMIN_PAGE},
 #else
 	{G_TYPE_STRING, PART_PAGE, "Drain Nodes", TRUE, ADMIN_PAGE},
 	{G_TYPE_STRING, PART_PAGE, "Resume Nodes", TRUE, ADMIN_PAGE},
 	{G_TYPE_STRING, PART_PAGE, "Put Nodes Down", TRUE, ADMIN_PAGE},
 	{G_TYPE_STRING, PART_PAGE, "Make Nodes Idle", TRUE, ADMIN_PAGE},
+	{G_TYPE_STRING, PART_PAGE, "Update Node Features", TRUE, ADMIN_PAGE},
 #endif
 	{G_TYPE_STRING, PART_PAGE, "Change Availablity Up/Down",
 	 TRUE, ADMIN_PAGE},
@@ -660,6 +669,7 @@ static void _layout_part_record(GtkTreeView *treeview,
 	sview_part_sub_t other_part_sub;
 	char tmp[1024];
 	char *temp_char = NULL;
+	int global_set = 0;
 
 	GtkTreeStore *treestore = 
 		GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
@@ -810,6 +820,13 @@ static void _layout_part_record(GtkTreeView *treeview,
 		
 		temp_part_sub->min_weight += sview_part_sub->min_weight;
 		temp_part_sub->max_weight += sview_part_sub->max_weight;
+		if(!global_set) {
+			global_set = 1;
+			/* store features and reasons in the others
+			   group */
+			other_part_sub.features = temp_part_sub->features;
+			other_part_sub.reason = temp_part_sub->reason;
+		}
 	}
 	convert_num_unit((float)alloc_part_sub.node_cnt, tmp_cnt, UNIT_NONE);
 	convert_num_unit((float)idle_part_sub.node_cnt, tmp_cnt1, UNIT_NONE);
@@ -819,6 +836,15 @@ static void _layout_part_record(GtkTreeView *treeview,
 	add_display_treestore_line(update, treestore, &iter,
 				   "Nodes (Allocated/Idle/Other)",
 				   tmp);
+	add_display_treestore_line(update, treestore, &iter, 
+				   find_col_name(display_data_part,
+						 SORTID_FEATURES), 
+				   other_part_sub.features);
+	add_display_treestore_line(update, treestore, &iter, 
+				   find_col_name(display_data_part,
+						 SORTID_REASON), 
+				   other_part_sub.reason);
+
 }
 
 static void _update_part_record(sview_part_info_t *sview_part_info,
@@ -922,6 +948,8 @@ static void _update_part_record(sview_part_info_t *sview_part_info,
 	gtk_tree_store_set(treestore, iter, SORTID_MEM, "", -1);
 	gtk_tree_store_set(treestore, iter, SORTID_WEIGHT, "", -1);
 	gtk_tree_store_set(treestore, iter, SORTID_UPDATED, 1, -1);	
+	gtk_tree_store_set(treestore, iter, SORTID_FEATURES, "", -1);	
+	gtk_tree_store_set(treestore, iter, SORTID_REASON, "", -1);	
 	
 	childern = gtk_tree_model_iter_children(GTK_TREE_MODEL(treestore),
 						&sub_iter, iter);
@@ -983,6 +1011,10 @@ static void _update_part_sub_record(sview_part_sub_t *sview_part_sub,
 			   tmp, -1);
 	gtk_tree_store_set(treestore, iter, SORTID_UPDATED, 1, -1);	
 	
+	gtk_tree_store_set(treestore, iter, SORTID_FEATURES,
+			   sview_part_sub->features, -1);
+	gtk_tree_store_set(treestore, iter, SORTID_REASON,
+			   sview_part_sub->reason, -1);
 		
 	return;
 }
@@ -1574,7 +1606,6 @@ extern void admin_edit_part(GtkCellRendererText *cell,
 	GtkTreeStore *treestore = GTK_TREE_STORE(data);
 	GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
 	GtkTreeIter iter;
-	update_node_msg_t *node_msg = xmalloc(sizeof(update_node_msg_t));
 	update_part_msg_t *part_msg = xmalloc(sizeof(update_part_msg_t));
 	
 	char *temp = NULL;
@@ -1636,7 +1667,6 @@ extern void admin_edit_part(GtkCellRendererText *cell,
 	}
 no_input:
 	slurm_free_update_part_msg(part_msg);
-	slurm_free_update_node_msg(node_msg);
 	gtk_tree_path_free (path);
 	g_free(old_text);
 	g_static_mutex_unlock(&sview_mutex);
@@ -2127,7 +2157,7 @@ extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type)
 	slurm_init_part_desc_msg(part_msg);
 	
 	part_msg->name = xstrdup(partid);
-
+		
 	if(!strcasecmp("Change Availablity Up/Down", type)) {
 		label = gtk_dialog_add_button(GTK_DIALOG(popup),
 					      GTK_STOCK_YES, GTK_RESPONSE_OK);
@@ -2158,9 +2188,17 @@ extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type)
 		label = gtk_label_new(tmp_char);
 		edit_type = EDIT_EDIT;
 		entry = _admin_full_edit_part(part_msg, model, iter);
+	} else if(!strncasecmp("Update", type, 6)) {
+		char *old_features = NULL;
+		gtk_tree_model_get(model, iter, SORTID_FEATURES,
+				   &old_features, -1);
+		update_features_node(GTK_DIALOG(popup),
+				     nodelist, old_features);
+		g_free(old_features);
+		goto end_it;
 	} else {
 		/* something that has to deal with a node state change */
-		update_state_node2(GTK_DIALOG(popup), nodelist, type);
+		update_state_node(GTK_DIALOG(popup), nodelist, type);
 		goto end_it;
 	}
 
@@ -2194,6 +2232,7 @@ extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type)
 		}
 	}
 end_it:
+		
 	g_free(state);
 	g_free(partid);
 	g_free(nodelist);
diff --git a/src/sview/sview.h b/src/sview/sview.h
index b543574795ded24b59c1a0720cf09004bc3db55f..a8726955b6f38c08234375b34a87738d806914bd 100644
--- a/src/sview/sview.h
+++ b/src/sview/sview.h
@@ -331,8 +331,10 @@ extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, char *type);
 extern void refresh_node(GtkAction *action, gpointer user_data);
 /* don't destroy the list from this function */
 extern List create_node_info_list(node_info_msg_t *node_info_ptr, int changed);
-extern int update_state_node2(GtkDialog *dialog,
-			      const char *nodelist, const char *type);
+extern int update_features_node(GtkDialog *dialog, const char *nodelist,
+				const char *old_features);
+extern int update_state_node(GtkDialog *dialog,
+			     const char *nodelist, const char *type);
 extern GtkListStore *create_model_node(int type);
 extern void admin_edit_node(GtkCellRendererText *cell,
 			    const char *path_string,