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

- New sync state machine, implemented and described in amf.c
- One AMF node reads the AMF config file (IMM style)
- One AMF node syncs others AMF nodes
- One AMF object is serialized and sent as one message
- Serialization/deserialization of most objects is trivial (memcpy)
except for component and csi-attributes objects which have variable size
arrays/strings.
- Depth first AMF object tree traversal preserves relations when syncing
- Ordered lists of SUs and SIs
- Constructors/destructor per class
- Serializers/deserializers per class
- Config-change changes sync state
- Sync callbacks executes the sync
- "Use case" tracing for sync using the SYNCTRACE macro (trace6)
- Sync master is initially the winner of a timeout race and if the
master leaves the cluster, the node with the lowest node ID becomes new master.
- amf_malloc implements an AMF central malloc routine with error handling.



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

Hans Feldt 19 лет назад
Родитель
Сommit
98dfb95e26
12 измененных файлов с 2600 добавлено и 357 удалено
  1. 2 0
      conf/amf.conf
  2. 874 40
      exec/amf.c
  3. 141 66
      exec/amf.h
  4. 87 9
      exec/amfapp.c
  5. 46 21
      exec/amfcluster.c
  6. 408 92
      exec/amfcomp.c
  7. 103 1
      exec/amfnode.c
  8. 115 10
      exec/amfsg.c
  9. 449 8
      exec/amfsi.c
  10. 172 25
      exec/amfsu.c
  11. 164 78
      exec/amfutil.c
  12. 39 7
      test/testamf1.c

+ 2 - 0
conf/amf.conf

