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

AMF changes:
- Revised cluster start
- Includes Steven's "amf invalid write patch"
- Includes "components not started with 0.76" patch
- New timer API use backed out of AMF (temporary)



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

Hans Feldt 19 лет назад
Родитель
Сommit
154a857c3b
11 измененных файлов с 400 добавлено и 103 удалено
  1. 18 19
      exec/amf.c
  2. 32 4
      exec/amf.h
  3. 42 6
      exec/amfapp.c
  4. 69 2
      exec/amfcluster.c
  5. 86 41
      exec/amfcomp.c
  6. 64 17
      exec/amfsg.c
  7. 60 0
      exec/amfsi.c
  8. 12 7
      exec/amfsu.c
  9. 7 6
      exec/amfutil.c
  10. 9 0
      exec/timer.h
  11. 1 1
      test/testamf1.c

+ 18 - 19
exec/amf.c

@@ -282,7 +282,7 @@ static struct openais_service_handler amf_service_handler = {
 };
 
 struct amf_node *this_amf_node;
-struct amf_cluster amf_cluster;
+struct amf_cluster *amf_cluster;
 
 static struct openais_service_handler *amf_get_handler_ver0 (void);
 
@@ -366,7 +366,6 @@ static void amf_sync_activate (void)
 
 static int amf_exec_init_fn (struct objdb_iface_ver0 *objdb)
 {
-	int res;
 	char *error_string;
 	char hostname[HOST_NAME_MAX + 1];
 	struct amf_node *node;
@@ -377,10 +376,10 @@ static int amf_exec_init_fn (struct objdb_iface_ver0 *objdb)
 		return 0;
 	}
 	
