[Spread-cvs] commit: r523 - in trunk: . daemon

jonathan at spread.org jonathan at spread.org
Thu May 3 15:02:36 EDT 2012


Author: jonathan
Date: 2012-05-03 15:02:36 -0400 (Thu, 03 May 2012)
New Revision: 523

Modified:
   trunk/CVS_Readme.txt
   trunk/daemon/Changelog
   trunk/daemon/conf_body.h
   trunk/daemon/config_parse.y
   trunk/daemon/configuration.c
   trunk/daemon/configuration.h
   trunk/daemon/groups.c
   trunk/daemon/groups.h
   trunk/daemon/network.c
   trunk/daemon/protocol.c
   trunk/daemon/session.c
Log:
Merge branch reconfig_groups_crash_bugfix rev 520 into trunk. This fixes the crash bugs when reloading a different daemon configuration file and adds some new apis to configuration

Modified: trunk/CVS_Readme.txt
===================================================================
--- trunk/CVS_Readme.txt	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/CVS_Readme.txt	2012-05-03 19:02:36 UTC (rev 523)
@@ -105,6 +105,9 @@
    lex.yy.c does not #include <unistd.h> without protecting it by 
    #ifndef ARCH_PC_WIN95 ... #endif
 
+   Modern lex/yacc now protect the unistd.h include with a #ifndef YY_NO_UNISTD_H
+   So Windows build files can define that to avoid the bad header. 
+
 To make binary release of Spread
 --------------------------------
 

Modified: trunk/daemon/Changelog
===================================================================
--- trunk/daemon/Changelog	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/Changelog	2012-05-03 19:02:36 UTC (rev 523)
@@ -1,3 +1,18 @@
+Thu May  3 14:58:47 2012  Jonathan Stanton  <jonathan at spreadconcepts.com>
+
+	* configuration.c, groups.c (G_signal_conf_reload): Rework how
+	groups handles configuration file reloads to fix crashes and 
+	other errors when a daemon configuration is changed. Also add
+	new configuration functions to support lookups of procs in 
+	different configurations. 
+
+2012-05-03  Jonathan Stanton  <jonathan at lock.int.spreadconcepts.com>
+
+	* network.c (Net_init): Fix compability problem between Spread's
+	use of DL_init_channel for multicast channels and the new semantics
+	in the new libspreadutil version of datalink. Bind to all interfaces 
+	with a INADDR_ANY for multicast groups not just the group itself. 
+
 Thu Apr 19 13:01:30 2012  Jonathan Stanton  <jonathan at spreadconcepts.com>
 
 	* flow_control.c (FC_init): Increase default flow control values 

Modified: trunk/daemon/conf_body.h
===================================================================
--- trunk/daemon/conf_body.h	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/conf_body.h	2012-05-03 19:02:36 UTC (rev 523)
@@ -57,7 +57,6 @@
 
 ext     configuration	*Config;
 ext     FILE		*yyin;
-ext	proc           	*Config_procs;
 ext     int       LinkWeights[MAX_SEGMENTS][MAX_SEGMENTS];
 
 #define MAX_CONF_STRING 20000

Modified: trunk/daemon/config_parse.y
===================================================================
--- trunk/daemon/config_parse.y	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/config_parse.y	2012-05-03 19:02:36 UTC (rev 523)
@@ -169,9 +169,9 @@
 
 	for ( i=0; i < num_procs; i++ )
 	{
-		if ( strcmp( Config_procs[i].name, name ) == 0 )
+		if ( strcmp( Config->allprocs[i].name, name ) == 0 )
 		{
-			*p = Config_procs[i];
+			*p = Config->allprocs[i];
 			return( i );
 		}
 	}