@@ -102,6 +102,8 @@ safAmfCluster = TEST_CLUSTER {
 					saAmfCompCmdEnv {
 					saAmfCompCmdEnv {
 						COMP_BINARY_PATH=/tmp/aistest
 						COMP_BINARY_PATH=/tmp/aistest
 						COMP_BINARY_NAME=testamf1
 						COMP_BINARY_NAME=testamf1
+						var1=val1
+						var2=val2
 					}
 					}
 					saAmfCompRecoveryOnError=component_restart
 					saAmfCompRecoveryOnError=component_restart
 					safHealthcheckKey = key1 {
 					safHealthcheckKey = key1 {

Разница между файлами не показана из-за своего большого размера
+ 874 - 40
exec/amf.c


+ 141 - 66
exec/amf.h

@@ -45,6 +45,7 @@
 #include "../include/ipc_gen.h"
 #include "../include/ipc_gen.h"
 #include "objdb.h"
 #include "objdb.h"
 #include "timer.h"
 #include "timer.h"
+#include "aispoll.h"
 
 
 enum clc_component_types {
 enum clc_component_types {
 	clc_component_sa_aware = 0,			/* sa aware */
 	clc_component_sa_aware = 0,			/* sa aware */
@@ -85,10 +86,38 @@ typedef enum {
 	SU_RC_RESTART_SU_ACTIVATING
 	SU_RC_RESTART_SU_ACTIVATING
 } su_restart_control_state_t;
 } su_restart_control_state_t;
 
 
+typedef enum {
+	AMF_NONE,
+	AMF_APPLICATION,
+	AMF_CLUSTER,
+	AMF_NODE,
+	AMF_SG,
+	AMF_SU,
+	AMF_COMP,
+	AMF_COMP_ENV_VAR,
+	AMF_COMP_CS_TYPE,
+	AMF_SI,
+	AMF_SI_ASSIGNMENT,
+	AMF_SI_RANKED_SU,
+	AMF_SI_DEPENDENCY,
+	AMF_CSI,
+	AMF_CSI_ASSIGNMENT,
+	AMF_CSI_ATTRIBUTE,
+	AMF_HEALTHCHECK,
+	AMF_CSI_DEPENDENCIES,
+	AMF_CS_TYPE,
+} amf_object_type_t;
+
 struct amf_si_assignment;
 struct amf_si_assignment;
 struct amf_csi_assignment;
 struct amf_csi_assignment;
 struct amf_healthcheck;
 struct amf_healthcheck;
 
 
+enum cluster_states {
+	CLUSTER_UNINSTANTIATED,
+	CLUSTER_STARTING,
+	CLUSTER_STARTED
+};
+
 struct amf_cluster {
 struct amf_cluster {
 	/* Configuration Attributes */
 	/* Configuration Attributes */
 	SaNameT name;
 	SaNameT name;
@@ -103,7 +132,8 @@ struct amf_cluster {
 	struct amf_application *application_head;
 	struct amf_application *application_head;
 
 
 	/* Implementation */
 	/* Implementation */
-	openais_timer_handle timeout_handle;
+	poll_timer_handle timeout_handle;
+	enum cluster_states state;
 };
 };
 
 
 struct amf_node {
 struct amf_node {
@@ -138,11 +168,12 @@ struct amf_application {
 	/* Relations */
 	/* Relations */
 	struct amf_cluster *cluster;
 	struct amf_cluster *cluster;
 	struct amf_sg      *sg_head;
 	struct amf_sg      *sg_head;
+	/* ordered list of SUs */
 	struct amf_si      *si_head;
 	struct amf_si      *si_head;
+	struct amf_si      *si_tail;
 
 
 	/* Implementation */
 	/* Implementation */
 	char clccli_path[PATH_MAX];
 	char clccli_path[PATH_MAX];
-	char binary_path[PATH_MAX];
 	struct amf_application *next;
 	struct amf_application *next;
 };
 };
 
 
@@ -172,11 +203,12 @@ struct amf_sg {
 
 
 	/* Relations */
 	/* Relations */
 	struct amf_application *application;
 	struct amf_application *application;
+
+    /* ordered list of SUs */
 	struct amf_su          *su_head;
 	struct amf_su          *su_head;
 
 
 	/* Implementation */
 	/* Implementation */
 	char clccli_path[PATH_MAX];
 	char clccli_path[PATH_MAX];
-	char binary_path[PATH_MAX];
 	struct amf_sg *next;
 	struct amf_sg *next;
 	sg_avail_control_state_t avail_state;
 	sg_avail_control_state_t avail_state;
 };
 };
@@ -209,7 +241,6 @@ struct amf_su {
 	su_restart_control_state_t restart_control_state;
 	su_restart_control_state_t restart_control_state;
 	su_restart_control_state_t escalation_level_history_state;
 	su_restart_control_state_t escalation_level_history_state;
 	char clccli_path[PATH_MAX];
 	char clccli_path[PATH_MAX];
-	char binary_path[PATH_MAX];
 	SaUint32T              su_failover_cnt; /* missing in SAF specs? */
 	SaUint32T              su_failover_cnt; /* missing in SAF specs? */
 	struct amf_su         *next;
 	struct amf_su         *next;
 };
 };
@@ -223,33 +254,33 @@ struct amf_comp {
 	SaUint32T saAmfCompNumMaxActiveCsi;
 	SaUint32T saAmfCompNumMaxActiveCsi;
 	SaUint32T saAmfCompNumMaxStandbyCsi;
 	SaUint32T saAmfCompNumMaxStandbyCsi;
 	SaStringT *saAmfCompCmdEnv;
 	SaStringT *saAmfCompCmdEnv;
-	int saAmfCompDefaultClcCliTimeout;
-	int saAmfCompDefaultCallbackTimeOut;
+	SaUint32T saAmfCompDefaultClcCliTimeout;
+	SaUint32T saAmfCompDefaultCallbackTimeOut;
 	SaStringT saAmfCompInstantiateCmd;
 	SaStringT saAmfCompInstantiateCmd;
 	SaStringT saAmfCompInstantiateCmdArgv;
 	SaStringT saAmfCompInstantiateCmdArgv;
-	int saAmfCompInstantiateTimeout;
+	SaUint32T saAmfCompInstantiateTimeout;
 	SaUint32T saAmfCompInstantiationLevel;
 	SaUint32T saAmfCompInstantiationLevel;
 	SaUint32T saAmfCompNumMaxInstantiateWithoutDelay;
 	SaUint32T saAmfCompNumMaxInstantiateWithoutDelay;
 	SaUint32T saAmfCompNumMaxInstantiateWithDelay;
 	SaUint32T saAmfCompNumMaxInstantiateWithDelay;
-	int saAmfCompDelayBetweenInstantiateAttempts;
+	SaUint32T saAmfCompDelayBetweenInstantiateAttempts;
 	SaStringT saAmfCompTerminateCmd;
 	SaStringT saAmfCompTerminateCmd;
-	int saAmfCompTerminateTimeout;
+	SaUint32T saAmfCompTerminateTimeout;
 	SaStringT saAmfCompTerminateCmdArgv;
 	SaStringT saAmfCompTerminateCmdArgv;
 	SaStringT saAmfCompCleanupCmd;
 	SaStringT saAmfCompCleanupCmd;
-	int saAmfCompCleanupTimeout;
+	SaUint32T saAmfCompCleanupTimeout;
 	SaStringT saAmfCompCleanupCmdArgv;
 	SaStringT saAmfCompCleanupCmdArgv;
 	SaStringT saAmfCompAmStartCmd;
 	SaStringT saAmfCompAmStartCmd;
-	int saAmfCompAmStartTimeout;
+	SaUint32T saAmfCompAmStartTimeout;
 	SaStringT saAmfCompAmStartCmdArgv;
 	SaStringT saAmfCompAmStartCmdArgv;
 	SaUint32T saAmfCompNumMaxAmStartAttempt;
 	SaUint32T saAmfCompNumMaxAmStartAttempt;
 	SaStringT saAmfCompAmStopCmd;
 	SaStringT saAmfCompAmStopCmd;
-	int saAmfCompAmStopTimeout;
+	SaUint32T saAmfCompAmStopTimeout;
 	SaStringT saAmfCompAmStopCmdArgv;
 	SaStringT saAmfCompAmStopCmdArgv;
 	SaUint32T saAmfCompNumMaxAmStopAttempt;
 	SaUint32T saAmfCompNumMaxAmStopAttempt;
-	int saAmfCompTerminateCallbackTimeout;
-	int saAmfCompCSISetCallbackTimeout;
-	int saAmfCompQuiescingCompleteTimeout;
-	int saAmfCompCSIRmvCallbackTimeout;
+	SaUint32T saAmfCompTerminateCallbackTimeout;
+	SaUint32T saAmfCompCSISetCallbackTimeout;
+	SaUint32T saAmfCompQuiescingCompleteTimeout;
+	SaUint32T saAmfCompCSIRmvCallbackTimeout;
 	SaAmfRecommendedRecoveryT saAmfCompRecoveryOnError;
 	SaAmfRecommendedRecoveryT saAmfCompRecoveryOnError;
 	SaBoolT saAmfCompDisableRestart;
 	SaBoolT saAmfCompDisableRestart;
 	SaNameT saAmfCompProxyCsi;
 	SaNameT saAmfCompProxyCsi;
@@ -261,17 +292,16 @@ struct amf_comp {
 	SaUint32T saAmfCompRestartCount;
 	SaUint32T saAmfCompRestartCount;
 /*     SaUint32T saAmfCompNumCurrActiveCsi;  */
 /*     SaUint32T saAmfCompNumCurrActiveCsi;  */
 /*     SaUint32T saAmfCompNumCurrStandbyCsi; */
 /*     SaUint32T saAmfCompNumCurrStandbyCsi; */
-	SaNameT saAmfCompAssignedCsi;
+/*	SaNameT saAmfCompAssignedCsi; */
 	SaNameT saAmfCompCurrProxyName;
 	SaNameT saAmfCompCurrProxyName;
-	SaNameT saAmfCompCurrProxiedNames;
+	SaNameT **saAmfCompCurrProxiedNames;
 
 
 	/* Relations */
 	/* Relations */
 	struct amf_comp *proxy_comp;
 	struct amf_comp *proxy_comp;
 	struct amf_su *su;
 	struct amf_su *su;
 
 
 	/* Implementation */
 	/* Implementation */
-	char clccli_path[PATH_MAX];
-	char binary_path[PATH_MAX];
+	SaStringT clccli_path;
 	struct amf_comp *next;
 	struct amf_comp *next;
 	void *conn;
 	void *conn;
 	enum clc_component_types comptype;
 	enum clc_component_types comptype;
@@ -280,7 +310,7 @@ struct amf_comp {
 	/**
 	/**
      * Flag that indicates of this component has a suspected error
      * Flag that indicates of this component has a suspected error
 	 */
 	 */
-	int error_suspected;
+	SaUint32T error_suspected;
 };
 };
 
 
 struct amf_healthcheck {
 struct amf_healthcheck {
@@ -297,8 +327,8 @@ struct amf_healthcheck {
 	int active;
 	int active;
 	SaAmfHealthcheckInvocationT invocationType;
 	SaAmfHealthcheckInvocationT invocationType;
 	SaAmfRecommendedRecoveryT recommendedRecovery;
 	SaAmfRecommendedRecoveryT recommendedRecovery;
-	openais_timer_handle timer_handle_duration;
-	openais_timer_handle timer_handle_period;
+	poll_timer_handle timer_handle_duration;
+	poll_timer_handle timer_handle_period;
 };
 };
 
 
 struct amf_si {
 struct amf_si {
@@ -420,7 +450,10 @@ enum amf_message_req_types {
 	MESSAGE_REQ_EXEC_AMF_COMPONENT_ERROR_REPORT = 1,
 	MESSAGE_REQ_EXEC_AMF_COMPONENT_ERROR_REPORT = 1,
 	MESSAGE_REQ_EXEC_AMF_CLC_CLEANUP_COMPLETED = 2,
 	MESSAGE_REQ_EXEC_AMF_CLC_CLEANUP_COMPLETED = 2,
 	MESSAGE_REQ_EXEC_AMF_HEALTHCHECK_TMO = 3,
 	MESSAGE_REQ_EXEC_AMF_HEALTHCHECK_TMO = 3,
-	MESSAGE_REQ_EXEC_AMF_RESPONSE = 4
+	MESSAGE_REQ_EXEC_AMF_RESPONSE = 4,
+	MESSAGE_REQ_EXEC_AMF_SYNC_START = 5,
+	MESSAGE_REQ_EXEC_AMF_SYNC_DATA = 6,
+	MESSAGE_REQ_EXEC_AMF_SYNC_READY = 7
 };
 };
 
 
 struct req_exec_amf_clc_cleanup_completed {
 struct req_exec_amf_clc_cleanup_completed {
@@ -438,15 +471,10 @@ struct req_exec_amf_healthcheck_tmo {
 /* amfutil.c */
 /* amfutil.c */
 
 
 extern struct amf_cluster *amf_config_read (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);
 extern void amf_runtime_attributes_print (struct amf_cluster *cluster);
 extern void amf_runtime_attributes_print (struct amf_cluster *cluster);
 extern int amf_enabled (struct objdb_iface_ver0 *objdb);
 extern int amf_enabled (struct objdb_iface_ver0 *objdb);
-extern int amf_invocation_create (int interface, void *data);
-extern int amf_invocation_get_and_destroy (
-	int invocation, int *interface,	void **data);
-extern void amf_invocation_destroy_by_data (void *data);
+extern void *_amf_malloc (size_t size, char *file, unsigned int line);
+#define amf_malloc(size) _amf_malloc ((size), __FILE__, __LINE__)
 
 
 extern const char *amf_admin_state (int state);
 extern const char *amf_admin_state (int state);
 extern const char *amf_op_state (int state);
 extern const char *amf_op_state (int state);
@@ -455,15 +483,31 @@ extern const char *amf_ha_state (int state);
 extern const char *amf_readiness_state (int state);
 extern const char *amf_readiness_state (int state);
 extern const char *amf_assignment_state (int state);
 extern const char *amf_assignment_state (int state);
 
 
+extern char *amf_serialize_SaNameT (
+	char *buf, int *size, int *offset, SaNameT *name);
+extern char *amf_serialize_SaStringT (
+	char *buf, int *size, int *offset, SaStringT str);
+extern char *amf_serialize_SaUint32T (
+	char *buf, int *size, int *offset, SaUint32T num);
+extern char *amf_serialize_SaUint64T (char *buf, SaUint64T num);
+extern char *amf_serialize_opaque (
+	char *buf, int *size, int *offset, char *cp, int cnt);
+extern char *amf_deserialize_SaNameT (char *buf, SaNameT *name);
+extern char *amf_deserialize_SaStringT (char *buf, SaStringT *str);
+extern char *amf_deserialize_SaUint32T (char *buf, SaUint32T *num);
+extern char *amf_deserialize_SaUint64T (char *buf, SaUint64T *num);
+extern char *amf_deserialize_opaque (char *buf, char *dst, int *cnt);
+
 /*===========================================================================*/
 /*===========================================================================*/
 /* amfnode.c */
 /* amfnode.c */
 
 
 /* General methods */
 /* General methods */
-extern struct amf_node *amf_node_create (void);
-extern int amf_node_serialize (
-	struct amf_node *node, char **buf, int *offset);
+extern struct amf_node *amf_node_new (struct amf_cluster *cluster, char *name);
+extern void amf_node_init (void);
+extern void *amf_node_serialize (struct amf_node *node, int *len);
 extern struct amf_node *amf_node_deserialize (
 extern struct amf_node *amf_node_deserialize (
-	char **buf, int *size, struct amf_cluster *cluster);
+	struct amf_cluster *cluster, char *buf, int size);
+extern struct amf_node *amf_node_find (SaNameT *name);
 
 
 /* Event methods */
 /* Event methods */
 extern void amf_node_sync_ready (struct amf_node *node);
 extern void amf_node_sync_ready (struct amf_node *node);
@@ -498,11 +542,9 @@ extern void timer_function_node_probation_period_expired (void *node);
 
 
 /* General methods */
 /* General methods */
 extern void amf_cluster_init (void);
 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 (
-	char **buf, int *size, struct amf_cluster *cluster);
+extern struct amf_cluster *amf_cluster_new (void);
+extern void *amf_cluster_serialize (struct amf_cluster *cluster, int *len);
+extern struct amf_cluster *amf_cluster_deserialize (char *buf, int size);
 
 
 /* Event methods */
 /* Event methods */
 extern void amf_cluster_start (struct amf_cluster *cluster);
 extern void amf_cluster_start (struct amf_cluster *cluster);
@@ -518,13 +560,17 @@ extern void amf_cluster_application_workload_assigned (
 
 
 /* General methods */
 /* General methods */
 extern void amf_application_init (void);
 extern void amf_application_init (void);
-extern struct amf_application *amf_application_create (void);
+extern struct amf_application *amf_application_find (
+	struct amf_cluster *cluster, char *name);
+extern struct amf_application *amf_application_new (
+	struct amf_cluster *cluster);
+extern void amf_application_delete (struct amf_application *app);
 extern int amf_application_calc_and_set_si_dependency_level (
 extern int amf_application_calc_and_set_si_dependency_level (
 	struct amf_application *app);
 	struct amf_application *app);
-extern int amf_application_serialize (
-	struct amf_application *application, char **buf, int *offset);
+extern void *amf_application_serialize (
+	struct amf_application *application, int *len);
 extern struct amf_application *amf_application_deserialize (
 extern struct amf_application *amf_application_deserialize (
-	char **buf, int *size, struct amf_cluster *cluster);
+	struct amf_cluster *cluster, char *buf, int size);
 
 
 /* Event methods */
 /* Event methods */
 extern void amf_application_start (
 extern void amf_application_start (
@@ -543,11 +589,12 @@ extern void amf_application_sg_assigned (
 
 
 /* General methods */
 /* General methods */
 extern void amf_sg_init (void);
 extern void amf_sg_init (void);
-extern struct amf_sg *amf_sg_create (void);
-extern int amf_sg_serialize (
-	struct amf_sg *sg, char **buf, int *offset);
+extern struct amf_sg *amf_sg_find (struct amf_application *app, char *name);
+extern struct amf_sg *amf_sg_new (struct amf_application *app, char *name);
+extern void amf_sg_delete (struct amf_sg *sg);
+extern void *amf_sg_serialize (struct amf_sg *sg, int *len);
 extern struct amf_sg *amf_sg_deserialize (
 extern struct amf_sg *amf_sg_deserialize (
-	char **buf, int *size, struct amf_cluster *cluster);
+	struct amf_application *app, char *buf, int size);
 
 
 /**
 /**
  * Request SG to start (instantiate all SUs)
  * Request SG to start (instantiate all SUs)
@@ -593,12 +640,14 @@ extern void amf_sg_si_activated (
 
 
 /* General methods */
 /* General methods */
 extern void amf_su_init (void);
 extern void amf_su_init (void);
-extern struct amf_su *amf_su_create (void);
+extern struct amf_su *amf_su_find (
+	struct amf_cluster *cluster, SaNameT *name);
+extern struct amf_su *amf_su_new (struct amf_sg *sg, char *name);
+extern void amf_su_delete (struct amf_su *su);
 extern char *amf_su_dn_make (struct amf_su *su, SaNameT *name);
 extern char *amf_su_dn_make (struct amf_su *su, SaNameT *name);
-extern int amf_su_serialize (
-	struct amf_su *su, char **buf, int *offset);
+extern void *amf_su_serialize (struct amf_su *su, int *len);
 extern struct amf_su *amf_su_deserialize (
 extern struct amf_su *amf_su_deserialize (
-	char **buf, int *size, struct amf_cluster *cluster);
+	struct amf_sg *sg, char *buf, int size);
 extern int amf_su_is_local (struct amf_su *su);
 extern int amf_su_is_local (struct amf_su *su);
 extern struct amf_si_assignment *amf_su_get_next_si_assignment (
 extern struct amf_si_assignment *amf_su_get_next_si_assignment (
 	struct amf_su *su, const struct amf_si_assignment *si_assignment);
 	struct amf_su *su, const struct amf_si_assignment *si_assignment);
@@ -648,14 +697,14 @@ extern void amf_su_comp_error_suspected (
 
 
 /* General methods */
 /* General methods */
 extern void amf_comp_init (void);
 extern void amf_comp_init (void);
-extern struct amf_comp *amf_comp_create (struct amf_su *su);
+extern struct amf_comp *amf_comp_new (struct amf_su *su, char *name);
+extern void amf_comp_delete (struct amf_comp *comp);
 extern char *amf_comp_dn_make (struct amf_comp *comp, SaNameT *name);
 extern char *amf_comp_dn_make (struct amf_comp *comp, SaNameT *name);
 extern struct amf_comp *amf_comp_find (
 extern struct amf_comp *amf_comp_find (
 	struct amf_cluster *cluster, SaNameT *name);
 	struct amf_cluster *cluster, SaNameT *name);
-extern int amf_comp_serialize (
-	struct amf_comp *comp, char **buf, int *offset);
+extern void *amf_comp_serialize (struct amf_comp *comp, int *len);
 extern struct amf_comp *amf_comp_deserialize (
 extern struct amf_comp *amf_comp_deserialize (
-	char **buf, int *size, struct amf_cluster *cluster);
+	struct amf_su *su, char *buf, int size);
 extern void amf_comp_foreach_csi_assignment (
 extern void amf_comp_foreach_csi_assignment (
 	struct amf_comp *component,
 	struct amf_comp *component,
 	void (*foreach_fn)(struct amf_comp *component,
 	void (*foreach_fn)(struct amf_comp *component,
@@ -723,9 +772,10 @@ extern void amf_comp_unregister (struct amf_comp *comp);
 extern void amf_comp_error_report (
 extern void amf_comp_error_report (
 	struct amf_comp *comp, SaAmfRecommendedRecoveryT recommendedRecovery);
 	struct amf_comp *comp, SaAmfRecommendedRecoveryT recommendedRecovery);
 extern int amf_comp_response_1 (
 extern int amf_comp_response_1 (
-	SaInvocationT invocation, SaAisErrorT error, SaAisErrorT *retval);
+	SaInvocationT invocation, SaAisErrorT error, SaAisErrorT *retval,
+	SaUint32T *interface, SaNameT *dn);
 extern struct amf_comp *amf_comp_response_2 (
 extern struct amf_comp *amf_comp_response_2 (
-	SaInvocationT invocation, SaAisErrorT error, SaAisErrorT *retval);
+	SaUint32T interface, SaNameT *dn, SaAisErrorT error, SaAisErrorT *retval);
 extern SaAisErrorT amf_comp_hastate_get (
 extern SaAisErrorT amf_comp_hastate_get (
 	struct amf_comp *comp, SaNameT *csi_name, SaAmfHAStateT *ha_state);
 	struct amf_comp *comp, SaNameT *csi_name, SaAmfHAStateT *ha_state);
 extern SaAisErrorT amf_comp_healthcheck_confirm (
 extern SaAisErrorT amf_comp_healthcheck_confirm (
@@ -733,17 +783,27 @@ extern SaAisErrorT amf_comp_healthcheck_confirm (
 	SaAmfHealthcheckKeyT *healthcheckKey,
 	SaAmfHealthcheckKeyT *healthcheckKey,
 	SaAisErrorT healthcheckResult);
 	SaAisErrorT healthcheckResult);
 
 
+extern void *amf_healthcheck_serialize (
+	struct amf_healthcheck *healthcheck, int *len);
+extern struct amf_healthcheck *amf_healthcheck_deserialize (
+	struct amf_comp *comp, char *buf, int size);
+
 /*===========================================================================*/
 /*===========================================================================*/
 /* amfsi.c */
 /* amfsi.c */
 
 
 /* General methods */
 /* General methods */
 extern void amf_si_init (void);
 extern void amf_si_init (void);
-extern struct amf_si *amf_si_create (void);
+extern struct amf_si *amf_si_find (struct amf_application *app, char *name);
+extern struct amf_si *amf_si_new (struct amf_application *app, char *name);
+extern void amf_si_delete (struct amf_si *si);
 extern int amf_si_calc_and_set_csi_dependency_level (struct amf_si *si);
 extern int amf_si_calc_and_set_csi_dependency_level (struct amf_si *si);
-extern int amf_si_serialize (
-	struct amf_si *si, char **buf, int *offset);
+extern void *amf_si_serialize (struct amf_si *si, int *len);
 extern struct amf_si *amf_si_deserialize (
 extern struct amf_si *amf_si_deserialize (
-	char **buf, int *size, struct amf_cluster *cluster);
+	struct amf_application *app, char *buf, int size);
+extern void *amf_si_assignment_serialize (
+	struct amf_si_assignment *si_assignment, int *len);
+extern struct amf_si_assignment *amf_si_assignment_deserialize (
+	struct amf_si *si, char *buf, int size);
 
 
 /**
 /**
  * Get number of active assignments for the specified SI
  * Get number of active assignments for the specified SI
@@ -835,12 +895,27 @@ extern void amf_si_comp_set_ha_state_failed (
 extern void amf_csi_delete_assignments (struct amf_csi *csi, struct amf_su *su);
 extern void amf_csi_delete_assignments (struct amf_csi *csi, struct amf_su *su);
 
 
 /* General methods */
 /* General methods */
-extern struct amf_csi *amf_csi_create (void);
-extern int amf_csi_serialize (
-	struct amf_csi *csi, char **buf, int *offset);
+extern struct amf_csi *amf_csi_new (struct amf_si *si);
+extern struct amf_csi *amf_csi_find (struct amf_si *si, char *name);
+extern void amf_csi_delete (struct amf_csi *csi);
+extern void *amf_csi_serialize (struct amf_csi *csi, int *len);
 extern struct amf_csi *amf_csi_deserialize (
 extern struct amf_csi *amf_csi_deserialize (
-	char **buf, int *size, struct amf_cluster *cluster);
+	struct amf_si *si, char *buf, int size);
+extern void *amf_csi_assignment_serialize (
+	struct amf_csi_assignment *csi_assignment, int *len);
+extern struct amf_csi_assignment *amf_csi_assignment_deserialize (
+	struct amf_csi *csi, char *buf, int size);
 extern char *amf_csi_dn_make (struct amf_csi *csi, SaNameT *name);
 extern char *amf_csi_dn_make (struct amf_csi *csi, SaNameT *name);
+extern char *amf_csi_assignment_dn_make (
+	struct amf_csi_assignment *csi_assignment, SaNameT *name);
+extern struct amf_csi_assignment *amf_csi_assignment_find (
+	struct amf_cluster *cluster, SaNameT *name);
+
+extern struct amf_csi_attribute *amf_csi_attribute_new (struct amf_csi *csi);
+extern void *amf_csi_attribute_serialize (
+	struct amf_csi_attribute *csi_attribute, int *len);
+extern struct amf_csi_attribute *amf_csi_attribute_deserialize (
+	struct amf_csi *csi, char *buf, int size);
 
 
 /*===========================================================================*/
 /*===========================================================================*/
 extern struct amf_node *this_amf_node;
 extern struct amf_node *this_amf_node;

+ 87 - 9
exec/amfapp.c

@@ -1,9 +1,10 @@
 /** @file amfapp.c
 /** @file amfapp.c
  * 
  * 
  * Copyright (c) 2006 Ericsson AB.
  * Copyright (c) 2006 Ericsson AB.
- *  Author: Hans Feldt
+ * Author: Hans Feldt, Anders Eriksson, Lars Holm
  *  - Refactoring of code into several AMF files
  *  - Refactoring of code into several AMF files
- *  Author: Anders Eriksson
+ *  - Constructors/destructors
+ *  - Serializers/deserializers
  *
  *
  * All rights reserved.
  * All rights reserved.
  *
  *
@@ -69,6 +70,7 @@
  * have been executed.
  * have been executed.
  * 
  * 
  */
  */
+#include <assert.h>
 
 
 #include "amf.h"
 #include "amf.h"
 #include "print.h"
 #include "print.h"
@@ -100,9 +102,7 @@ void amf_application_start (
 
 
 	ENTER ("'%s'", app->name.value);
 	ENTER ("'%s'", app->name.value);
 
 
-	/*
-     * TODO: Calculate and set SI dependency levels
-     */
+	/* TODO: Calculate and set SI dependency levels  */
 
 
 	for (sg = app->sg_head; sg != NULL; sg = sg->next) {
 	for (sg = app->sg_head; sg != NULL; sg = sg->next) {
 		amf_sg_start (sg, node);
 		amf_sg_start (sg, node);
@@ -115,10 +115,10 @@ void amf_application_assign_workload (
 	struct amf_sg *sg;
 	struct amf_sg *sg;
 
 
 	/*                                                              
 	/*                                                              
-     * TODO: dependency level ignored
-     * Each dependency level should be looped and amf_sg_assign_si
-     * called several times.
-     */
+	 * 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) {
 	for (sg = app->sg_head; sg != NULL; sg = sg->next) {
 		amf_sg_assign_si (sg, 0);
 		amf_sg_assign_si (sg, 0);
 	}
 	}
@@ -146,4 +146,82 @@ void amf_application_sg_assigned (
 	amf_cluster_application_workload_assigned (app->cluster, app);
 	amf_cluster_application_workload_assigned (app->cluster, app);
 }
 }
 
 
+struct amf_application *amf_application_new (struct amf_cluster *cluster)
+{
+	struct amf_application *app = amf_malloc (sizeof (struct amf_application));
+
+	app->cluster = cluster;
+	return app;
+}
+
+void amf_application_delete (struct amf_application *app)
+{
+	struct amf_sg *sg;
+	struct amf_si *si;
+
+	for (sg = app->sg_head; sg != NULL;) {
+		struct amf_sg *tmp = sg;
+		sg = sg->next;
+		amf_sg_delete (tmp);
+	}
+
+	for (si = app->si_head; si != NULL;) {
+		struct amf_si *tmp = si;
+		si = si->next;
+		amf_si_delete (tmp);
+	}
+
+	free (app);
+}
+
+void *amf_application_serialize (
+	struct amf_application *app, int *len)
+{
+	int objsz = sizeof (struct amf_application);
+	struct amf_application *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, app, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_application *amf_application_deserialize (
+	struct amf_cluster *cluster, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_application);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_application *obj = amf_application_new (cluster);
+		assert (obj);
+		memcpy (obj, buf, objsz);
+		TRACE8 ("%s", obj->name.value);
+		obj->cluster = cluster;
+		obj->sg_head = NULL;
+		obj->si_head = NULL;
+		obj->next = cluster->application_head;
+		cluster->application_head = obj;
+		return obj;
+	}
+}
+
+struct amf_application *amf_application_find (
+	struct amf_cluster *cluster, char *name)
+{
+	struct amf_application *app;
+
+	ENTER ("%s", name);
+
+	for (app = cluster->application_head; app != NULL; app = app->next) {
+		if (strncmp (name, (char*)app->name.value, app->name.length) == 0) {
+			break;
+		}
+	}
+
+	return app;
+}
 
 

+ 46 - 21
exec/amfcluster.c

@@ -1,9 +1,10 @@
 /** @file amfcluster.c
 /** @file amfcluster.c
  * 
  * 
  * Copyright (c) 2006 Ericsson AB.
  * Copyright (c) 2006 Ericsson AB.
- *  Author: Hans Feldt
+ * Author: Hans Feldt, Anders Eriksson, Lars Holm
  *  - Refactoring of code into several AMF files
  *  - Refactoring of code into several AMF files
- *  Author: Anders Eriksson
+ *  - Constructors/destructors
+ *  - Serializers/deserializers
  *
  *
  * All rights reserved.
  * All rights reserved.
  *
  *
@@ -107,42 +108,32 @@ static void timer_function_cluster_assign_workload_tmo (void *_cluster)
 	struct amf_application *app;
 	struct amf_application *app;
 	struct amf_cluster *cluster = _cluster;
 	struct amf_cluster *cluster = _cluster;
 
 
-	dprintf("2nd Cluster start timer expired, assigning workload to application\n");
+	dprintf("Cluster start timer expired, assigning workload to application\n");
 
 
 	for (app = cluster->application_head; app != NULL; app = app->next) {
 	for (app = cluster->application_head; app != NULL; app = app->next) {
 		amf_application_assign_workload (app, this_amf_node);
 		amf_application_assign_workload (app, this_amf_node);
 	}
 	}
 }
 }
 
 
-static void timer_function_cluster_startup_tmo (void *_cluster)
+void amf_cluster_start (struct amf_cluster *cluster)
 {
 {
-	struct amf_cluster *cluster = _cluster;
 	struct amf_application *app;
 	struct amf_application *app;
 
 
-	log_printf(LOG_NOTICE, "AMF Cluster: starting applications.");
+	log_printf(LOG_NOTICE, "Cluster: starting applications.");
+
+	amf_cluster->state = CLUSTER_STARTING;
 
 
 	for (app = cluster->application_head; app != NULL; app = app->next) {
 	for (app = cluster->application_head; app != NULL; app = app->next) {
 		amf_application_start (app, NULL);
 		amf_application_start (app, NULL);
 	}
 	}
 
 
 	/* wait a while before assigning workload */
 	/* wait a while before assigning workload */
-	poll_timer_add (aisexec_poll_handle,
-		cluster->saAmfClusterStartupTimeout,
+	poll_timer_add (aisexec_poll_handle, cluster->saAmfClusterStartupTimeout,
 		cluster,
 		cluster,
 		timer_function_cluster_assign_workload_tmo,
 		timer_function_cluster_assign_workload_tmo,
 		&cluster->timeout_handle);
 		&cluster->timeout_handle);
 }
 }
 
 
-void amf_cluster_start (struct amf_cluster *cluster)
-{
-	/* wait a while before starting applications */
-	poll_timer_add (aisexec_poll_handle,
-		cluster->saAmfClusterStartupTimeout,
-		cluster,
-		timer_function_cluster_startup_tmo,
-		&cluster->timeout_handle);
-}
-
 void amf_cluster_init (void)
 void amf_cluster_init (void)
 {
 {
 	log_init ("AMF");
 	log_init ("AMF");
@@ -156,7 +147,8 @@ void amf_cluster_application_started (
 	if (all_applications_started (cluster)) {
 	if (all_applications_started (cluster)) {
 		struct amf_application *app;
 		struct amf_application *app;
 
 
-		log_printf(LOG_NOTICE, "AMF Cluster: all applications started, assigning workload.");
+		log_printf(LOG_NOTICE,
+				   "Cluster: all applications started, assigning workload.");
 
 
 		if (cluster->timeout_handle) {
 		if (cluster->timeout_handle) {
 			poll_timer_delete (aisexec_poll_handle, cluster->timeout_handle);
 			poll_timer_delete (aisexec_poll_handle, cluster->timeout_handle);
@@ -168,7 +160,7 @@ void amf_cluster_application_started (
 	}
 	}
 }
 }
 
 
-struct amf_cluster *amf_cluster_create (void)
+struct amf_cluster *amf_cluster_new (void)
 {
 {
 	struct amf_cluster *cluster = calloc (1, sizeof (struct amf_cluster));
 	struct amf_cluster *cluster = calloc (1, sizeof (struct amf_cluster));
 
 
@@ -185,6 +177,39 @@ struct amf_cluster *amf_cluster_create (void)
 void amf_cluster_application_workload_assigned (
 void amf_cluster_application_workload_assigned (
 	struct amf_cluster *cluster, struct amf_application *app)
 	struct amf_cluster *cluster, struct amf_application *app)
 {
 {
-	log_printf(LOG_NOTICE, "AMF Cluster: all workload assigned.");
+	log_printf(LOG_NOTICE, "Cluster: all workload assigned.");
+	amf_cluster->state = CLUSTER_STARTED;
+}
+
+void *amf_cluster_serialize (struct amf_cluster *cluster, int *len)
+{
+	int objsz = sizeof (struct amf_cluster);
+	struct amf_cluster *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, cluster, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_cluster *amf_cluster_deserialize (char *buf, int size)
+{
+	int objsz = sizeof (struct amf_cluster);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_cluster *obj = amf_cluster_new ();
+		if (obj == NULL) {
+			return NULL;
+		}
+		memcpy (obj, buf, objsz);
+		TRACE8 ("%s", obj->name.value);
+		obj->node_head = NULL;
+		obj->application_head = NULL;
+		return obj;
+	}
 }
 }
 
 

+ 408 - 92
exec/amfcomp.c

@@ -8,13 +8,14 @@
  *
  *
  * Author: Steven Dake (sdake@mvista.com)
  * Author: Steven Dake (sdake@mvista.com)
  *
  *
- * Author: Hans Feldt
+ * Author: Hans Feldt, Anders Eriksson, Lars Holm
  * - Introduced AMF B.02 information model
  * - Introduced AMF B.02 information model
  * - Use DN in API and multicast messages
  * - Use DN in API and multicast messages
  * - (Re-)Introduction of event based multicast messages
  * - (Re-)Introduction of event based multicast messages
  * - Refactoring of code into several AMF files
  * - Refactoring of code into several AMF files
- * Author: Anders Eriksson, Lars Holm
  * - Component/SU restart, SU failover
  * - Component/SU restart, SU failover
+ * - Constructors/destructors
+ * - Serializers/deserializers
  *
  *
  * This software licensed under BSD license, the text of which follows:
  * This software licensed under BSD license, the text of which follows:
  * 
  * 
@@ -137,12 +138,13 @@
 #include "../include/ipc_gen.h"
 #include "../include/ipc_gen.h"
 #include "../include/ipc_amf.h"
 #include "../include/ipc_amf.h"
 #include "totempg.h"
 #include "totempg.h"
-#include "main.h"
+#include "timer.h"
 #include "ipc.h"
 #include "ipc.h"
 #include "service.h"
 #include "service.h"
 #include "util.h"
 #include "util.h"
 #include "amf.h"
 #include "amf.h"
 #include "print.h"
 #include "print.h"
+#include "main.h"
 
 
 enum clc_command_run_operation_type {
 enum clc_command_run_operation_type {
 	CLC_COMMAND_RUN_OPERATION_TYPE_INSTANTIATE = 1,
 	CLC_COMMAND_RUN_OPERATION_TYPE_INSTANTIATE = 1,
@@ -251,7 +253,7 @@ static int invocation_create (
 		invocation_temp = (struct invocation *)realloc (invocation_entries,
 		invocation_temp = (struct invocation *)realloc (invocation_entries,
 			(invocation_entries_size + 1) * sizeof (struct invocation));
 			(invocation_entries_size + 1) * sizeof (struct invocation));
 		if (invocation_temp == NULL) {
 		if (invocation_temp == NULL) {
-			return (-1);
+			openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
 		}
 		}
 		invocation_entries = invocation_temp;
 		invocation_entries = invocation_temp;
 		invocation_addr = &invocation_entries[invocation_entries_size];
 		invocation_addr = &invocation_entries[invocation_entries_size];
@@ -265,8 +267,8 @@ static int invocation_create (
 	return (loc);
 	return (loc);
 }
 }
 
 
-static int invocation_get_and_destroy (SaUint64T invocation, int *interface,
-	void **data)
+static int invocation_get_and_destroy (
+	SaUint64T invocation, unsigned int *interface, void **data)
 {
 {
 	if (invocation > invocation_entries_size) {
 	if (invocation > invocation_entries_size) {
 		return (-1);
 		return (-1);
@@ -282,8 +284,9 @@ static int invocation_get_and_destroy (SaUint64T invocation, int *interface,
 	return (0);
 	return (0);
 }
 }
 
 
-static int invocation_get (SaUint64T invocation, int *interface,
-	void **data)
+#if 0
+static int invocation_get (
+	SaUint64T invocation, unsigned int *interface, void **data)
 {
 {
 	if (invocation > invocation_entries_size) {
 	if (invocation > invocation_entries_size) {
 		return (-1);
 		return (-1);
@@ -297,6 +300,7 @@ static int invocation_get (SaUint64T invocation, int *interface,
 	
 	
 	return (0);
 	return (0);
 }
 }
+#endif
 
 
 static void invocation_destroy_by_data (void *data)
 static void invocation_destroy_by_data (void *data)
 {
 {
@@ -369,16 +373,24 @@ static void *clc_command_run (void *context)
 	if (pid) {
 	if (pid) {
 		xprintf ("waiting for pid %d to finish\n", pid);
 		xprintf ("waiting for pid %d to finish\n", pid);
 		waitpid (pid, &status, 0);
 		waitpid (pid, &status, 0);
-		if (WEXITSTATUS(status) != 0) {
-			fprintf (stderr, "Error: CLC_CLI failed with exit status:"
-							 " %d - %s\n", WEXITSTATUS(status),
+		if (WIFEXITED (status) != 0 && WEXITSTATUS(status) != 0) {
+			fprintf (stderr, "Error: CLC_CLI (%d) failed with exit status:"
+							 " %d - %s\n", pid, WEXITSTATUS(status),
 						strerror (WEXITSTATUS(status)));
 						strerror (WEXITSTATUS(status)));
 			/*                                                              
 			/*                                                              
              * TODO: remove this and handle properly later...
              * TODO: remove this and handle properly later...
              */
              */
 			openais_exit_error (AIS_DONE_FATAL_ERR);
 			openais_exit_error (AIS_DONE_FATAL_ERR);
 		}
 		}
-		xprintf ("process (%d) finished with %d\n", pid, status);
+		if (WIFSIGNALED (status) != 0) {
+			fprintf (stderr, "Error: CLC_CLI (%d) failed with exit status:"
+							 " %d\n", pid, WTERMSIG(status));
+			/*                                                              
+			 * TODO: remove this and handle properly later...
+			 */
+			openais_exit_error (AIS_DONE_FATAL_ERR);
+		}
+		xprintf ("process (%d) finished with %x\n", pid, status);
 		if (clc_command_run_data->completion_callback) {
 		if (clc_command_run_data->completion_callback) {
 			clc_command_run_data->completion_callback (context);
 			clc_command_run_data->completion_callback (context);
 		}
 		}
@@ -407,7 +419,8 @@ static void *clc_command_run (void *context)
 
 
 	/* If command is not an absolute path, search for paths in parent objects */
 	/* If command is not an absolute path, search for paths in parent objects */
 	if (cmd[0] != '/') {
 	if (cmd[0] != '/') {
-		if (strlen (clc_command_run_data->comp->clccli_path)) {
+		if (clc_command_run_data->comp->clccli_path != NULL &&
+			strlen (clc_command_run_data->comp->clccli_path)) {
 			sprintf (path, "%s/%s",
 			sprintf (path, "%s/%s",
 					 clc_command_run_data->comp->clccli_path, cmd);
 					 clc_command_run_data->comp->clccli_path, cmd);
 		} else if (strlen (clc_command_run_data->comp->su->clccli_path)) {
 		} else if (strlen (clc_command_run_data->comp->su->clccli_path)) {
@@ -424,11 +437,7 @@ static void *clc_command_run (void *context)
 	}
 	}
 
 
 	argv_size = 2;
 	argv_size = 2;
-	argv = malloc (sizeof (char*) * argv_size);
-	if (argv == NULL) {
-		fprintf (stderr, "out-of-memory");
-		exit (-1);
-	}
+	argv = amf_malloc (sizeof (char*) * argv_size);
 	argv[0] = cmd;
 	argv[0] = cmd;
 	{
 	{
 		/* make a proper argv array */
 		/* make a proper argv array */
@@ -459,11 +468,7 @@ static void *clc_command_run (void *context)
 
 
     /* two is for component name and NULL termination */
     /* two is for component name and NULL termination */
 	envp_size = 2;
 	envp_size = 2;
-	envp = malloc (sizeof (char*) * envp_size);
-	if (envp == NULL) {
-		fprintf (stderr, "out-of-memory");
-		exit (-1);
-	}
+	envp = amf_malloc (sizeof (char*) * envp_size);
 	envp[0] = comp_name;
 	envp[0] = comp_name;
 	for (i = 1; clc_command_run_data->comp->saAmfCompCmdEnv &&
 	for (i = 1; clc_command_run_data->comp->saAmfCompCmdEnv &&
 		   clc_command_run_data->comp->saAmfCompCmdEnv[i - 1]; i++) {
 		   clc_command_run_data->comp->saAmfCompCmdEnv[i - 1]; i++) {
@@ -509,10 +514,7 @@ static int clc_cli_instantiate (struct amf_comp *comp)
 
 
 	ENTER("comp '%s'\n", getSaNameT (&comp->name));
 	ENTER("comp '%s'\n", getSaNameT (&comp->name));
 
 
-	clc_command_run_data = malloc (sizeof (struct clc_command_run_data));
-	if (clc_command_run_data == NULL) {
-		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
-	}
+	clc_command_run_data = amf_malloc (sizeof (struct clc_command_run_data));
 	clc_command_run_data->comp = comp;
 	clc_command_run_data->comp = comp;
 	clc_command_run_data->type = CLC_COMMAND_RUN_OPERATION_TYPE_INSTANTIATE;
 	clc_command_run_data->type = CLC_COMMAND_RUN_OPERATION_TYPE_INSTANTIATE;
 	clc_command_run_data->completion_callback = NULL;
 	clc_command_run_data->completion_callback = NULL;
@@ -568,10 +570,7 @@ static int lib_comp_terminate_request (struct amf_comp *comp)
 	memcpy (&res_lib.compName, &comp->name, sizeof (SaNameT));
 	memcpy (&res_lib.compName, &comp->name, sizeof (SaNameT));
 
 
 	component_terminate_callback_data =
 	component_terminate_callback_data =
-		malloc (sizeof (struct component_terminate_callback_data));
-	if (component_terminate_callback_data == NULL) {
-		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
-	}
+		amf_malloc (sizeof (struct component_terminate_callback_data));
 	component_terminate_callback_data->comp = comp;
 	component_terminate_callback_data->comp = comp;
 
 
 	res_lib.invocation =
 	res_lib.invocation =
@@ -630,10 +629,7 @@ static int clc_cli_cleanup (struct amf_comp *comp)
 	struct clc_command_run_data *clc_command_run_data;
 	struct clc_command_run_data *clc_command_run_data;
 
 
 	dprintf ("clc_cli_cleanup\n");
 	dprintf ("clc_cli_cleanup\n");
-	clc_command_run_data = malloc (sizeof (struct clc_command_run_data));
-	if (clc_command_run_data == NULL) {
-		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
-	}
+	clc_command_run_data = amf_malloc (sizeof (struct clc_command_run_data));
 	clc_command_run_data->comp = comp;
 	clc_command_run_data->comp = comp;
 	clc_command_run_data->type = CLC_COMMAND_RUN_OPERATION_TYPE_CLEANUP;
 	clc_command_run_data->type = CLC_COMMAND_RUN_OPERATION_TYPE_CLEANUP;
 	clc_command_run_data->completion_callback = mcast_cleanup_completion_event;
 	clc_command_run_data->completion_callback = mcast_cleanup_completion_event;
@@ -694,25 +690,83 @@ struct amf_healthcheck *amf_comp_find_healthcheck (
 	return (ret_healthcheck);
 	return (ret_healthcheck);
 }
 }
 
 
-struct amf_comp *amf_comp_create(struct amf_su *su)
+/**
+ * Constructor for component objects. Adds component last in
+ * the list owned by the specified SU. Always returns a
+ * valid comp object, out-of-memory problems are handled
+ * here. Default values are initialized.
+ * @param su
+ * @param name
+ * 
+ * @return struct amf_comp*
+ */
+struct amf_comp *amf_comp_new(struct amf_su *su, char *name)
 {
 {
+	struct amf_comp *tail = su->comp_head;
 	struct amf_comp *comp = calloc (1, sizeof (struct amf_comp));
 	struct amf_comp *comp = calloc (1, sizeof (struct amf_comp));
 
 
 	if (comp == NULL) {
 	if (comp == NULL) {
 		openais_exit_error(AIS_DONE_OUT_OF_MEMORY);
 		openais_exit_error(AIS_DONE_OUT_OF_MEMORY);
 	}
 	}
-	comp->next = su->comp_head;
-	su->comp_head = comp;
+	while (tail != NULL) {
+		if (tail->next == NULL) {
+			break;
+		}
+		tail = tail->next;
+	}
+
+	if (tail == NULL) {
+		su->comp_head = comp;
+	} else {
+		tail->next = comp;
+	}
 	comp->su = su;
 	comp->su = su;
-	comp->saAmfCompOperState = SA_AMF_OPERATIONAL_DISABLED;
-	comp->saAmfCompPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
+
+	/* setup default values from spec. */
 	comp->saAmfCompNumMaxInstantiateWithoutDelay = 2;
 	comp->saAmfCompNumMaxInstantiateWithoutDelay = 2;
 	comp->saAmfCompNumMaxAmStartAttempt = 2;
 	comp->saAmfCompNumMaxAmStartAttempt = 2;
 	comp->saAmfCompNumMaxAmStopAttempt = 2;
 	comp->saAmfCompNumMaxAmStopAttempt = 2;
 
 
+	comp->saAmfCompOperState = SA_AMF_OPERATIONAL_DISABLED;
+	comp->saAmfCompPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
+	setSaNameT (&comp->name, name);
+
 	return comp;
 	return comp;
 }
 }
 
 
+void amf_comp_delete (struct amf_comp *comp)
+{
+	int i;
+	struct amf_healthcheck *healthcheck;
+
+	for (healthcheck = comp->healthcheck_head; healthcheck != NULL;) {
+		struct amf_healthcheck *tmp = healthcheck;
+		healthcheck = healthcheck->next;
+		free (tmp);
+	}
+
+	for (i = 0; comp->saAmfCompCsTypes[i] != NULL; i++) {
+		free (comp->saAmfCompCsTypes[i]);
+	}
+	for (i = 0; comp->saAmfCompCmdEnv[i] != NULL; i++) {
+		free (comp->saAmfCompCmdEnv[i]);
+	}
+
+	free (comp->saAmfCompInstantiateCmd);
+	free (comp->saAmfCompInstantiateCmdArgv);
+	free (comp->saAmfCompTerminateCmd);
+	free (comp->saAmfCompTerminateCmdArgv);
+	free (comp->saAmfCompCleanupCmd);
+	free (comp->saAmfCompCleanupCmdArgv);
+	free (comp->saAmfCompAmStartCmd);
+	free (comp->saAmfCompAmStartCmdArgv);
+	free (comp->saAmfCompAmStopCmd);
+	free (comp->saAmfCompAmStopCmdArgv);
+	free (comp->clccli_path);
+
+	free (comp);
+}
+
 struct amf_comp *amf_comp_find (struct amf_cluster *cluster, SaNameT *name)
 struct amf_comp *amf_comp_find (struct amf_cluster *cluster, SaNameT *name)
 {
 {
 	struct amf_application *app;
 	struct amf_application *app;
@@ -727,8 +781,8 @@ struct amf_comp *amf_comp_find (struct amf_cluster *cluster, SaNameT *name)
 	char *buf;
 	char *buf;
 
 
 	/* malloc new buffer since strtok_r writes to its first argument */
 	/* malloc new buffer since strtok_r writes to its first argument */
-	buf = malloc (name->length + 1);
-	memcpy (buf, name->value,name ->length);
+	buf = amf_malloc (name->length + 1);
+	memcpy (buf, name->value,name ->length + 1);
 
 
 	comp_name = strtok_r(buf, ",", &ptrptr);
 	comp_name = strtok_r(buf, ",", &ptrptr);
 	su_name = strtok_r(NULL, ",", &ptrptr);
 	su_name = strtok_r(NULL, ",", &ptrptr);
@@ -745,26 +799,22 @@ struct amf_comp *amf_comp_find (struct amf_cluster *cluster, SaNameT *name)
 	sg_name += 6;
 	sg_name += 6;
 	app_name += 7;
 	app_name += 7;
 
 
-	for (app = cluster->application_head; app != NULL; app = app->next) {
-		if (strncmp (app_name,
-					 (char*)app->name.value, app->name.length) == 0) {
-			for (sg = app->sg_head; sg != NULL; sg = sg->next) {
-				if (strncmp (sg_name, (char*)sg->name.value,
-							 sg->name.length) == 0) {
-					for (su = sg->su_head; su != NULL; su = su->next) {
-						if (strncmp (su_name, (char*)su->name.value,
-									 su->name.length) == 0) {
-							for (comp = su->comp_head;
-								  comp != NULL;
-								  comp = comp->next) {
-								if (strncmp (comp_name,
-											 (char*)comp->name.value,
-											 comp->name.length) == 0) {
-									goto end;
-								}
-							}
-						}
-					}
+	app = amf_application_find (cluster, app_name);
+	if (app == NULL) {
+		goto end;
+	}
+
+	sg = amf_sg_find (app, sg_name);
+	if (sg == NULL) {
+		goto end;
+	}
+
+	for (su = sg->su_head; su != NULL; su = su->next) {
+		if (strncmp (su_name, (char*)su->name.value, su->name.length) == 0) {
+			for (comp = su->comp_head; comp != NULL; comp = comp->next) {
+				if (strncmp (comp_name,	(char*)comp->name.value,
+					comp->name.length) == 0) {
+					goto end;
 				}
 				}
 			}
 			}
 		}
 		}
@@ -958,10 +1008,9 @@ static void healthcheck_deactivate (
              getSaNameT (&healthcheck_active->comp->name));
              getSaNameT (&healthcheck_active->comp->name));
 
 
     poll_timer_delete (aisexec_poll_handle,
     poll_timer_delete (aisexec_poll_handle,
-		healthcheck_active->timer_handle_period);
-
+					   healthcheck_active->timer_handle_period);
 	poll_timer_delete (aisexec_poll_handle,
 	poll_timer_delete (aisexec_poll_handle,
-		healthcheck_active->timer_handle_duration);
+					   healthcheck_active->timer_handle_duration);
 
 
 	invocation_destroy_by_data ((void *)healthcheck_active);
 	invocation_destroy_by_data ((void *)healthcheck_active);
 	healthcheck_active->active = 0;
 	healthcheck_active->active = 0;
@@ -1041,7 +1090,7 @@ static void lib_healthcheck_request (struct amf_healthcheck *healthcheck)
 	memcpy (&res_lib.key, &healthcheck->safHealthcheckKey,
 	memcpy (&res_lib.key, &healthcheck->safHealthcheckKey,
 		sizeof (SaAmfHealthcheckKeyT));
 		sizeof (SaAmfHealthcheckKeyT));
 
 
-	TRACE8 ("sending healthcheck request to component %s",
+	TRACE7 ("sending healthcheck request to component %s",
 			res_lib.compName.value);
 			res_lib.compName.value);
 	openais_conn_send_response (
 	openais_conn_send_response (
 		openais_conn_partner_get (healthcheck->comp->conn),
 		openais_conn_partner_get (healthcheck->comp->conn),
@@ -1081,12 +1130,8 @@ static void lib_csi_set_request (
 			char_length_of_csi_attrs += 2;
 			char_length_of_csi_attrs += 2;
 		}
 		}
 	}
 	}
-	p = malloc(sizeof(struct res_lib_amf_csisetcallback) +
+	p = amf_malloc(sizeof(struct res_lib_amf_csisetcallback) +
 			   char_length_of_csi_attrs);
 			   char_length_of_csi_attrs);
-	if (p == NULL) {
-		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
-	}
-
 	res_lib = (struct res_lib_amf_csisetcallback*)p;
 	res_lib = (struct res_lib_amf_csisetcallback*)p;
 
 
 	/* Address of the buffer containing the Csi name value pair  */
 	/* Address of the buffer containing the Csi name value pair  */
@@ -1148,7 +1193,6 @@ static void lib_csi_set_request (
 	res_lib->haState = csi_assignment->requested_ha_state;
 	res_lib->haState = csi_assignment->requested_ha_state;
 	res_lib->invocation =
 	res_lib->invocation =
 		invocation_create (AMF_RESPONSE_CSISETCALLBACK, csi_assignment);
 		invocation_create (AMF_RESPONSE_CSISETCALLBACK, csi_assignment);
-
 	openais_conn_send_response (
 	openais_conn_send_response (
 		openais_conn_partner_get (comp->conn), res_lib,	res_lib->header.size);
 		openais_conn_partner_get (comp->conn), res_lib,	res_lib->header.size);
 
 
@@ -1377,13 +1421,13 @@ void amf_comp_readiness_state_set (struct amf_comp *comp,
  * @return >0  do not respond to component, multicast response
  * @return >0  do not respond to component, multicast response
  */
  */
 int amf_comp_response_1 (
 int amf_comp_response_1 (
-	SaInvocationT invocation, SaAisErrorT error, SaAisErrorT *retval)
+	SaInvocationT invocation, SaAisErrorT error, SaAisErrorT *retval,
+	SaUint32T *interface, SaNameT *dn)
 {
 {
 	int res;
 	int res;
-	int interface;
 	void *data;
 	void *data;
 
 
-	res = invocation_get (invocation, &interface, &data);
+	res = invocation_get_and_destroy (invocation, interface, &data);
 
 
 	if (res == -1) {
 	if (res == -1) {
 		log_printf (LOG_ERR, "Lib response: invocation not found\n");
 		log_printf (LOG_ERR, "Lib response: invocation not found\n");
@@ -1391,17 +1435,17 @@ int amf_comp_response_1 (
 		return 0;
 		return 0;
 	}
 	}
 
 
-	switch (interface) {
+	switch (*interface) {
 		case AMF_RESPONSE_HEALTHCHECKCALLBACK: {
 		case AMF_RESPONSE_HEALTHCHECKCALLBACK: {
 			struct amf_healthcheck *healthcheck = data;
 			struct amf_healthcheck *healthcheck = data;
 			SaNameT name;
 			SaNameT name;
-			TRACE8 ("Healthcheck response from '%s': %d",
+			TRACE7 ("Healthcheck response from '%s': %d",
 					amf_comp_dn_make (healthcheck->comp, &name), error);
 					amf_comp_dn_make (healthcheck->comp, &name), error);
 
 
 			if (healthcheck->invocationType == SA_AMF_HEALTHCHECK_AMF_INVOKED) {
 			if (healthcheck->invocationType == SA_AMF_HEALTHCHECK_AMF_INVOKED) {
 				/* the response was on time, delete supervision timer */
 				/* the response was on time, delete supervision timer */
 				poll_timer_delete (aisexec_poll_handle,
 				poll_timer_delete (aisexec_poll_handle,
-				   healthcheck->timer_handle_duration);
+					healthcheck->timer_handle_duration);
 				healthcheck->timer_handle_duration = 0;
 				healthcheck->timer_handle_duration = 0;
 
 
 				/* start timer to execute next healthcheck request */
 				/* start timer to execute next healthcheck request */
@@ -1419,7 +1463,8 @@ int amf_comp_response_1 (
 			break;
 			break;
 		}
 		}
 		case AMF_RESPONSE_CSISETCALLBACK: /* fall-through */
 		case AMF_RESPONSE_CSISETCALLBACK: /* fall-through */
-	    case AMF_RESPONSE_CSIREMOVECALLBACK:
+		case AMF_RESPONSE_CSIREMOVECALLBACK:
+			amf_csi_assignment_dn_make (data, dn);
 			return 1; /* multicast event */
 			return 1; /* multicast event */
 			break;
 			break;
 #if 0
 #if 0
@@ -1454,27 +1499,20 @@ int amf_comp_response_1 (
  * @return component to which the response should be sent
  * @return component to which the response should be sent
  */
  */
 struct amf_comp *amf_comp_response_2 (
 struct amf_comp *amf_comp_response_2 (
-	SaInvocationT invocation, SaAisErrorT error, SaAisErrorT *retval)
+	SaUint32T interface, SaNameT *dn, SaAisErrorT error, SaAisErrorT *retval)
 {
 {
-	int res;
-	int interface;
-	void *data;
+	struct amf_csi_assignment *csi_assignment;
 	struct amf_comp *comp = NULL;
 	struct amf_comp *comp = NULL;
 
 
 	assert (retval != NULL);
 	assert (retval != NULL);
 
 
 	*retval = SA_AIS_OK;
 	*retval = SA_AIS_OK;
 
 
-	res = invocation_get_and_destroy (invocation, &interface, &data);
-	if (res == -1) {
-		log_printf (LOG_ERR, "Comp response: invocation not found\n");
-		*retval = SA_AIS_ERR_INVALID_PARAM;
-		return NULL;
-	}
-
 	switch (interface) {
 	switch (interface) {
 		case AMF_RESPONSE_CSISETCALLBACK: {
 		case AMF_RESPONSE_CSISETCALLBACK: {
-			struct amf_csi_assignment *csi_assignment = data;
+			csi_assignment = amf_csi_assignment_find (amf_cluster, dn);
+			assert (csi_assignment != NULL);
+			comp = csi_assignment->comp;
 			dprintf ("CSI '%s' set callback response from '%s', error: %d",
 			dprintf ("CSI '%s' set callback response from '%s', error: %d",
 				csi_assignment->csi->name.value,
 				csi_assignment->csi->name.value,
 				csi_assignment->comp->name.value, error);
 				csi_assignment->comp->name.value, error);
@@ -1491,7 +1529,8 @@ struct amf_comp *amf_comp_response_2 (
 			break;
 			break;
 		}
 		}
 		case AMF_RESPONSE_CSIREMOVECALLBACK: {
 		case AMF_RESPONSE_CSIREMOVECALLBACK: {
-			struct amf_csi_assignment *csi_assignment = data;
+			csi_assignment = amf_csi_assignment_find (amf_cluster, dn);
+			assert (csi_assignment != NULL);
 			dprintf ("Lib csi '%s' remove callback response from '%s', error: %d",
 			dprintf ("Lib csi '%s' remove callback response from '%s', error: %d",
 				csi_assignment->csi->name.value,
 				csi_assignment->csi->name.value,
 				csi_assignment->comp->name.value, error);
 				csi_assignment->comp->name.value, error);
@@ -1507,6 +1546,7 @@ struct amf_comp *amf_comp_response_2 (
 			}
 			}
 			break;
 			break;
 		}
 		}
+#if 0
 	    case AMF_RESPONSE_COMPONENTTERMINATECALLBACK: {
 	    case AMF_RESPONSE_COMPONENTTERMINATECALLBACK: {
 			struct component_terminate_callback_data *callback_data = data;
 			struct component_terminate_callback_data *callback_data = data;
 			dprintf ("Lib comp '%s' terminate callback response, error: %d",
 			dprintf ("Lib comp '%s' terminate callback response, error: %d",
@@ -1515,6 +1555,7 @@ struct amf_comp *amf_comp_response_2 (
 				SA_AMF_PRESENCE_UNINSTANTIATED);
 				SA_AMF_PRESENCE_UNINSTANTIATED);
 			break;
 			break;
 		}
 		}
+#endif
 		default:
 		default:
 			assert (0);
 			assert (0);
 			break;
 			break;
@@ -1546,6 +1587,8 @@ void amf_comp_hastate_set (
 			assert (0);
 			assert (0);
 		}
 		}
 	}
 	}
+	
+	LEAVE("");
 }
 }
 
 
 /**
 /**
@@ -1721,3 +1764,276 @@ SaAmfReadinessStateT amf_comp_get_saAmfCompReadinessState (
 	/* XXX we fall here in case NDEBUG is set */
 	/* XXX we fall here in case NDEBUG is set */
 	return -1;
 	return -1;
 }
 }
+
+/**
+ * Serialize a component including variable length arrays and
+ * strings to a buffer returned. Buffer is to be freed by
+ * caller.
+ * @param component
+ * @param len
+ * 
+ * @return void*
+ */
+void *amf_comp_serialize (struct amf_comp *component, int *len)
+{
+	char *buf = NULL;
+	int i, offset = 0, size = 0;
+
+	TRACE8 ("%s", component->name.value);
+
+	buf = amf_serialize_SaNameT (buf, &size, &offset, &component->name);
+
+    /* count cstypes and write to buf */
+	for (i = 0; component->saAmfCompCsTypes &&
+		  component->saAmfCompCsTypes[i] != NULL; i++);
+	buf = amf_serialize_SaUint32T (buf, &size, &offset, i);
+
+	for (i = 0; component->saAmfCompCsTypes &&
+		  component->saAmfCompCsTypes[i] != NULL; i++) {
+		buf = amf_serialize_SaNameT (
+			buf, &size, &offset, component->saAmfCompCsTypes[i]);
+	}
+
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompCategory);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompCapability);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompNumMaxActiveCsi);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompNumMaxStandbyCsi);
+
+    /* count environment vars and write to buf */
+	for (i = 0; component->saAmfCompCmdEnv[i] != NULL; i++);
+	buf = amf_serialize_SaUint32T (buf, &size, &offset, i);
+
+	for (i = 0; component->saAmfCompCmdEnv[i] != NULL; i++) {
+		buf = amf_serialize_SaStringT (
+			buf, &size, &offset, component->saAmfCompCmdEnv[i]);
+	}
+
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompDefaultClcCliTimeout);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompDefaultCallbackTimeOut);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompInstantiateCmd);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompInstantiateCmdArgv);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompInstantiateTimeout);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompInstantiationLevel);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompNumMaxInstantiateWithoutDelay);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompNumMaxInstantiateWithDelay);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompDelayBetweenInstantiateAttempts);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompTerminateCmd);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompTerminateTimeout);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompTerminateCmdArgv);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompCleanupCmd);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompCleanupTimeout);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompCleanupCmdArgv);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompAmStartCmd);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompAmStartTimeout);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompAmStartCmdArgv);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompNumMaxAmStartAttempt);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompAmStopCmd);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompAmStopTimeout);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->saAmfCompAmStopCmdArgv);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompNumMaxAmStopAttempt);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompTerminateCallbackTimeout);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompCSISetCallbackTimeout);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompQuiescingCompleteTimeout);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompCSIRmvCallbackTimeout);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompRecoveryOnError);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompDisableRestart);
+	buf = amf_serialize_SaNameT (
+		buf, &size, &offset, &component->saAmfCompProxyCsi);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompOperState);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompPresenceState);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->saAmfCompRestartCount);
+	buf = amf_serialize_SaNameT (
+		buf, &size, &offset, &component->saAmfCompCurrProxyName);
+	buf = amf_serialize_SaStringT (
+		buf, &size, &offset, component->clccli_path);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->comptype);
+	buf = amf_serialize_SaUint32T (
+		buf, &size, &offset, component->error_suspected);
+
+	*len = offset;
+
+	return buf;
+}
+
+/**
+ * Deserialize a buffer into a AMF component object.
+ * @param su
+ * @param buf
+ * @param size
+ * 
+ * @return struct amf_comp*
+ */
+struct amf_comp *amf_comp_deserialize (struct amf_su *su, char *buf, int size)
+{
+	char *tmp = buf;
+	struct amf_comp *component;
+	int i;
+	SaUint32T cnt;
+
+	component = amf_comp_new (su, "");
+
+	tmp = amf_deserialize_SaNameT (tmp, &component->name);
+	tmp = amf_deserialize_SaUint32T (tmp, &cnt);
+	component->saAmfCompCsTypes = amf_malloc ((cnt + 1) * sizeof (SaNameT*));
+	for (i = 0; i < cnt; i++) {
+		component->saAmfCompCsTypes[i] = amf_malloc (sizeof (SaNameT));
+		tmp = amf_deserialize_SaNameT (tmp, component->saAmfCompCsTypes[i]);
+	}
+	component->saAmfCompCsTypes[i] = NULL;
+
+	tmp = amf_deserialize_SaUint32T (tmp, &component->saAmfCompCategory);
+	tmp = amf_deserialize_SaUint32T (tmp, &component->saAmfCompCapability);
+	tmp = amf_deserialize_SaUint32T (tmp, &component->saAmfCompNumMaxActiveCsi);
+	tmp = amf_deserialize_SaUint32T (tmp, &component->saAmfCompNumMaxStandbyCsi);
+
+	tmp = amf_deserialize_SaUint32T (tmp, &cnt);
+	component->saAmfCompCmdEnv = amf_malloc ((cnt + 1) * sizeof (SaStringT*));
+	for (i = 0; i < cnt; i++) {
+		tmp = amf_deserialize_SaStringT (tmp, &component->saAmfCompCmdEnv[i]);
+	}
+	component->saAmfCompCmdEnv[i] = NULL;
+
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompDefaultClcCliTimeout);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompDefaultCallbackTimeOut);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompInstantiateCmd);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompInstantiateCmdArgv);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompInstantiateTimeout);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompInstantiationLevel);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompNumMaxInstantiateWithoutDelay);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompNumMaxInstantiateWithDelay);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompDelayBetweenInstantiateAttempts);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompTerminateCmd);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompTerminateTimeout);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompTerminateCmdArgv);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompCleanupCmd);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompCleanupTimeout);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompCleanupCmdArgv);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompAmStartCmd);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompAmStartTimeout);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompAmStartCmdArgv);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompNumMaxAmStartAttempt);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompAmStopCmd);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompAmStopTimeout);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->saAmfCompAmStopCmdArgv);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompNumMaxAmStopAttempt);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompTerminateCallbackTimeout);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompCSISetCallbackTimeout);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompQuiescingCompleteTimeout);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompCSIRmvCallbackTimeout);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompRecoveryOnError);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompDisableRestart);
+	tmp = amf_deserialize_SaNameT (
+		tmp, &component->saAmfCompProxyCsi);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompOperState);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompPresenceState);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->saAmfCompRestartCount);
+	tmp = amf_deserialize_SaNameT (
+		tmp, &component->saAmfCompCurrProxyName);
+	tmp = amf_deserialize_SaStringT (
+		tmp, &component->clccli_path);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->comptype);
+	tmp = amf_deserialize_SaUint32T (
+		tmp, &component->error_suspected);
+
+	return component;
+}
+
+void *amf_healthcheck_serialize (struct amf_healthcheck *healthcheck, int *len)
+{
+	int objsz = sizeof (struct amf_healthcheck);
+	struct amf_healthcheck *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, healthcheck, objsz);
+	*len = objsz;
+
+	return copy;
+}
+
+struct amf_healthcheck *amf_healthcheck_deserialize (
+	struct amf_comp *comp, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_healthcheck);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_healthcheck *obj = amf_malloc (sizeof (struct amf_healthcheck));
+		memcpy (obj, buf, objsz);
+		obj->comp = comp;
+		obj->next = comp->healthcheck_head;
+		comp->healthcheck_head = obj;
+		return obj;
+	}
+}
+

