Quellcode durchsuchen

enhancement 1145
Patch from Lars to implement csi attribute setting in config file and delivered
via callback.


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

Steven Dake vor 20 Jahren
Ursprung
Commit
cc89d721cc
9 geänderte Dateien mit 606 neuen und 91 gelöschten Zeilen
  1. 121 27
      conf/groups.conf
  2. 258 50
      exec/amf.c
  3. 80 0
      exec/amfconfig.c
  4. 14 0
      exec/amfconfig.h
  5. 1 0
      exec/main.c
  6. 13 1
      include/ipc_amf.h
  7. 3 2
      include/saAmf.h
  8. 49 3
      lib/amf.c
  9. 67 8
      test/testamf1.c

+ 121 - 27
conf/groups.conf

@@ -3,12 +3,12 @@
 group {
 	name=raid
 	model=nplusm
-	preferred-active-units=3
-	maximum-active-instances=3
+	preferred-active-units=2
+	maximum-active-instances=2
 	preferred-standby-units=2
 	maximum-standby-instances=4
-	clccli_path=/home/sdake/amfb-dec/test
-	binary_path=/home/sdake/amfb-dec/test
+	clccli_path=/tmp/trunktest/test
+	binary_path=/tmp/trunktest/test
 	component_restart_probation=100000
 	component_restart_max=4
 	unit_restart_probation=200000
@@ -23,6 +23,12 @@ group {
 			instantiate=clc_cli_script
 			terminate=clc_cli_script
 			cleanup=clc_cli_script
+			csi_type_name {
+				name=for_comp_a_x
+			}
+			csi_type_name {
+				name=for_comp_a_y
+			}
 		}
 		component {
 			name=comp_b_in_su_1
@@ -31,6 +37,9 @@ group {
 			instantiate=clc_cli_script
 			terminate=clc_cli_script
 			cleanup=clc_cli_script
+			csi_type_name {
+				name=for_comp_b
+			}
 		}
 	}
 	unit {  
@@ -42,6 +51,12 @@ group {
 			instantiate=clc_cli_script
 			terminate=clc_cli_script
 			cleanup=clc_cli_script
+			csi_type_name {
+				name=for_comp_a_x
+			}
+			csi_type_name {
+				name=for_comp_a_y
+			}
 		}
 		component {
 			name=comp_b_in_su_2
@@ -50,6 +65,9 @@ group {
 			instantiate=clc_cli_script
 			terminate=clc_cli_script
 			cleanup=clc_cli_script
+			csi_type_name {
+				name=for_comp_b
+			}
 		}
 	}
 	unit {  
@@ -61,6 +79,12 @@ group {
 			instantiate=clc_cli_script
 			terminate=clc_cli_script
 			cleanup=clc_cli_script
+			csi_type_name {
+				name=for_comp_a_x
+			}
+			csi_type_name {
+				name=for_comp_a_y
+			}
 		}
 		component {
 			name=comp_b_in_su_3
@@ -69,6 +93,9 @@ group {
 			instantiate=clc_cli_script
 			terminate=clc_cli_script
 			cleanup=clc_cli_script
+			csi_type_name {
+				name=for_comp_b
+			}
 		}
 	}
 	unit {  
@@ -80,6 +107,12 @@ group {
 			instantiate=clc_cli_script
 			terminate=clc_cli_script
 			cleanup=clc_cli_script
+			csi_type_name {
+				name=for_comp_a_x
+			}
+			csi_type_name {
+				name=for_comp_a_y
+			}
 		}
 		component {
 			name=comp_b_in_su_4
@@ -88,37 +121,98 @@ group {
 			instantiate=clc_cli_script
 			terminate=clc_cli_script
 			cleanup=clc_cli_script
+			csi_type_name {
+				name=for_comp_b
+			}
 		}
 	}
-	unit {  
-		name=SU_5
-		component {
-			name=comp_a_in_su_5
-			comptype=sa_aware
-			bn=testamf1
-			instantiate=clc_cli_script
-			terminate=clc_cli_script
-			cleanup=clc_cli_script
+
+	serviceinstance {
+		name = SI_1
+		csi_descriptor {
+			csi_name=csi_ax_in_si_1
+			type_name=for_comp_a_x
+			name_value {
+				name=good_health_limit
+				value=0
+			}
+			name_value {
+				name=ax_attr2
+				value=ax1_val2
+			}
 		}
-		component {
-			name=comp_b_in_su_5
-			comptype=sa_aware
-			bn=testamf1
-			instantiate=clc_cli_script
-			terminate=clc_cli_script
-			cleanup=clc_cli_script
+		csi_descriptor {
+			csi_name=csi_ay_in_si_1
+			type_name=for_comp_a_y
+			name_value {
+				name=ay_attr1
+				value=ay1_val1
+			}
+			name_value {
+				name=ay_attr2
+				value=ay1_val2
+			}
+		}
+		csi_descriptor {
+			csi_name=csi_b_in_si_1
+			type_name=for_comp_b
+			name_value {
+				name=good_health_limit
+				value=0
+			}
+			name_value {
+				name=b_attr2
+				value=b1_val2
+			}
 		}
 	}
 	serviceinstance {
-		name = siaa
-	}
-	serviceinstance {
-		name = sibb
-	}
-	serviceinstance {
-		name = sicc
+		name = SI_2
+
+		csi_descriptor {
+			csi_name=csi_ax_in_si_2
+			type_name=for_comp_a_x
+			name_value {
+				name=good_health_limit
+				value=10
+			}
+			name_value {
+				name=ax_attr2
+				value=ax2_val2
+			}
+		}
+		csi_descriptor {
+			csi_name=csi_b_in_si_2
+			type_name=for_comp_b
+			name_value {
+				name=good_health_limit
+				value=0
+			}
+			name_value {
+				name=b_attr2
+				value=b2_val2
+			}
+		}
+		csi_descriptor {
+			csi_name=csi_ay_in_si_2
+			type_name=for_comp_a_y
+			name_value {
+				name=ay_attr1
+				value=ay2_val1
+			}
+			name_value {
+				name=ay_attr2
+				value=ay2_val2
+			}
+		}
 	}
 #	serviceinstance {
+#		name = sibb
+#	}
+#	serviceinstance {
+#		name = sicc
+#	}
+#	serviceinstance {
 #		name = sidd
 #	}
 #	serviceinstance {

+ 258 - 50
exec/amf.c

@@ -386,7 +386,7 @@ static struct openais_exec_handler amf_exec_service[] = {
 	}
 };
 
-
+void amf_dump(void);
 /*
  * Exports the interface for the service
  */
@@ -402,6 +402,7 @@ struct openais_service_handler amf_service_handler = {
 	.exec_service			= amf_exec_service,
 	.exec_service_count		= sizeof (amf_exec_service) / sizeof (struct openais_exec_handler),
 	.confchg_fn			= amf_confchg_fn,
+    .exec_dump_fn       = amf_dump
 };
 
 struct openais_service_handler *amf_get_handler_ver0 (void);
@@ -1370,41 +1371,148 @@ void csi_comp_set_callback (
 	struct amf_csi *csi,
 	struct amf_pg *pg)
 {
-	struct res_lib_amf_csisetcallback res_lib_amf_csisetcallback;
-	struct csi_set_callback_data *csi_set_callback_data;
+    struct list_head *name_value_list;
+    struct res_lib_amf_csisetcallback* res_lib_amf_csisetcallback;     
+    void*  p;
 
-	printf ("\t%s\n",
-		getSaNameT (&comp->name));
+    struct csi_set_callback_data *csi_set_callback_data;
+    struct amf_csi_name_value *name_value;
 
-	res_lib_amf_csisetcallback.header.id = MESSAGE_RES_AMF_CSISETCALLBACK;
-	res_lib_amf_csisetcallback.header.size = sizeof (struct res_lib_amf_csisetcallback);
-	res_lib_amf_csisetcallback.header.error = SA_AIS_OK;
 
 
-	memcpy (&res_lib_amf_csisetcallback.compName,
+    size_t char_legnth_of_csi_attrs=0;
+    size_t num_of_csi_attrs=0;
+    printf("\t   Assigning CSI %s to component\n", getSaNameT (&csi->name));
+
+    for (name_value_list = csi->name_value_head.next;
+	name_value_list != &csi->name_value_head;
+	name_value_list = name_value_list->next) {
+	num_of_csi_attrs++;
+	name_value = list_entry (name_value_list, struct amf_csi_name_value, list);
+	printf("\t\tname = %s, value = %s\n", name_value->name, name_value->value);
+	char_legnth_of_csi_attrs += strlen(name_value->name);
+	char_legnth_of_csi_attrs += strlen(name_value->value);
+	char_legnth_of_csi_attrs += 2;
+    }
+    p = malloc(sizeof(struct res_lib_amf_csisetcallback)+
+	       char_legnth_of_csi_attrs);
+
+
+    assert(p);
+
+    res_lib_amf_csisetcallback = (struct res_lib_amf_csisetcallback*)p;
+
+
+
+
+    
+    /* Address of the buffer containing the Csi name value pair  */
+    char* csi_attribute_buf = res_lib_amf_csisetcallback->csi_attr_buf;
+				       
+
+
+
+
+   /* Byteoffset start att the zero byte  */
+   unsigned int byte_offset = 0;
+
+   for (name_value_list = csi->name_value_head.next;
+	 name_value_list != &csi->name_value_head;
+	 name_value_list = name_value_list->next) {
+       
+	  name_value = list_entry (name_value_list, struct amf_csi_name_value, list);
+	  
+	  strcpy(&csi_attribute_buf[byte_offset],
+		 (char*)name_value->name);
+
+	  byte_offset += strlen(name_value->name) + 1;
+
+	  strcpy(&csi_attribute_buf[byte_offset],
+		 (char*)name_value->value);
+
+	  byte_offset += strlen(name_value->value) + 1;
+   }
+
+   res_lib_amf_csisetcallback->number = num_of_csi_attrs;
+      
+
+   res_lib_amf_csisetcallback->csiFlags = SA_AMF_CSI_ADD_ONE;  
+
+   switch (comp->unit->requested_ha_state) {
+      case SA_AMF_HA_ACTIVE:
+	  {
+	      res_lib_amf_csisetcallback->csiStateDescriptor.activeDescriptor.activeCompName.length = 0;
+	      res_lib_amf_csisetcallback->csiStateDescriptor.activeDescriptor.transitionDescriptor =
+		  SA_AMF_CSI_NEW_ASSIGN; 
+	      break;
+	  }
+      case  SA_AMF_HA_STANDBY:
+	  {
+	      
+	      res_lib_amf_csisetcallback->csiStateDescriptor.standbyDescriptor.activeCompName.length = 0; 
+	      res_lib_amf_csisetcallback->csiStateDescriptor.standbyDescriptor.standbyRank =  1;
+
+
+	      break;
+	  }
+      case  SA_AMF_HA_QUIESCED:
+	  {
+	      /*TODO*/
+	      break;
+	  }
+      case SA_AMF_HA_QUIESCING:
+	  {
+	      /*TODO*/
+	      break;
+	  }
+      default:
+	  {
+	      assert(SA_AMF_HA_ACTIVE||SA_AMF_HA_STANDBY||SA_AMF_HA_QUIESCING||SA_AMF_HA_QUIESCED);	      
+	      break;
+	  }
+
+      }
+
+	 
+      res_lib_amf_csisetcallback->header.id = 
+	  MESSAGE_RES_AMF_CSISETCALLBACK;
+
+      res_lib_amf_csisetcallback->header.size = 
+	  sizeof (struct res_lib_amf_csisetcallback)+
+	  char_legnth_of_csi_attrs;
+
+      res_lib_amf_csisetcallback->header.error = SA_AIS_OK;
+
+
+	memcpy (&res_lib_amf_csisetcallback->compName,
 		&comp->name, sizeof (SaNameT));
 
-	memcpy (&res_lib_amf_csisetcallback.csiDescriptor.csiName,
+	memcpy (&res_lib_amf_csisetcallback->csiName,
 		&csi->name, sizeof (SaNameT));
 
-	res_lib_amf_csisetcallback.haState = comp->unit->requested_ha_state;
-
+	res_lib_amf_csisetcallback->haState = comp->unit->requested_ha_state;
+	
 	csi_set_callback_data = malloc (sizeof (struct csi_set_callback_data));
 	assert (csi_set_callback_data); // TODO failure here of malloc
 	csi_set_callback_data->comp = comp;
 	csi_set_callback_data->csi = csi;
 	csi_set_callback_data->pg = pg;
-	printf ("pg is %p\n", pg);
+ 
 
-	res_lib_amf_csisetcallback.invocation =
+	res_lib_amf_csisetcallback->invocation =
 		invocation_create (
 		AMF_RESPONSE_CSISETCALLBACK,
 		csi_set_callback_data);
-				        
-	openais_conn_send_response (
-		openais_conn_partner_get (comp->conn),
-		&res_lib_amf_csisetcallback,
-		sizeof (struct res_lib_amf_csisetcallback));
+
+	
+	int result = openais_conn_send_response (
+	    openais_conn_partner_get (comp->conn),
+	    res_lib_amf_csisetcallback,
+	    res_lib_amf_csisetcallback->header.size);
+
+
+
+	free(p);
 }
 
 void pg_create (struct amf_si *si, struct amf_pg **pg_out)
@@ -1419,31 +1527,67 @@ void pg_create (struct amf_si *si, struct amf_pg **pg_out)
 	list_add (&pg->pg_list, &si->pg_head);
 	*pg_out = pg;
 }
-
-void csi_unit_set_callback (struct amf_csi *csi_in)
-{
-	struct list_head *list;
-	struct amf_comp *comp;
-	struct amf_pg *pg;
-
-	pg_create (csi_in->si, &pg);
-	// TODO remove si from csi data structure
-
-	printf ("assigning CSI %s to ",
-		getSaNameT (&csi_in->name));
-
-	printf ("SU %s for components:\n",
-		getSaNameT (&csi_in->unit->name));
-	for (list = csi_in->unit->comp_head.next;
-		list != &csi_in->unit->comp_head;
-		list = list->next) {
-
-		comp = list_entry (list,
-			struct amf_comp, comp_list);
-
-		csi_comp_set_callback (comp, csi_in, pg);
-	}
-}
+void csi_unit_set_callback (struct amf_unit *unit, struct amf_si *si)
+{
+    struct list_head *complist;
+    struct list_head *csilist;
+    struct list_head *typenamelist;
+    struct amf_csi *csi;
+    struct amf_pg *pg;
+    struct amf_comp *comp;
+    struct amf_comp_csi_type_name *type_name;
+
+//    pg_create (csi_in->si, &pg);
+    // TODO remove si from csi data structure
+
+    printf ("assigning SI %s to ",
+        getSaNameT (&si->name));
+
+    printf ("SU %s for components:\n",
+        getSaNameT (&unit->name));
+
+    /*
+    ** for each component in SU, find a CSI in the SI with the same type
+    */
+    for (complist = unit->comp_head.next;
+        complist != &unit->comp_head;
+        complist = complist->next) {
+
+        comp = list_entry (complist, struct amf_comp, comp_list);
+
+        printf ("\t%s\n", getSaNameT (&comp->name));
+
+        int no_of_csi_types = 0;
+        for (typenamelist = comp->csi_type_name_head.next;
+             typenamelist != &comp->csi_type_name_head;
+             typenamelist = typenamelist->next) {
+
+                type_name = list_entry (typenamelist, struct amf_comp_csi_type_name, list);
+                no_of_csi_types++;
+                int no_of_assignments = 0;
+
+                for (csilist = si->csi_head.next;
+                      csilist != &si->csi_head;
+                      csilist = csilist->next) {
+
+                        csi = list_entry (csilist, struct amf_csi, list);
+
+                        if (!memcmp(csi->type_name.value, type_name->name.value, type_name->name.length)) {
+                                csi_comp_set_callback (comp, csi, pg);
+                                no_of_assignments++;
+                        }
+                }
+                if (no_of_assignments == 0) {
+                    printf ("\t   No CSIs of type %s configured?!!\n",
+                            getSaNameT (&type_name->name));
+                }
+        }
+        if (no_of_csi_types == 0) {
+            printf ("\t   No CSI types configured for %s ?!!\n",
+                    getSaNameT (&comp->name));
+                }
+    }
+} 
 
 void csi_comp_remove_callback (struct amf_comp *comp, struct amf_csi *csi)
 {
@@ -1701,7 +1845,6 @@ void csi_unit_create (struct amf_unit *unit, struct amf_si *si,
 void ha_state_unit_set (struct amf_unit *unit, struct amf_si *si,
 		SaAmfHAStateT ha_state)
 {
-	struct amf_csi *csi;
 
 	printf ("Assigning SI %s ", getSaNameT (&si->name));
 	printf ("to SU %s ", getSaNameT (&unit->name));
@@ -1709,9 +1852,7 @@ void ha_state_unit_set (struct amf_unit *unit, struct amf_si *si,
 
 	unit->requested_ha_state = ha_state;
 
-	csi_unit_create (unit, si, &csi);
-
-	csi_unit_set_callback (csi);
+	csi_unit_set_callback (unit, si);
 }
 
 
@@ -4744,12 +4885,13 @@ static char *hastate_ntoa (SaAmfHAStateT state)
 	return (str);
 }
 
-#ifdef COMPILE_OUT
 static void amf_dump_comp (struct amf_comp *component ,void *data)
 {
 	char	name[64];
 	int	level = LOG_LEVEL_NOTICE;
 	data = NULL;
+        struct list_head* type_name_list;
+        struct amf_comp_csi_type_name* type_name;
 
 	log_printf (level, "----------------\n" );
 	log_printf (level, "registered            = %d\n" ,component->registered);
@@ -4758,6 +4900,22 @@ static void amf_dump_comp (struct amf_comp *component ,void *data)
 	memset (name, 0 , sizeof(name));
 	memcpy (name, component->name.value, component->name.length);
 	log_printf (level, "name                  = %s\n" ,name );
+#if 1
+        log_printf (level, "csi type names\n");
+            for (type_name_list = component->csi_type_name_head.next;
+                    type_name_list != &component->csi_type_name_head;
+                    type_name_list = type_name_list->next) {
+
+                    type_name = list_entry (type_name_list,
+                            struct amf_comp_csi_type_name, list);
+
+                    log_printf (level, "   name      = %s\n" , type_name->name);
+            }
+#endif
+#if COMPILE_OUT
+	/*
+	*  TODO Change to correct state syntax and implement new ...state_ntoa
+	*/    
 	log_printf (level, "currentReadinessState = %s\n" ,readinessstate_ntoa (component->currentReadinessState));
 	log_printf (level, "newReadinessState     = %s\n" ,readinessstate_ntoa (component->newReadinessState));
 	log_printf (level, "currentHAState        = %s\n" ,hastate_ntoa (component->currentHAState));
@@ -4765,6 +4923,56 @@ static void amf_dump_comp (struct amf_comp *component ,void *data)
 	log_printf (level, "enabledUnlockedState  = %s\n" ,enabledunlockedstate_ntoa (component->enabledUnlockedState));
 	log_printf (level, "disabledUnlockedState = %s\n" ,disabledunlockedstate_ntoa (component->disabledUnlockedState));
 	log_printf (level, "probableCause         = %d\n" ,component->probableCause );
+#endif
+}
+
+void enumerate_components (
+	void (*function)(struct amf_comp *, void *data),
+	void *data)
+{
+	struct list_head *AmfGroupList;
+	struct list_head *AmfUnitList;
+	struct list_head *AmfComponentList;
+
+	struct amf_group *saAmfGroup;
+	struct amf_unit *AmfUnit;
+	struct amf_comp *AmfComponent;
+
+
+	/*
+	 * Search all groups
+	 */
+	for (AmfGroupList = amf_groupHead.next;
+		AmfGroupList != &amf_groupHead;
+		AmfGroupList = AmfGroupList->next) {
+
+		saAmfGroup = list_entry (AmfGroupList,
+			struct amf_group, group_list);
+
+		/*
+		 * Search all units
+		 */
+		for (AmfUnitList = saAmfGroup->unit_head.next;
+			AmfUnitList != &saAmfGroup->unit_head;
+			AmfUnitList = AmfUnitList->next) {
+
+			AmfUnit = list_entry (AmfUnitList,
+				struct amf_unit, unit_list);
+
+			/*
+			 * Search all components
+			 */
+			for (AmfComponentList = AmfUnit->comp_head.next;
+				AmfComponentList != &AmfUnit->comp_head;
+				AmfComponentList = AmfComponentList->next) {
+
+				AmfComponent = list_entry (AmfComponentList,
+					struct amf_comp, comp_list);
+
+				function (AmfComponent, data);
+			}
+		}
+	}
 }
 
 void amf_dump ( )
@@ -4774,4 +4982,4 @@ void amf_dump ( )
 
 	return;
 }
-#endif
+

+ 80 - 0
exec/amfconfig.c

@@ -61,7 +61,10 @@ typedef enum {
 	AMF_GROUP,
 	AMF_UNIT,
 	AMF_COMPONENT,
+        AMF_COMPONENT_CSI_TYPE_NAMES,
 	AMF_SERVICEINSTANCE,
+        AMF_SERVICEINSTANCE_CSIDESCRIPTOR,
+        AMF_SERVICEINSTANCE_CSIDESCRIPTOR_NAMEVALUE,
 	AMF_HEALTHCHECK
 } amf_parse_t;
 
@@ -224,8 +227,13 @@ extern int openais_amf_config_read (char **error_string)
 	struct amf_comp *amf_comp = 0;
 	struct amf_si *amf_si = 0;
 	struct amf_healthcheck *amf_healthcheck = 0;
+        struct amf_comp_csi_type_name *csi_type_name = 0;
+        struct amf_csi *amf_csi = 0;
+        struct amf_csi_name_value *csi_name_value;
+
 
 	fp = fopen (OPENAIS_CONFDIR "/groups.conf", "r");
+
 	if (fp == 0) {
 		sprintf (error_string_response,
 			"Can't read %s/groups.conf file reason = (%s).\n",
@@ -386,6 +394,7 @@ extern int openais_amf_config_read (char **error_string)
 
 				list_init (&amf_comp->comp_list);
 				list_init (&amf_comp->healthcheck_list);
+                                list_init (&amf_comp->csi_type_name_head);
 				list_add_tail (&amf_comp->comp_list, &amf_unit->comp_head);
 
 				memset (amf_comp->clccli_path, 0, sizeof (&amf_comp->clccli_path));
@@ -478,6 +487,15 @@ extern int openais_amf_config_read (char **error_string)
 			if ((loc = strstr_rs (line, "bn=")) != 0) {
 				strcpy (amf_comp->binary_name, loc);
 			} else
+			if ((loc = strstr_rs (line, "csi_type_name{")) != 0) {
+                                csi_type_name =
+                                        (struct amf_comp_csi_type_name*)mempool_malloc (sizeof(struct amf_comp_csi_type_name));
+
+                                list_init(&csi_type_name->list);
+                                list_add_tail (&csi_type_name->list, &amf_comp->csi_type_name_head);
+
+                                current_parse = AMF_COMPONENT_CSI_TYPE_NAMES;
+                        } else
 			if (strstr_rs (line, "}")) {
 				current_parse = AMF_UNIT;
 			} else {
@@ -485,16 +503,78 @@ extern int openais_amf_config_read (char **error_string)
 			}
 			break;
 
+                case AMF_COMPONENT_CSI_TYPE_NAMES:
+                        if ((loc = strstr_rs (line, "name=")) != 0) {
+                                setSaNameT(&csi_type_name->name, loc);
+                        } else
+                        if ((loc = strstr_rs (line, "csi_type_name{")) != 0) {
+                                csi_type_name =
+                                (struct amf_comp_csi_type_name*)mempool_malloc (sizeof(struct amf_comp_csi_type_name));
+
+                                list_init(&csi_type_name->list);
+                                list_add_tail (&csi_type_name->list, &amf_comp->csi_type_name_head);
+
+                                current_parse = AMF_COMPONENT_CSI_TYPE_NAMES;
+                        } else
+                        if (strstr_rs (line, "}")) {
+                                current_parse = AMF_COMPONENT;
+                        } else {
+                                goto parse_error;
+                        }
+                        break;
 		case AMF_SERVICEINSTANCE:
 			if ((loc = strstr_rs (line, "name=")) != 0) {
 				setSaNameT (&amf_si->name, loc);
 			} else
+                        if ((loc = strstr_rs (line, "csi_descriptor{")) != 0) {
+                                amf_csi = (struct amf_csi*)mempool_malloc (sizeof(struct amf_csi));
+
+                                list_init(&amf_csi->list);
+                                list_init(&amf_csi->name_value_head);
+                                list_add_tail (&amf_csi->list, &amf_si->csi_head);
+
+                                current_parse = AMF_SERVICEINSTANCE_CSIDESCRIPTOR;
+                        } else
 			if (strstr_rs (line, "}")) {
 				current_parse = AMF_GROUP;
 			} else {
 				goto parse_error;
 			}
 			break;
+                case AMF_SERVICEINSTANCE_CSIDESCRIPTOR:
+                        if ((loc = strstr_rs (line, "csi_name=")) != 0) {
+                                setSaNameT (&amf_csi->name, loc);
+                        } else
+                        if ((loc = strstr_rs (line, "type_name=")) != 0) {
+                                setSaNameT (&amf_csi->type_name, loc);
+                        } else
+                        if ((loc = strstr_rs (line, "name_value{")) != 0) {
+                                 csi_name_value = (struct amf_csi_name_value*)mempool_malloc (sizeof(struct amf_csi_name_value));
+
+                                 list_init(&csi_name_value->list);
+                                 list_add_tail (&csi_name_value->list, &amf_csi->name_value_head);
+
+                                 current_parse = AMF_SERVICEINSTANCE_CSIDESCRIPTOR_NAMEVALUE;
+                        } else
+                        if (strstr_rs (line, "}")) {
+                                current_parse = AMF_SERVICEINSTANCE;
+                        } else {
+                                goto parse_error;
+                        }
+                        break;
+                case AMF_SERVICEINSTANCE_CSIDESCRIPTOR_NAMEVALUE:
+                        if ((loc = strstr_rs (line, "name=")) != 0) {
+                                strcpy(csi_name_value->name, loc);
+                        } else
+                        if ((loc = strstr_rs (line, "value=")) != 0) {
+                                strcpy(csi_name_value->value, loc);
+                        } else
+                        if (strstr_rs (line, "}")) {
+                                current_parse = AMF_SERVICEINSTANCE_CSIDESCRIPTOR;
+                        } else {
+                                goto parse_error;
+                        }
+                        break;
 
 		case AMF_HEALTHCHECK:
 			if ((loc = strstr_rs (line, "key=")) != 0) {

+ 14 - 0
exec/amfconfig.h

@@ -95,13 +95,21 @@ struct amf_unit {
 	enum escalation_levels escalation_level;
 };
 
+struct amf_csi_name_value {
+        struct list_head list;
+        char name[128];
+        char value[128];
+};
+
 struct amf_si;
 struct amf_csi {
 	SaNameT name;
+	SaNameT type_name;
 	struct list_head list;
 	struct amf_unit *unit;
 	struct list_head csi_list;
 	struct list_head unit_head;
+	struct list_head name_value_head;
 	struct amf_si *si;
 	int pg_set;
 };
@@ -173,6 +181,7 @@ struct amf_comp {
 
 	struct list_head comp_list;
 	struct list_head healthcheck_list;
+	struct list_head csi_type_name_head;
 
 	enum clc_component_types comptype;
 
@@ -193,6 +202,11 @@ struct amf_comp {
 	OpenaisCfgPresenceStateT presence_state;
 };
 
+struct amf_comp_csi_type_name {
+	struct list_head list;
+        SaNameT name;
+};
+
 extern struct list_head amf_group_head;
 
 extern struct amf_comp *find_comp (SaNameT *name);

+ 1 - 0
exec/main.c

@@ -1020,6 +1020,7 @@ static void aisexec_mempool_init (void)
 
 static void aisexec_tty_detach (void)
 {
+#define DEBUG
 #ifndef DEBUG
 	/*
 	 * Disconnect from TTY if this is not a debug run

+ 13 - 1
include/ipc_amf.h

@@ -244,12 +244,24 @@ struct res_lib_amf_componentterminatecallback {
 
 #endif
 
+/* struct res_lib_amf_csisetcallback {        */
+/*         struct res_header header;          */
+/*         SaInvocationT invocation;          */
+/*         SaNameT compName;                  */
+/*         SaAmfHAStateT haState;             */
+/*         SaAmfCSIDescriptorT csiDescriptor; */
+/* };                                         */
+
 struct res_lib_amf_csisetcallback {
 	struct res_header header;
 	SaInvocationT invocation;
 	SaNameT compName;
 	SaAmfHAStateT haState;
-	SaAmfCSIDescriptorT csiDescriptor;
+	SaAmfCSIFlagsT csiFlags;
+	SaNameT csiName;
+	SaAmfCSIStateDescriptorT csiStateDescriptor;
+	SaUint32T number;
+	char csi_attr_buf[1]; /* Actual length will be calculated  */
 };
 
 struct res_lib_amf_csiremovecallback {

+ 3 - 2
include/saAmf.h

@@ -99,8 +99,9 @@ typedef union {
 } SaAmfCSIStateDescriptorT;
 
 typedef struct {
-	SaUint8T *attrName;
-	SaUint8T *attrValue;
+    SaUint8T *attrName;
+    SaUint8T *attrValue;
+
 } SaAmfCSIAttributeT;
 
 typedef struct {

+ 49 - 3
lib/amf.c

@@ -51,6 +51,7 @@
 #include "../include/ipc_amf.h"
 #include "util.h"
 
+
 struct res_overlay {
 	struct res_header header;
 	char data[4096];
@@ -173,6 +174,7 @@ saAmfSelectionObjectGet (
 	return (SA_AIS_OK);
 }
 
+
 SaAisErrorT
 saAmfDispatch (
 	SaAmfHandleT amfHandle,
@@ -235,6 +237,7 @@ saAmfDispatch (
 		if (amfInstance->finalize == 1) {
 			error = SA_AIS_OK;
 			pthread_mutex_unlock (&amfInstance->dispatch_mutex);
+
 			goto error_unlock;
 		}
 
@@ -251,21 +254,27 @@ saAmfDispatch (
 		if (ufds.revents & POLLIN) {
 			/*
 			 * Queue empty, read response from socket
-			 */
+			 */ 
 			error = saRecvRetry (amfInstance->dispatch_fd, &dispatch_data.header,
 				sizeof (struct res_header));
+
 			if (error != SA_AIS_OK) {
+
 				goto error_unlock;
 			}
 			if (dispatch_data.header.size > sizeof (struct res_header)) {
+
 				error = saRecvRetry (amfInstance->dispatch_fd, &dispatch_data.data,
 					dispatch_data.header.size - sizeof (struct res_header));
+
 				if (error != SA_AIS_OK) {
+
 					goto error_unlock;
 				}
 			}
 		} else {
 			pthread_mutex_unlock (&amfInstance->dispatch_mutex);
+
 			continue;
 		}
 
@@ -274,12 +283,14 @@ saAmfDispatch (
 		 * A risk of this dispatch method is that the callback routines may
 		 * operate at the same time that amfFinalize has been called in another thread.
 		 */
+
 		memcpy (&callbacks, &amfInstance->callbacks, sizeof (SaAmfCallbacksT));
 		pthread_mutex_unlock (&amfInstance->dispatch_mutex);
 
 		/*
 		 * Dispatch incoming response
 		 */
+
 		switch (dispatch_data.header.id) {
 
 		case MESSAGE_RES_AMF_HEALTHCHECKCALLBACK:
@@ -292,14 +303,49 @@ saAmfDispatch (
 			break;
 
 		case MESSAGE_RES_AMF_CSISETCALLBACK:
+		    {
 			res_lib_amf_csisetcallback = (struct res_lib_amf_csisetcallback *)&dispatch_data;
+
+
+
+			SaAmfCSIDescriptorT csi_descriptor;
+
+			csi_descriptor.csiFlags = res_lib_amf_csisetcallback->csiFlags;
+			memcpy(&csi_descriptor.csiName, &res_lib_amf_csisetcallback->csiName, 
+			       sizeof(SaNameT));
+			csi_descriptor.csiStateDescriptor = res_lib_amf_csisetcallback->csiStateDescriptor;
+			csi_descriptor.csiAttr.number = res_lib_amf_csisetcallback->number;
+
+			SaAmfCSIAttributeT* csi_attribute_array = malloc( sizeof( SaAmfCSIAttributeT ) * 
+									  csi_descriptor.csiAttr.number );
+
+			if( csi_attribute_array == 0) {
+			    return SA_AIS_ERR_LIBRARY;
+			}
+			csi_descriptor.csiAttr.attr = csi_attribute_array;
+
+			char* p = res_lib_amf_csisetcallback->csi_attr_buf;
+			int i;
+			
+			for (i=0; i<csi_descriptor.csiAttr.number; i++) {
+			    csi_attribute_array[i].attrName = p;
+
+			    p += strlen(p) + 1;
+			    csi_attribute_array[i].attrValue = p;
+
+			    p += strlen(p) + 1;
+			}
+			
+
 			callbacks.saAmfCSISetCallback (
 				res_lib_amf_csisetcallback->invocation,
 				&res_lib_amf_csisetcallback->compName,
 				res_lib_amf_csisetcallback->haState,
-				&res_lib_amf_csisetcallback->csiDescriptor);
-			break;
+				&csi_descriptor);
 
+			free(csi_attribute_array);
+			break;
+		    }
 		case MESSAGE_RES_AMF_CSIREMOVECALLBACK:
 			res_lib_amf_csiremovecallback = (struct res_lib_amf_csiremovecallback *)&dispatch_data;
 			callbacks.saAmfCSIRemoveCallback (

+ 67 - 8
test/testamf1.c

@@ -55,6 +55,8 @@ SaAmfHealthcheckKeyT key0 = {
 	.keyLen = 4
 };
 SaNameT compNameGlobal;
+int good_health = 0;
+int good_health_limit = 0;
 
 void printSaNameT (SaNameT *name)
 {
@@ -80,7 +82,9 @@ void HealthcheckCallback (SaInvocationT invocation,
 {
 	SaAisErrorT res;
 
-	healthcheck_no++;
+	if( !good_health && healthcheck_no++);
+
+
 /*
 	printf ("Healthcheck %u for key '%s' for component ",
 		healthcheck_no, healthcheckKey->key);
@@ -88,7 +92,7 @@ void HealthcheckCallback (SaInvocationT invocation,
 	printSaNameT ((SaNameT *)compName);
 	printf ("\n");
 */
-	if (healthcheck_no == 10) {
+	if (healthcheck_no == good_health_limit ) {
 printf ("COMPONENT REPORTING ERROR %s\n", compNameGlobal.value);
 		saAmfComponentErrorReport (handle, compName, 0, SA_AMF_COMPONENT_RESTART, 0);
 		res = saAmfResponse (handle, invocation, SA_AIS_OK);
@@ -98,12 +102,12 @@ printf ("COMPONENT DONE REPORTING ERROR\n");
 	}
 
 /*
-	if (healthcheck_no < 10) {
+	if (healthcheck_no < good_health_limit) {
 		res = saAmfResponse (handle, invocation, SA_AIS_OK);
 	}
 */
 /*
-	if (healthcheck_no == 3) {
+	if (healthcheck_no == good_health_limit) {
 		res = saAmfHealthcheckStop (handle, &compNameGlobal, &key0);
 		stop = 1;
 	}
@@ -119,12 +123,30 @@ void ComponentTerminateCallback (
 	exit (0);
 }
 
+#if 1
+    #include <sys/time.h>
+    #define TRU "%d"
+    #define TRS "%s" 
+    #define TR(format,x) do {                               \
+	struct timeval t;\
+	gettimeofday(&t,NULL);                                   \ 	
+	printf("%s:%d: %s : %d : %u: %u :%s : " format "\n",\
+		__FILE__,__LINE__,__FUNCTION__,             \
+		getpid(),(int)t.tv_sec, (int)t.tv_usec,#x,x);          \
+    }while(0)
+#else
+    #define TRU "%d"
+    #define TRS "%s" 
+    #define TR(format,x)
+#endif
+
 void CSISetCallback (
 	SaInvocationT invocation,
 	const SaNameT *compName,
 	SaAmfHAStateT haState,
 	SaAmfCSIDescriptorT *csiDescriptor)
 {
+
 	int res;
 	switch (haState) {
 	case SA_AMF_HA_ACTIVE:
@@ -136,17 +158,54 @@ void CSISetCallback (
 		printf ("'");
  		printf (" requested to enter hastate SA_AMF_ACTIVE.\n");
 		res = saAmfResponse (handle, invocation, SA_AIS_OK);
-		break;
+		int i;
+		TR(TRU, csiDescriptor->csiAttr.number);
+		for(i=0; i<csiDescriptor->csiAttr.number; i++) {
+
+		    if( strcmp(csiDescriptor->csiAttr.attr[i].attrName, "good_health_limit") == 0){
+			good_health = strcmp(csiDescriptor->csiAttr.attr[i].attrValue, "0") ? 0 : 1;
+			good_health_limit = atoi(csiDescriptor->csiAttr.attr[i].attrValue);
+			
+		    }
+
+ 
+		    TR(TRS,csiDescriptor->csiAttr.attr[i].attrName);
+		    TR(TRS, csiDescriptor->csiAttr.attr[i].attrValue);
+		} 
 
+		TR(TRU, csiDescriptor->csiFlags);
+
+
+		printSaNameT((SaNameT*) &csiDescriptor->csiStateDescriptor.activeDescriptor.activeCompName);
+		TR(TRU, csiDescriptor->csiStateDescriptor.activeDescriptor.transitionDescriptor);
+
+		break;  
+         
 	case SA_AMF_HA_STANDBY:
 		printf ("CSISetCallback:"); 
 		printf ("for CSI '");
-		printSaNameT ((SaNameT *)compName);
+		printSaNameT ((SaNameT *)&csiDescriptor->csiName);
 		printf ("' for component ");
 		printSaNameT ((SaNameT *)compName);
 		printf ("'");
 		printf (" requested to enter hastate SA_AMF_STANDBY.\n");
-		saAmfResponse (handle, invocation, SA_AIS_OK);
+		res = saAmfResponse (handle, invocation, SA_AIS_OK);
+		
+		TR(TRU,csiDescriptor->csiAttr.number);
+		for(i=0; i<csiDescriptor->csiAttr.number; i++) {
+		    if(!strcmp(csiDescriptor->csiAttr.attr[i].attrName, "good_health") && 
+		       !strcmp(csiDescriptor->csiAttr.attr[i].attrValue, "true")){
+			good_health = 1;
+		    }
+		    TR(TRS,csiDescriptor->csiAttr.attr[i].attrName);
+		    TR(TRS,csiDescriptor->csiAttr.attr[i].attrValue);
+		} 
+		printf("%s:%d:%s:%d\n",__FILE__,__LINE__,__FUNCTION__,res);
+		TR(TRU,csiDescriptor->csiFlags);
+
+		printSaNameT((SaNameT*) &csiDescriptor->csiStateDescriptor.standbyDescriptor.activeCompName);
+		TR(TRU,csiDescriptor->csiStateDescriptor.standbyDescriptor.standbyRank);
+
 		break;
 	case SA_AMF_HA_QUIESCED:
 		break;
@@ -216,7 +275,7 @@ static struct sched_param sched_param = {
 void sigintr_handler (int signum) {
 	exit (0);
 }
-
+ 
 void write_pid (void) {
 	char pid[256];
 	char filename[256];