[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