+ 103 - 1
exec/amfnode.c

@@ -1,7 +1,9 @@
 /** @file amfnode.c
 /** @file amfnode.c
  * 
  * 
  * Copyright (c) 2006 Ericsson AB.
  * Copyright (c) 2006 Ericsson AB.
- * Author: Anders Eriksson
+ * Author: Hans Feldt, Anders Eriksson, Lars Holm
+ * - Constructors/destructors
+ * - Serializers/deserializers
  *
  *
  * All rights reserved.
  * All rights reserved.
  *
  *
@@ -105,3 +107,103 @@
  * 
  * 
  */
  */
 
 
+#include <stdlib.h>
+#include <assert.h>
+
+#include "amf.h"
+#include "util.h"
+#include "print.h"
+
+/**
+ * Node constructor
+ * @param loc
+ * @param cluster
+ * @param node
+ */
+struct amf_node *amf_node_new (struct amf_cluster *cluster, char *name)
+{
+	struct amf_node *node = calloc (1, sizeof (struct amf_node));
+
+	if (node == NULL) {
+		openais_exit_error(AIS_DONE_OUT_OF_MEMORY);
+	}
+	node->next = cluster->node_head;
+	node->saAmfNodeAdminState = SA_AMF_ADMIN_UNLOCKED;
+	node->saAmfNodeOperState = SA_AMF_OPERATIONAL_ENABLED;
+	node->saAmfNodeAutoRepair = SA_TRUE;
+	node->cluster = cluster;
+	node->saAmfNodeSuFailOverProb = -1;
+	node->saAmfNodeSuFailoverMax = ~0;
+	setSaNameT (&node->name, name);
+
+	return node;
+}
+
+void *amf_node_serialize (struct amf_node *node, int *len)
+{
+	int objsz = sizeof (struct amf_node);
+	struct amf_node *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, node, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_node *amf_node_deserialize (
+	struct amf_cluster *cluster, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_node);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_node *obj = amf_node_new (cluster, "");
+		if (obj == NULL) {
+			return NULL;
+		}
+		memcpy (obj, buf, objsz);
+		TRACE8 ("%s", obj->name.value);
+		obj->cluster = cluster;
+		obj->next = cluster->node_head;
+		cluster->node_head = obj;
+		return obj;
+	}
+}
+
+void amf_node_sync_ready (struct amf_node *node)
+{
+	struct amf_application *app;
+
+	assert (node != NULL);
+
+	log_printf(LOG_NOTICE, "Node %s sync ready, starting hosted SUs.",
+			   node->name.value);
+
+	for (app = amf_cluster->application_head; app != NULL; app = app->next) {
+		amf_application_start (app, node);
+	}
+}
+
+void amf_node_init (void)
+{
+	log_init ("AMF");
+}
+
+struct amf_node *amf_node_find (SaNameT *name)
+{
+	struct amf_node *node;
+
+	ENTER ("");
+
+	for (node = amf_cluster->node_head; node != NULL; node = node->next) {
+		if (name_match (&node->name, name)) {
+			return node;
+		}
+	}
+
+	return NULL;
+}
+