@@ -567,11 +567,11 @@
 				segment_procs);
 			  for(i=(num_procs - segment_procs); i<num_procs; i++) {
                                   /* This '1' is to keep each proc with the same port as the segment.*/
-			    if( 1 || Config_procs[i].port==0)  {
-			      Config_procs[i].port=
+			    if( 1 || Config->allprocs[i].port==0)  {
+			      Config->allprocs[i].port=
 				Config->segments[segments].port;
 			    }
-			    alarm_print_proc(&Config_procs[i],
+			    alarm_print_proc(&(Config->allprocs[i]),
 			    	Config->segments[segments].port);
 			  }
                           /* generate string representation of segment */
@@ -597,14 +597,14 @@
                           SEGMENT_SIZE_CHECK( segment_procs, $1.string );
                           if (procs_interfaces == 0)
                                   yyerror("Interfaces section declared but no actual interface addresses defined\n");
-                          strcpy(Config_procs[num_procs].name, $1.string);
-                          Config_procs[num_procs].id = $2.ip.addr.s_addr;
- 		          Config_procs[num_procs].port = $2.ip.port;
-			  Config_procs[num_procs].seg_index = segments;
-			  Config_procs[num_procs].index_in_seg = segment_procs;
-                          Config_procs[num_procs].num_if = procs_interfaces;
+                          strcpy(Config->allprocs[num_procs].name, $1.string);
+                          Config->allprocs[num_procs].id = $2.ip.addr.s_addr;
+ 		          Config->allprocs[num_procs].port = $2.ip.port;
+			  Config->allprocs[num_procs].seg_index = segments;
+			  Config->allprocs[num_procs].index_in_seg = segment_procs;
+                          Config->allprocs[num_procs].num_if = procs_interfaces;
 			  Config->segments[segments].procs[segment_procs] = 
-                                  &Config_procs[num_procs];
+                              &(Config->allprocs[num_procs]);
 			  num_procs++;
 			  segment_procs++;
                           procs_interfaces = 0;
@@ -617,15 +617,15 @@
                           SEGMENT_SIZE_CHECK( segment_procs, $1.string );
                           if (procs_interfaces == 0)
                                   yyerror("Interfaces section declared but no actual interface addresses defined\n");
-                          strcpy(Config_procs[num_procs].name, $1.string);
-                          Config_procs[num_procs].id =
-			    name2ip(Config_procs[num_procs].name);
- 		          Config_procs[num_procs].port = 0;
-			  Config_procs[num_procs].seg_index = segments;
-			  Config_procs[num_procs].index_in_seg = segment_procs;
-                          Config_procs[num_procs].num_if = procs_interfaces;
+                          strcpy(Config->allprocs[num_procs].name, $1.string);
+                          Config->allprocs[num_procs].id =
+			    name2ip(Config->allprocs[num_procs].name);
+ 		          Config->allprocs[num_procs].port = 0;
+			  Config->allprocs[num_procs].seg_index = segments;
+			  Config->allprocs[num_procs].index_in_seg = segment_procs;
+                          Config->allprocs[num_procs].num_if = procs_interfaces;
 			  Config->segments[segments].procs[segment_procs] = 
-                                  &Config_procs[num_procs];
+                              &(Config->allprocs[num_procs]);
 			  num_procs++;
 			  segment_procs++;
                           procs_interfaces = 0;
@@ -636,17 +636,17 @@
                           PROCS_CHECK( num_procs, $1.string );
                           SEGMENT_CHECK( segments, $1.string );
                           SEGMENT_SIZE_CHECK( segment_procs, $1.string );
-                          strcpy(Config_procs[num_procs].name, $1.string);
-                          Config_procs[num_procs].id = $2.ip.addr.s_addr;
- 		          Config_procs[num_procs].port = $2.ip.port;
-			  Config_procs[num_procs].seg_index = segments;
-			  Config_procs[num_procs].index_in_seg = segment_procs;
-                          Config_procs[num_procs].num_if = 1;
-                          Config_procs[num_procs].ifc[0].ip = Config_procs[num_procs].id;
-                          Config_procs[num_procs].ifc[0].port = Config_procs[num_procs].port;
-                          Config_procs[num_procs].ifc[0].type = IFTYPE_ALL | IFTYPE_ANY;
+                          strcpy(Config->allprocs[num_procs].name, $1.string);
+                          Config->allprocs[num_procs].id = $2.ip.addr.s_addr;
+ 		          Config->allprocs[num_procs].port = $2.ip.port;
+			  Config->allprocs[num_procs].seg_index = segments;
+			  Config->allprocs[num_procs].index_in_seg = segment_procs;
+                          Config->allprocs[num_procs].num_if = 1;
+                          Config->allprocs[num_procs].ifc[0].ip = Config->allprocs[num_procs].id;
+                          Config->allprocs[num_procs].ifc[0].port = Config->allprocs[num_procs].port;
+                          Config->allprocs[num_procs].ifc[0].type = IFTYPE_ALL | IFTYPE_ANY;
 			  Config->segments[segments].procs[segment_procs] = 
-                                  &Config_procs[num_procs];
+                              &(Config->allprocs[num_procs]);
 			  num_procs++;
 			  segment_procs++;
                           procs_interfaces = 0;
@@ -657,18 +657,18 @@
                           PROCS_CHECK( num_procs, $1.string );
                           SEGMENT_CHECK( segments, $1.string );
                           SEGMENT_SIZE_CHECK( segment_procs, $1.string );
-                          strcpy(Config_procs[num_procs].name, $1.string);
-                          Config_procs[num_procs].id =
-			    name2ip(Config_procs[num_procs].name);
- 		          Config_procs[num_procs].port = 0;
-			  Config_procs[num_procs].seg_index = segments;
-			  Config_procs[num_procs].index_in_seg = segment_procs;
-                          Config_procs[num_procs].num_if = 1;
-                          Config_procs[num_procs].ifc[0].ip = Config_procs[num_procs].id;
-                          Config_procs[num_procs].ifc[0].port = Config_procs[num_procs].port;
-                          Config_procs[num_procs].ifc[0].type = IFTYPE_ALL | IFTYPE_ANY;
+                          strcpy(Config->allprocs[num_procs].name, $1.string);
+                          Config->allprocs[num_procs].id =
+			    name2ip(Config->allprocs[num_procs].name);
+ 		          Config->allprocs[num_procs].port = 0;
+			  Config->allprocs[num_procs].seg_index = segments;
+			  Config->allprocs[num_procs].index_in_seg = segment_procs;
+                          Config->allprocs[num_procs].num_if = 1;
+                          Config->allprocs[num_procs].ifc[0].ip = Config->allprocs[num_procs].id;
+                          Config->allprocs[num_procs].ifc[0].port = Config->allprocs[num_procs].port;
+                          Config->allprocs[num_procs].ifc[0].type = IFTYPE_ALL | IFTYPE_ANY;
 			  Config->segments[segments].procs[segment_procs] = 
-                                  &Config_procs[num_procs];
+                              &(Config->allprocs[num_procs]);
 			  num_procs++;
 			  segment_procs++;
                           procs_interfaces = 0;
@@ -697,12 +697,12 @@
                           SEGMENT_CHECK( segments, $1.string );
                           SEGMENT_SIZE_CHECK( segment_procs, $1.string );
                           INTERFACE_NUM_CHECK( procs_interfaces, $1.string );
-                          Config_procs[num_procs].ifc[procs_interfaces].ip = $2.ip.addr.s_addr;
-                          Config_procs[num_procs].ifc[procs_interfaces].port = $2.ip.port;
+                          Config->allprocs[num_procs].ifc[procs_interfaces].ip = $2.ip.addr.s_addr;
+                          Config->allprocs[num_procs].ifc[procs_interfaces].port = $2.ip.port;
                           if ($1.mask == 0)
-                                  Config_procs[num_procs].ifc[procs_interfaces].type = IFTYPE_ALL;
+                                  Config->allprocs[num_procs].ifc[procs_interfaces].type = IFTYPE_ALL;
                           else 
-                                  Config_procs[num_procs].ifc[procs_interfaces].type = $1.mask;
+                                  Config->allprocs[num_procs].ifc[procs_interfaces].type = $1.mask;
                           procs_interfaces++;
 			}
 		;

Modified: trunk/daemon/configuration.c
===================================================================
--- trunk/daemon/configuration.c	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/configuration.c	2012-05-03 19:02:36 UTC (rev 523)
@@ -110,14 +110,10 @@
 static  bool    Conf_Reload_State = FALSE;
 static  bool    Conf_Reload_Singleton_State = FALSE;
 static  configuration *Config_Previous;
-static  proc    *Config_Previous_Procs;
 static  char    Conf_FileName[80];
 static  char    Conf_MyName_buf[80];
 static  char    *Conf_MyName;
 
-static  int	Conf_prev_proc_by_id( int32u id, proc *p );
-static  void    Conf_config_copy( configuration *src_conf, configuration *dst_conf, proc *src_procs, proc *dst_procs);
-
 /* Hash function for string to 32 bit int */
 static LOC_INLINE int32u conf_hash_string(const void * key, int32u key_len)
 {
@@ -143,6 +139,7 @@
 
 void	Conf_init( char *file_name, char *my_name )
 {
+        proc *config_procs;
         strncpy(Conf_FileName, file_name, 80);
         if (my_name != NULL) {
                 strncpy(Conf_MyName_buf, my_name, 80);
@@ -155,11 +152,13 @@
         if (Config == NULL) {
                 Alarmp( SPLOG_FATAL, CONF_SYS, "Conf_init: Failed to allocate memory for configuration structure\n");
         }
-        Config_procs = Mem_alloc( MAX_PROCS_RING * sizeof( proc ) );
-        if (Config_procs == NULL) {
+        config_procs = Mem_alloc( MAX_PROCS_RING * sizeof( proc ) );
+        if (config_procs == NULL) {
                 Alarmp( SPLOG_FATAL, CONF_SYS, "Conf_init: Failed to allocate memory for configuration procs array\n");
         }
 
+        Config->allprocs = config_procs;
+
         Conf_load_conf_file( file_name, my_name);
 }
 
@@ -218,19 +217,16 @@
         proc    np, op;
         int     i, pi;
 
-        Config_Previous = Config;
-        Config_Previous_Procs = Config_procs;
-
         Config_Previous = Mem_alloc( sizeof( configuration ) );
         if (Config_Previous == NULL) {
                 Alarmp( SPLOG_FATAL, CONF_SYS, "Conf_reload_initiate: Failed to allocate memory for old configuration structure\n");
         }
-        Config_Previous_Procs = Mem_alloc( MAX_PROCS_RING * sizeof( proc ) );
-        if (Config_Previous_Procs == NULL) {
+        Config_Previous->allprocs = Mem_alloc( MAX_PROCS_RING * sizeof( proc ) );
+        if (Config_Previous->allprocs == NULL) {
                 Alarmp( SPLOG_FATAL, CONF_SYS, "Conf_reload_initiate: Failed to allocate memory for old configuration procs array\n");
         }
 
-        Conf_config_copy( Config, Config_Previous, Config_procs, Config_Previous_Procs );
+        Conf_config_copy( Config, Config_Previous);
 
         Conf_load_conf_file( Conf_FileName, Conf_MyName );
 
@@ -243,7 +239,7 @@
                 /* I am no longer in config */
                 Alarmp(SPLOG_FATAL, CONF_SYS, "Conf_reload_initiate: I (%d.%d.%d.%d) am no longer in config, so exiting.\n", IP1(My.id), IP2(My.id), IP3(My.id), IP4(My.id));
         }
-        if ( Conf_prev_proc_by_id( My.id, &op ) < 0 ) {
+        if ( Conf_proc_by_id_in_conf( Config_Previous, My.id, &op ) < 0 ) {
                 Alarmp(SPLOG_FATAL, CONF_SYS, "Conf_reload_initiate: BUG! I (%d.%d.%d.%d) am not in previous config, so exiting.\n", IP1(My.id), IP2(My.id), IP3(My.id), IP4(My.id));
         } 
 
@@ -266,8 +262,8 @@
         /* Check if only new configuration contains only additions and subtractions of daemons and no changes */
 	for ( pi=0; pi < Config->num_total_procs; pi++ )
 	{
-                np = Config_procs[pi];
-                if ( Conf_prev_proc_by_id( np.id, &op ) < 0 ) {
+                np = Config->allprocs[pi];
+                if ( Conf_proc_by_id_in_conf( Config_Previous, np.id, &op ) < 0 ) {
                         Alarmp( SPLOG_INFO, CONF_SYS, "Conf_reload_initiate: Config Added daemon at %d.%d.%d.%d \n", IP1(np.id), IP2(np.id), IP3(np.id), IP4(np.id));
                 } else {
                         /* compare proc entries to check if identical */
@@ -292,11 +288,10 @@
 	} /* for */
 
         /* free old config structs and arrays since they will never be used again */
+        dispose( Config_Previous->allprocs );
         dispose( Config_Previous );
-        dispose( Config_Previous_Procs );
 
         Config_Previous = NULL;
-        Config_Previous_Procs = NULL;
         
         Alarmp( SPLOG_DEBUG, CONF_SYS, "Conf_reload_initiate: Return need_partition = %d\n", need_partition);
         return(need_partition);
@@ -354,7 +349,7 @@
         ConfStringRep[0] = '\0';
         ConfStringLen = 0;
 
-	/* init Config, Config_procs from file
+	/* init Config from file
 	   init My from host
 	 */
         configfile_location[0] = '\0';
@@ -505,15 +500,25 @@
 
 int	Conf_proc_by_id( int32u id, proc *p )
 {
+        return( Conf_proc_by_id_in_conf( Config, id, p ));
+}
+
+int 	Conf_proc_by_name( char *name, proc *p )
+{
+        return( Conf_proc_by_name_in_conf( Config, name, p));
+}
+
+int	Conf_proc_by_id_in_conf( configuration *config, int32u id, proc *p )
+{
 	int	i,j;
 
-	for ( i=0; i < Config->num_total_procs; i++ )
+	for ( i=0; i < config->num_total_procs; i++ )
 	{
-                for ( j=0; j < Config_procs[i].num_if; j++)
+                for ( j=0; j < config->allprocs[i].num_if; j++)
                 {
-                        if ( Config_procs[i].ifc[j].ip == id )
+                        if ( config->allprocs[i].ifc[j].ip == id )
                         {
-                                *p =  Config_procs[i] ;
+                                *p =  config->allprocs[i] ;
                                 return( i );
                         }
                 }
@@ -521,21 +526,22 @@
 	return( -1 );
 }
 
-int 	Conf_proc_by_name( char *name, proc *p )
+int 	Conf_proc_by_name_in_conf( configuration *config, char *name, proc *p )
 {
 	int	i;
 
-	for ( i=0; i < Config->num_total_procs; i++ )
+	for ( i=0; i < config->num_total_procs; i++ )
 	{
-		if ( strcmp( Config_procs[i].name, name ) == 0 )
+		if ( strcmp( config->allprocs[i].name, name ) == 0 )
 		{
-			*p = Config_procs[i];
+			*p = config->allprocs[i];
 			return( i );
 		}
 	}
 	return( -1 );
 }
 
+
 int	Conf_id_in_seg( segment *seg, int32u id )
 {
 	int 	i,j;
@@ -550,41 +556,31 @@
 	}
 	return( -1 );
 }
-static  int     Conf_config_lookup_id( configuration *conf, proc *procs, int32u id)
-{
-	int	i,j;
 
-	for ( i=0; i < conf->num_total_procs; i++ )
-	{
-                for ( j=0; j < procs[i].num_if; j++)
-                {
-                        if ( procs[i].ifc[j].ip == id )
-                        {
-                                return( i );
-                        }
-                }
-	}
-	return( -1 );
-}
-
-static  void    Conf_config_copy( configuration *src_conf, configuration *dst_conf, proc *src_procs, proc *dst_procs)
+void    Conf_config_copy( configuration *src_conf, configuration *dst_conf)
 {
     int i,j,p_index;
+    proc p;
 
-    *dst_conf = *src_conf;
+    dst_conf->hash_code = src_conf->hash_code;
+    dst_conf->num_segments = src_conf->num_segments;
+    dst_conf->num_total_procs = src_conf->num_total_procs;
 
     for (i=0; i < src_conf->num_total_procs; i++ )
     {
-        dst_procs[i] = src_procs[i];
+        memcpy( &dst_conf->allprocs[i], &src_conf->allprocs[i], sizeof( proc ) );
     }
 
     for (i=0; i < src_conf->num_segments; i++ )
     {
+        dst_conf->segments[i].bcast_address = src_conf->segments[i].bcast_address;
+        dst_conf->segments[i].port = src_conf->segments[i].port;
+        dst_conf->segments[i].num_procs = src_conf->segments[i].num_procs;
         for ( j=0; j < src_conf->segments[i].num_procs; j++ )
         {
-            p_index = Conf_config_lookup_id(dst_conf, dst_procs, src_conf->segments[i].procs[j]->id);
+            p_index = Conf_proc_by_id_in_conf(dst_conf, src_conf->segments[i].procs[j]->id, &p);
             assert(p_index != -1);
-            dst_conf->segments[i].procs[j] = &dst_procs[p_index];
+            dst_conf->segments[i].procs[j] = &(dst_conf->allprocs[p_index]);
         }
     }        
 
@@ -606,11 +602,11 @@
 
 	for ( i=0; i < Config->num_total_procs; i++ )
 	{
-                for ( j=0; j < Config_procs[i].num_if; j++)
+                for ( j=0; j < Config->allprocs[i].num_if; j++)
                 {
-                        if ( Config_procs[i].ifc[j].ip == id )
+                        if ( Config->allprocs[i].ifc[j].ip == id )
                         {
-                                *p = &Config_procs[i];
+                                *p = &Config->allprocs[i];
                                 return( i );
                         }
                 }
@@ -618,24 +614,6 @@
 	return( -1 );
 }
 
-static  int	Conf_prev_proc_by_id( int32u id, proc *p )
-{
-	int	i,j;
-
-	for ( i=0; i < Config_Previous->num_total_procs; i++ )
-	{
-                for ( j=0; j < Config_Previous_Procs[i].num_if; j++)
-                {
-                        if ( Config_Previous_Procs[i].ifc[j].ip == id )
-                        {
-                                *p =  Config_Previous_Procs[i] ;
-                                return( i );
-                        }
-                }
-	}
-	return( -1 );
-}
-
 int     Conf_append_id_to_seg( segment *seg, int32u id)
 {
         proc *p;
@@ -766,10 +744,30 @@
 			Alarm( PRINT, "\t\t%-20s\t%-16s\n", pr.name, ip );
 		}
 	}
-	Alarm( PRINT, "====================" );
+	Alarm( PRINT, "====================\n" );
 	return( '\n' );
 }
 
+
+char	Conf_print_procs(configuration *config)
+{
+	int 	i;
+	char	ip[16];
+
+	Alarm( PRINT, "--------------------\n" );
+	Alarm( PRINT, "Configured Procs\n");
+	Alarm( PRINT, "Total Num %d\n",config->num_total_procs );
+	for ( i=0; i < config->num_total_procs; i++ )
+	{
+                Conf_id_to_str( config->allprocs[i].id, ip );
+                Alarm( PRINT, "\t%s:%d\tID: %-16s NumIF: %d\n",
+                       config->allprocs[i].name, config->allprocs[i].port,
+                       ip, config->allprocs[i].num_if);
+        }
+	Alarm( PRINT, "====================\n" );
+	return( '\n' );
+}
+
 bool    Conf_get_dangerous_monitor_state(void)
 {
         return(EnableDangerousMonitor);

Modified: trunk/daemon/configuration.h
===================================================================
--- trunk/daemon/configuration.h	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/configuration.h	2012-05-03 19:02:36 UTC (rev 523)
@@ -81,6 +81,7 @@
         int32u  hash_code;
 	int	num_segments;
         int     num_total_procs;
+        proc    *allprocs;
 	segment	segments[MAX_SEGMENTS];
 } configuration;
 
@@ -92,11 +93,14 @@
 
 void		Conf_init( char *file_name, char *my_name );
 void	        Conf_load_conf_file( char *file_name, char *my_name );
+void            Conf_config_copy( configuration *src_conf, configuration *dst_conf);
 configuration	Conf(void);
 configuration   *Conf_ref(void);
 proc		Conf_my(void);
 int		Conf_proc_by_id( int32u id, proc *p );
 int		Conf_proc_by_name( char *name, proc *p );
+int		Conf_proc_by_id_in_conf( configuration *config, int32u id, proc *p );
+int		Conf_proc_by_name_in_conf( configuration *config, char *name, proc *p );
 int		Conf_id_in_seg( segment *seg, int32u id );	
 int		Conf_id_in_conf( configuration *config, int32u id );	
 int		Conf_num_procs( configuration *config );
@@ -109,6 +113,7 @@
 int	        Conf_num_procs_in_seg( configuration *config, int16 seg_index );
 void		Conf_id_to_str( int32u id, char *str );
 char 		Conf_print(configuration *config);
+char	        Conf_print_procs(configuration *config);
 
 bool            Conf_in_reload_state(void);
 void            Conf_reload_state_begin(void);

Modified: trunk/daemon/groups.c
===================================================================
--- trunk/daemon/groups.c	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/groups.c	2012-05-03 19:02:36 UTC (rev 523)
@@ -107,6 +107,8 @@
   return grp->name;
 }
 
+static  configuration   Cn_active;
+static  configuration   Cn_interim;
 static	int		Gstate;
 static	configuration	Trans_memb;
 static	membership_id	Trans_memb_id;
@@ -172,8 +174,9 @@
 static  void            G_remove_group( group *grp );
 static  void            G_remove_mailbox( group *grp, mailbox m );
 
-static  int             G_compare_cstrptr(const void *, const void *);
+static  int             G_compare_nameptr(const void *, const void *);
 static  int             G_compare_proc_ids_by_conf( const void *, const void * );
+static  int             G_compare_proc_ids_by_conf_internal( configuration *config, const void *a, const void *b);
 static  int             G_compare_daemon_vs_set( const void *, const void * );
 
 static  int             G_compare_memb_ids( const membership_id *mid1,
@@ -181,21 +184,59 @@
 
 static  void            G_shift_to_GOP( void );
 
-static int G_compare_cstrptr(const void *a, const void *b)
+static int G_compare_nameptr(const void *a, const void *b)
 {
-  return strcmp(*(const char**) a, *(const char**) b);
+  return strncmp(*(const char**) a, *(const char**) b, MAX_GROUP_NAME);
 }
 
 static int G_compare_proc_ids_by_conf(const void *a, const void *b)
 {
+    return G_compare_proc_ids_by_conf_internal( &Cn_active, a, b);
+}
+
+static int G_compare_proc_ids_by_conf_interim(const void *a, const void *b)
+{
+    return G_compare_proc_ids_by_conf_internal( &Cn_interim, a, b);
+}
+
+/* Compare two procs based on the specified configuration structure
+ * The ordering is defined by the order the procs occur in the configuration. 
+ * If a proc is no longer in the active configuration, it is ordered after all active procs
+ * based on it's IP address.
+ */
+static int G_compare_proc_ids_by_conf_internal( configuration *config, const void *a, const void *b)
+{
   proc dummy_proc;
-  int  ia = Conf_proc_by_id( **(const int32**) a, &dummy_proc );
-  int  ib = Conf_proc_by_id( **(const int32**) b, &dummy_proc );
+  const int32u aip = **(const int32u**)a;
+  const int32u bip = **(const int32u**)b;
 
-  assert( ia > -1 );
-  assert( ib > -1 );
+  int  ia = Conf_proc_by_id_in_conf( config, aip, &dummy_proc );
+  int  ib = Conf_proc_by_id_in_conf( config, bip, &dummy_proc );
 
-  return ia - ib;
+  /* common case */
+  if (ia > -1 && ib > -1) {
+      /* both are active */
+      return ia - ib;
+  }
+  if (ia < 0 && ib < 0 ) {
+      /* both not active so compare IP addresses */
+      if (aip == bip)
+          return 0;
+      else 
+          if ( aip < bip )
+              return -1;
+          else  
+              return 1;
+
+  } else  
+      if (ia < 0)
+          return 1;
+      else
+          if (ib < 0)
+              return -1;
+          else
+              /* dup rule for all are active to keep compiler happy */
+              return ia - ib;
 }
 
 static int G_compare_daemon_vs_set(const void *a, const void *b)
@@ -255,7 +296,12 @@
         MySyncedSet.proc_ids[0] = My.id;
         G_print_synced_set( SPLOG_INFO, &MySyncedSet, "G_init" );
 
-	ret = stdskl_construct(&GroupsList, sizeof(group*), 0, G_compare_cstrptr);
+        Cn_active.allprocs = Mem_alloc( MAX_PROCS_RING * sizeof( proc ) );
+        if (Cn_active.allprocs == NULL) {
+                Alarmp( SPLOG_FATAL, GROUPS, "G_init: Failed to allocate memory for Cn_active procs array\n");
+        }
+
+	ret = stdskl_construct(&GroupsList, sizeof(group*), 0, G_compare_nameptr);
 	if (ret != 0) {
                 Alarmp( SPLOG_FATAL, GROUPS, "G_init: Failure to Initialize GroupsList\n");
 	}
@@ -298,9 +344,180 @@
         Gathered.complete    = 0;
 	Gathered.next        = NULL;
 
+        Conf_config_copy( Conf_ref(), &Cn_active );
+
         G_shift_to_GOP();
 }
 
+
+/* 
+ * Called from Prot_initiate_conf_reload after configuration file is reloaded (potentially with changes to spread configuration)
+ * Needs to update any static-scope variables that depend on current configuration
+ *
+  Algorithm to clean up existing DaemonList skiplists that are stored for every group. 
+  Each skiplist needs to be reformed with a different comparison function using the new Config structure.
+  Once they are all reformed, we need to move the temporary daemon lists back into the main GroupsList structure entries.
+
+  Steps:
+  1) 
+    make new grp skiplist to store temporary copies of all of the daemon lists.
+    loop over all grps:
+      copy damon list from current skiplist to new skiplist with comparison function (G_compare_proc_ids_by_conf_interim) that uses the new config structure. This maintains the daemon_members in each entry, but inserts them into a new skiplist in a new order based on the new configuration. 
+      store new skiplist in the new grp list so we can store all of them with new structures before destroying them all and switching the active Conf
+    end
+  2)
+    loop over all grps:
+      destruct the current daemonlist for all groups
+    end
+  3)
+    Set Config variable to point to new config (old config no longer available)
+  4) 
+    loop over all grps:
+      create new daemon skiplsit for each group with normal comparison function (will effectively use new config now)
+      get begin and end iterators for temp daemon skiplist with stdstk_begin() and stdskl_end()
+      call stdstk_insert_seq() to insert contents of temp skiplist into new permantent skiplist
+      destrcut temp skiplist
+    end
+    destruct temp grp skiplist.
+
+ At the end of this function (which runs atomically with regards to any other groups functions):
+  - all of the skiplists with daemons in them will be valid with the new Conf structure and can find the 'old' daemons. 
+  - There are no changes to the handling of the groups membership code that runs when the ring is reformed as it can correctly remove the daemons when it thinks it should beauase they are correctly indexed and sorted in the skiplist. 
+
+ */
+
+void    G_signal_conf_reload(void)
+{
+    int                 ret;
+    group		*grp, *tmp_grp;
+    daemon_members      *dmn;
+    stdit               git, dit;
+    stdskl              tmp_GroupsList;
+
+    ret = stdskl_construct(&tmp_GroupsList, sizeof(group*), 0, G_compare_nameptr);
+    if (ret != 0) {
+        Alarmp( SPLOG_FATAL, GROUPS, "G_init: Failure to Initialize GroupsList\n");
+    }
+
+    /* 
+     0) Get copy of new configuration to use while we still have old config also.
+        A shallow copy is fine as:
+         - we want the current Conf(), 
+         - do not need our own copy of allprocs,
+         - and only need it valid for this function call.
+    */
+
+    Cn_interim = Conf();
+
+    /* 
+     1) 
+      loop over all grps:
+        copy damon list from current skiplist to new skiplist with new config as comparison fucntion 
+        store new skiplist in the new grp list.
+      end
+    */
+    for (stdskl_begin(&GroupsList, &git); !stdskl_is_end(&GroupsList, &git); ) 
+    {
+        grp = *(group**) stdskl_it_key(&git);
+        stdskl_it_next(&git);  /* NOTE: need to do advancement before potential erasure below */
+        
+        tmp_grp = new( GROUP );
+        memset( tmp_grp->name, 0, MAX_GROUP_NAME );
+        strcpy( tmp_grp->name, grp->name );
+
+        if (stdskl_construct(&tmp_grp->DaemonsList, sizeof(daemon_members*), 0, G_compare_proc_ids_by_conf_interim) != 0) {
+            Alarmp( SPLOG_FATAL, GROUPS, "%s: %d: memory allocation failed\n", __FILE__, __LINE__ );
+        }
+        tmp_grp->changed     = FALSE;
+        tmp_grp->num_members = 0;
+        tmp_grp->grp_id = grp->grp_id;
+
+        if (stdskl_put(&tmp_GroupsList, NULL, &tmp_grp, NULL, STDFALSE) != 0) {
+            Alarmp( SPLOG_FATAL, GROUPS, "%s: %d: memory allocation failed\n", __FILE__, __LINE__ );
+        }
+
+        for (stdskl_begin(&grp->DaemonsList, &dit); !stdskl_is_end(&grp->DaemonsList, &dit); ) 
+        {
+            dmn = *(daemon_members**) stdskl_it_key(&dit);
+            stdskl_it_next(&dit);  /* NOTE: need to do advancement before potential erasure below */
+            
+            /* insert this dmn into the new skiplist */
+            if (stdskl_put(&tmp_grp->DaemonsList, NULL, &dmn, NULL, STDFALSE) != 0) {
+                Alarmp( SPLOG_FATAL, GROUPS, "%s: %d: memory allocation failed\n", __FILE__, __LINE__ );
+            }
+        }
+
+    }
+    /*
+      2) 
+      loop over all grps:
+        destruct the current daemonlist
+      end
+    */
+    for (stdskl_begin(&GroupsList, &git); !stdskl_is_end(&GroupsList, &git); ) 
+    {
+        grp = *(group**) stdskl_it_key(&git);
+        stdskl_it_next(&git);  /* NOTE: need to do advancement before potential erasure below */
+        
+        stdskl_destruct( &grp->DaemonsList);
+    }
+
+    /* 3) 
+       Set Cn_active variable to point to new config (old config no longer available) 
+       This has to be a deep copy because it must preserve all of the procs array when the configuration is next reloaded 
+       and the configuration.c version of Conf changes. 
+     */
+    Conf_config_copy( Conf_ref(), &Cn_active );
+
+    /* 4)
+       loop over all grps:
+         create new daemon skiplsit for each group with normal comparison function (will effectively use new config now)
+         get begin and end iterators for temp daemon skiplist with stdstk_begin() and stdskl_end()
+         call stdstk_insert_seq() to insert contents of temp skiplist into new permantent skiplist
+         destruct temp skiplist
+         free temp grp structure
+       end
+       destruct temp grp skiplist.
+     */
+
+    for (stdskl_begin(&GroupsList, &git); !stdskl_is_end(&GroupsList, &git); ) 
+    {
+        stdit bskl, eskl, it;
+        
+        grp = *(group**) stdskl_it_key(&git);
+        stdskl_it_next(&git);  /* NOTE: need to do advancement before potential erasure below */
+
+        if (stdskl_construct(&grp->DaemonsList, sizeof(daemon_members*), 0, G_compare_proc_ids_by_conf) != 0) {
+            Alarmp( SPLOG_FATAL, GROUPS, "%s: %d: memory allocation failed\n", __FILE__, __LINE__ );
+        }
+
+        /* find tmp_grp corresponding to grp */
+        stdskl_find(&tmp_GroupsList, &it, &grp);
+        if (stdskl_is_end(&tmp_GroupsList, &it)) {
+            Alarmp( SPLOG_FATAL, GROUPS, "G_signal_conf_reload: failed to find group (%s) in tmp_GroupsList\n", grp->name);
+        }
+        tmp_grp = *(group**) stdskl_it_key(&it);
+
+        stdskl_begin(&tmp_grp->DaemonsList, &bskl);
+        stdskl_end(&tmp_grp->DaemonsList, &eskl);
+        stdskl_begin(&grp->DaemonsList, &dit);
+        /* Insert entire tmp_grp->DaemonsList (from begin to last) into grp->DaemonsList */
+        stdskl_insert_seq(&grp->DaemonsList, &dit, &bskl, &eskl, STDTRUE);
+
+        /* destroy interim DaemonList since we are done with it */
+	stdskl_erase(&tmp_GroupsList, &it);
+        stdskl_destruct( &tmp_grp->DaemonsList);
+	dispose(tmp_grp);
+    }
+
+    if ( ! stdskl_empty( &tmp_GroupsList) ) {
+        Alarmp( SPLOG_FATAL, GROUPS, "G_signal_conf_reload: About to destroy temporary GroupsList but it isn't empty.\n");
+    }
+    stdskl_destruct( &tmp_GroupsList );
+
+}
+
+
 void	G_handle_reg_memb( configuration reg_memb, membership_id reg_memb_id )
 {
 	group		    *grp;
@@ -788,7 +1005,7 @@
                         new_dmn = new( DAEMON_MEMBERS );
                         new_dmn->proc_id = new_p.id;
 
-			if (stdskl_construct(&new_dmn->MembersList, sizeof(member*), 0, G_compare_cstrptr) != 0) {
+			if (stdskl_construct(&new_dmn->MembersList, sizeof(member*), 0, G_compare_nameptr) != 0) {
 			  Alarmp( SPLOG_FATAL, GROUPS, "%s: %d: memory allocation failed\n", __FILE__, __LINE__ );
 			}
 
@@ -2214,7 +2431,7 @@
                                 ip_string, dmn->memb_id.time );
                         Alarmp( SPLOG_DEBUG, GROUPS, "G_mess_to_groups: \t\twith %u members:\n", num_memb );
 
-			if (stdskl_construct(&dmn->MembersList, sizeof(member*), 0, G_compare_cstrptr) != 0) {
+			if (stdskl_construct(&dmn->MembersList, sizeof(member*), 0, G_compare_nameptr) != 0) {
 			  Alarmp( SPLOG_FATAL, GROUPS, "%s: %d: memory allocation failed\n", __FILE__, __LINE__ );
 			}
 

Modified: trunk/daemon/groups.h
===================================================================
--- trunk/daemon/groups.h	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/groups.h	2012-05-03 19:02:36 UTC (rev 523)
@@ -55,6 +55,7 @@
                                  / MAX_GROUP_NAME )
 
 void	G_init(void);
+void    G_signal_conf_reload(void);
 
 void	G_handle_reg_memb( configuration reg_memb, membership_id reg_memb_id );
 void	G_handle_trans_memb( configuration trans_memb,

Modified: trunk/daemon/network.c
===================================================================
--- trunk/daemon/network.c	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/network.c	2012-05-03 19:02:36 UTC (rev 523)
@@ -140,7 +140,7 @@
                                     bcast_bound = TRUE;
                                 }
                         }
-                        Bcast_channel[Num_bcast_channels++] = DL_init_channel( RECV_CHANNEL, My.port, Bcast_address, interface_addr );
+                        Bcast_channel[Num_bcast_channels++] = DL_init_channel( RECV_CHANNEL | DL_BIND_ALL, My.port, Bcast_address, interface_addr );
                         Token_channel[Num_token_channels++] = DL_init_channel( RECV_CHANNEL, My.port+1, 0, interface_addr );
                 }
         }

Modified: trunk/daemon/protocol.c
===================================================================
--- trunk/daemon/protocol.c	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/protocol.c	2012-05-03 19:02:36 UTC (rev 523)
@@ -754,6 +754,7 @@
         /* Signal all subsystems to update Conf and My strucures */
         Net_signal_conf_reload();
         Memb_signal_conf_reload();
+        /* Note: the Sess_signal also calls G_signal_conf_reload() */
         Sess_signal_conf_reload();
 
         /* update protocol varialbes with new conf */

Modified: trunk/daemon/session.c
===================================================================
--- trunk/daemon/session.c	2012-05-03 16:21:58 UTC (rev 522)
+++ trunk/daemon/session.c	2012-05-03 19:02:36 UTC (rev 523)
@@ -441,6 +441,8 @@
 void    Sess_signal_conf_reload(void)
 {
         My = Conf_my();
+
+        G_signal_conf_reload();
 }
 
 void	Sess_set_active_threshold()




More information about the Spread-cvs mailing list