Просмотр исходного кода

This patch improves AMF's behaviour for handling component instantiation level.
AMF is complemented to handle termination and instantiation with respect to
instantiation level also for the following scenarios:
- SU restart
- termination/instantiation errors during component/SU restart
- instantiation error during cluster start up



git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1352 fd59a12c-fef9-0310-b244-a6a79926bd2f

Hans Feldt 19 лет назад
Родитель
Сommit
1675a43aef
4 измененных файлов с 277 добавлено и 139 удалено
  1. 2 1
      exec/amf.h
  2. 2 0
      exec/amfnode.c
  3. 4 1
      exec/amfsg.c
  4. 269 137
      exec/amfsu.c

+ 2 - 1
exec/amf.h

@@ -177,7 +177,8 @@ typedef enum {
 	SU_RC_RESTART_SU_TERMINATING,
 	SU_RC_RESTART_SU_INSTANTIATING,
 	SU_RC_RESTART_SU_SETTING,
-	SU_RC_RESTART_SU_ACTIVATING
+	SU_RC_RESTART_SU_ACTIVATING,
+	SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED
 } su_restart_control_state_t;
 
 typedef enum {

+ 2 - 0
exec/amfnode.c

@@ -283,7 +283,9 @@ static int has_all_sg_on_node_failed_over (amf_node_t *node)
 		for (sg = app->sg_head; sg != NULL; sg = sg->next) {
 			for (su = sg->su_head; su != NULL; su = su->next) {
 				if (name_match(&su->saAmfSUHostedByNode, &node->name)) {
+
 					if (sg->avail_state != SG_AC_Idle) {
+						TRACE1("%s %s",sg->name.value, su->name.value);
 						has_all_sg_on_node_failed_over = 0;
 						goto out;
 					}

+ 4 - 1
exec/amfsg.c

@@ -2465,6 +2465,7 @@ void amf_sg_su_state_changed (struct amf_sg *sg, struct amf_su *su,
 {
 	ENTER ("'%s' SU '%s' state %s",
 		sg->name.value, su->name.value, amf_presence_state(state));
+
 	if (sg->avail_state != SG_AC_Idle) {
 		if (type == SA_AMF_PRESENCE_STATE) {
 			switch (state) {
@@ -2483,6 +2484,9 @@ void amf_sg_su_state_changed (struct amf_sg *sg, struct amf_su *su,
 				case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
 					amf_sg_su_state_changed_to_instantiation_failed(sg, su);
 					break;
+				case SA_AMF_PRESENCE_TERMINATING:
+					; /* nop */
+					break;
 				default :
 					dprintf("sg->avail_state = %d, su instantiation state = %d",
 						sg->avail_state, state);
@@ -2491,7 +2495,6 @@ void amf_sg_su_state_changed (struct amf_sg *sg, struct amf_su *su,
 			}
 		}
 	}
-
 }
 
 /**

+ 269 - 137
exec/amfsu.c

@@ -117,31 +117,53 @@
  * 1.1  State Transition Table
  * ===========================
  * 
- * State:                  Event:                Action:  New state:
+ * State:                  Event:                 Action:  New state:
  * ===========================================================================
- * IDLE_ESCALATION_x       comp_restart          A9       RS_COMP_RESTARTING
- * IDLE_ESCALATION_x       su_restart            A20      RS_SU_INSTANTIATING
- * IDLE_ESCALATION_0       error_suspected       A1       IDLE_ESCALATION_1
- * IDLE_ESCALATION_1       error_suspected [!C3] A1       IDLE_ESCALATION_1
- * IDLE_ESCALATION_1       error_suspected [C3]  A2       IDLE_ESCALATION_2
- * IDLE_ESCALATION_2       error_suspected       A2       IDLE_ESCALATION_2
- * RS_COMP_RESTARTING      comp_instantiated     A11      RS_COMP_SETTING
- * RS_COMP_RESTARTING      comp_inst_failed      A19      IDLE_ESCALATION_x
- * RS_COMP_RESTARTING      comp_term_failed      A19      IDLE_ESCALATION_x
- * RS_COMP_RESTARTING      error_suspected       A18      RS_COMP_RESTARTING      
- * RS_COMP_SETTING         ha_state_assumed [C7] A19      IDLE_ESCALATION_x
- * RS_COMP_SETTING         error_suspected       A18      RS_COMP_SETTING
- * RS_SU_INSTANTIATING     comp_instantiated [C12] A11    RS_SU_SETTING
- * RS_SU_INSTANTIATING     comp_inst_failed [C12] A19     IDLE_ESCALATION_X
- * RS_SU_INSTANTIATING     comp_term_failed [C12] A19     IDLE_ESCALATION_X
- * RS_SU_INSTANTIATING     error_suspected        A18     RS_SU_INSTANTIATING
- * RS_SU_SETTING           ha_state_assumed [C10] A19     IDLE_ESCALATION_X
- * RS_SU_SETTING           error_suspected        A18     RS_SU_SETTING
- *
+ * IDLE_ESCALATION_x       comp_restart           A9	   RS_COMP_RESTARTING
+ * IDLE_ESCALATION_x       su_restart             A20      RS_SU_TERMINATING
+ * IDLE_ESCALATION_0       error_suspected        A1,A3    IDLE_ESCALATION_1
+ * IDLE_ESCALATION_1       error_suspected [!C3]  A1,A3    IDLE_ESCALATION_1
+ * IDLE_ESCALATION_1       error_suspected [C3]   A2,A5    IDLE_ESCALATION_2
+ * IDLE_ESCALATION_2       error_suspected        A2       IDLE_ESCALATION_2
+ * RS_COMP_RESTARTING      comp_instantiated      A11      RS_COMP_SETTING
+ * RS_COMP_RESTARTING      comp_inst_failed       A14,A15  RS_COMP_T-ING_2
+ * RS_COMP_RESTARTING      comp_term_failed       A19      IDLE_ESCALATION_x
+ * RS_COMP_RESTARTING      error_suspected        A18      RS_COMP_RESTARTING
+ * RS_COMP_T-ING_2         comp_uninst..ed [C8]   A16,A15  RS_COMP_T-ING_2
+ * RS_COMP_T-ING_2         comp_uninst..ed [C100]          IDLE_ESCALATION_x
+ * RS_COMP_T-ING_2         comp_uninst..ed [C101] A25      IDLE_ESCALATION_x
+ * RS_COMP_T-ING_2         comp_uninst..ed [C102] A26      IDLE_ESCALATION_x
+ * RS_COMP_T-ING_2         comp_term_failed [C100]         RS_COMP_T-ING_2
+ * RS_COMP_T-ING_2         error_suspected        A18      RS_COMP_T-ING_2      
+ * RS_COMP_SETTING         ha_state_assumed [C7]  A19      IDLE_ESCALATION_x
+ * RS_COMP_SETTING         error_suspected        A18      RS_COMP_SETTING
+ * RS_SU_TERMINATING       comp_uninst..ed [C8]   A16,A15  RS_SU_TERMINATING
+ * RS_SU_TERMINATING       comp_uninst..ed [C103] A17,A23  RS_SU_INSTANTIATING
+ * RS_SU_TERMINATING       comp_uninst..ed [C104] A19      IDLE_ESCALATION_x
+ * RS_SU_TERMINATING       comp_term_failed [C104]A19      IDLE_ESCALATION_X
+ * RS_SU_TERMINATING       error_suspected        A18      RS_SU_TERMINATING
+ * RS_SU_INSTANTIATING     comp_instantiated [C14]A21,A22  RS_SU_INSTANTIATING
+ * RS_SU_INSTANTIATING     comp_instantiated [C105]A15     RS_SU_T-ING_2
+ * RS_SU_INSTANTIATING     comp_instantiated [C106]A11     RS_SU_SETTING
+ * RS_SU_INSTANTIATING     comp_inst_failed [C105]A15      RS_SU_T-ING_2
+ * RS_SU_INSTANTIATING     error_suspected        A18      RS_SU_INSTANTIATING
+ * RS_SU_T-ING_2           comp_uninst..ed [C8]   A16,A15  RS_SU_T-ING_2
+ * RS_SU_T-ING_2           comp_uninst..ed [C100]          IDLE_ESCALATION_x
+ * RS_SU_T-ING_2           comp_uninst..ed [C101] A25      IDLE_ESCALATION_x
+ * RS_SU_T-ING_2           comp_uninst..ed [C102] A26      IDLE_ESCALATION_x
+ * RS_SU_T-ING_2           comp_term_failed [C100]         RS_SU_T-ING_2
+ * RS_SU_T-ING_2           error_suspected        A18      RS_SU_T-ING_2
+ * RS_SU_SETTING           ha_state_assumed [C10] A19      IDLE_ESCALATION_X
+ * RS_SU_SETTING           error_suspected        A18      RS_SU_SETTING
+ * 
  * 1.2 State Description
  * =====================
  * IDLE_ESCALATION_x - This is just an abbreviated notation for 
  *                     IDLE_ESCALATION_0, IDLE_ESCALATION_1 or IDLE_ESCALATION_2
+ *                     When leaving any of the idle states, a history state
+ *                     is used to save the (exact) state value. When returning
+ *                     to idle, the value of the history state is used to set
+ *                     the correct idle state.
  *
  * IDLE_ESCALATION_0 - SU_RC_IDLE_ESCALATION_LEVEL_0
  *                    Service unit is idle and the restart probation timer is
@@ -176,6 +198,12 @@
  *                     ordered one of its components to restart and waits for
  *                     the component to indicate that the restart is done.
  * 
+ * RS_COMP_T-ING_2 - SU_RC_RESTART_COMP_TERMINATING_AFTER_INST_FAILED
+ *					Service unit is busy handling restart of one of its
+ *					components. In this sub-state, the restart of the component
+ *					has failed and the rest of the components in the service 
+ *					unit has to be terminated.
+ *
  * RS_COMP_SETTING - SU_RC_RESTART_COMP_SETTING
  *                  Service unit is busy handling restart of one of its
  *                  components. In this sub-state, the service unit has ordered
@@ -219,6 +247,12 @@
  *                    for an acknowledgement that all components are done with
  *                    the instantiation.
  *
+ * RS_SU_T-ING_2 - SU_RC_RESTART_SU_TERMINATING_AFTER_INST_FAILED
+ *					Service unit is busy handling restart of all of its
+ *					components. In this sub-state, the instantiation at least
+ *					one component has failed and the rest of the components in
+ *					the service unit has to be terminated.
+ *
  * RS_SU_SETTING -  SU_RC_RESTART_SU_SETTING
  *                  Service unit is busy handling restart of all of its
  *                  components. In this sub-state, the service unit has ordered
@@ -241,43 +275,98 @@
  * ===========
  * A1  - generate event comp_restart
  * A2  - forward component restart request to the node which hosts current su
- * A3  - 
- * A4  - 
- * A5  - 
- * A6  - 
- * A7  - 
- * A8  - 
+ * A3  - start probation timer (SaAmfSGCompRestartProb)
+ * A4  - [foreach component in su]/ cnt += SaAmfSGCompRestartCount
+ * A5  - stop probation timer
+ * A6  - restart ??
+ * A7  - set restarting_comp = component
+ * A8  - [foreach csi-assignment assigned to component] SI deactivate csi
  * A9  - order component to restart
- * A10 -
+ * A10 - set restarting_comp == ALL
  * A11 - initiate setting of the same HA-state as was set before the restart
- * A12 -
- * A13 -
- * A14 -
- * A15 -
- * A16 -
- * A17 -
+ * A12 - SI activate
+ * A13 - [foreach si-assignment assigned to su] SI deactivate
+ * A14 - set current instantiation level = highest level 
+ * A15 - [foreach component on current instantiation level]/terminate component
+ * A16 - current instantiation level is decremented
+ * A17 - request the presence state state machine to instantiate the su
  * A18 - defer the event
  * A19 - recall deferred event
  * A20 - restart all components contained in current su
+ * A21 - current instantiation level is incremented
+ * A22 - [foreach component on current instantiation level]/instantiate
+ *       component
+ * A23 - set current instantiation level = lowest level
+ * A24 - order SG to do component failover
+ * A25 - order Node to do node failover
+ * A26 - order SG to do SU failover
  *
  * 1.4 Guards
  * ==========
- * C1  - 
- * C2  - 
+ * C1  - disableRestart == False
+ * C2  - the component has been restarted less than SaAmfSGCompRestartMax times
  * C3  - the component has been restarted SaAmfSGCompRestartMax number of times
- * C4  - 
+ * C4  - all si-assignments have confirmed-ha-state == QUIESCED or the
+ *       operation failed flag set.
  * C5  - for each si-assignment related to the restarting component where
- *       requested-ha-state != confirmed-ha-state
- * C6  - 
+ *       requested-ha-state != confirmed-ha-state and requested-ha-state !=
+ *       ACTIVE
+ * C6  - - for each si-assignment related to the restarting component where
+ *       requested-ha-state != confirmed-ha-state and requested-ha-state ==
+ *       ACTIVE
  * C7  - all si-assignments related to the restarting component have
- *       requested-ha-state == confirmed-ha-state or the operation has failed
- * C8  - 
- * C9  - 
+ *       requested-ha-state == confirmed-ha-state or has the operation failed
+ *       flag set
+ * C8  - all components on current instantiation level == UNINSTANTIATED
+ * C9  - current instantiation level < lowest instantiation level
  * C10 - all si-assignments related to current service unit have
- *       requested-ha-state == confirmed-ha-state or the operation has failed
- * C11 -
+ *       requested-ha-state == confirmed-ha-state or the operation failed
+ *       flag set.
+ * C11 - for each si-assignment related to current su where
+ *       requested-ha-state != confirmed-ha-state and requested-ha-state ==
+ *       ACTIVE
  * C12 - for each si-assignment related to current su where
- *       requested-ha-state != confirmed-ha-state
+ *       requested-ha-state != confirmed-ha-state and requested-ha-state ==
+ *       STANDBY
+ * C13 - at least one component has presence state == TERMINATION_FAILED
+ * C14 - all components on current instantiation level == INSTANTIATED,
+ *       INSTANTIATION_FAILED or INSTANTIATION_FAILED_REBOOT_NODE
+ * C15 - current instantiation level is highest
+ * C16 - all components has presence state == INSTANTIATED
+ * C17 - at least one component has presence state == INSTANTIATION_FAILED and
+ *       it is not allowed to reboot the node because of this problem
+ * C18 - at least one component has presence state == INSTANTIATION_FAILED and
+ *       it is allowed to reboot the node to recover from this problem
+ * C19 - all components in the SU permit restart
+ *
+ * 1.4.2 Composed Guards
+ * =====================
+ *
+ * C100 - C9 & C13
+ * C101 - C9 & C18
+ * C102 - C9 & C17
+ * C103 - C8 & C9 & !C13
+ * C104 - C8 & C9 & C13
+ * C105 - C14 & (C17 | C18)
+ * C106 - C14 & C15 & C16
+ *
+ * 1.5 Events
+ * ==========
+ *
+ * E1  - component restart request
+ * E2  - restart
+ * E3  - probation timer expired
+ * E4  - escalation reverted
+ * E5  - operation failed
+ * E6  - deactivated
+ * E7  - comp_state(prsm, INSTANTIATED)
+ * E8  - comp_state(prsm, INSTANTIATION_FAILED)
+ * E9  - comp_state(prsm, TERMINATION_FAILED)
+ * E10 - si_state(ha-state)
+ * E11 - activated
+ * E12 - comp_state(prsm, UNINSTANTIATED)
+ * E13 - 
+ * E14 - 
  *
  */
 
@@ -294,7 +383,6 @@
 static int terminate_all_components_in_level (struct amf_su *su, 
 	SaUint32T current_instantiation_level);
 static int are_all_comps_in_level_uninst_or_term_failed (struct amf_su *su);
-static int are_all_comps_in_level_uninst (struct amf_su *su);
 static int are_all_comps_in_level_instantiated (struct amf_su *su);
 static int instantiate_all_components_in_level (struct amf_su *su, 
 	SaUint32T current_instantiation_level);
@@ -406,6 +494,7 @@ static void su_presence_state_set (struct amf_su *su,
 		amf_su_foreach_si_assignment (su, clear_ha_state);
 	}
 
+
 	su->saAmfSUPresenceState = presence_state;
 	log_printf (LOG_NOTICE, "Setting SU '%s' presence state: %s\n",
 		su->name.value, amf_presence_state (presence_state));
@@ -417,6 +506,16 @@ static void su_presence_state_set (struct amf_su *su,
 			presence_state);
 	}
 }
+static void enter_idle (struct amf_su *su)
+{
+  su->restart_control_state = su->escalation_level_history_state;
+}
+
+static void enter_idle_with_recall (struct amf_su *su)
+{
+	su->restart_control_state = su->escalation_level_history_state;
+	su_recall_deferred_events (su);
+}
 
 /**
  * This function sets operational state to the specified value. It also has the
@@ -569,6 +668,22 @@ static int is_any_comp_instantiation_failed (amf_su_t *su)
 	return comp_instantiation_failed;
 }
 
+static int is_any_comp_termination_failed (amf_su_t *su)
+{
+	amf_comp_t *comp_;
+	int comp_instantiation_failed = 0;
+
+	for (comp_ = su->comp_head; comp_ != NULL; comp_ = comp_->next) {
+
+		if (comp_->saAmfCompPresenceState == 
+			SA_AMF_PRESENCE_TERMINATION_FAILED) {
+			comp_instantiation_failed = 1;
+			break;
+		}
+	}
+	return comp_instantiation_failed;
+}
+
 /**
  * Finds the component within the specified su that has the highest value of it
  * presence state. With current definition of values the highest value can also
@@ -615,7 +730,7 @@ static void su_comp_presence_state_changed (struct amf_su *su,
 {
 	ENTER ("'%s', '%s' %d %d", su->name.value, comp->name.value, state,
 		su->restart_control_state);
-    amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
+	amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
 	switch (state) {
 		case SA_AMF_PRESENCE_INSTANTIATED:
 			switch (su->restart_control_state) {
@@ -626,14 +741,15 @@ static void su_comp_presence_state_changed (struct amf_su *su,
 						if (are_all_comps_in_level_instantiated (su)) {
 							if (instantiate_all_components_in_level (su, 
 								++comp->su->current_comp_instantiation_level)) {
-                                /* All levels of instantiation is done */
+								/* All levels of instantiation is done */
 								su_presence_state_set (comp->su, 
 									SA_AMF_PRESENCE_INSTANTIATED);
 							}
 						} else {
 							if (is_any_comp_instantiation_failed (su)) {
-								su_presence_state_set (comp->su, 
+								su_presence_state_set (su, 
 									SA_AMF_PRESENCE_INSTANTIATION_FAILED);
+
 							} else {
 								assert (0);
 							}
@@ -646,21 +762,21 @@ static void su_comp_presence_state_changed (struct amf_su *su,
 					break;
 				case SU_RC_RESTART_SU_INSTANTIATING:
 					if (!is_any_component_instantiating(su)) {
-						if (amf_su_are_all_comps_in_su (
-							comp->su, SA_AMF_PRESENCE_INSTANTIATED)) {
-							su->restart_control_state = SU_RC_RESTART_SU_SETTING;
-							su_presence_state_set (comp->su, 
-								SA_AMF_PRESENCE_INSTANTIATED);
-							reassume_ha_state (comp->su);
-						} else {
-							if (is_any_comp_instantiation_failed (su)) {
+						if (are_all_comps_in_level_instantiated (su)) {
+							if (instantiate_all_components_in_level (su, 
+								++comp->su->current_comp_instantiation_level)) {
+								su->restart_control_state = SU_RC_RESTART_SU_SETTING;
 								su_presence_state_set (comp->su, 
-									SA_AMF_PRESENCE_INSTANTIATION_FAILED);
-							} else {
-								TRACE1("%s,%s",comp->su->name.value, 
-									comp->name.value);
-								assert (0);
+									SA_AMF_PRESENCE_INSTANTIATED);
+								reassume_ha_state (comp->su);
 							}
+						} else if (is_any_comp_instantiation_failed (su)) {
+							su->restart_control_state = 
+								SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
+							terminate_all_components_in_level (su,
+								su->current_comp_instantiation_level);
+						} else {
+							assert (0);
 						}
 					}
 					break;
@@ -675,38 +791,79 @@ static void su_comp_presence_state_changed (struct amf_su *su,
 				case SU_RC_IDLE_ESCALATION_LEVEL_0:
 				case SU_RC_IDLE_ESCALATION_LEVEL_1:
 				case SU_RC_IDLE_ESCALATION_LEVEL_2:
-
 					if (!is_any_component_terminating (su)) {
 						if (are_all_comps_in_level_uninst_or_term_failed (su)) {
 							if (terminate_all_components_in_level (su,
 								--su->current_comp_instantiation_level)) {
 								su_presence_state_set (su,
 									get_worst_comps_presence_state_in_su (su));
+							} else {
+								if (is_any_comp_termination_failed (su)) {
+									su_presence_state_set (comp->su, 
+										SA_AMF_PRESENCE_TERMINATION_FAILED);
+								} else {
+									assert (0);
+								}
 							}
-						} 
-					} 
+						}
+					}
 					break;
 				case SU_RC_RESTART_SU_INSTANTIATING:
 					break;
 				case SU_RC_RESTART_COMP_RESTARTING:
 					break;
+				case SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED:
+					if (!is_any_component_terminating (su)) {
+						if (terminate_all_components_in_level (su,
+							--su->current_comp_instantiation_level)) {
+							if (!is_any_comp_termination_failed (su)) {
+								su_presence_state_set (su, 
+									SA_AMF_PRESENCE_INSTANTIATION_FAILED);
+								if (node->saAmfNodeRebootOnInstantiationFailure) {
+									amf_node_failover(node);
+								} else {
+									amf_node_comp_failover_req(node, comp);
+								}
+								enter_idle (su);
+							} else {
+								if (!node->saAmfNodeRebootOnTerminationFailure) {
+									su_presence_state_set (su,
+										get_worst_comps_presence_state_in_su (su));
+								} else {
+									/* TODO Implement and request Node Failed Fast */
+									;
+								}
+								enter_idle_with_recall (su);
+							}
+						}
+					}
+					break;
 				case SU_RC_RESTART_SU_TERMINATING:
 					if (!is_any_component_terminating (su)) {
-						if (are_all_comps_in_level_uninst (su)) {
-							if (terminate_all_components_in_level (su,
-								--su->current_comp_instantiation_level)) {
+						if (terminate_all_components_in_level (su,
+							--su->current_comp_instantiation_level)) {
+							if (!is_any_comp_termination_failed (su)) {
 								su->restart_control_state = 
 									SU_RC_RESTART_SU_INSTANTIATING;
 								instantiate_all_components_in_level (su, 
-									su_lowest_comp_instantiation_level_set (su));
+									su_lowest_comp_instantiation_level_set (
+									su));
+							} else {
+								if (!node->saAmfNodeRebootOnTerminationFailure) {
+									su_presence_state_set (su,
+										get_worst_comps_presence_state_in_su (su));
+								} else {
+									/* TODO Implement and request Node Failed Fast */
+									;
+								}
+								enter_idle_with_recall (su);
 							}
-						} else {
-							su_history_state_set (su,
-								SA_AMF_PRESENCE_TERMINATION_FAILED);
 						}
 					}
 					break;
 				default:
+					dprintf ("state %d", su->restart_control_state);
+					assert (0);
 					break;
 			}
 			break;
@@ -714,8 +871,12 @@ static void su_comp_presence_state_changed (struct amf_su *su,
 			su_presence_state_set (comp->su,SA_AMF_PRESENCE_INSTANTIATING);
 			break;
 		case SA_AMF_PRESENCE_RESTARTING:
+			if (amf_su_are_all_comps_in_su (su, SA_AMF_PRESENCE_RESTARTING)) {
+				su_presence_state_set (comp->su, SA_AMF_PRESENCE_RESTARTING);
+			}
 			break;
 		case SA_AMF_PRESENCE_TERMINATING:
+			su_presence_state_set (comp->su, SA_AMF_PRESENCE_TERMINATING);
 			break;
 		case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
 			switch (su->restart_control_state) {
@@ -723,44 +884,30 @@ static void su_comp_presence_state_changed (struct amf_su *su,
 				case SU_RC_IDLE_ESCALATION_LEVEL_1:
 				case SU_RC_IDLE_ESCALATION_LEVEL_2:
 					if (!is_any_component_instantiating (su)) {
-						su_presence_state_set (comp->su,
+						su_presence_state_set (su, 
 							SA_AMF_PRESENCE_INSTANTIATION_FAILED);
 					}
 					break;
-                case SU_RC_RESTART_COMP_RESTARTING:
-					if (!is_any_component_instantiating (su)) {
-                        if (node->saAmfNodeRebootOnInstantiationFailure) {
-							su_history_state_set (su,
-								AMF_PRESENCE_TERMINATION_FAILED_REBOOT);
-							amf_node_failover(node);
-                        }else{
-							su_history_state_set (su,
-								SA_AMF_PRESENCE_INSTANTIATION_FAILED);
-							amf_node_comp_failover_req(node, comp);
-                        }
-                    }
-					break; 
+				case SU_RC_RESTART_COMP_RESTARTING:
+					su->restart_control_state = 
+						SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
+					amf_su_terminate (su);
+					break;
 				case SU_RC_RESTART_SU_INSTANTIATING:
 					if (!is_any_component_instantiating (su)) {
-					    if (node->saAmfNodeRebootOnInstantiationFailure) {
-							su_history_state_set (su,
-								AMF_PRESENCE_TERMINATION_FAILED_REBOOT);
-							amf_node_failover(node);
-                        }else{
-							su_history_state_set (su,
-								SA_AMF_PRESENCE_INSTANTIATION_FAILED);
-							amf_sg_failover_su_req(comp->su->sg, comp->su, node);
-                        }
+						su->restart_control_state = 
+							SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
+						su_presence_state_set (su, 
+							SA_AMF_PRESENCE_INSTANTIATION_FAILED);
+						terminate_all_components_in_level (su,
+							su->current_comp_instantiation_level);
 					}
 					break;
 				default:
+					dprintf ("state %d", su->restart_control_state);
 					assert (0);
 					break;
 			}
-#ifdef COMPILE_OUT
-			su_presence_state_set (comp->su, 
-				SA_AMF_PRESENCE_INSTANTIATION_FAILED);
-#endif
 			break;
 		case SA_AMF_PRESENCE_TERMINATION_FAILED:
 			switch (su->restart_control_state) {
@@ -769,25 +916,35 @@ static void su_comp_presence_state_changed (struct amf_su *su,
 				case SU_RC_IDLE_ESCALATION_LEVEL_2:
 					break;
 				case SU_RC_RESTART_COMP_RESTARTING:
-				case SU_RC_RESTART_SU_INSTANTIATING:
-					if (!node->saAmfNodeRebootOnInstantiationFailure) {
-						su_history_state_set (su,
+					if (!node->saAmfNodeRebootOnTerminationFailure) {
+						su_presence_state_set (su,
 							SA_AMF_PRESENCE_TERMINATION_FAILED);
+						enter_idle_with_recall (su);
 					} else {
 						/* TODO Implement and request Node Failed Fast */
 						;
 					}
 					break;
+				case SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED:
 				case SU_RC_RESTART_SU_TERMINATING:
-					if (!node->saAmfNodeRebootOnInstantiationFailure) {
-						su_history_state_set (su,
-							SA_AMF_PRESENCE_TERMINATION_FAILED);
-					} else {
-						/* TODO Implement and request Node Failed Fast */
-						;
+					if (!is_any_component_terminating (su)) {
+						if (terminate_all_components_in_level (su,
+							--su->current_comp_instantiation_level)) {
+							if (!node->saAmfNodeRebootOnTerminationFailure) {
+								su_presence_state_set (su,
+									get_worst_comps_presence_state_in_su (su));
+								enter_idle_with_recall (su);
+							} else {
+								/* TODO Implement and request Node Failed Fast */
+								;
+							}
+						}
 					}
 					break;
 				default:
+					log_printf (LOG_LEVEL_NOTICE,"%s %d",su->name.value, 
+						su->restart_control_state);
+					dprintf ("state %d", su->restart_control_state);
 					assert (0);
 					break;
 			}
@@ -947,6 +1104,8 @@ static int terminate_all_components_in_level (struct amf_su *su,
 {
 	amf_comp_t *comp;
 	int all_components_in_level = 1;
+	TRACE8("terminate comp->saAmfCompInstantiationLevel=%u", 
+		current_instantiation_level);
 	for (comp = su->comp_head; comp != NULL; comp = comp->next) {
 		/* 
          * Terminate all components in instantiation level in SU
@@ -984,24 +1143,6 @@ static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su)
 	return comp_instantiation_level;
 }
 
-static int are_all_comps_in_level_uninst (
-	struct amf_su *su)
-{
-	SaUint32T level = su->current_comp_instantiation_level;
-	amf_comp_t *comp;
-	int all = 1;
-
-	for (comp = su->comp_head; comp != NULL; comp = comp->next) {
-		if (level == comp->saAmfCompInstantiationLevel) {
-			if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_UNINSTANTIATED) {
-				all = 0;
-				break;
-			}
-		}
-	}
-	return all;
-}
-
 
 /**
  * An order to SU to instantiate its components.
@@ -1124,7 +1265,6 @@ void amf_su_comp_error_suspected (
  */
 void amf_su_restart (struct amf_su *su)
 {
-	struct amf_comp *comp;
 	SaNameT dn;
 
 	ENTER ("'%s'", su->name.value);
@@ -1133,17 +1273,12 @@ void amf_su_restart (struct amf_su *su)
 	log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
 		"action: SU restart", dn.value);
 
-    /*                                                                          
-     * TODO: Find out what the three lines below means !                                                                          
-     */
 	su->restart_control_state = SU_RC_RESTART_SU_DEACTIVATING;
 	su->restart_control_state = SU_RC_RESTART_SU_TERMINATING;
 	su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
+	su->current_comp_instantiation_level = get_instantiation_max_level (su);
 	su->saAmfSURestartCount += 1;
-
-	for (comp = su->comp_head; comp != NULL; comp = comp->next) {
-		amf_comp_terminate (comp);
-	}
+	terminate_all_components_in_level(su, su->current_comp_instantiation_level);
 }
 
 /******************************************************************************
@@ -1214,10 +1349,7 @@ static void si_ha_state_assumed_cbfn (
 				assert (0);
 				break;
 		}
-		si_assignment->su->restart_control_state =
-			si_assignment->su->escalation_level_history_state;
-		su_recall_deferred_events (si_assignment->su);
-
+		enter_idle_with_recall (si_assignment->su);
 	}
 }