+ 115 - 10
exec/amfsg.c

@@ -4,13 +4,14 @@
  * Author: Steven Dake (sdake@mvista.com)
  * Author: Steven Dake (sdake@mvista.com)
  *
  *
  * Copyright (c) 2006 Ericsson AB.
  * Copyright (c) 2006 Ericsson AB.
- *  Author: Hans Feldt
+ * Author: Hans Feldt, Anders Eriksson, Lars Holm
  * - Introduced AMF B.02 information model
  * - Introduced AMF B.02 information model
  * - Use DN in API and multicast messages
  * - Use DN in API and multicast messages
  * - (Re-)Introduction of event based multicast messages
  * - (Re-)Introduction of event based multicast messages
  * - Refactoring of code into several AMF files
  * - Refactoring of code into several AMF files
- *  Author: Anders Eriksson, Lars Holm
- *  - Component/SU restart, SU failover
+ * - Component/SU restart, SU failover
+ * - Constructors/destructors
+ * - Serializers/deserializers
  *
  *
  * All rights reserved.
  * All rights reserved.
  *
  *
@@ -555,9 +556,7 @@ void amf_sg_assign_si (struct amf_sg *sg, int dependency_level)
 
 
 	ENTER ("'%s'", sg->name.value);
 	ENTER ("'%s'", sg->name.value);
 
 