-	res = amf_config_read (&amf_cluster, &error_string);
-	if (res == -1) {
+	amf_cluster = amf_config_read (&error_string);
+	if (amf_cluster == NULL) {
 		log_printf (LOG_LEVEL_ERROR, error_string);
-		return res;
+		return -1;
 	}
 
 	if (gethostname (hostname, sizeof(hostname)) == -1) {
@@ -389,7 +388,7 @@ static int amf_exec_init_fn (struct objdb_iface_ver0 *objdb)
 	}
 
 	/* look for this node */
-	for (node = amf_cluster.node_head; node != NULL; node = node->next) {
+	for (node = amf_cluster->node_head; node != NULL; node = node->next) {
 		if (strcmp(hostname, getSaNameT (&node->name)) == 0) {
 			this_amf_node = node;
 		}
@@ -404,7 +403,7 @@ static int amf_exec_init_fn (struct objdb_iface_ver0 *objdb)
 		amf_si_init();
 
 		this_amf_node->saAmfNodeOperState = SA_AMF_OPERATIONAL_ENABLED;
-		amf_cluster_start (&amf_cluster);
+		amf_cluster_start (amf_cluster);
 	} else {
 		log_printf (LOG_LEVEL_INFO,
 			"This CLM node (%s) is not configured as an AMF node, disabling.",
@@ -475,7 +474,7 @@ static void message_handler_req_exec_amf_comp_register (
 	struct amf_comp *comp;
 	SaAisErrorT error;
 
-	comp = amf_comp_find (&amf_cluster, &req_exec->compName);
+	comp = amf_comp_find (amf_cluster, &req_exec->compName);
 	assert (comp != NULL);
 	ENTER ("'%s'", comp->name.value);
 	error = amf_comp_register (comp);
@@ -495,7 +494,7 @@ static void message_handler_req_exec_amf_comp_error_report (
 	struct req_exec_amf_comp_error_report *req_exec = message;
 	struct amf_comp *comp;
 
-	comp = amf_comp_find (&amf_cluster, &req_exec->erroneousComponent);
+	comp = amf_comp_find (amf_cluster, &req_exec->erroneousComponent);
 	assert (comp != NULL);
 	amf_comp_error_report (comp, req_exec->recommendedRecovery);
 }
@@ -506,7 +505,7 @@ static void message_handler_req_exec_amf_clc_cleanup_completed (
 	struct req_exec_amf_clc_cleanup_completed *req_exec = message;
 	struct amf_comp *comp;
 
-	comp = amf_comp_find (&amf_cluster, &req_exec->compName);
+	comp = amf_comp_find (amf_cluster, &req_exec->compName);
 	if (comp == NULL) {
 		log_printf (LOG_ERR, "'%s' not found", &req_exec->compName.value);
 		return;
@@ -522,7 +521,7 @@ static void message_handler_req_exec_amf_healthcheck_tmo (
 	struct amf_comp *comp;
 	struct amf_healthcheck *healthcheck;
 
-	comp = amf_comp_find (&amf_cluster, &req_exec->compName);
+	comp = amf_comp_find (amf_cluster, &req_exec->compName);
 	if (comp == NULL) {
 		log_printf (LOG_ERR, "'%s' not found", &req_exec->compName.value);
 		return;
@@ -562,7 +561,7 @@ static void message_handler_req_lib_amf_componentregister (
 	struct req_lib_amf_componentregister *req_lib = msg;
 	struct amf_comp *comp;
 
-	comp = amf_comp_find (&amf_cluster, &req_lib->compName);
+	comp = amf_comp_find (amf_cluster, &req_lib->compName);
 	if (comp) {
 		struct req_exec_amf_comp_register req_exec;
 		struct iovec iovec;
@@ -614,7 +613,7 @@ static void message_handler_req_lib_amf_componentunregister (
 		req_lib_amf_componentunregister,
 		sizeof (struct req_lib_amf_componentunregister));
 
-	component = amf_comp_find (&amf_cluster, &req_lib_amf_componentunregister->compName);
+	component = amf_comp_find (amf_cluster, &req_lib_amf_componentunregister->compName);
 	if (component && component->registered && component->local) {
 //		component->probableCause = SA_AMF_NOT_RESPONDING;
 	}
@@ -646,7 +645,7 @@ static void message_handler_req_lib_amf_healthcheckstart (
 	struct amf_comp *comp;
 	SaAisErrorT error = SA_AIS_OK;
 
-	comp = amf_comp_find (&amf_cluster, &req_lib->compName);
+	comp = amf_comp_find (amf_cluster, &req_lib->compName);
 
 	if (comp != NULL) {
 		comp->conn = conn;
@@ -674,7 +673,7 @@ static void message_handler_req_lib_amf_healthcheckconfirm (
 	struct amf_comp *comp;
 	SaAisErrorT error = SA_AIS_OK;
 
-	comp = amf_comp_find (&amf_cluster, &req_lib->compName);
+	comp = amf_comp_find (amf_cluster, &req_lib->compName);
 	if (comp != NULL) {
 		error = amf_comp_healthcheck_confirm (
 			comp, &req_lib->healthcheckKey, req_lib->healthcheckResult);
@@ -698,7 +697,7 @@ static void message_handler_req_lib_amf_healthcheckstop (
 	struct amf_comp *comp;
 	SaAisErrorT error = SA_AIS_OK;
 
-	comp = amf_comp_find (&amf_cluster, &req_lib->compName);
+	comp = amf_comp_find (amf_cluster, &req_lib->compName);
 	if (comp != NULL) {
 		error = amf_comp_healthcheck_stop (comp, &req_lib->healthcheckKey);
 	} else {
@@ -721,7 +720,7 @@ static void message_handler_req_lib_amf_hastateget (void *conn, void *msg)
 	SaAmfHAStateT ha_state;
 	SaAisErrorT error;
 
-	comp = amf_comp_find (&amf_cluster, &req_lib->compName);
+	comp = amf_comp_find (amf_cluster, &req_lib->compName);
 	if (comp != NULL) {
 		error = amf_comp_hastate_get (comp, &req_lib->csiName, &ha_state);
 		res_lib.haState = ha_state;
@@ -865,7 +864,7 @@ static void message_handler_req_lib_amf_componenterrorreport (
 	struct req_lib_amf_componenterrorreport *req_lib = msg;
 	struct amf_comp *comp;
 
-	comp = amf_comp_find (&amf_cluster, &req_lib->erroneousComponent);
+	comp = amf_comp_find (amf_cluster, &req_lib->erroneousComponent);
 	if (comp != NULL) {
 		struct req_exec_amf_comp_error_report req_exec;
 		struct iovec iovec;
@@ -973,5 +972,5 @@ static void message_handler_req_lib_amf_response (void *conn, void *msg)
 
 static void amf_dump_fn (void)
 {
-	amf_runtime_attributes_print (&amf_cluster);
+	amf_runtime_attributes_print (amf_cluster);
 }

+ 32 - 4
exec/amf.h

@@ -331,6 +331,7 @@ struct amf_si_assignment {
 	struct amf_si *si;
 
 	/* Implementation */
+	SaAmfHAStateT requested_ha_state;
 	struct amf_si_assignment *next;
 };
 
@@ -403,7 +404,7 @@ struct req_exec_amf_healthcheck_tmo {
 /*===========================================================================*/
 /* amfutil.c */
 
-extern int amf_config_read (struct amf_cluster *cluster, char **error_string);
+extern struct amf_cluster *amf_config_read (char **error_string);
 extern char *amf_serialize (struct amf_cluster *cluster);
 extern int amf_deserialize (char *buf, struct amf_cluster *cluster);
 extern void amf_state_print (struct amf_cluster *cluster);
@@ -463,6 +464,7 @@ extern void timer_function_node_probation_period_expired (void *node);
 
 /* General methods */
 extern void amf_cluster_init (void);
+extern struct amf_cluster *amf_cluster_create (void);
 extern int amf_cluster_serialize (
 	struct amf_cluster *cluster, char **buf, int *offset);
 extern struct amf_cluster *amf_cluster_deserialize (
@@ -489,7 +491,6 @@ extern int amf_application_serialize (
 	struct amf_application *application, char **buf, int *offset);
 extern struct amf_application *amf_application_deserialize (
 	char **buf, int *size, struct amf_cluster *cluster);
-extern int amf_application_si_count_get (struct amf_application *app);
 
 /* Event methods */
 extern void amf_application_start (
@@ -516,6 +517,12 @@ extern struct amf_sg *amf_sg_deserialize (
 
 /* Event methods */
 extern void amf_sg_start (struct amf_sg *sg, struct amf_node *node);
+
+/**
+ * Assign SIs on a certain dependency level to SUs
+ * @param sg
+ * @param dependency_level
+ */
 extern void amf_sg_assign_si (struct amf_sg *sg, int dependency_level);
 
 extern void amf_sg_failover_node_req (
@@ -534,6 +541,8 @@ extern void amf_sg_si_ha_state_changed (
 	struct amf_sg *sg, struct amf_si *si, int state);
 extern void amf_sg_su_assignment_removed (
 	struct amf_sg *sg, struct amf_su *su);
+extern void amf_sg_si_activated (
+	struct amf_sg *sg, struct amf_si *si);
 
 /* Timer event methods */
 //static void timer_function_auto_adjust_tmo (void *sg);
@@ -563,9 +572,11 @@ extern void amf_su_remove_assignment (struct amf_su *su);
 /* Response event methods */
 extern void amf_su_comp_state_changed (
 	struct amf_su *su, struct amf_comp *comp, SaAmfStateT type, int state);
+#if 0
 extern void amf_su_comp_hastate_changed (
 	struct amf_su *su, struct amf_comp *comp,
 	struct amf_csi_assignment *csi_assignment);
+#endif
 extern void amf_su_comp_error_suspected (
 	struct amf_su *su,
 	struct amf_comp *comp,
@@ -645,6 +656,12 @@ extern struct amf_si *amf_si_deserialize (
 	char **buf, int *size, struct amf_cluster *cluster);
 
 /* Event methods */
+
+/**
+ * Activate all active assignments
+ * @param si
+ * @param activated_callback_fn
+ */
 extern void amf_si_activate (
 	struct amf_si *si,
 	void (*activated_callback_fn)(struct amf_si *si, int result));
@@ -657,9 +674,20 @@ extern void amf_si_set_ha_state (
 	SaAmfHAStateT ha_state,
 	void (*set_ha_state_callback_fn)(struct amf_si *si, int result));
 
-/* Response event methods */
+/**
+ * Component reports to SI that a workload assignment succeeded.
+ * 
+ * @param si
+ * @param csi_assignment
+ */
 extern void amf_si_comp_set_ha_state_done (
 	struct amf_si *si, struct amf_csi_assignment *csi_assignment);
+
+/**
+ * Component reports to SI that a workload assignment failed.
+ * @param si
+ * @param csi_assignment
+ */
 extern void amf_si_comp_set_ha_state_failed (
 	struct amf_si *si, struct amf_csi_assignment *csi_assignment);
 
@@ -674,6 +702,6 @@ extern char *amf_csi_dn_make (struct amf_csi *csi, SaNameT *name);
 
 /*===========================================================================*/
 extern struct amf_node *this_amf_node;
-extern struct amf_cluster amf_cluster;
+extern struct amf_cluster *amf_cluster;
 
 #endif /* AMF_H_DEFINED */

+ 42 - 6
exec/amfapp.c

@@ -73,15 +73,24 @@
 #include "amf.h"
 #include "print.h"
 
-int amf_application_si_count_get (struct amf_application *app)
+static int all_sg_started(struct amf_application *app)
 {
-	struct amf_si *si;
-	int answer = 0;
+	struct amf_sg *sg;
+	struct amf_su *su;
+	int all_su_instantiated = 1;
+
+	/* TODO: spare SUs... */
 
-	for (si = app->si_head; si != NULL; si = si->next) {
-		answer += 1;
+	for (sg = app->sg_head; sg != NULL; sg = sg->next) {
+		for (su = sg->su_head; su != NULL; su = su->next) {
+			if (su->saAmfSUPresenceState != SA_AMF_PRESENCE_INSTANTIATED) {
+				all_su_instantiated = 0;
+				break;
+			}
+		}
 	}
-	return (answer);
+
+	return all_su_instantiated;
 }
 
 void amf_application_start (
@@ -91,6 +100,10 @@ void amf_application_start (
 
 	ENTER ("'%s'", app->name.value);
 
+	/*
+     * TODO: Calculate and set SI dependency levels
+     */
+
 	for (sg = app->sg_head; sg != NULL; sg = sg->next) {
 		amf_sg_start (sg, node);
 	}
@@ -101,6 +114,11 @@ void amf_application_assign_workload (
 {
 	struct amf_sg *sg;
 
+	/*                                                              
+     * TODO: dependency level ignored
+     * Each dependency level should be looped and amf_sg_assign_si
+     * called several times.
+     */
 	for (sg = app->sg_head; sg != NULL; sg = sg->next) {
 		amf_sg_assign_si (sg, 0);
 	}
@@ -111,3 +129,21 @@ void amf_application_init (void)
 	log_init ("AMF");
 }
 
+void amf_application_sg_started (
+	struct amf_application *app, struct amf_sg *sg,	struct amf_node *node)
+{
+	ENTER ("'%s'", app->name.value);
+
+	if (all_sg_started (app)) {
+		amf_cluster_application_started (app->cluster, app);
+	}
+}
+
+void amf_application_sg_assigned (
+	struct amf_application *app, struct amf_sg *sg)
+{
+	ENTER ("'%s'", app->name.value);
+	amf_cluster_application_workload_assigned (app->cluster, app);
+}
+
+

+ 69 - 2
exec/amfcluster.c

@@ -74,6 +74,34 @@
 #include "util.h"
 #include "main.h"
 
+/**
+ * Determine if all applications are started
+ * @param cluster
+ * 
+ * @return int
+ */
+static int all_applications_started (struct amf_cluster *cluster)
+{
+	int all_started = 1;
+	struct amf_application *app;
+	struct amf_sg *sg;
+	struct amf_su *su;
+
+	for (app = cluster->application_head; app != NULL; app = app->next) {
+		for (sg = app->sg_head; sg != NULL; sg = sg->next) {
+			for (su = sg->su_head; su != NULL; su = su->next) {
+				if (su->saAmfSUPresenceState != SA_AMF_PRESENCE_INSTANTIATED) {
+					all_started = 0;
+					goto done;
+				}
+			}
+		}
+	}
+
+done:
+	return all_started;
+}
+
 static void timer_function_cluster_assign_workload_tmo (void *_cluster)
 {
 	struct amf_application *app;
@@ -98,7 +126,7 @@ static void timer_function_cluster_startup_tmo (void *_cluster)
 	}
 
 	/* wait a while before assigning workload */
-	openais_timer_add (
+	poll_timer_add (aisexec_poll_handle,
 		cluster->saAmfClusterStartupTimeout,
 		cluster,
 		timer_function_cluster_assign_workload_tmo,
@@ -108,7 +136,7 @@ static void timer_function_cluster_startup_tmo (void *_cluster)
 void amf_cluster_start (struct amf_cluster *cluster)
 {
 	/* wait a while before starting applications */
-	openais_timer_add (
+	poll_timer_add (aisexec_poll_handle,
 		cluster->saAmfClusterStartupTimeout,
 		cluster,
 		timer_function_cluster_startup_tmo,
@@ -120,3 +148,42 @@ void amf_cluster_init (void)
 	log_init ("AMF");
 }
 
+void amf_cluster_application_started (
+	struct amf_cluster *cluster, struct amf_application *application)
+{
+	ENTER ("application '%s' started", application->name.value);
+
+	if (cluster->timeout_handle) {
+		poll_timer_delete (aisexec_poll_handle, cluster->timeout_handle);
+	}
+
+	if (all_applications_started (cluster)) {
+		struct amf_application *app;
+		dprintf("All applications started, assigning workload.");
+
+		for (app = cluster->application_head; app != NULL; app = app->next) {
+			amf_application_assign_workload (app, this_amf_node);
+		}
+	}
+}
+
+struct amf_cluster *amf_cluster_create (void)
+{
+	struct amf_cluster *cluster = calloc (1, sizeof (struct amf_cluster));
+
+	if (cluster == NULL) {
+		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
+	}
+
+	cluster->saAmfClusterStartupTimeout = -1;
+	cluster->saAmfClusterAdminState = SA_AMF_ADMIN_UNLOCKED;
+
+	return cluster;
+}
+
+void amf_cluster_application_workload_assigned (
+	struct amf_cluster *cluster, struct amf_application *app)
+{
+	ENTER ("'%s'", app->name.value);
+}
+

+ 86 - 41
exec/amfcomp.c

@@ -320,6 +320,9 @@ char *amf_comp_dn_make (struct amf_comp *comp, SaNameT *name)
 	return (char *)name->value;
 }
 
+#ifndef xprintf
+#define xprintf(...)
+#endif
 static void *clc_command_run (void *context)
 {
 	struct clc_command_run_data *clc_command_run_data =
@@ -340,14 +343,14 @@ static void *clc_command_run (void *context)
 	pid = fork();
 
 	if (pid == -1) {
-		dprintf ("Couldn't fork process %s\n", strerror (errno));
+		fprintf (stderr, "Couldn't fork process %s\n", strerror (errno));
 		return (0);
 	}
 
 	if (pid) {
-		dprintf ("waiting for pid %d to finish\n", pid);
+		xprintf ("waiting for pid %d to finish\n", pid);
 		waitpid (pid, &status, 0);
-		dprintf ("process (%d) finished with %d\n", pid, status);
+		xprintf ("process (%d) finished with %d\n", pid, status);
 		if (clc_command_run_data->completion_callback) {
 			clc_command_run_data->completion_callback (context);
 		}
@@ -423,18 +426,18 @@ static void *clc_command_run (void *context)
 	envp[i] = NULL;
 	assert (i < 10);
 
-	dprintf ("running command '%s' with environment:\n", cmd);
+	xprintf ("running command '%s' with environment:\n", cmd);
 	for (i = 0; envp[i] != NULL; i++) {
-		dprintf ("   %s\n", envp[i]);
+		xprintf ("   %s\n", envp[i]);
 	}
-	dprintf (" and argv:\n", cmd);
+	xprintf (" and argv:\n");
 	for (i = 0; argv[i] != NULL; i++) {
-		dprintf ("   %s\n", argv[i]);
+		xprintf ("   %s\n", argv[i]);
 	}
 		
 	res = execve (cmd, argv, envp);
 	if (res == -1) {
-		log_printf (LOG_LEVEL_ERROR, "Couldn't exec program %s (%s)\n",
+		fprintf (stderr, "Couldn't exec program %s (%s)\n",
 					cmd, strerror (errno));
 	}
 	assert (res != -1);
@@ -463,7 +466,8 @@ static int clc_cli_instantiate (struct amf_comp *comp)
 	clc_command_run_data->completion_callback = NULL;
 	pthread_attr_init (&thread_attr);
 	pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
-	res = pthread_create (&thread, &thread_attr, clc_command_run, (void *)clc_command_run_data);
+	res = pthread_create (&thread, &thread_attr, clc_command_run,
+		(void *)clc_command_run_data);
 	if (res != 0) {
 		log_printf (LOG_LEVEL_ERROR, "pthread_create failed: %d", res);
 	}
@@ -592,7 +596,8 @@ static int clc_cli_cleanup (struct amf_comp *comp)
 
 	pthread_attr_init (&thread_attr);
 	pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
-	res = pthread_create (&thread, &thread_attr, clc_command_run, (void *)clc_command_run_data);
+	res = pthread_create (&thread, &thread_attr, clc_command_run,
+		(void *)clc_command_run_data);
 	if (res != 0) {
 		log_printf (LOG_LEVEL_ERROR, "pthread_create failed: %d", res);
 	}
@@ -678,7 +683,7 @@ struct amf_comp *amf_comp_find (struct amf_cluster *cluster, SaNameT *name)
 	char *buf;
 
 	/* malloc new buffer since strtok_r writes to its first argument */
-	buf = malloc (name->length);
+	buf = malloc (name->length + 1);
 	memcpy (buf, name->value,name ->length);
 
 	comp_name = strtok_r(buf, ",", &ptrptr);
@@ -749,29 +754,47 @@ static void comp_ha_state_set (	struct amf_comp *comp,
 	struct amf_csi_assignment *csi_assignment,
 	SaAmfHAStateT ha_state)
 {
-	csi_assignment->saAmfCSICompHAState = ha_state;
-	TRACE1 ("Setting comp '%s' HA state: %s\n",
-			comp->name.value, amf_ha_state (csi_assignment->saAmfCSICompHAState));
-	amf_su_comp_hastate_changed (comp->su, comp, csi_assignment);
+	/*                                                              
+     * Filter component restart from reporting to SI. TODO: how is
+     * this handled the right way?
+     */
+	if (csi_assignment->saAmfCSICompHAState !=
+		csi_assignment->requested_ha_state) {
+
+		/* set confirmed HA state */
+		csi_assignment->saAmfCSICompHAState = ha_state;
+		TRACE1 ("Setting comp '%s', SU '%s' CSI '%s', HA state: %s\n",
+				comp->name.value, comp->su->name.value,
+				csi_assignment->csi->name.value,
+				amf_ha_state (csi_assignment->saAmfCSICompHAState));
+		amf_si_comp_set_ha_state_done (csi_assignment->csi->si, csi_assignment);
+	}
 }
 
 static void comp_presence_state_set (struct amf_comp *comp,
 	SaAmfPresenceStateT presence_state)
 {
+	SaAmfPresenceStateT old = comp->saAmfCompPresenceState;
+
 	comp->saAmfCompPresenceState = presence_state;
-	TRACE1 ("Setting comp '%s' presence state: %s\n",
-			comp->name.value, amf_presence_state (comp->saAmfCompPresenceState));
+	TRACE1 ("Setting comp '%s', SU '%s' presence state: %s\n",
+		comp->name.value, comp->su->name.value,
+		amf_presence_state (comp->saAmfCompPresenceState));
 
-	amf_su_comp_state_changed (
-		comp->su, comp, SA_AMF_PRESENCE_STATE, presence_state);
+	/* TODO: ugly, should be done by SU... */
+	if (old != SA_AMF_PRESENCE_RESTARTING) {
+		amf_su_comp_state_changed (
+			comp->su, comp, SA_AMF_PRESENCE_STATE, presence_state);
+	}
 }
 
 static void comp_operational_state_set (struct amf_comp *comp,
 	SaAmfOperationalStateT oper_state)
 {
 	comp->saAmfCompOperState = oper_state;
-	TRACE1 ("Setting comp '%s' operational state: %s\n",
-			comp->name.value, amf_op_state (comp->saAmfCompOperState));
+	TRACE1 ("Setting comp '%s', SU '%s' operational state: %s\n",
+		comp->name.value, comp->su->name.value,
+		amf_op_state (comp->saAmfCompOperState));
 	amf_su_comp_state_changed (
 		comp->su, comp, SA_AMF_OP_STATE, oper_state);
 }
@@ -821,7 +844,7 @@ static void comp_reassign_csis (struct amf_comp *comp)
 
 	for (; csi_assignment; csi_assignment = csi_assignment->comp_next) {
 		amf_comp_hastate_set (comp, csi_assignment,
-			csi_assignment->saAmfCSICompHAState);
+			csi_assignment->requested_ha_state);
 	}
 }
 
@@ -831,9 +854,11 @@ static void healthcheck_deactivate (
 	dprintf ("deactivating healthcheck for component %s\n",
              getSaNameT (&healthcheck_active->comp->name));
 
-    openais_timer_delete (healthcheck_active->timer_handle_period);
+    poll_timer_delete (aisexec_poll_handle,
+		healthcheck_active->timer_handle_period);
 
-	openais_timer_delete (healthcheck_active->timer_handle_duration);
+	poll_timer_delete (aisexec_poll_handle,
+		healthcheck_active->timer_handle_duration);
 
 	invocation_destroy_by_data ((void *)healthcheck_active);
 	healthcheck_active->active = 0;
@@ -852,7 +877,7 @@ static void timer_function_healthcheck_next_fn (void *_healthcheck)
 	lib_healthcheck_request (healthcheck);
 
 	/* start duration timer for response */
-	openais_timer_add (
+	poll_timer_add (aisexec_poll_handle,
 		healthcheck->saAmfHealthcheckMaxDuration,
 		(void *)healthcheck,
 		timer_function_healthcheck_tmo,
@@ -944,7 +969,7 @@ static void lib_csi_set_request (
 	csi_assignment->requested_ha_state = requested_ha_state;
 	csi = csi_assignment->csi;
 
-	dprintf("\t   Assigning CSI '%s' state %s to comp '%s'\n",
+	dprintf("Assigning CSI '%s' state %s to comp '%s'\n",
 		getSaNameT (&csi->name), amf_ha_state (requested_ha_state),
 			comp->name.value);
 
@@ -1043,8 +1068,8 @@ SaAisErrorT amf_comp_register (struct amf_comp *comp)
 			comp_reassign_csis (comp);
 		}
 	} else if (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_INSTANTIATING) {
-		comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATED);
 		comp_operational_state_set (comp, SA_AMF_OPERATIONAL_ENABLED);
+		comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATED);
 	}
 	else {
 		assert (0);
@@ -1093,7 +1118,14 @@ void amf_comp_healthcheck_tmo (
 void amf_comp_cleanup_completed (struct amf_comp *comp)
 {
 	TRACE2("Exec CLC cleanup completed for '%s'", &comp->name.value);
-	amf_comp_instantiate (comp);
+
+	if (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_RESTARTING) {
+		amf_comp_instantiate (comp);
+	} else {
+		comp_presence_state_set (comp, SA_AMF_PRESENCE_UNINSTANTIATED);
+		amf_su_comp_state_changed (comp->su, comp, SA_AMF_PRESENCE_STATE,
+								   SA_AMF_PRESENCE_UNINSTANTIATED);
+	}
 }
 
 /**
@@ -1145,14 +1177,14 @@ SaAisErrorT amf_comp_healthcheck_start (
 
 	if (invocationType == SA_AMF_HEALTHCHECK_AMF_INVOKED) {
 		/* start timer to execute first healthcheck request */
-		openais_timer_add (
+		poll_timer_add (aisexec_poll_handle,
 			healthcheck->saAmfHealthcheckPeriod,
 			(void *)healthcheck,
 			timer_function_healthcheck_next_fn,
 			&healthcheck->timer_handle_period);
 	} else if (invocationType == SA_AMF_HEALTHCHECK_COMPONENT_INVOKED) {
 		/* start supervision timer */
-		openais_timer_add (
+		poll_timer_add (aisexec_poll_handle,
 			healthcheck->saAmfHealthcheckPeriod,
 			(void *)healthcheck,
 			timer_function_healthcheck_tmo,
@@ -1210,7 +1242,8 @@ void amf_comp_instantiate (struct amf_comp *comp)
 {
 	int res = 0;
 
-	ENTER ("'%s'", getSaNameT (&comp->name));
+	ENTER ("'%s' SU '%s'", getSaNameT (&comp->name),
+		getSaNameT (&comp->su->name));
 
 	if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_RESTARTING) {
 		comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATING);
@@ -1275,16 +1308,17 @@ int amf_comp_response_1 (
 		case AMF_RESPONSE_HEALTHCHECKCALLBACK: {
 			struct amf_healthcheck *healthcheck = data;
 			SaNameT name;
-			TRACE3 ("Healthcheck response from '%s': %d",
+			TRACE8 ("Healthcheck response from '%s': %d",
 					amf_comp_dn_make (healthcheck->comp, &name), error);
 
 			if (healthcheck->invocationType == SA_AMF_HEALTHCHECK_AMF_INVOKED) {
 				/* the response was on time, delete supervision timer */
-				openais_timer_delete (healthcheck->timer_handle_duration);
+				poll_timer_delete (aisexec_poll_handle,
+				   healthcheck->timer_handle_duration);
 				healthcheck->timer_handle_duration = 0;
 
 				/* start timer to execute next healthcheck request */
-				openais_timer_add (
+				poll_timer_add (aisexec_poll_handle,
 					healthcheck->saAmfHealthcheckPeriod,
 					(void *)healthcheck,
 					timer_function_healthcheck_next_fn,
@@ -1351,14 +1385,15 @@ struct amf_comp *amf_comp_response_2 (
 		case AMF_RESPONSE_CSISETCALLBACK: {
 			struct amf_csi_assignment *csi_assignment = data;
 			dprintf ("CSI '%s' set callback response from '%s', error: %d",
-					 csi_assignment->csi->name.value, csi_assignment->comp->name.value, error);
+				csi_assignment->csi->name.value,
+				csi_assignment->comp->name.value, error);
 			comp = csi_assignment->comp;
 			if (error == SA_AIS_OK) {
 				comp_ha_state_set (comp, csi_assignment,
 								   csi_assignment->requested_ha_state);
 			} else if (error == SA_AIS_ERR_FAILED_OPERATION) {
-				amf_su_comp_error_suspected (comp->su, comp,
-											 comp->saAmfCompRecoveryOnError);
+				amf_si_comp_set_ha_state_failed (csi_assignment->csi->si,
+					csi_assignment);
 			} else {
 				*retval = SA_AIS_ERR_INVALID_PARAM;
 			}
@@ -1367,9 +1402,18 @@ struct amf_comp *amf_comp_response_2 (
 		case AMF_RESPONSE_CSIREMOVECALLBACK: {
 			struct amf_csi_assignment *csi_assignment = data;
 			dprintf ("Lib csi '%s' remove callback response from '%s', error: %d",
-					 csi_assignment->csi->name.value, csi_assignment->comp->name.value, error);
+				csi_assignment->csi->name.value,
+				csi_assignment->comp->name.value, error);
 			comp = csi_assignment->comp;
-			amf_su_comp_hastate_changed (comp->su, comp, csi_assignment);
+			if (error == SA_AIS_OK) {
+				comp_ha_state_set (comp, csi_assignment,
+								   csi_assignment->requested_ha_state);
+			} else if (error == SA_AIS_ERR_FAILED_OPERATION) {
+				amf_si_comp_set_ha_state_failed (csi_assignment->csi->si,
+					csi_assignment);
+			} else {
+				*retval = SA_AIS_ERR_INVALID_PARAM;
+			}
 			break;
 		}
 #if 0
@@ -1491,8 +1535,9 @@ SaAisErrorT amf_comp_healthcheck_confirm (
 	} else if (healthcheck->active) {
 		if (healthcheckResult == SA_AIS_OK) {
 			/* the response was on time, restart the supervision timer */
-			openais_timer_delete (healthcheck->timer_handle_period);
-			openais_timer_add (
+			poll_timer_delete (aisexec_poll_handle,
+				healthcheck->timer_handle_period);
+			poll_timer_add (aisexec_poll_handle,
 				healthcheck->saAmfHealthcheckPeriod,
 				(void *)healthcheck,
 				timer_function_healthcheck_tmo,

+ 64 - 17
exec/amfsg.c

@@ -144,6 +144,7 @@
 #include "amf.h"
 #include "print.h"
 #include "main.h"
+#include "util.h"
 
 static inline int div_round (int a, int b)
 {
@@ -155,21 +156,19 @@ static inline int div_round (int a, int b)
 	return res;
 }
 
-static int sg_all_su_in_service(struct amf_sg *sg)
+static int all_su_instantiated(struct amf_sg *sg)
 {
 	struct amf_su   *su;
-	struct amf_comp *comp;
-	int ready = 1;
+	int all_instantiated = 1;
 
 	for (su = sg->su_head; su != NULL; su = su->next) {
-		for (comp = su->comp_head; comp != NULL; comp = comp->next) {
-			if (su->saAmfSUReadinessState != SA_AMF_READINESS_IN_SERVICE) {
-				ready = 0;
-			}
+		if (su->saAmfSUPresenceState != SA_AMF_PRESENCE_INSTANTIATED) {
+			all_instantiated = 0;
+			break;
 		}
 	}
 
-	return ready;
+	return all_instantiated;
 }
 
 static int application_si_count_get (struct amf_application *app)
@@ -297,6 +296,18 @@ static int su_inservice_count_get (struct amf_sg *sg)
 	return (answer);
 }
 
+static void si_activated_callback (struct amf_si *si, int result)
+{
+	/*                                                              
+     * TODO: not implemented yet...
+     */
+}
+
+/**
+ * TODO: dependency_level not used, hard coded
+ * @param sg
+ * @param dependency_level
+ */
 void amf_sg_assign_si (struct amf_sg *sg, int dependency_level)
 {
 	int active_sus_needed;
@@ -310,8 +321,15 @@ void amf_sg_assign_si (struct amf_sg *sg, int dependency_level)
 	int su_spare_assign;
 
 	ENTER ("'%s'", sg->name.value);
-	/*
-	 * Number of SUs to assign to active or standby state
+
+	/**
+     * Phase 1: Calculate assignments and create all runtime objects in
+     * information model. Do not do the actual assignment, done in
+     * phase 2.
+     */
+
+	/**
+	 * Calculate number of SUs to assign to active or standby state
 	 */
 	inservice_count = (float)su_inservice_count_get (sg);
 
@@ -336,7 +354,7 @@ void amf_sg_assign_si (struct amf_sg *sg, int dependency_level)
 		ii_spare = 0;
 	}
 
-	/*
+    /**
 	 * Determine number of active and standby service units
 	 * to assign based upon reduction procedure
 	 */
@@ -389,6 +407,20 @@ void amf_sg_assign_si (struct amf_sg *sg, int dependency_level)
 		inservice_count, su_active_assign, su_standby_assign, su_spare_assign);
 	sg_assign_nm_active (sg, su_active_assign);
 	sg_assign_nm_standby (sg, su_standby_assign);
+
+	/**
+     * Phase 2: do the actual assignment to the component
+     */
+	{
+		struct amf_si *si;
+
+		for (si = sg->application->si_head; si != NULL; si = si->next) {
+			if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
+				amf_si_activate (si, si_activated_callback);
+			}
+		}
+	}
+
 	LEAVE ("'%s'", sg->name.value);
 }
 
@@ -403,15 +435,24 @@ void amf_sg_start (struct amf_sg *sg, struct amf_node *node)
 	}
 }
 
-extern void amf_sg_su_state_changed (
+void amf_sg_su_state_changed (
 	struct amf_sg *sg, struct amf_su *su, SaAmfStateT type, int state)
 {
-	if (sg_all_su_in_service(su->sg)) {
-		TRACE1 ("All SUs in SG '%s' in service, assigning SIs\n", su->sg->name.value);
-		amf_sg_assign_si (su->sg, 0);
-		if (amf_cluster.timeout_handle) {
-			openais_timer_delete (amf_cluster.timeout_handle);
+	ENTER ("'%s' SU '%s' state %d", sg->name.value, su->name.value, state);
+
+	if (type == SA_AMF_PRESENCE_STATE) {
+		if (state == SA_AMF_PRESENCE_INSTANTIATED) {
+			/*
+			 * If all SU presence states are INSTANTIATED, report to SG.
+			 */
+			if (all_su_instantiated(su->sg)) {
+				amf_application_sg_started (sg->application, sg, this_amf_node);
+			}
+		} else {
+			assert (0);
 		}
+	} else {
+		assert (0);
 	}
 }
 
@@ -420,3 +461,9 @@ void amf_sg_init (void)
 	log_init ("AMF");
 }
 
+void amf_sg_si_activated (struct amf_sg *sg, struct amf_si *si)
+{
+	ENTER ("");
+	amf_application_sg_assigned (sg->application, sg);
+}
+

+ 60 - 0
exec/amfsi.c

@@ -130,3 +130,63 @@ void amf_si_init (void)
 	log_init ("AMF");
 }
 
+void amf_si_comp_set_ha_state_done (
+	struct amf_si *si, struct amf_csi_assignment *csi_assignment)
+{
+	struct amf_csi *csi;
+	int all_confirmed = 1;
+
+	ENTER ("");
+
+	/**
+     * If all requested active/standby CSIs in SI are
+     * confirmed by the component, tell SG that the SI is
+     * activated.
+     */
+	for (csi = si->csi_head; csi != NULL; csi = csi->next) {
+		struct amf_csi_assignment *tmp;
+		for (tmp = csi->csi_assignments; tmp != NULL; tmp = tmp->csi_next) {
+			if (tmp->requested_ha_state != tmp->saAmfCSICompHAState) {
+				all_confirmed = 0;
+				goto done;
+			}
+		}
+	}
+
+done:
+	if (all_confirmed) {
+		amf_sg_si_activated (csi_assignment->comp->su->sg, si);
+	}
+}
+
+void amf_si_activate (
+	struct amf_si *si,
+	void (*activated_callback_fn)(struct amf_si *si, int result))
+{
+	struct amf_csi *csi;
+
+	ENTER ("'%s'", si->name.value);
+
+	for (csi = si->csi_head; csi != NULL; csi = csi->next) {
+		struct amf_csi_assignment *csi_assignment;
+
+		for (csi_assignment = csi->csi_assignments; csi_assignment != NULL;
+			csi_assignment = csi_assignment->csi_next) {
+
+			/*                                                              
+			 * TODO: only active assignments should be set when dependency
+			 * levels are used.
+			 */
+			amf_comp_hastate_set (csi_assignment->comp, csi_assignment,
+				csi_assignment->requested_ha_state);
+		}
+	}
+}
+
+void amf_si_comp_set_ha_state_failed (
+	struct amf_si *si, struct amf_csi_assignment *csi_assignment)
+{
+	ENTER ("");
+	assert (0);
+}
+

+ 12 - 7
exec/amfsu.c

@@ -155,6 +155,7 @@ static void su_presence_state_set (struct amf_su *su,
 	su->saAmfSUPresenceState = presence_state;
 	TRACE1 ("Setting SU '%s' presence state: %s\n",
 		su->name.value, amf_presence_state (presence_state));
+	amf_sg_su_state_changed (su->sg, su, SA_AMF_PRESENCE_STATE, presence_state);
 }
 
 static void su_operational_state_set (struct amf_su *su,
@@ -179,7 +180,7 @@ static void su_operational_state_set (struct amf_su *su,
 			amf_comp_readiness_state_set (comp, SA_AMF_READINESS_IN_SERVICE);
 		}
 
-		amf_sg_su_state_changed (su->sg, su, SA_AMF_OP_STATE, SA_AMF_OPERATIONAL_ENABLED);
+//		amf_sg_su_state_changed (su->sg, su, SA_AMF_OP_STATE, SA_AMF_OPERATIONAL_ENABLED);
 	} else if (oper_state == SA_AMF_OPERATIONAL_DISABLED) {
 		su_readiness_state_set (su, SA_AMF_READINESS_OUT_OF_SERVICE);
 	}
@@ -190,7 +191,7 @@ static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
 {
 	struct amf_csi_assignment *csi_assignment;
 
-	dprintf ("  Assigning CSI '%s' to comp '%s' with hastate %s\n",
+	dprintf ("  Creating CSI '%s' to comp '%s' with hastate %s\n",
 		getSaNameT (&csi->name), getSaNameT (&comp->name),
 		amf_ha_state (ha_state));
 
@@ -201,11 +202,14 @@ static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
 
 	csi_assignment->comp_next = comp->assigned_csis;
 	comp->assigned_csis = csi_assignment;
+	csi_assignment->csi_next = csi->csi_assignments;
+	csi->csi_assignments = csi_assignment;
 	setSaNameT (&csi_assignment->name, (char*)comp->name.value);
 	csi_assignment->saAmfCSICompHAState = ha_state;
 	csi_assignment->csi = csi;
 	csi_assignment->comp = comp;
-	csi_assignment->saAmfCSICompHAState = ha_state;
+	csi_assignment->saAmfCSICompHAState = 0; /* undefined confirmed HA state */
+	csi_assignment->requested_ha_state = ha_state;
 
 	if (ha_state == SA_AMF_HA_ACTIVE)
 		comp->saAmfCompNumCurrActiveCsi++;
@@ -213,8 +217,6 @@ static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
 		comp->saAmfCompNumCurrStandbyCsi++;
 	else
 		assert (0);
-
-	amf_comp_hastate_set (comp, csi_assignment, ha_state);
 }
 
 static void su_cleanup (struct amf_su *su)
@@ -286,7 +288,7 @@ void amf_su_assign_si (struct amf_su *su, struct amf_si *si,
 {
 	struct amf_si_assignment *si_assignment;
 
-	dprintf ("Assigning SI '%s' to SU '%s' with hastate %s\n",
+	dprintf ("Creating SI '%s' to SU '%s' with hastate %s\n",
 		getSaNameT (&si->name), getSaNameT (&su->name),
 		amf_ha_state (ha_state));
 
@@ -295,10 +297,13 @@ void amf_su_assign_si (struct amf_su *su, struct amf_si *si,
 		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
 	}
 	setSaNameT (&si_assignment->name, (char*)su->name.value);
-	si_assignment->saAmfSISUHAState = ha_state;
+	si_assignment->saAmfSISUHAState = 0; /* undefined confirmed HA state */
+	si_assignment->requested_ha_state = ha_state;
 	si_assignment->next = su->assigned_sis;
 	su->assigned_sis = si_assignment;
 	si_assignment->si = si;
+	memcpy (&si_assignment->si->saAmfSIProtectedbySG,
+		&su->sg->name, sizeof (SaNameT));
 
 	if (ha_state == SA_AMF_HA_ACTIVE) {
 		si->saAmfSINumCurrActiveAssignments++;

+ 7 - 6
exec/amfutil.c

@@ -244,7 +244,7 @@ static char *rm_beginning_ws(char *str)
 	return s;
 }
 
-int amf_config_read (struct amf_cluster *cluster, char **error_string)
+struct amf_cluster *amf_config_read (char **error_string)
 {
 	char buf[1024];
 	char *line;
@@ -254,6 +254,7 @@ int amf_config_read (struct amf_cluster *cluster, char **error_string)
 	int line_number = 0;
 	char *loc;
 	int i;
+	struct amf_cluster       *cluster;
 	struct amf_application   *app = 0;
 	struct amf_node          *node = 0;
 	struct amf_sg            *sg = 0;
@@ -283,11 +284,11 @@ int amf_config_read (struct amf_cluster *cluster, char **error_string)
 		sprintf (buf, "Can't read %s file reason = (%s).\n",
 				 filename, strerror (errno));
 		*error_string = buf;
-		return (-1);
+		return NULL;
 	}
 
-	cluster->saAmfClusterStartupTimeout = -1;
-	cluster->saAmfClusterAdminState = SA_AMF_ADMIN_UNLOCKED;
+	cluster = amf_cluster_create ();
+	assert (cluster != NULL);
 
 	while (fgets (buf, 255, fp)) {
 		line_number += 1;
@@ -880,14 +881,14 @@ int amf_config_read (struct amf_cluster *cluster, char **error_string)
 	}
 
 	fclose (fp);
-	return (0);
+	return cluster;
 
 parse_error:
 	sprintf (buf, "parse error at %s: %d: %s\n",
 			 filename, line_number, error_reason);
 	*error_string = buf;
 	fclose (fp);
-	return (-1);
+	return NULL;
 }
 
 void amf_runtime_attributes_print (struct amf_cluster *cluster)

+ 9 - 0
exec/timer.h

@@ -49,6 +49,15 @@ extern int openais_timer_add (
 	void (*timer_fn) (void *data),
 	timer_handle *handle);
 
+/*
+ * This should be called when the timer is added from a timer expiration
+ */
+extern int openais_timer_add_unlocked (
+	unsigned int msec_in_future,
+	void *data,
+	void (*timer_fn) (void *data),
+	timer_handle *handle);
+
 extern void openais_timer_delete (timer_handle timer_handle);
 
 extern void openais_timer_delete_data (timer_handle timer_handle);

+ 1 - 1
test/testamf1.c

@@ -331,7 +331,7 @@ int main (int argc, char **argv) {
 
     {
         SaNameT badname;
-        strcpy (badname.value, "badname");
+        strcpy ((char*)badname.value, "badname");
         badname.length = 7;
         result = saAmfComponentRegister (handle, &badname, NULL);
         printf ("register result is %d (should be %d)\n", result, SA_AIS_ERR_INVALID_PARAM);