[Openais] lcr take 6 - going in soon - last chance for comments :)

Steven Dake sdake at mvista.com
Wed Jan 25 11:05:45 PST 2006


Patrick
Your patch looks great

I will apply it after we finish the extraction of conn_info from the
service handlers which should be in the next few days

regards
-steve

On Wed, 2006-01-25 at 16:04 +0000, Patrick Caulfield wrote:
> Steven Dake wrote:
> > 
> > Yes I want to do this - just have not got there yet.  What I had
> > intended is for "uic" to send a message to "uis" to load a service
> > handler.  uis on startup creates a thread to listen to socket I/Os from
> > uic.  Then code in the UIS handler would dynamically load the service
> > handler.
> > 
> > So the command would look something like
> > "passthrough load service "servicename" and then the interface loader
> > would try to load the service and instantiate it.
> > 
> > This should work for already running aisexecs.
> > 
> > I don't really want to have to change the lcr code much to achieve these
> > results so scanning all lcrsos for their interface names doesn't work.
> > I want to "dynamicize" all of the code, not just the service handlers.
> > And The intent is that others could use the lcrsos in their own program
> > designs.  The purpose of the lcr then is to live-replace, not dynamic
> > loading (we just get that for free:)
> > 
> > Another option you mention which I like is to extract the "dynamic
> > services" data structure into a configuration file which lists all of
> > the services and their version numbers that should be loaded at startup.
> > This would then populate the dynamic services data structure.
> > 
> > If you want to make a patch for that I'd like it :)
> 
> Attached.
> 
> I've also added a config_init_fn to allow components to affect the
> configuration of the daemon. Only CMAN currently uses this but it paves the
> way for other plugin configurators. The normal config file will be used if no
> interfaces have been set by the components.
> 
> Of course there's a chicken-and-egg situation here in that you need to add
> configurators via the config file so you still need a config file! but there
> are still things read from openais.conf that precede all module loading anyway!
> 
> components can be added to the /etc/ais/openais.conf like this:
> 
> components {
>         openais_evs:0
>         openais_clm:0
>         openais_amf:0
>         openais_ckpt:0
>         openais_evt:0
>         openais_lck:0
>         openais_msg:0
>         openais_cfg:0
> }
> 
> where 0 is the version. If none are specified then the defaults (above) are
> used, otherwise the config file should specify all components to be used
> 
> plain text document attachment (dyn-patch)
> Index: exec/handlers.h
> ===================================================================
> --- exec/handlers.h	(revision 905)
> +++ exec/handlers.h	(working copy)
> @@ -69,6 +69,7 @@
>  	int lib_handlers_count;
>  	struct openais_exec_handler *exec_handlers;
>  	int (*exec_init_fn) (struct openais_config *);
> +	int (*config_init_fn) (struct openais_config *);
>  	void (*exec_dump_fn) (void);
>  	int exec_handlers_count;
>  	void (*confchg_fn) (
> Index: exec/mainconfig.c
> ===================================================================
> --- exec/mainconfig.c	(revision 905)
> +++ exec/mainconfig.c	(working copy)
> @@ -56,7 +56,8 @@
>  	MAIN_HEAD,
>  	MAIN_LOGGING,
>  	MAIN_EVENT,
> -	MAIN_AMF
> +	MAIN_AMF,
> +	MAIN_COMPONENTS
>  } main_parse_t;
>  
>  char *strstr_rs (const char *haystack, const char *needle)
> @@ -87,6 +88,55 @@
>  	return (end_address);
>  }
>  
> +#ifdef BUILD_DYNAMIC
> +static void set_default_services(struct openais_config *config)
> +{
> +	config->dynamic_services[0].name = "openais_evs";
> +	config->dynamic_services[0].ver = 0;
> +	config->dynamic_services[1].name = "openais_clm";
> +	config->dynamic_services[1].ver = 0;
> +	config->dynamic_services[2].name = "openais_amf";
> +	config->dynamic_services[2].ver = 0;
> +	config->dynamic_services[3].name = "openais_ckpt";
> +	config->dynamic_services[3].ver = 0;
> +	config->dynamic_services[4].name = "openais_evt";
> +	config->dynamic_services[4].ver = 0;
> +	config->dynamic_services[5].name = "openais_lck";
> +	config->dynamic_services[5].ver = 0;
> +	config->dynamic_services[6].name = "openais_msg";
> +	config->dynamic_services[6].ver = 0;
> +	config->dynamic_services[7].name = "openais_cfg";
> +	config->dynamic_services[7].ver = 0;
> +	config->num_dynamic_services = 8;
> +}
> +
> +/* Returns an allocated string */
> +static char *get_component(const char *line, int *version)
> +{
> +	char *start_address;
> +	char *end_address;
> +	char *newline;
> +	char *compname;
> +
> +	newline = strdup(line);
> +
> +	start_address = newline + strspn(newline, " \t");
> +	end_address = start_address + strcspn(start_address, " \t:");
> +
> +	*end_address = '\0';
> +	compname = strdup(start_address);
> +
> +	/* Now get version */
> +	start_address = end_address+1;
> +	start_address = start_address + strspn(start_address, " \t:");
> +
> +	*version = atoi(start_address);
> +	free(newline);
> +
> +	return compname;
> +}
> +#endif
> +
>  extern int openais_main_config_read (char **error_string,
>      struct openais_config *openais_config,
>  	int interface_max)
> @@ -97,6 +147,7 @@
>  	int logging_parsed = 0;
>  	int event_parsed = 0;
>  	int amf_parsed = 0;
> +	int components_parsed = 0;
>  	char *loc;
>  	int i;
>  	int parse_done = 0;
> @@ -147,6 +198,10 @@
>  			if (amf_parsed == 0 && strstr_rs (line, "amf{")) {
>  				amf_parsed = 1;
>  				parse = MAIN_AMF;
> +			} else
> +			if (components_parsed == 0 && strstr_rs (line, "components{")) {
> +				components_parsed = 1;
> +				parse = MAIN_COMPONENTS;
>  			} else {
>  				continue;
>  			}
> @@ -225,10 +280,25 @@
>  				goto parse_error;
>  			}
>  			break;
> -
> +		case MAIN_COMPONENTS:
> +			if ((loc = strstr_rs (line, "}"))) {
> +				parse = MAIN_HEAD;
> +			}
> +#ifdef BUILD_DYNAMIC
> +			else {
> +				int version;
> +				char *name = get_component(line, &version);
> +				if (name) {
> +					openais_config->dynamic_services[openais_config->num_dynamic_services].name = name;
> +					openais_config->dynamic_services[openais_config->num_dynamic_services].ver = version;
> +					openais_config->num_dynamic_services++;
> +				}
> +			}
> +#endif
> +			break;
>  		default:
>  			assert (0 == 1); /* SHOULDN'T HAPPEN */
> -			break;	
> +			break;
>  		}
>  	}
>  
> @@ -237,6 +307,12 @@
>  		goto parse_error;
>  	}
>  
> +#ifdef BUILD_DYNAMIC
> +	/* Load default services if the config file doesn't specify */
> +	if (!openais_config->num_dynamic_services) {
> +		set_default_services(openais_config);
> +	}
> +#endif
>  	if (parse == MAIN_HEAD) {
>  		fclose (fp);
>  		return (0);
> Index: exec/mainconfig.h
> ===================================================================
> --- exec/mainconfig.h	(revision 905)
> +++ exec/mainconfig.h	(working copy)
> @@ -41,6 +41,19 @@
>  #ifndef MAINCONFIG_H_DEFINED
>  #define MAINCONFIG_H_DEFINED
>  
> +/*
> + * All service handlers in the AIS
> + */
> +#ifdef BUILD_DYNAMIC
> +struct dynamic_service {
> +	char *name;
> +	unsigned int ver;
> +	unsigned int handle;
> +	struct openais_service_handler_iface_ver0 *iface_ver0;
> +};
> +#define MAX_DYNAMIC_SERVICES 128
> +#endif
> +
>  struct openais_config {
>  	/*
>  	 * logging
> @@ -60,6 +73,10 @@
>  	unsigned int amf_enabled;
>  
>  	struct totem_config totem_config;
> +#ifdef BUILD_DYNAMIC
> +	struct dynamic_service dynamic_services[MAX_DYNAMIC_SERVICES];
> +	int num_dynamic_services;
> +#endif
>  };
>  
>  extern char *strstr_rs (const char *haystack, const char *needle);
> Index: exec/main.c
> ===================================================================
> --- exec/main.c	(revision 905)
> +++ exec/main.c	(working copy)
> @@ -90,72 +90,6 @@
>  int ais_uid = 0;
>  int gid_valid = 0;
>  
> -/*
> - * All service handlers in the AIS
> - */
> -#ifdef BUILD_DYNAMIC
> -struct dynamic_service {
> -	char *name;
> -	unsigned int ver;
> -	unsigned int handle;
> -	struct openais_service_handler_iface_ver0 *iface_ver0;
> -};
> -
> -/*
> - * Still need to know the name of the service interface and version number
> - */
> -struct dynamic_service dynamic_services[128] = {
> -	{
> -		.name			= "openais_evs",
> -		.ver			= 0,
> -		.handle			= 0,
> -		.iface_ver0		= NULL
> -	},
> -	{
> -		.name			= "openais_clm",
> -		.ver			= 0,
> -		.handle			= 0,
> -		.iface_ver0		= NULL
> -	},
> -	{
> -		.name			= "openais_amf",
> -		.ver			= 0,
> -		.handle			= 0,
> -		.iface_ver0		= NULL
> -	},
> -	{
> -		.name			= "openais_ckpt",
> -		.ver			= 0,
> -		.handle			= 0,
> -		.iface_ver0		= NULL
> -	},
> -	{
> -		.name			= "openais_evt",
> -		.ver			= 0,
> -		.handle			= 0,
> -		.iface_ver0		= NULL
> -	},
> -	{
> -		.name			= "openais_lck",
> -		.ver			= 0,
> -		.handle			= 0,
> -		.iface_ver0		= NULL
> -	},
> -	{
> -		.name			= "openais_msg",
> -		.ver			= 0,
> -		.handle			= 0,
> -		.iface_ver0		= NULL
> -	},
> -	{
> -		.name			= "openais_cfg",
> -		.ver			= 0,
> -		.handle			= 0,
> -		.iface_ver0		= NULL
> -	}
> -};
> -#endif /* BUILD_DYNAMIC */
> -		
>  static struct openais_service_handler *ais_service_handlers[32];
>  
>  static unsigned int service_handlers_count = 32;
> @@ -188,6 +122,7 @@
>  	AIS_DONE_MAINCONFIGREAD = -9,
>  	AIS_DONE_LOGSETUP = -10,
>  	AIS_DONE_AMFCONFIGREAD = -11,
> +	AIS_DONE_DYNAMICLOAD = -12,
>  };
>  
>  extern int openais_amf_config_read (char **error_string);
> @@ -1106,10 +1041,22 @@
>  	assert (ais_service_handlers[handler->id] == NULL);
>  	log_printf (LOG_LEVEL_NOTICE, "Registering service handler '%s'\n", handler->name);
>  	ais_service_handlers[handler->id] = handler;
> +	if (ais_service_handlers[handler->id]->config_init_fn) {
> +		res = ais_service_handlers[handler->id]->config_init_fn (config);
> +	}
> +	return (res);
> +}
> +
> +int service_handler_init (
> +	struct openais_service_handler *handler,
> +	struct openais_config *config)
> +{
> +	int res = 0;
> +	assert (ais_service_handlers[handler->id] != NULL);
> +	log_printf (LOG_LEVEL_NOTICE, "Initialising service handler '%s'\n", handler->name);
>  	if (ais_service_handlers[handler->id]->exec_init_fn) {
>  		res = ais_service_handlers[handler->id]->exec_init_fn (config);
>  	}
> -	
>  	return (res);
>  }
>  
> @@ -1118,16 +1065,20 @@
>  #ifdef BUILD_DYNAMIC
>  	int i;
>  
> -	for (i = 0; i < 8; i++) {
> +	for (i = 0; i < openais_config->num_dynamic_services; i++) {
>  		lcr_ifact_reference (
> -			&dynamic_services[i].handle,
> -			dynamic_services[i].name,
> -			dynamic_services[i].ver,
> -			(void **)&dynamic_services[i].iface_ver0,
> +			&openais_config->dynamic_services[i].handle,
> +			openais_config->dynamic_services[i].name,
> +			openais_config->dynamic_services[i].ver,
> +			(void **)&openais_config->dynamic_services[i].iface_ver0,
>  			(void *)0);
>  
> +		if (!openais_config->dynamic_services[i].iface_ver0) {
> +			log_printf(LOG_LEVEL_ERROR, "AIS Component %s did not load.\n", openais_config->dynamic_services[i].name);
> +			ais_done(AIS_DONE_DYNAMICLOAD);
> +		}
>  		service_handler_register (
> -			dynamic_services[i].iface_ver0->openais_get_service_handler_ver0(),
> +			openais_config->dynamic_services[i].iface_ver0->openais_get_service_handler_ver0(),
>  			openais_config);
>  	}
>  
> @@ -1147,6 +1098,32 @@
>  #endif /* BUILD_DYNAMIC */
>  }
>  
> +void default_services_init (struct openais_config *openais_config)
> +{
> +#ifdef BUILD_DYNAMIC
> +	int i;
> +
> +	for (i = 0; i < openais_config->num_dynamic_services; i++) {
> +		service_handler_init (openais_config->dynamic_services[i].iface_ver0->openais_get_service_handler_ver0(),
> +				      openais_config);
> +	}
> +
> +#else /* NOT BUILD_DYNAMIC */
> +	/*
> +	 * link everything together - better for debugging - smaller memory footprint
> +	 */
> +
> +	service_handler_init (&evs_service_handler, openais_config);
> +	service_handler_init (&clm_service_handler, openais_config);
> +	service_handler_init (&amf_service_handler, openais_config);
> +	service_handler_init (&ckpt_service_handler, openais_config);
> +	service_handler_init (&evt_service_handler, openais_config);
> +	service_handler_init (&lck_service_handler, openais_config);
> +	service_handler_init (&msg_service_handler, openais_config);
> +	service_handler_init (&cfg_service_handler, openais_config);
> +#endif /* BUILD_DYNAMIC */
> +}
> +
>  int main (int argc, char **argv)
>  {
>  	int libais_server_fd;
> @@ -1186,12 +1163,14 @@
>  		log_printf (LOG_LEVEL_ERROR, error_string);
>  		ais_done (AIS_DONE_AMFCONFIGREAD);
>  	}
> -	
> -	res = totem_config_read (&openais_config.totem_config, &error_string, 1);
> -	if (res == -1) {
> -		log_printf (LOG_LEVEL_NOTICE, "AIS Executive Service: Copyright (C) 2002-2004 MontaVista Software, Inc and contributors.\n");
> -		log_printf (LOG_LEVEL_ERROR, error_string);
> -		ais_done (AIS_DONE_MAINCONFIGREAD);
> +
> +	if (!openais_config.totem_config.interface_count) {
> +		res = totem_config_read (&openais_config.totem_config, &error_string, 1);
> +		if (res == -1) {
> +			log_printf (LOG_LEVEL_NOTICE, "AIS Executive Service: Copyright (C) 2002-2004 MontaVista Software, Inc and contributors.\n");
> +			log_printf (LOG_LEVEL_ERROR, error_string);
> +			ais_done (AIS_DONE_MAINCONFIGREAD);
> +		}
>  	}
>  
>  	res = totem_config_keyread ("/etc/ais/authkey", &openais_config.totem_config, &error_string);
> @@ -1232,6 +1211,8 @@
>  	openais_config.totem_config.totem_logging_configuration.log_level_debug = mklog (LOG_LEVEL_DEBUG, LOG_SERVICE_GMI);
>  	openais_config.totem_config.totem_logging_configuration.log_printf = internal_log_printf;
>  
> +	default_services_register(&openais_config); 
> +	
>  	totempg_initialize (
>  		aisexec_poll_handle,
>  		&openais_config.totem_config);
> @@ -1248,7 +1229,7 @@
>  
>  	this_ip = &openais_config.totem_config.interfaces[0].boundto;
>  
> -	default_services_register(&openais_config);
> +	default_services_init(&openais_config); 
>  
>  	sync_register (openais_sync_callbacks_retrieve, openais_sync_completed);
>  




More information about the Openais mailing list