-	if (sg->avail_state == SG_AC_Idle) {
-		sg->avail_state = SG_AC_AssigningOnRequest;
-	}
+	sg->avail_state = SG_AC_AssigningOnRequest;
 
 
 	/**
 	/**
 	 * Phase 1: Calculate assignments and create all runtime objects in
 	 * Phase 1: Calculate assignments and create all runtime objects in
@@ -689,10 +688,15 @@ void amf_sg_start (struct amf_sg *sg, struct amf_node *node)
 
 
 	sg->avail_state = SG_AC_InstantiatingServiceUnits;
 	sg->avail_state = SG_AC_InstantiatingServiceUnits;
 
 
-	if (node == NULL) {
-		/* Cluster start */
-		for (su = sg->su_head; su != NULL; su = su->next) {
+	for (su = sg->su_head; su != NULL; su = su->next) {
+		if (node == NULL) {
+			/* Cluster start */
 			amf_su_instantiate (su);
 			amf_su_instantiate (su);
+		} else {
+            /* Node start, match if SU is hosted on the specified node */
+			if (name_match (&node->name, &su->saAmfSUHostedByNode)) {
+				amf_su_instantiate (su);
+			}
 		}
 		}
 	}
 	}
 }
 }
@@ -700,7 +704,8 @@ void amf_sg_start (struct amf_sg *sg, struct amf_node *node)
 void amf_sg_su_state_changed (
 void amf_sg_su_state_changed (
 	struct amf_sg *sg, struct amf_su *su, SaAmfStateT type, int state)
 	struct amf_sg *sg, struct amf_su *su, SaAmfStateT type, int state)
 {
 {
-	ENTER ("'%s' SU '%s' state %d", sg->name.value, su->name.value, state);
+	ENTER ("'%s' SU '%s' state %s",
+		   sg->name.value, su->name.value, amf_presence_state(state));
 
 
 	if (type == SA_AMF_PRESENCE_STATE) {
 	if (type == SA_AMF_PRESENCE_STATE) {
 		if (state == SA_AMF_PRESENCE_INSTANTIATED) {
 		if (state == SA_AMF_PRESENCE_INSTANTIATED) {
@@ -761,4 +766,104 @@ void amf_sg_failover_su_req (
 	}
 	}
 }
 }
 
 
+/**
+ * Constructor for SG objects. Adds SG to the list owned by
+ * the specified application. Always returns a valid SG
+ * object, out-of-memory problems are handled here. Default
+ * values are initialized.
+ * @param sg
+ * @param name
+ * 
+ * @return struct amf_sg*
+ */
+
+struct amf_sg *amf_sg_new (struct amf_application *app, char *name)
+{
+	struct amf_sg *sg = calloc (1, sizeof (struct amf_sg));
+
+	if (sg == NULL) {
+		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
+	}
+
+	sg->next = app->sg_head;
+	app->sg_head = sg;
+	sg->saAmfSGAdminState = SA_AMF_ADMIN_UNLOCKED;
+	sg->saAmfSGNumPrefActiveSUs = 1;
+	sg->saAmfSGNumPrefStandbySUs = 1;
+	sg->saAmfSGNumPrefInserviceSUs = ~0;
+	sg->saAmfSGCompRestartProb = -1;
+	sg->saAmfSGCompRestartMax = ~0;
+	sg->saAmfSGSuRestartProb = -1;
+	sg->saAmfSGSuRestartMax = ~0;
+	sg->saAmfSGAutoAdjustProb = -1;
+	sg->saAmfSGAutoRepair = SA_TRUE;
+	sg->application = app;
+	setSaNameT (&sg->name, name);
+
+	return sg;
+}
+
+void amf_sg_delete (struct amf_sg *sg)
+{
+	struct amf_su *su;
+
+	for (su = sg->su_head; su != NULL;) {
+		struct amf_su *tmp = su;
+		su = su->next;
+		amf_su_delete (tmp);
+	}
+
+	free (sg);
+}
+
+void *amf_sg_serialize (struct amf_sg *sg, int *len)
+{
+	int objsz = sizeof (struct amf_sg);
+	struct amf_sg *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, sg, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_sg *amf_sg_deserialize (
+	struct amf_application *app, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_sg);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		/*                                                              
+         * TODO: use amf_sg_new
+         */
+		struct amf_sg *sg = calloc (1, sizeof (struct amf_sg));
+		if (sg == NULL) {
+			return NULL;
+		}
+		memcpy (sg, buf, objsz);
+		TRACE8 ("%s", sg->name.value);
+		sg->application = app;
+		sg->su_head = NULL;
+		sg->next = app->sg_head;
+		app->sg_head = sg;
+		return sg;
+	}
+}
+
+struct amf_sg *amf_sg_find (struct amf_application *app, char *name)
+{
+	struct amf_sg *sg;
+
+	for (sg = app->sg_head; sg != NULL; sg = sg->next) {
+		if (strncmp (name, (char*)sg->name.value, sg->name.length) == 0) {
+			break;
+		}
+	}
+
+	return sg;
+}
 
 

+ 449 - 8
exec/amfsi.c

@@ -1,10 +1,11 @@
 /** @file amfsi.c
 /** @file amfsi.c
  * 
  * 
  * Copyright (c) 2006 Ericsson AB.
  * Copyright (c) 2006 Ericsson AB.
- *  Author: Hans Feldt
+ * Author: Hans Feldt, Anders Eriksson, Lars Holm
  * - Refactoring of code into several AMF files
  * - Refactoring of code into several AMF files
- *  Author: Anders Eriksson, Lars Holm
- *  - Component/SU restart, SU failover
+ * - Component/SU restart, SU failover
+ * - Constructors/destructors
+ * - Serializers/deserializers
  *
  *
  * All rights reserved.
  * All rights reserved.
  *
  *
@@ -377,11 +378,8 @@ void amf_si_ha_state_assume (
 	 */
 	 */
 	if (csi_assignment_cnt == hastate_set_done_cnt) {
 	if (csi_assignment_cnt == hastate_set_done_cnt) {
 		poll_timer_handle handle;
 		poll_timer_handle handle;
-		poll_timer_add (aisexec_poll_handle,
-			0,
-			si_assignment,
-			timer_function_ha_state_assumed,
-			&handle);
+		poll_timer_add (aisexec_poll_handle, 0, si_assignment,
+						timer_function_ha_state_assumed, &handle);
 	}
 	}
 }
 }
 
 
@@ -461,3 +459,446 @@ void amf_csi_delete_assignments (struct amf_csi *csi, struct amf_su *su)
 	free (csi_assignment);
 	free (csi_assignment);
 }
 }
 
 
+/**
+ * Constructor for SI objects. Adds SI last in the ordered
+ * list owned by the specified application. Always returns a
+ * valid SI object, out-of-memory problems are handled here.
+ * Default values are initialized.
+ * @param app
+ * 
+ * @return struct amf_si*
+ */
+struct amf_si *amf_si_new (struct amf_application *app, char *name)
+{
+	struct amf_si *tail = app->si_head;
+	struct amf_si *si = calloc (1, sizeof (struct amf_si));
+
+	if (si == NULL) {
+		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
+	}
+
+	while (tail != NULL) {
+		if (tail->next == NULL) {
+			break;
+		}
+		tail = tail->next;
+	}
+
+	if (tail == NULL) {
+		app->si_head = si;
+	} else {
+		tail->next = si;
+	}
+
+	si->application = app;
+
+	/* setup default values from spec. */
+	si->saAmfSIAdminState = SA_AMF_ADMIN_UNLOCKED;
+	si->saAmfSIRank = 0;
+	si->saAmfSIPrefActiveAssignments = 1;
+	si->saAmfSIPrefStandbyAssignments = 1;
+
+	si->assigned_sis = NULL;
+	si->csi_head = NULL;
+	setSaNameT (&si->name, name);
+
+	return si;
+}
+
+void amf_si_delete (struct amf_si *si)
+{
+	struct amf_si_assignment *si_assignment;
+	struct amf_csi *csi;
+
+	for (csi = si->csi_head; csi != NULL;) {
+		struct amf_csi *tmp = csi;
+		csi = csi->next;
+		amf_csi_delete (tmp);
+	}
+
+	for (si_assignment = si->assigned_sis; si_assignment != NULL;) {
+		struct amf_si_assignment *tmp = si_assignment;
+		si_assignment = si_assignment->next;
+		free (tmp);
+	}
+
+	free (si);
+}
+
+void *amf_si_serialize (struct amf_si *si, int *len)
+{
+	int objsz = sizeof (struct amf_si);
+	struct amf_si *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, si, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_si *amf_si_deserialize (struct amf_application *app, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_si);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_si *tmp = (struct amf_si*) buf;
+		struct amf_si *si = amf_si_new (app, (char*)tmp->name.value);
+		TRACE8 ("%s", si->name.value);
+
+		memcpy (&si->saAmfSIProtectedbySG, &tmp->saAmfSIProtectedbySG,
+				sizeof (SaNameT));
+		si->saAmfSIRank = tmp->saAmfSIRank;
+		si->saAmfSINumCSIs = tmp->saAmfSINumCSIs;
+		si->saAmfSIPrefActiveAssignments = tmp->saAmfSIPrefActiveAssignments;
+		si->saAmfSIPrefStandbyAssignments = tmp->saAmfSIPrefStandbyAssignments;
+		si->saAmfSIAdminState = tmp->saAmfSIAdminState;
+		return si;
+	}
+}
+
+/*****************************************************************************
+ * SI Assignment class implementation                          *              
+ ****************************************************************************/
+
+struct amf_si_assignment *amf_si_assignment_new (struct amf_si *si)
+{
+	struct amf_si_assignment *si_assignment;
+
+	si_assignment =	amf_malloc (sizeof (struct amf_si_assignment));
+	si_assignment->si = si;
+
+	return si_assignment;
+}
+
+void *amf_si_assignment_serialize (
+	struct amf_si_assignment *si_assignment, int *len)
+{
+	int objsz = sizeof (struct amf_si_assignment);
+	struct amf_si_assignment *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, si_assignment, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_si_assignment *amf_si_assignment_deserialize (
+	struct amf_si *si, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_si_assignment);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_si_assignment *obj = amf_si_assignment_new (si);
+		if (obj == NULL) {
+			return NULL;
+		}
+		memcpy (obj, buf, objsz);
+		TRACE8 ("%s", obj->name.value);
+		obj->si = si;
+		obj->su = amf_su_find (si->application->cluster, &obj->name);
+		obj->next = si->assigned_sis;
+		si->assigned_sis = obj;
+		return obj;
+	}
+}
+
+struct amf_si *amf_si_find (struct amf_application *app, char *name)
+{
+	struct amf_si *si;
+
+	ENTER ("%s", name);
+
+	for (si = app->si_head; si != NULL; si = si->next) {
+		if (strncmp (name, (char*)si->name.value, si->name.length) == 0) {
+			break;
+		}
+	}
+
+	return si;
+}
+
+/*****************************************************************************
+ * CSI class implementation                                    *
+ ****************************************************************************/
+
+struct amf_csi *amf_csi_new (struct amf_si *si)
+{
+	struct amf_csi *csi;
+
+	csi = amf_malloc (sizeof (struct amf_csi));
+	csi->si = si;
+
+	return csi;
+}
+
+void amf_csi_delete (struct amf_csi *csi)
+{
+	struct amf_csi_assignment *csi_assignment;
+
+	for (csi_assignment = csi->assigned_csis; csi_assignment != NULL;) {
+		struct amf_csi_assignment *tmp = csi_assignment;
+		csi_assignment = csi_assignment->next;
+		free (tmp);
+	}
+
+	free (csi);
+}
+
+void *amf_csi_serialize (struct amf_csi *csi, int *len)
+{
+	int objsz = sizeof (struct amf_csi);
+	struct amf_csi *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, csi, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_csi *amf_csi_deserialize (struct amf_si *si, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_csi);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_csi *obj = amf_csi_new (si);
+		if (obj == NULL) {
+			return NULL;
+		}
+		memcpy (obj, buf, objsz);
+		TRACE8 ("%s", obj->name.value);
+		obj->si = si;
+		obj->assigned_csis = NULL;
+		obj->attributes_head = NULL;
+		obj->next = si->csi_head;
+		si->csi_head = obj;
+		return obj;
+	}
+}
+
+struct amf_csi *amf_csi_find (struct amf_si *si, char *name)
+{
+	struct amf_csi *csi;
+
+	ENTER ("%s", name);
+
+	for (csi = si->csi_head; csi != NULL; csi = csi->next) {
+		if (strncmp (name, (char*)csi->name.value, csi->name.length) == 0) {
+			break;
+		}
+	}
+
+	return csi;
+}
+
+/*****************************************************************************
+ * CSI Assignment class implementation                         *              
+ ****************************************************************************/
+
+struct amf_csi_assignment *amf_csi_assignment_new (struct amf_csi *csi)
+{
+	struct amf_csi_assignment *csi_assignment;
+
+	csi_assignment = amf_malloc (sizeof (struct amf_csi_assignment));
+	csi_assignment->csi = csi;
+
+	return csi_assignment;
+}
+
+void *amf_csi_assignment_serialize (
+	struct amf_csi_assignment *csi_assignment, int *len)
+{
+	int objsz = sizeof (struct amf_csi_assignment);
+	struct amf_csi_assignment *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, csi_assignment, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_csi_assignment *amf_csi_assignment_deserialize (
+	struct amf_csi *csi, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_csi_assignment);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_csi_assignment *obj = amf_csi_assignment_new (csi);
+		if (obj == NULL) {
+			return NULL;
+		}
+		memcpy (obj, buf, objsz);
+		TRACE8 ("%s", obj->name.value);
+		obj->csi = csi;
+		obj->comp = amf_comp_find (csi->si->application->cluster, &obj->name);
+		obj->next = csi->assigned_csis;
+		csi->assigned_csis = obj;
+		return obj;
+	}
+}
+
+char *amf_csi_assignment_dn_make (
+	struct amf_csi_assignment *csi_assignment, SaNameT *name)
+{
+	SaNameT comp_name;
+	struct amf_csi *csi = csi_assignment->csi;
+	int i;
+
+	amf_comp_dn_make (csi_assignment->comp, &comp_name);
+
+	i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
+		"safCSIComp=%s,safCsi=%s,safSi=%s,safApp=%s",
+		comp_name.value,
+		csi->name.value, csi->si->name.value,
+		csi->si->application->name.value);
+	assert (i <= SA_MAX_NAME_LENGTH);
+	name->length = i;
+
+	return(char *)name->value;
+}
+
+struct amf_csi_assignment *amf_csi_assignment_find (
+	struct amf_cluster *cluster, SaNameT *name)
+{
+	struct amf_application *app;
+	struct amf_si *si;
+	struct amf_csi *csi;
+	struct amf_csi_assignment *csi_assignment = NULL;
+	char *app_name;
+	char *si_name;
+	char *csi_name;
+	char *csi_assignment_name;
+	char *buf;
+
+	ENTER ("%s", name->value);
+
+    /* malloc new buffer since we need to write to the buffer */
+	buf = amf_malloc (name->length + 1);
+	memcpy (buf, name->value, name->length + 1);
+
+	csi_assignment_name = strstr (buf, "safCSIComp=");
+	csi_name = strstr (buf, "safCsi=");
+	si_name = strstr (buf, "safSi=");
+	app_name = strstr (buf, "safApp=");
+	app_name++;
+	app_name = strstr (app_name, "safApp=");
+
+	if (csi_assignment_name == NULL || csi_name == NULL || si_name == NULL ||
+		app_name == NULL) {
+
+		goto end;
+	}
+
+	*(csi_name - 1) = '\0';
+	*(si_name - 1) = '\0';
+	*(app_name - 1) = '\0';
+
+    /* jump to value */
+	csi_assignment_name += 11;
+	csi_name += 7;
+	si_name += 6;
+	app_name += 7;
+
+	app = amf_application_find (cluster, app_name);
+	if (app == NULL) {
+		goto end;
+	}
+
+	si = amf_si_find (app, si_name);
+	if (si == NULL) {
+		goto end;
+	}
+
+	csi = amf_csi_find (si, csi_name);
+	if (csi == NULL) {
+		goto end;
+	}
+
+	for (csi_assignment = csi->assigned_csis; csi_assignment != NULL;
+		csi_assignment = csi_assignment->next) {
+
+		if (strncmp (csi_assignment_name,
+			(char*)csi_assignment->name.value,
+			csi_assignment->name.length) == 0) {
+			goto end;
+		}
+	}
+
+end:
+	free (buf);
+	return csi_assignment;
+}
+
+struct amf_csi_attribute *amf_csi_attribute_new (struct amf_csi *csi)
+{
+	struct amf_csi_attribute *csi_attribute;
+
+	csi_attribute = amf_malloc (sizeof (struct amf_csi_assignment));
+	csi_attribute->next = csi->attributes_head;
+	csi->attributes_head = csi_attribute;
+
+	return csi_attribute;
+}
+
+void *amf_csi_attribute_serialize (
+	struct amf_csi_attribute *csi_attribute, int *len)
+{
+	char *buf = NULL;
+	int i, offset = 0, size = 0;
+
+	TRACE8 ("%s", csi_attribute->name);
+
+	buf = amf_serialize_SaStringT (buf, &size, &offset, csi_attribute->name);
+
+	/* count value and write to buf */
+	for (i = 0; csi_attribute->value &&
+		  csi_attribute->value[i] != NULL; i++);
+	buf = amf_serialize_SaUint32T (buf, &size, &offset, i);
+
+	for (i = 0; csi_attribute->value &&
+		  csi_attribute->value[i] != NULL; i++) {
+		buf = amf_serialize_SaStringT (
+			buf, &size, &offset, csi_attribute->value[i]);
+	}
+
+	*len = offset;
+
+	return buf;
+}
+
+struct amf_csi_attribute *amf_csi_attribute_deserialize (
+	struct amf_csi *csi, char *buf, int size)
+{
+	char *tmp = buf;
+	struct amf_csi_attribute *csi_attribute;
+	int i;
+	SaUint32T cnt;
+
+	csi_attribute = amf_csi_attribute_new (csi);
+
+	tmp = amf_deserialize_SaStringT (tmp, &csi_attribute->name);
+	tmp = amf_deserialize_SaUint32T (tmp, &cnt);
+	csi_attribute->value = amf_malloc ((cnt + 1) * sizeof (SaStringT*));
+	for (i = 0; i < cnt; i++) {
+		tmp = amf_deserialize_SaStringT (tmp, &csi_attribute->value[i]);
+	}
+	csi_attribute->value[i] = NULL;
+
+	return csi_attribute;
+}
+

+ 172 - 25
exec/amfsu.c

@@ -4,13 +4,14 @@
  * Author: Steven Dake (sdake@mvista.com)
  * Author: Steven Dake (sdake@mvista.com)
  *
  *
  * Copyright (c) 2006 Ericsson AB.
  * Copyright (c) 2006 Ericsson AB.
- *  Author: Hans Feldt
+ * Author: Hans Feldt, Anders Eriksson, Lars Holm
  * - Introduced AMF B.02 information model
  * - Introduced AMF B.02 information model
  * - Use DN in API and multicast messages
  * - Use DN in API and multicast messages
  * - (Re-)Introduction of event based multicast messages
  * - (Re-)Introduction of event based multicast messages
  * - Refactoring of code into several AMF files
  * - Refactoring of code into several AMF files
- *  Author: Anders Eriksson, Lars Holm
- *  - Component/SU restart, SU failover
+ * - Component/SU restart, SU failover
+ * - Constructors/destructors
+ * - Serializers/deserializers
  *
  *
  * All rights reserved.
  * All rights reserved.
  *
  *
@@ -166,8 +167,8 @@ static void su_presence_state_set (struct amf_su *su,
 	SaAmfPresenceStateT presence_state)
 	SaAmfPresenceStateT presence_state)
 {
 {
 	/*                                                              
 	/*                                                              
-     * Set all SI's confirmed HA state to unknown if uninstantiated
-     */
+	 * Set all SI's confirmed HA state to unknown if uninstantiated
+	*/
 	if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED) {
 	if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED) {
 		amf_su_foreach_si_assignment (su, clear_ha_state);
 		amf_su_foreach_si_assignment (su, clear_ha_state);
 	}
 	}
@@ -214,11 +215,7 @@ static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
 		getSaNameT (&csi->name), getSaNameT (&comp->name),
 		getSaNameT (&csi->name), getSaNameT (&comp->name),
 		amf_ha_state (ha_state));
 		amf_ha_state (ha_state));
 
 
-	csi_assignment = malloc (sizeof (struct amf_csi_assignment));
-	if (csi_assignment == NULL) {
-		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
-	}
-
+	csi_assignment = amf_malloc (sizeof (struct amf_csi_assignment));
 	csi_assignment->next = csi->assigned_csis;
 	csi_assignment->next = csi->assigned_csis;
 	csi->assigned_csis = csi_assignment;
 	csi->assigned_csis = csi_assignment;
 	amf_comp_dn_make (comp, &csi_assignment->name);
 	amf_comp_dn_make (comp, &csi_assignment->name);
@@ -287,10 +284,7 @@ void amf_su_assign_si (struct amf_su *su, struct amf_si *si,
 		getSaNameT (&si->name), getSaNameT (&su->name),
 		getSaNameT (&si->name), getSaNameT (&su->name),
 		amf_ha_state (ha_state));
 		amf_ha_state (ha_state));
 
 
-	si_assignment = malloc (sizeof (struct amf_si_assignment));
-	if (si_assignment == NULL) {
-		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
-	}
+	si_assignment = amf_malloc (sizeof (struct amf_si_assignment));
 	amf_su_dn_make (su, &si_assignment->name);
 	amf_su_dn_make (su, &si_assignment->name);
 	si_assignment->saAmfSISUHAState = 0; /* undefined confirmed HA state */
 	si_assignment->saAmfSISUHAState = 0; /* undefined confirmed HA state */
 	si_assignment->requested_ha_state = ha_state;
 	si_assignment->requested_ha_state = ha_state;
@@ -408,9 +402,9 @@ static void su_comp_presence_state_changed (
 		case SA_AMF_PRESENCE_INSTANTIATED:
 		case SA_AMF_PRESENCE_INSTANTIATED:
 			switch (su->restart_control_state) {
 			switch (su->restart_control_state) {
 				case SU_RC_ESCALATION_LEVEL_2:
 				case SU_RC_ESCALATION_LEVEL_2:
-					/*                                                              
-                     * TODO: send to node
-                     */
+					/* 
+					 * TODO: send to node
+					*/
 				case SU_RC_ESCALATION_LEVEL_0:
 				case SU_RC_ESCALATION_LEVEL_0:
 					if (presence_state_all_comps_in_su_are_set (
 					if (presence_state_all_comps_in_su_are_set (
 						comp->su, SA_AMF_PRESENCE_INSTANTIATED)) {
 						comp->su, SA_AMF_PRESENCE_INSTANTIATED)) {
@@ -541,8 +535,8 @@ void amf_su_comp_error_suspected (
 	ENTER ("Comp '%s', SU '%s'", comp->name.value, su->name.value);
 	ENTER ("Comp '%s', SU '%s'", comp->name.value, su->name.value);
 
 
 	/*                                                              
 	/*                                                              
-     * Defer all new events. Workaround to be able to use gdb.
-     */
+	 * Defer all new events. Workaround to be able to use gdb.
+	*/
 	if (su->sg->avail_state != SG_AC_Idle) {
 	if (su->sg->avail_state != SG_AC_Idle) {
 		ENTER ("Comp '%s', SU '%s'", comp->name.value, su->name.value);
 		ENTER ("Comp '%s', SU '%s'", comp->name.value, su->name.value);
 		fprintf (stderr, "Warning Debug: event deferred!\n");
 		fprintf (stderr, "Warning Debug: event deferred!\n");
@@ -576,8 +570,8 @@ void amf_su_comp_error_suspected (
 			if (su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax) {
 			if (su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax) {
 
 
 				/*                                                              
 				/*                                                              
-                 * TODO: delegate to node
-                 */
+				 * TODO: delegate to node
+				*/
 				struct amf_si_assignment *si_assignment =
 				struct amf_si_assignment *si_assignment =
 					amf_su_get_next_si_assignment (su, NULL);
 					amf_su_get_next_si_assignment (su, NULL);
 				if (si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) {
 				if (si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) {
@@ -616,9 +610,9 @@ void amf_su_terminate (struct amf_su *su)
 	ENTER ("'%s'", su->name.value);
 	ENTER ("'%s'", su->name.value);
 
 
 	for (comp = su->comp_head; comp != NULL; comp = comp->next) {
 	for (comp = su->comp_head; comp != NULL; comp = comp->next) {
-		/*                                                              
-         * Terminate all components in SU abruptly
-         */
+		/* 
+		 * Terminate all components in SU abruptly
+		*/
 		comp->error_suspected = 1;
 		comp->error_suspected = 1;
 		amf_comp_terminate (comp);
 		amf_comp_terminate (comp);
 	}
 	}
@@ -644,6 +638,9 @@ struct amf_si_assignment *amf_su_get_next_si_assignment (
 	amf_su_dn_make (su, &dn);
 	amf_su_dn_make (su, &dn);
 
 
 	if (si_assignment == NULL) {
 	if (si_assignment == NULL) {
+		assert (su->sg);
+		assert (su->sg->application);
+		assert (su->sg->application->si_head);
 		si = su->sg->application->si_head;
 		si = su->sg->application->si_head;
 		tmp_si_assignment = si->assigned_sis;
 		tmp_si_assignment = si->assigned_sis;
 	} else {
 	} else {
@@ -696,7 +693,7 @@ int amf_su_get_saAmfSUNumCurrActiveSIs(struct amf_su *su)
 {
 {
 	int cnt = 0;
 	int cnt = 0;
 	struct amf_si_assignment *si_assignment;
 	struct amf_si_assignment *si_assignment;
-	
+
 	si_assignment = amf_su_get_next_si_assignment (su, NULL); 
 	si_assignment = amf_su_get_next_si_assignment (su, NULL); 
 	while (si_assignment != NULL) {
 	while (si_assignment != NULL) {
 		if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
 		if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
@@ -748,3 +745,153 @@ SaAmfReadinessStateT amf_su_get_saAmfSUReadinessState (struct amf_su *su)
 		return SA_AMF_READINESS_OUT_OF_SERVICE;
 		return SA_AMF_READINESS_OUT_OF_SERVICE;
 	}
 	}
 }
 }
+
+/**
+ * Constructor for SU objects. Adds SU last in the ordered
+ * list owned by the specified SG. Always returns a
+ * valid SU object, out-of-memory problems are handled here.
+ * Default values are initialized.
+ * @param sg
+ * @param name
+ * 
+ * @return struct amf_su*
+ */
+struct amf_su *amf_su_new (struct amf_sg *sg, char *name)
+{
+	struct amf_su *tail = sg->su_head;
+	struct amf_su *su = calloc (1, sizeof (struct amf_su));
+
+	if (su == NULL) {
+		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
+	}
+
+	while (tail != NULL) {
+		if (tail->next == NULL) {
+			break;
+		}
+		tail = tail->next;
+	}
+
+	if (tail == NULL) {
+		sg->su_head	 = su;
+	} else {
+		tail->next = su;
+	}
+	su->sg = sg;
+
+	/* setup default values from spec. */
+	su->saAmfSURank = 0;
+	su->saAmfSUIsExternal = 0;
+	su->saAmfSUFailover = 1;
+	su->saAmfSUAdminState = SA_AMF_ADMIN_UNLOCKED;
+	su->saAmfSUOperState = SA_AMF_OPERATIONAL_DISABLED;
+	su->saAmfSUPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
+	su->restart_control_state = SU_RC_ESCALATION_LEVEL_0;
+
+	setSaNameT (&su->name, name);
+
+	return su;
+}
+
+void amf_su_delete (struct amf_su *su)
+{
+	struct amf_comp *comp;
+
+	for (comp = su->comp_head; comp != NULL;) {
+		struct amf_comp *tmp = comp;
+		comp = comp->next;
+		amf_comp_delete (tmp);
+	}
+
+	free (su);
+}
+
+void *amf_su_serialize (struct amf_su *su, int *len)
+{
+	int objsz = sizeof (struct amf_su);
+	struct amf_su *copy;
+
+	copy = amf_malloc (objsz);
+	memcpy (copy, su, objsz);
+	*len = objsz;
+	TRACE8 ("%s", copy->name.value);
+
+	return copy;
+}
+
+struct amf_su *amf_su_deserialize (struct amf_sg *sg, char *buf, int size)
+{
+	int objsz = sizeof (struct amf_su);
+
+	if (objsz > size) {
+		return NULL;
+	} else {
+		struct amf_su *tmp = (struct amf_su*) buf;
+		struct amf_su *su;
+
+		su = amf_su_new (sg, (char*) tmp->name.value);
+		su->saAmfSURank = tmp->saAmfSURank;
+		su->saAmfSUNumComponents = tmp->saAmfSUNumComponents;
+		su->saAmfSUIsExternal = tmp->saAmfSUIsExternal;
+		su->saAmfSUFailover = tmp->saAmfSUFailover;
+		su->saAmfSUPreInstantiable = tmp->saAmfSUPreInstantiable;
+		su->saAmfSUOperState = tmp->saAmfSUOperState;
+		su->saAmfSUAdminState = tmp->saAmfSUAdminState;
+		su->saAmfSUPresenceState = tmp->saAmfSUPresenceState;
+		memcpy (&su->saAmfSUHostedByNode, &tmp->saAmfSUHostedByNode,
+				sizeof (SaNameT));
+
+		TRACE8 ("%s", su->name.value);
+		return su;
+	}
+}
+
+struct amf_su *amf_su_find (struct amf_cluster *cluster, SaNameT *name)
+{
+	struct amf_application *app;
+	struct amf_sg *sg;
+	struct amf_su *su = NULL;
+	char *app_name;
+	char *sg_name;
+	char *su_name;
+	char *ptrptr;
+	char *buf;
+
+	/* malloc new buffer since strtok_r writes to its first argument */
+	buf = amf_malloc (name->length + 1);
+	memcpy (buf, name->value, name->length);
+
+	su_name = strtok_r(buf, ",", &ptrptr);
+	sg_name = strtok_r(NULL, ",", &ptrptr);
+	app_name = strtok_r(NULL, ",", &ptrptr);
+
+	if (su_name == NULL || sg_name == NULL || app_name == NULL) {
+		goto end;
+	}
+
+	su_name += 6;
+	sg_name += 6;
+	app_name += 7;
+
+	app = amf_application_find (cluster, app_name);
+	if (app == NULL) {
+		goto end;
+	}
+
+	for (sg = app->sg_head; sg != NULL; sg = sg->next) {
+		if (strncmp (sg_name, (char*)sg->name.value,
+			sg->name.length) == 0) {
+			for (su = sg->su_head; su != NULL; su = su->next) {
+				if (strncmp (su_name, (char*)su->name.value,
+					su->name.length) == 0) {
+					goto end;
+				}
+			}
+		}
+	}
+
+end:
+	free (buf);
+	return su;
+}
+

+ 164 - 78
exec/amfutil.c

@@ -8,6 +8,7 @@
  * Description:
  * Description:
  * - Reworked to match AMF B.02 information model Description:
  * - Reworked to match AMF B.02 information model Description:
  * - Refactoring of code into several AMF files
  * - Refactoring of code into several AMF files
+ * - Serializers/deserializers
  *
  *
  * All rights reserved.
  * All rights reserved.
  *
  *
@@ -57,26 +58,8 @@
 #include "amf.h"
 #include "amf.h"
 #include "totem.h"
 #include "totem.h"
 #include "print.h"
 #include "print.h"
-
-typedef enum {
-	AMF_HEAD,
-	AMF_APPLICATION,
-	AMF_CLUSTER,
-	AMF_NODE,
-	AMF_SG,
-	AMF_SU,
-	AMF_COMP,
-	AMF_COMP_ENV_VAR,
-	AMF_COMP_CS_TYPE,
-	AMF_SI,
-	AMF_SI_RANKED_SU,
-	AMF_SI_DEPENDENCY,
-	AMF_CSI,
-	AMF_CSI_ATTRIBUTE,
-	AMF_HEALTHCHECK,
-	AMF_CSI_DEPENDENCIES,
-	AMF_CS_TYPE,
-} amf_parse_t;
+#include "aispoll.h"
+#include "main.h"
 
 
 #ifndef OPENAIS_CLUSTER_STARTUP_TIMEOUT
 #ifndef OPENAIS_CLUSTER_STARTUP_TIMEOUT
 #define OPENAIS_CLUSTER_STARTUP_TIMEOUT 5000
 #define OPENAIS_CLUSTER_STARTUP_TIMEOUT 5000
@@ -250,7 +233,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 	char *line;
 	char *line;
 	FILE *fp;
 	FILE *fp;
 	char *filename;
 	char *filename;
-	amf_parse_t current_parse = AMF_HEAD;
+	amf_object_type_t current_parse = AMF_NONE;
 	int line_number = 0;
 	int line_number = 0;
 	char *loc;
 	char *loc;
 	int i;
 	int i;
@@ -289,7 +272,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 		return NULL;
 		return NULL;
 	}
 	}
 
 
-	cluster = amf_cluster_create ();
+	cluster = amf_cluster_new ();
 	assert (cluster != NULL);
 	assert (cluster != NULL);
 
 
 	while (fgets (buf, 255, fp)) {
 	while (fgets (buf, 255, fp)) {
@@ -319,7 +302,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 		error_reason = line;
 		error_reason = line;
 		error_reason = NULL;
 		error_reason = NULL;
 		switch (current_parse) {
 		switch (current_parse) {
-		case AMF_HEAD:
+		case AMF_NONE:
 			if ((loc = strstr_rs (line, "safAmfCluster=")) != 0) {
 			if ((loc = strstr_rs (line, "safAmfCluster=")) != 0) {
 				setSaNameT (&cluster->name, trim_str (loc));
 				setSaNameT (&cluster->name, trim_str (loc));
 				current_parse = AMF_CLUSTER;
 				current_parse = AMF_CLUSTER;
@@ -334,15 +317,8 @@ struct amf_cluster *amf_config_read (char **error_string)
 			} else if ((loc = strstr_rs (line, "saAmfClusterStartupTimeout=")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfClusterStartupTimeout=")) != 0) {
 				cluster->saAmfClusterStartupTimeout = atol(loc);
 				cluster->saAmfClusterStartupTimeout = atol(loc);
 			} else if ((loc = strstr_rs (line, "safAmfNode=")) != 0) {
 			} else if ((loc = strstr_rs (line, "safAmfNode=")) != 0) {
-				node = calloc (1, sizeof (struct amf_node));
-				node->next = cluster->node_head;
+				node = amf_node_new (cluster, trim_str (loc));
 				cluster->node_head = node;
 				cluster->node_head = node;
-				node->saAmfNodeAdminState = SA_AMF_ADMIN_UNLOCKED;
-				node->saAmfNodeAutoRepair = SA_TRUE;
-				node->cluster = cluster;
-				node->saAmfNodeSuFailOverProb = -1;
-				node->saAmfNodeSuFailoverMax = ~0;
-				setSaNameT (&node->name, trim_str (loc));
 				current_parse = AMF_NODE;
 				current_parse = AMF_NODE;
 			} else if ((loc = strstr_rs (line, "safApp=")) != 0) {
 			} else if ((loc = strstr_rs (line, "safApp=")) != 0) {
 				app = calloc (1, sizeof (struct amf_application));
 				app = calloc (1, sizeof (struct amf_application));
@@ -362,7 +338,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 				if (cluster->saAmfClusterStartupTimeout == 0) {
 				if (cluster->saAmfClusterStartupTimeout == 0) {
 					cluster->saAmfClusterStartupTimeout = OPENAIS_CLUSTER_STARTUP_TIMEOUT;
 					cluster->saAmfClusterStartupTimeout = OPENAIS_CLUSTER_STARTUP_TIMEOUT;
 				}
 				}
-				current_parse = AMF_HEAD;
+				current_parse = AMF_NONE;
 			} else {
 			} else {
 				goto parse_error;
 				goto parse_error;
 			}
 			}
@@ -416,33 +392,12 @@ struct amf_cluster *amf_config_read (char **error_string)
 			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
 			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
 				strcpy (app->clccli_path, loc);
 				strcpy (app->clccli_path, loc);
 			} else if ((loc = strstr_rs (line, "safSg=")) != 0) {
 			} else if ((loc = strstr_rs (line, "safSg=")) != 0) {
+				sg = amf_sg_new (app, trim_str (loc));
 				sg_cnt++;
 				sg_cnt++;
-				sg = calloc (1, sizeof (struct amf_sg));
-				sg->next = app->sg_head;
-				app->sg_head = sg;
-				sg->saAmfSGAdminState = SA_AMF_ADMIN_UNLOCKED;
-				sg->saAmfSGNumPrefActiveSUs = 1;
-				sg->saAmfSGNumPrefStandbySUs = 1;
-				sg->saAmfSGNumPrefInserviceSUs = ~0;
-				sg->saAmfSGCompRestartProb = -1;
-				sg->saAmfSGCompRestartMax = ~0;
-				sg->saAmfSGSuRestartProb = -1;
-				sg->saAmfSGSuRestartMax = ~0;
-				sg->saAmfSGAutoAdjustProb = -1;
-				sg->saAmfSGAutoRepair = SA_TRUE;
-				sg->application = app;
 				current_parse = AMF_SG;
 				current_parse = AMF_SG;
 				su_cnt = 0;
 				su_cnt = 0;
-				setSaNameT (&sg->name, trim_str (loc));
 			} else if ((loc = strstr_rs (line, "safSi=")) != 0) {
 			} else if ((loc = strstr_rs (line, "safSi=")) != 0) {
-				si = calloc (1, sizeof (struct amf_si));
-				si->next = app->si_head;
-				app->si_head = si;
-				si->application = app;
-				si->saAmfSIPrefActiveAssignments = 1;
-				si->saAmfSIPrefStandbyAssignments = 1;
-				setSaNameT (&si->name, trim_str (loc));
-				si->saAmfSIAdminState = SA_AMF_ADMIN_UNLOCKED;
+				si = amf_si_new (app, trim_str (loc));
 				current_parse = AMF_SI;
 				current_parse = AMF_SI;
 			} else if ((loc = strstr_rs (line, "safCSType=")) != 0) {
 			} else if ((loc = strstr_rs (line, "safCSType=")) != 0) {
 				current_parse = AMF_CS_TYPE;
 				current_parse = AMF_CS_TYPE;
@@ -507,17 +462,8 @@ struct amf_cluster *amf_config_read (char **error_string)
 			} else if ((loc = strstr_rs (line, "saAmfSGAutoRepair=")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfSGAutoRepair=")) != 0) {
 				sg->saAmfSGAutoRepair = atoi (loc);
 				sg->saAmfSGAutoRepair = atoi (loc);
 			} else if ((loc = strstr_rs (line, "safSu=")) != 0) {
 			} else if ((loc = strstr_rs (line, "safSu=")) != 0) {
-				su = calloc (1, sizeof (struct amf_su));
+				su = amf_su_new (sg, trim_str (loc));
 				su_cnt++;
 				su_cnt++;
-				su->next = sg->su_head;
-				sg->su_head = su;
-				su->sg = sg;
-				su->saAmfSUAdminState = SA_AMF_ADMIN_UNLOCKED;
-				su->saAmfSUOperState = SA_AMF_OPERATIONAL_DISABLED;
-				su->saAmfSUPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
-				su->restart_control_state = SU_RC_ESCALATION_LEVEL_0;
-				su->saAmfSUFailover = 1;
-				setSaNameT (&su->name, trim_str (loc));
 				current_parse = AMF_SU;
 				current_parse = AMF_SU;
 			} else if (strstr_rs (line, "}")) {
 			} else if (strstr_rs (line, "}")) {
 				if (sg->saAmfSGRedundancyModel == 0) {
 				if (sg->saAmfSGRedundancyModel == 0) {
@@ -569,10 +515,9 @@ struct amf_cluster *amf_config_read (char **error_string)
 			} else if ((loc = strstr_rs (line, "saAmfSUHostedByNode=")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfSUHostedByNode=")) != 0) {
 				setSaNameT (&su->saAmfSUHostedByNode, loc);
 				setSaNameT (&su->saAmfSUHostedByNode, loc);
 			} else if ((loc = strstr_rs (line, "safComp=")) != 0) {
 			} else if ((loc = strstr_rs (line, "safComp=")) != 0) {
-				comp = amf_comp_create (su);
+				comp = amf_comp_new (su, trim_str (loc));
 				comp_env_var_cnt = 0;
 				comp_env_var_cnt = 0;
 				comp_cs_type_cnt = 0;
 				comp_cs_type_cnt = 0;
-				setSaNameT (&comp->name, trim_str (loc));
 				current_parse = AMF_COMP;
 				current_parse = AMF_COMP;
 			} else if (strstr_rs (line, "}")) {
 			} else if (strstr_rs (line, "}")) {
 				if (su->saAmfSUNumComponents == 0) {
 				if (su->saAmfSUNumComponents == 0) {
@@ -599,6 +544,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 
 
 		case AMF_COMP:
 		case AMF_COMP:
 			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
 			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
+				comp->clccli_path = amf_malloc (strlen (loc) + 1);
 				strcpy (comp->clccli_path, loc);
 				strcpy (comp->clccli_path, loc);
 			} else if ((loc = strstr_rs (line, "saAmfCompCsTypes{")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfCompCsTypes{")) != 0) {
 				current_parse = AMF_COMP_CS_TYPE;
 				current_parse = AMF_COMP_CS_TYPE;
@@ -623,10 +569,10 @@ struct amf_cluster *amf_config_read (char **error_string)
 			} else if ((loc = strstr_rs(line, "saAmfCompDefaultCallbackTimeOut=")) != 0) {
 			} else if ((loc = strstr_rs(line, "saAmfCompDefaultCallbackTimeOut=")) != 0) {
 				comp->saAmfCompDefaultCallbackTimeOut = atol (loc);
 				comp->saAmfCompDefaultCallbackTimeOut = atol (loc);
 			} else if ((loc = strstr_rs (line, "saAmfCompInstantiateCmdArgv=")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfCompInstantiateCmdArgv=")) != 0) {
-				comp->saAmfCompInstantiateCmdArgv = malloc (strlen(loc) + 1);
+				comp->saAmfCompInstantiateCmdArgv = amf_malloc (strlen(loc) + 1);
 				strcpy (comp->saAmfCompInstantiateCmdArgv, loc);
 				strcpy (comp->saAmfCompInstantiateCmdArgv, loc);
 			} else if ((loc = strstr_rs ( line, "saAmfCompInstantiateCmd=")) != 0) {
 			} else if ((loc = strstr_rs ( line, "saAmfCompInstantiateCmd=")) != 0) {
-				comp->saAmfCompInstantiateCmd = malloc (strlen(loc) + 1);
+				comp->saAmfCompInstantiateCmd = amf_malloc (strlen(loc) + 1);
 				strcpy (comp->saAmfCompInstantiateCmd, loc);
 				strcpy (comp->saAmfCompInstantiateCmd, loc);
 			} else if ((loc = strstr_rs(line, "saAmfCompInstantiateTimeout=")) != 0) {
 			} else if ((loc = strstr_rs(line, "saAmfCompInstantiateTimeout=")) != 0) {
 				comp->saAmfCompInstantiateTimeout = atol (loc);
 				comp->saAmfCompInstantiateTimeout = atol (loc);
@@ -639,18 +585,18 @@ struct amf_cluster *amf_config_read (char **error_string)
 			} else if ((loc = strstr_rs(line, "saAmfCompDelayBetweenInstantiateAttempts=")) != 0) {
 			} else if ((loc = strstr_rs(line, "saAmfCompDelayBetweenInstantiateAttempts=")) != 0) {
 				comp->saAmfCompDelayBetweenInstantiateAttempts = atol (loc);
 				comp->saAmfCompDelayBetweenInstantiateAttempts = atol (loc);
 			} else if ((loc = strstr_rs (line, "saAmfCompTerminateCmdArgv=")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfCompTerminateCmdArgv=")) != 0) {
-				comp->saAmfCompTerminateCmdArgv = malloc (strlen(loc) + 1);
+				comp->saAmfCompTerminateCmdArgv = amf_malloc (strlen(loc) + 1);
 				strcpy (comp->saAmfCompTerminateCmdArgv, loc);
 				strcpy (comp->saAmfCompTerminateCmdArgv, loc);
 			} else if ((loc = strstr_rs (line, "saAmfCompTerminateCmd=")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfCompTerminateCmd=")) != 0) {
-				comp->saAmfCompTerminateCmd = malloc (strlen(loc) + 1);
+				comp->saAmfCompTerminateCmd = amf_malloc (strlen(loc) + 1);
 				strcpy (comp->saAmfCompTerminateCmd, loc);
 				strcpy (comp->saAmfCompTerminateCmd, loc);
 			} else if ((loc = strstr_rs(line, "saAmfCompTerminateTimeout=")) != 0) {
 			} else if ((loc = strstr_rs(line, "saAmfCompTerminateTimeout=")) != 0) {
 				comp->saAmfCompTerminateTimeout = atol (loc);
 				comp->saAmfCompTerminateTimeout = atol (loc);
 			} else if ((loc = strstr_rs (line, "saAmfCompCleanupCmdArgv=")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfCompCleanupCmdArgv=")) != 0) {
-				comp->saAmfCompCleanupCmdArgv = malloc (strlen(loc) + 1);
+				comp->saAmfCompCleanupCmdArgv = amf_malloc (strlen(loc) + 1);
 				strcpy (comp->saAmfCompCleanupCmdArgv, loc);
 				strcpy (comp->saAmfCompCleanupCmdArgv, loc);
 			} else if ((loc = strstr_rs (line, "saAmfCompCleanupCmd=")) != 0) {
 			} else if ((loc = strstr_rs (line, "saAmfCompCleanupCmd=")) != 0) {
-				comp->saAmfCompCleanupCmd = malloc (strlen(loc) + 1);
+				comp->saAmfCompCleanupCmd = amf_malloc (strlen(loc) + 1);
 				strcpy (comp->saAmfCompCleanupCmd, loc);
 				strcpy (comp->saAmfCompCleanupCmd, loc);
 			} else if ((loc = strstr_rs(line, "saAmfCompCleanupTimeout=")) != 0) {
 			} else if ((loc = strstr_rs(line, "saAmfCompCleanupTimeout=")) != 0) {
 				comp->saAmfCompCleanupTimeout = atol (loc);
 				comp->saAmfCompCleanupTimeout = atol (loc);
@@ -742,7 +688,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 				comp->saAmfCompCsTypes = realloc (comp->saAmfCompCsTypes,
 				comp->saAmfCompCsTypes = realloc (comp->saAmfCompCsTypes,
 												 (comp_cs_type_cnt + 1) * sizeof(SaNameT));
 												 (comp_cs_type_cnt + 1) * sizeof(SaNameT));
 				comp->saAmfCompCsTypes[comp_cs_type_cnt] = NULL;
 				comp->saAmfCompCsTypes[comp_cs_type_cnt] = NULL;
-				comp->saAmfCompCsTypes[comp_cs_type_cnt - 1] = malloc (sizeof(SaNameT));
+				comp->saAmfCompCsTypes[comp_cs_type_cnt - 1] = amf_malloc (sizeof(SaNameT));
 				setSaNameT (comp->saAmfCompCsTypes[comp_cs_type_cnt - 1], line);
 				setSaNameT (comp->saAmfCompCsTypes[comp_cs_type_cnt - 1], line);
 			}
 			}
 			break;
 			break;
@@ -755,7 +701,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 				comp->saAmfCompCmdEnv = realloc (comp->saAmfCompCmdEnv,
 				comp->saAmfCompCmdEnv = realloc (comp->saAmfCompCmdEnv,
 												 (comp_env_var_cnt + 1) * sizeof(SaStringT));
 												 (comp_env_var_cnt + 1) * sizeof(SaStringT));
 				comp->saAmfCompCmdEnv[comp_env_var_cnt] = NULL;
 				comp->saAmfCompCmdEnv[comp_env_var_cnt] = NULL;
-				env_var = comp->saAmfCompCmdEnv[comp_env_var_cnt - 1] = malloc (strlen (line) + 1);
+				env_var = comp->saAmfCompCmdEnv[comp_env_var_cnt - 1] = amf_malloc (strlen (line) + 1);
 				strcpy (env_var, line);
 				strcpy (env_var, line);
 			} else {
 			} else {
 				goto parse_error;
 				goto parse_error;
@@ -843,7 +789,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 				attribute = calloc (1, sizeof(struct amf_csi_attribute));
 				attribute = calloc (1, sizeof(struct amf_csi_attribute));
 				attribute->next = csi->attributes_head;
 				attribute->next = csi->attributes_head;
 				csi->attributes_head = attribute;
 				csi->attributes_head = attribute;
-				attribute->name = malloc (strlen (loc) + 1);
+				attribute->name = amf_malloc (strlen (loc) + 1);
 				strcpy (attribute->name, trim_str (loc));
 				strcpy (attribute->name, trim_str (loc));
 				csi_attr_cnt = 1;
 				csi_attr_cnt = 1;
 				current_parse = AMF_CSI_ATTRIBUTE;
 				current_parse = AMF_CSI_ATTRIBUTE;
@@ -870,7 +816,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 					(csi_dependencies_cnt + 1) * sizeof(SaNameT));
 					(csi_dependencies_cnt + 1) * sizeof(SaNameT));
 				csi->saAmfCSIDependencies[csi_dependencies_cnt] = NULL;
 				csi->saAmfCSIDependencies[csi_dependencies_cnt] = NULL;
 				csi->saAmfCSIDependencies[csi_dependencies_cnt - 1] =
 				csi->saAmfCSIDependencies[csi_dependencies_cnt - 1] =
-					malloc (sizeof(SaNameT));
+					amf_malloc (sizeof(SaNameT));
 				setSaNameT (
 				setSaNameT (
 					csi->saAmfCSIDependencies[csi_dependencies_cnt - 1], loc);
 					csi->saAmfCSIDependencies[csi_dependencies_cnt - 1], loc);
 			} else {
 			} else {
@@ -886,7 +832,7 @@ struct amf_cluster *amf_config_read (char **error_string)
 				attribute->value = realloc (attribute->value,
 				attribute->value = realloc (attribute->value,
 					sizeof (SaStringT) * (csi_attr_cnt + 1));
 					sizeof (SaStringT) * (csi_attr_cnt + 1));
 				attribute->value[csi_attr_cnt - 1] =
 				attribute->value[csi_attr_cnt - 1] =
-					malloc (strlen (value) + 1);
+					amf_malloc (strlen (value) + 1);
 				strcpy (attribute->value[csi_attr_cnt - 1], value);
 				strcpy (attribute->value[csi_attr_cnt - 1], value);
 				attribute->value[csi_attr_cnt] = NULL;
 				attribute->value[csi_attr_cnt] = NULL;
 				csi_attr_cnt++;
 				csi_attr_cnt++;
@@ -1096,3 +1042,143 @@ const char *amf_assignment_state (int state)
 	return assignment_state_text[state];
 	return assignment_state_text[state];
 }
 }
 
 
+#define ALIGN_ADDR(addr) ((addr) + (4 - ((unsigned long)(addr) % 4)))
+
+char *amf_serialize_SaNameT (char *buf, int *size, int *offset, SaNameT *name)
+{
+	char *tmp = buf;
+
+	if ((*size - *offset ) < sizeof (SaNameT)) {
+		*size += sizeof (SaNameT);
+		tmp = realloc (buf, *size);
+		if (tmp == NULL) {
+			openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
+		}
+	}
+
+	memcpy (&tmp[*offset], name, sizeof (SaNameT));
+
+	(*offset) += sizeof (SaNameT);
+
+	return tmp;
+}
+
+char *amf_serialize_SaStringT (char *buf, int *size, int *offset, SaStringT str)
+{
+	unsigned int len;
+
+	if (str != NULL) {
+		len = strlen ((char*)str);
+	} else {
+		len = 0;
+	}
+
+	return amf_serialize_opaque (buf, size, offset, str, len);
+}
+
+char *amf_serialize_SaUint32T (char *buf, int *size, int *offset, SaUint32T num)
+{
+	char *tmp = buf;
+
+	if ((*size - *offset ) < sizeof (SaUint32T)) {
+		*size += sizeof (SaUint32T);
+		tmp = realloc (buf, *size);
+		if (tmp == NULL) {
+			openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
+		}
+	}
+
+	*((SaUint32T *)&tmp[*offset]) = num;
+	(*offset) += sizeof (SaUint32T);
+
+	return tmp;
+}
+
+char *amf_serialize_SaUint64T (char *buf, SaUint64T num)
+{
+	*((SaUint64T *)buf) = num;
+	return buf + sizeof (SaUint64T);
+}
+
+char *amf_serialize_opaque (
+	char *buf, int *size, int *offset, char *src, int cnt)
+{
+	unsigned int required_size;
+	char *tmp = buf;
+
+	required_size = cnt + sizeof (SaUint32T);
+
+	if ((*size - *offset ) < required_size) {
+		*size += required_size;
+		tmp = realloc (buf, *size);
+		if (tmp == NULL) {
+			openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
+		}
+	}
+
+	*((SaUint32T *)&tmp[*offset]) = cnt;
+	(*offset) += sizeof (SaUint32T);
+	memcpy (&tmp[*offset], src, cnt);
+	(*offset) += cnt;
+
+	return tmp;
+}
+
+char *amf_deserialize_SaNameT (char *buf, SaNameT *name)
+{
+	memcpy (name, buf, sizeof (SaNameT));
+	return (buf + sizeof (SaNameT));
+}
+
+char *amf_deserialize_SaStringT (char *buf, SaStringT *str)
+{
+	int len;
+	char *tmp, *tmp_str;
+
+	len = *((SaUint32T *)buf);
+	tmp = buf + sizeof (SaUint32T);
+
+	if (len > 0) {
+		tmp_str = amf_malloc (len + 1);
+		memcpy (tmp_str, tmp, len);
+		tmp_str[len] = '\0';
+		*str = tmp_str;
+	} else  {
+		*str = NULL;
+	}
+
+	tmp += len;
+
+	return tmp;
+}
+
+char *amf_deserialize_SaUint32T (char *buf, SaUint32T *num)
+{
+	*num = *((SaUint32T *)buf);
+	return buf + sizeof (SaUint32T);
+}
+
+char *amf_deserialize_SaUint64T (char *buf, SaUint64T *num)
+{
+	*num = *((SaUint64T *)buf);
+	return buf + sizeof (SaUint64T);
+}
+
+char *amf_deserialize_opaque (char *buf, char *dst, int *cnt)
+{
+	*cnt = *((SaUint32T *)buf);
+	memcpy (dst, buf + sizeof (SaUint32T), *cnt);
+	return buf + *cnt + sizeof (SaUint32T);
+}
+
+void *_amf_malloc (size_t size, char *file, unsigned int line)
+{
+	void *tmp = malloc (size);
+
+	if (tmp == NULL) {
+		log_printf (LOG_LEVEL_ERROR, "AMF out-of-memory at %s:%u", file, line);
+		openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
+	}
+
+	return tmp;
+}

+ 39 - 7
test/testamf1.c

@@ -295,11 +295,33 @@ int main (int argc, char **argv) {
 	extern char *optarg;
 	extern char *optarg;
 	extern int optind;
 	extern int optind;
 	char *name = getenv ("SA_AMF_COMPONENT_NAME");
 	char *name = getenv ("SA_AMF_COMPONENT_NAME");
+	char *env;
+
+	printf("%d: Hello world from %s\n", (int)getpid(), name);
 
 
 	/* test that it exist */
 	/* test that it exist */
 	if (name == NULL) {
 	if (name == NULL) {
 		fprintf(stderr, "SA_AMF_COMPONENT_NAME missing\n");
 		fprintf(stderr, "SA_AMF_COMPONENT_NAME missing\n");
-		exit (-1);
+		exit (1);
+	}
+
+	env = getenv ("var1");
+	if (env == NULL) {
+		printf("var1 missing\n");
+		exit (2);
+	}
+	if (strcmp (env, "val1") != 0) {
+		fprintf(stderr, "var1 value wrong\n");
+		exit (3);
+	}
+	env = getenv ("var2");
+	if (env == NULL) {
+		fprintf(stderr, "var2 wrong\n");
+		exit (4);
+	}
+	if (strcmp (env, "val2") != 0) {
+		fprintf(stderr, "var2 value wrong\n");
+		exit (5);
 	}
 	}
 
 
 	/* test for correct value */
 	/* test for correct value */
@@ -310,8 +332,6 @@ int main (int argc, char **argv) {
 	}
 	}
 #endif
 #endif
 
 
-	printf("%d: Hello world from %s\n", (int)getpid(), name);
-
 	signal (SIGINT, sigintr_handler);
 	signal (SIGINT, sigintr_handler);
 #if ! defined(TS_CLASS) && (defined(OPENAIS_BSD) || defined(OPENAIS_LINUX) || defined(OPENAIS_SOLARIS))
 #if ! defined(TS_CLASS) && (defined(OPENAIS_BSD) || defined(OPENAIS_LINUX) || defined(OPENAIS_SOLARIS))
 	result = sched_setscheduler (0, SCHED_RR, &sched_param);
 	result = sched_setscheduler (0, SCHED_RR, &sched_param);
@@ -323,7 +343,7 @@ int main (int argc, char **argv) {
 	result = saAmfInitialize (&handle, &amfCallbacks, &version);
 	result = saAmfInitialize (&handle, &amfCallbacks, &version);
 	if (result != SA_AIS_OK) {
 	if (result != SA_AIS_OK) {
 		printf ("initialize result is %d\n", result);
 		printf ("initialize result is %d\n", result);
-		exit (1);
+		exit (6);
 	}
 	}
 
 
 	FD_ZERO (&read_fds);
 	FD_ZERO (&read_fds);
@@ -345,13 +365,25 @@ int main (int argc, char **argv) {
         SaNameT badname;
         SaNameT badname;
         strcpy ((char*)badname.value, "badname");
         strcpy ((char*)badname.value, "badname");
         badname.length = 7;
         badname.length = 7;
-        result = saAmfComponentRegister (handle, &badname, NULL);
+		do {
+			result = saAmfComponentRegister (handle, &badname, NULL);
+			if (result == SA_AIS_ERR_TRY_AGAIN) {
+				printf("%d: TRY_AGAIN received\n", getpid());
+				sleep (1);
+			}
+		} while (result == SA_AIS_ERR_TRY_AGAIN);
 		if (result != SA_AIS_ERR_INVALID_PARAM) {
 		if (result != SA_AIS_ERR_INVALID_PARAM) {
 			printf ("Error: register result is %d\n", result);
 			printf ("Error: register result is %d\n", result);
 		}
 		}
     }
     }
 
 
-    result = saAmfComponentRegister (handle, &compNameGlobal, NULL);
+	do {
+		result = saAmfComponentRegister (handle, &compNameGlobal, NULL);
+		if (result == SA_AIS_ERR_TRY_AGAIN) {
+			printf("%d: TRY_AGAIN received\n", getpid());
+			sleep (1);
+		}
+	} while (result == SA_AIS_ERR_TRY_AGAIN);
 	if (result != SA_AIS_OK) {
 	if (result != SA_AIS_OK) {
 		printf ("Error: register result is %d\n", result);
 		printf ("Error: register result is %d\n", result);
 	}
 	}
@@ -373,7 +405,7 @@ int main (int argc, char **argv) {
 		result = saAmfDispatch (handle, SA_DISPATCH_ALL);
 		result = saAmfDispatch (handle, SA_DISPATCH_ALL);
 
 
 		if (result != SA_AIS_OK) {
 		if (result != SA_AIS_OK) {
-			exit (-1);
+			exit (7);
 		}
 		}
 	} while (result && stop == 0);
 	} while (result && stop == 0);
 
 

Некоторые файлы не были показаны из-за большого количества измененных файлов