This patch has been kicking around for trunk for some time but never
merged.

It is now being merged since it has undergone some pretty heavy
community testing with Pacemaker.

Regards
-steve
Index: test/openais-cfgtool.c
===================================================================
--- test/openais-cfgtool.c	(revision 1527)
+++ test/openais-cfgtool.c	(working copy)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Red Hat Inc
+ * Copyright (c) 2006-2007 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -98,19 +98,61 @@
 	openais_cfg_finalize (handle);
 }
 
+void service_load_do (char *service, unsigned int version)
+{
+	SaAisErrorT result;
+	openais_cfg_handle_t handle;
+
+	printf ("Loading service '%s' version '%d'\n", service, version);
+	result = openais_cfg_initialize (&handle, NULL);
+	if (result != SA_AIS_OK) {
+		printf ("Could not initialize openais configuration API error %d\n", result);
+		exit (1);
+	}
+	result = openais_cfg_service_load (handle, service, version);
+	if (result != SA_AIS_OK) {
+		printf ("Could not load service (error = %d)\n", result);
+	}
+	openais_cfg_finalize (handle);
+}
+
+void service_unload_do (char *service, unsigned int version)
+{
+	SaAisErrorT result;
+	openais_cfg_handle_t handle;
+
+	printf ("Unloading service '%s' version '%d'\n", service, version);
+	result = openais_cfg_initialize (&handle, NULL);
+	if (result != SA_AIS_OK) {
+		printf ("Could not initialize openais configuration API error %d\n", result);
+		exit (1);
+	}
+	result = openais_cfg_service_unload (handle, service, version);
+	if (result != SA_AIS_OK) {
+		printf ("Could not unload service (error = %d)\n", result);
+	}
+	openais_cfg_finalize (handle);
+}
+
 void usage_do (void)
 {
-	printf ("openais-cfgtool [-s] [-r]\n\n");
+	printf ("openais-cfgtool [-s] [-r] [-l] [-u] [service_name] [-v] [version]\n\n");
 	printf ("A tool for displaying and configuring active parameters within openais.\n");
 	printf ("options:\n");
 	printf ("\t-s\tDisplays the status of the current rings on this node.\n");
 	printf ("\t-r\tReset redundant ring state cluster wide after a fault to\n");
 	printf ("\t\tre-enable redundant ring operation.\n");
+	printf ("\t-l\tLoad a service identified by name.\n");
+	printf ("\t-u\tUnload a service identified by name.\n");
 }
 
 int main (int argc, char *argv[]) {
-	const char *options = "sr";
+	const char *options = "srl:u:v:";
 	int opt;
+	int service_load = 0;
+	int service_unload = 0;
+	char *service;
+	unsigned int version;
 
 	if (argc == 1) {
 		usage_do ();
@@ -123,8 +165,25 @@
 		case 'r':
 			ringreenable_do ();
 			break;
+		case 'l':
+			service_load = 1;
+			service = strdup (optarg);
+			break;
+		case 'u':
+			service_unload = 1;
+			service = strdup (optarg);
+			break;
+		case 'v':
+			version = atoi (optarg);
 		}
 	}
 
+	if (service_load) {
+		service_load_do (service, version);
+	} else 
+	if (service_unload) {
+		service_unload_do (service, version);
+	}
+		
 	return (0);
 }
Index: include/ipc_cfg.h
===================================================================
--- include/ipc_cfg.h	(revision 1527)
+++ include/ipc_cfg.h	(working copy)
@@ -46,6 +46,8 @@
         MESSAGE_REQ_CFG_STATETRACKSTOP = 3,
         MESSAGE_REQ_CFG_ADMINISTRATIVESTATESET = 4,
         MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET = 5,
+        MESSAGE_REQ_CFG_SERVICELOAD = 6,
+        MESSAGE_REQ_CFG_SERVICEUNLOAD = 7
 };
 
 enum res_lib_cfg_types {
@@ -55,6 +57,8 @@
         MESSAGE_RES_CFG_STATETRACKSTOP = 3,
         MESSAGE_RES_CFG_ADMINISTRATIVESTATESET = 4,
         MESSAGE_RES_CFG_ADMINISTRATIVESTATEGET = 5,
+        MESSAGE_RES_CFG_SERVICELOAD = 6,
+        MESSAGE_RES_CFG_SERVICEUNLOAD = 7
 };
 
 struct req_lib_cfg_statetrack {
@@ -116,6 +120,26 @@
 	mar_res_header_t header __attribute__((aligned(8)));
 };
 
+struct req_lib_cfg_serviceload {
+	mar_res_header_t header __attribute__((aligned(8)));
+	char *service_name[256] __attribute__((aligned(8)));
+	unsigned int service_ver;
+};
+
+struct res_lib_cfg_serviceload {
+	mar_res_header_t header __attribute__((aligned(8)));
+};
+
+struct req_lib_cfg_serviceunload {
+	mar_res_header_t header __attribute__((aligned(8)));
+	char *service_name[256] __attribute__((aligned(8)));
+	unsigned int service_ver;
+};
+
+struct res_lib_cfg_serviceunload {
+	mar_res_header_t header __attribute__((aligned(8)));
+};
+
 typedef enum {
 	AIS_AMF_ADMINISTRATIVETARGET_SERVICEUNIT = 0,
 	AIS_AMF_ADMINISTRATIVETARGET_SERVICEGROUP = 1,
Index: include/cfg.h
===================================================================
--- include/cfg.h	(revision 1527)
+++ include/cfg.h	(working copy)
@@ -140,6 +140,18 @@
 	openais_cfg_handle_t cfg_handle);
 
 SaAisErrorT
+openais_cfg_service_load (
+	openais_cfg_handle_t cfg_handle,
+	char *service_name,
+	unsigned int service_ver);
+
+SaAisErrorT
+openais_cfg_service_unload (
+	openais_cfg_handle_t cfg_handle,
+	char *service_name,
+	unsigned int service_ver);
+
+SaAisErrorT
 openais_cfg_administrative_state_get (
 	openais_cfg_handle_t cfg_handle,
 	OpenaisCfgAdministrativeTargetT administrativeTarget,
Index: exec/cfg.c
===================================================================
--- exec/cfg.c	(revision 1527)
+++ exec/cfg.c	(working copy)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2005-2006 MontaVista Software, Inc.
- * Copyright (c) 2006 Red Hat, Inc.
+ * Copyright (c) 2006-2007 Red Hat, Inc.
  * Copyright (c) 2006 Sun Microsystems, Inc.
  *
  * All rights reserved.
@@ -68,7 +68,7 @@
 #include "logsys.h"
 #include "main.h"
 
-LOGSYS_DECLARE_SUBSYS ("AMF", LOG_INFO);
+LOGSYS_DECLARE_SUBSYS ("CFG", LOG_INFO);
 
 enum cfg_message_req_types {
         MESSAGE_REQ_EXEC_CFG_RINGREENABLE = 0
@@ -115,6 +115,14 @@
 	void *conn,
 	void *msg);
 
+static void message_handler_req_lib_cfg_serviceload (
+	void *conn,
+	void *msg);
+
+static void message_handler_req_lib_cfg_serviceunload (
+	void *conn,
+	void *msg);
+
 /*
  * Service Handler Definition
  */
@@ -126,35 +134,47 @@
 		.response_id		= MESSAGE_RES_CFG_RINGSTATUSGET,
 		.flow_control		= OPENAIS_FLOW_CONTROL_REQUIRED
 	},
-	{ /* 0 */
+	{ /* 1 */
 		.lib_handler_fn		= message_handler_req_lib_cfg_ringreenable,
 		.response_size		= sizeof (struct res_lib_cfg_ringreenable),
 		.response_id		= MESSAGE_RES_CFG_RINGREENABLE,
 		.flow_control		= OPENAIS_FLOW_CONTROL_REQUIRED
 	},
-	{ /* 0 */
+	{ /* 2 */
 		.lib_handler_fn		= message_handler_req_lib_cfg_statetrack,
 		.response_size		= sizeof (struct res_lib_cfg_statetrack),
 		.response_id		= MESSAGE_RES_CFG_STATETRACKSTART,
 		.flow_control		= OPENAIS_FLOW_CONTROL_REQUIRED
 	},
-	{ /* 1 */
+	{ /* 3 */
 		.lib_handler_fn		= message_handler_req_lib_cfg_statetrackstop,
 		.response_size		= sizeof (struct res_lib_cfg_statetrackstop),
 		.response_id		= MESSAGE_RES_CFG_STATETRACKSTOP,
 		.flow_control		= OPENAIS_FLOW_CONTROL_REQUIRED
 	},
-	{ /* 2 */
+	{ /* 4 */
 		.lib_handler_fn		= message_handler_req_lib_cfg_administrativestateset,
 		.response_size		= sizeof (struct res_lib_cfg_administrativestateset),
 		.response_id		= MESSAGE_RES_CFG_ADMINISTRATIVESTATESET,
 		.flow_control		= OPENAIS_FLOW_CONTROL_NOT_REQUIRED
 	},
-	{ /* 3 */
+	{ /* 5 */
 		.lib_handler_fn		= message_handler_req_lib_cfg_administrativestateget,
 		.response_size		= sizeof (struct res_lib_cfg_administrativestateget),
 		.response_id		= MESSAGE_RES_CFG_ADMINISTRATIVESTATEGET,
 		.flow_control		= OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+	},
+	{ /* 6 */
+		.lib_handler_fn		= message_handler_req_lib_cfg_serviceload,
+		.response_size		= sizeof (struct res_lib_cfg_serviceload),
+		.response_id		= MESSAGE_RES_CFG_SERVICELOAD,
+		.flow_control		= OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+	},
+	{ /* 7 */
+		.lib_handler_fn		= message_handler_req_lib_cfg_serviceunload,
+		.response_size		= sizeof (struct res_lib_cfg_serviceunload),
+		.response_id		= MESSAGE_RES_CFG_SERVICEUNLOAD,
+		.flow_control		= OPENAIS_FLOW_CONTROL_NOT_REQUIRED
 	}
 };
 
@@ -183,6 +203,8 @@
 	.confchg_fn				= cfg_confchg_fn,
 };
 
+static struct objdb_iface_ver0 *my_objdb;
+
 /*
  * Dynamic Loader definition
  */
@@ -231,6 +253,7 @@
 
 static int cfg_exec_init_fn (struct objdb_iface_ver0 *objdb)
 {
+	my_objdb = objdb;
 	return (0);
 }
 
@@ -386,3 +409,49 @@
 	LEAVE("");
 }
 
+static void message_handler_req_lib_cfg_serviceload (
+	void *conn,
+	void *msg)
+{
+	struct req_lib_cfg_serviceload *req_lib_cfg_serviceload =
+		(struct req_lib_cfg_serviceload *)msg;
+	struct res_lib_cfg_serviceload res_lib_cfg_serviceload;
+
+	ENTER("");
+	openais_service_link_and_init (
+		my_objdb,
+		(char *)req_lib_cfg_serviceload->service_name,
+		req_lib_cfg_serviceload->service_ver);
+
+	res_lib_cfg_serviceload.header.id = MESSAGE_RES_CFG_SERVICEUNLOAD;
+	res_lib_cfg_serviceload.header.size = sizeof (struct res_lib_cfg_serviceload);
+	res_lib_cfg_serviceload.header.error = SA_AIS_OK;
+	openais_conn_send_response (
+		conn,
+		&res_lib_cfg_serviceload,
+		sizeof (struct res_lib_cfg_serviceload));
+	LEAVE("");
+}
+
+static void message_handler_req_lib_cfg_serviceunload (
+	void *conn,
+	void *msg)
+{
+	struct req_lib_cfg_serviceunload *req_lib_cfg_serviceunload =
+		(struct req_lib_cfg_serviceunload *)msg;
+	struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload;
+
+	ENTER("");
+	openais_service_unlink_and_exit (
+		my_objdb,
+		(char *)req_lib_cfg_serviceunload->service_name,
+		req_lib_cfg_serviceunload->service_ver);
+	res_lib_cfg_serviceunload.header.id = MESSAGE_RES_CFG_SERVICEUNLOAD;
+	res_lib_cfg_serviceunload.header.size = sizeof (struct res_lib_cfg_serviceunload);
+	res_lib_cfg_serviceunload.header.error = SA_AIS_OK;
+	openais_conn_send_response (
+		conn,
+		&res_lib_cfg_serviceunload,
+		sizeof (struct res_lib_cfg_serviceunload));
+	LEAVE("");
+}
Index: exec/service.c
===================================================================
--- exec/service.c	(revision 1527)
+++ exec/service.c	(working copy)
@@ -1,11 +1,10 @@
 /*
- * vi: set autoindent tabstop=4 shiftwidth=4 :
- *
  * Copyright (c) 2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2007 Red Hat, Inc.
  *
  * All rights reserved.
  *
- * Author: Steven Dake ([EMAIL PROTECTED])
+ * Author: Steven Dake ([EMAIL PROTECTED])
  *
  * This software licensed under BSD license, the text of which follows:
  *
@@ -99,54 +98,14 @@
 
 struct openais_service_handler *ais_service[SERVICE_HANDLER_MAXIMUM_COUNT];
 
-/*
- * Adds a service handler to the object database
- */
-int openais_service_objdb_add (
-	struct objdb_iface_ver0 *objdb,
-	char *name,
-	int version)
+static unsigned int default_services_requested (struct objdb_iface_ver0 *objdb)
 {
-	unsigned int object_handle;
-
-	objdb->object_create (OBJECT_PARENT_HANDLE, &object_handle,
-		"service", strlen ("service"));
-	objdb->object_key_create (object_handle, "name", strlen ("name"),
-		name, strlen (name) + 1);
-	objdb->object_key_create (object_handle, "ver", strlen ("ver"),
-		&version, sizeof (version));
-
-	return (0);
-}
-
-static int service_handler_config (
-	struct openais_service_handler *handler,
-	struct objdb_iface_ver0 *objdb)
-{
-	int res = 0;
-
-	/* Already loaded? */
-	if (ais_service[handler->id] != NULL)
-		return 0;
-
-	log_printf (LOG_LEVEL_NOTICE, "Registering service handler '%s'\n", handler->name);
-	ais_service[handler->id] = handler;
-	if (ais_service[handler->id]->config_init_fn) {
-		res = ais_service[handler->id]->config_init_fn (objdb);
-	}
-	return (res);
-}
-
-/*
- * adds the default services to the object database
- */
-int openais_service_default_objdb_set (struct objdb_iface_ver0 *objdb)
-{
-	int i;
 	unsigned int object_service_handle;
-	char *value = NULL;
+	char *value;
 
-	/* Load default services unless they have been explicitly disabled */
+	/*
+	 * Don't link default services if they have been disabled
+	 */
 	objdb->object_find_reset (OBJECT_PARENT_HANDLE);
 	if (objdb->object_find (
 		OBJECT_PARENT_HANDLE,
@@ -155,36 +114,111 @@
 		&object_service_handle) == 0) {
 
 		if ( ! objdb->object_key_get (object_service_handle,
-					      "defaultservices",
-					      strlen ("defaultservices"),
-					      (void *)&value,
-					      NULL)) {
+			"defaultservices",
+			strlen ("defaultservices"),
+			(void *)&value,
+			NULL)) {
 
 			if (value && strcmp (value, "no") == 0) {
 				return 0;
 			}
 		}
 	}
+		return (-1);
+}
 
-	for (i = 0; i < sizeof (default_services) / sizeof (struct default_service); i++) {
-		openais_service_objdb_add (objdb, default_services[i].name, default_services[i].ver);
+unsigned int openais_service_link_and_init (
+	struct objdb_iface_ver0 *objdb,
+	char *service_name,
+	unsigned int service_ver)
+{
+	struct openais_service_handler_iface_ver0 *iface_ver0;
+	void *iface_ver0_p;
+	unsigned int handle;
+	struct openais_service_handler *service;
+	unsigned int res;
+	unsigned int object_handle;
+
+	/*
+	 * reference the service interface
+	 */
+	iface_ver0_p = NULL;
+	lcr_ifact_reference (
+		&handle,
+		service_name,
+		service_ver,
+		&iface_ver0_p,
+		(void *)0);
+
+	iface_ver0 = (struct openais_service_handler_iface_ver0 *)iface_ver0_p;
+
+	if (iface_ver0 == 0) {
+		log_printf(LOG_LEVEL_ERROR, "Service failed to load '%s'.\n", service_name);
+		return (-1);
 	}
-	return (0);
+
+
+	/*
+	 * Initialize service
+	 */
+	service = iface_ver0->openais_get_service_handler_ver0();
+
+	ais_service[service->id] = service;
+	if (service->config_init_fn) {
+		res = service->config_init_fn (objdb);
+	}
+
+	if (service->exec_init_fn) {
+		res = service->exec_init_fn (objdb);
+	}
+
+	/*
+	 * Store service in object database
+	 */
+	objdb->object_create (OBJECT_PARENT_HANDLE,
+		&object_handle,
+		"service",
+		strlen ("service"));
+
+	objdb->object_key_create (object_handle,
+		"name",
+		strlen ("name"),
+		service_name,
+		strlen (service_name) + 1);
+
+	objdb->object_key_create (object_handle,
+		"ver",
+		strlen ("ver"),
+		&service_ver,
+		sizeof (service_ver));
+
+	res = objdb->object_key_create (object_handle,
+		"handle",
+		strlen ("handle"),
+		&handle,
+		sizeof (handle));
+
+	objdb->object_key_create (object_handle,
+		"service_id",
+		strlen ("service_id"),
+		&service->id,
+		sizeof (service->id));
+
+	log_printf (LOG_LEVEL_NOTICE, "Service initialized '%s'\n", service->name);
+	return (res);
 }
 
-/*
- * Links dynamic services into the executive
- */
-int openais_service_link_all (struct objdb_iface_ver0 *objdb)
+extern unsigned int openais_service_unlink_and_exit (
+	struct objdb_iface_ver0 *objdb,
+	char *service_name,
+	unsigned int service_ver)
 {
-	char *service_name;
-	char *service_ver;
 	unsigned int object_service_handle;
-	int ret;
-	unsigned int handle;
-	struct openais_service_handler_iface_ver0 *iface_ver0;
-	void *iface_ver0_p;
-	unsigned int ver_int;
+	char *found_service_name;
+	unsigned int *found_service_ver;
+	unsigned int *found_service_handle;
+	unsigned short *service_id;
+	unsigned int res;
 
 	objdb->object_find_reset (OBJECT_PARENT_HANDLE);
 	while (objdb->object_find (
@@ -196,57 +230,64 @@
 		objdb->object_key_get (object_service_handle,
 			"name",
 			strlen ("name"),
-			(void *)&service_name,
+			(void *)&found_service_name,
 			NULL);
 
-		ret = objdb->object_key_get (object_service_handle,
+		objdb->object_key_get (object_service_handle,
 			"ver",
 			strlen ("ver"),
-			(void *)&service_ver,
+			(void *)&found_service_ver,
 			NULL);
-
-		ver_int = atoi (service_ver);
-
+				
 		/*
-		 * reference the interface and register it
+		 * If service found and linked exit it
 		 */
-		iface_ver0_p = NULL;
-		lcr_ifact_reference (
-			&handle,
-			service_name,
-			ver_int,
-			&iface_ver0_p,
-			(void *)0);
+		if ((strcmp (service_name, found_service_name) == 0) &&
+			(service_ver == *found_service_ver)) {
 
-		iface_ver0 = (struct openais_service_handler_iface_ver0 *)iface_ver0_p;
+			res = objdb->object_key_get (object_service_handle,
+				"handle",
+				strlen ("handle"),
+				(void *)&found_service_handle,
+				NULL);
 
-		if (iface_ver0 == 0) {
-			log_printf(LOG_LEVEL_ERROR, "openais component %s did not load.\n", service_name);
-			openais_exit_error (AIS_DONE_DYNAMICLOAD);
-		} else {
-			log_printf(LOG_LEVEL_NOTICE, "openais component %s loaded.\n", service_name);
+			res = objdb->object_key_get (object_service_handle,
+				"service_id",
+				strlen ("service_id"),
+				(void *)&service_id,
+				NULL);
+					
+			if (ais_service[*service_id]->exec_exit_fn) {
+				ais_service[*service_id]->exec_exit_fn (objdb);
+			}
+			ais_service[*service_id] = NULL;
+
+			res = lcr_ifact_release (*found_service_handle);	
+			objdb->object_destroy (object_service_handle);
+			return (res);
 		}
-
-		service_handler_config (
-			iface_ver0->openais_get_service_handler_ver0(), objdb);
 	}
-	return (0);
+	return (-1);
 }
 
-int openais_service_init_all (int service_count,
-			      struct objdb_iface_ver0 *objdb)
+/*
+ * Links default services into the executive
+ */
+unsigned int openais_service_defaults_link_and_init (struct objdb_iface_ver0 *objdb)
 {
-	int i;
-	int res=0;
+	unsigned int i;
 
-	for (i = 0; i < service_count; i++) {
-		if (ais_service[i] && ais_service[i]->exec_init_fn) {
-			log_printf (LOG_LEVEL_NOTICE, "Initialising service handler '%s'\n", ais_service[i]->name);
-			res = ais_service[i]->exec_init_fn (objdb);
-			if (res != 0) {
-				break;
-			}
-		}
+	if (default_services_requested (objdb) == 0) {
+		return (0);
 	}
-	return (res);
+	for (i = 0;
+		i < sizeof (default_services) / sizeof (struct default_service); i++) {
+
+		openais_service_link_and_init (
+			objdb,
+			default_services[i].name,
+			default_services[i].ver);
+	}
+			
+	return (0);
 }
Index: exec/service.h
===================================================================
--- exec/service.h	(revision 1527)
+++ exec/service.h	(working copy)
@@ -1,9 +1,10 @@
 /*
  * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2007 Red Hat, Inc.
  *
  * All rights reserved.
  *
- * Author: Steven Dake ([EMAIL PROTECTED])
+ * Author: Steven Dake ([EMAIL PROTECTED])
  *
  * This software licensed under BSD license, the text of which follows:
  *
@@ -65,6 +66,7 @@
 	int lib_service_count;
 	struct openais_exec_handler *exec_service;
 	int (*exec_init_fn) (struct objdb_iface_ver0 *);
+	int (*exec_exit_fn) (struct objdb_iface_ver0 *);
 	int (*config_init_fn) (struct objdb_iface_ver0 *);
 	void (*exec_dump_fn) (void);
 	int exec_service_count;
@@ -81,28 +83,38 @@
 };
 
 struct openais_service_handler_iface_ver0 {
-	void (*test) (void);
 	struct openais_service_handler *(*openais_get_service_handler_ver0) (void);
 };
 
-extern int openais_service_objdb_add (
-	struct objdb_iface_ver0 *objdb,
-	char *name,
-	int version);
+/*
+ * Link and initialize a service
+ */
+extern unsigned int openais_service_link_and_init (
+    struct objdb_iface_ver0 *objdb,
+    char *service_name,
+    unsigned int service_ver);
 
+/*
+ * Unlink and exit a service
+ */
+extern unsigned int openais_service_unlink_and_exit (
+    struct objdb_iface_ver0 *objdb,
+    char *service_name,
+    unsigned int service_ver);
 
-extern int openais_service_handler_register (
-	struct openais_service_handler *handler);
+/*
+ * Unlink and exit all openais services
+ */
+extern unsigned int openais_service_unlink_all (
+    struct objdb_iface_ver0 *objdb);
 
-extern int openais_service_default_objdb_set (struct objdb_iface_ver0 *objdb);
 
-extern int openais_service_link_all (
+/*
+ * Load all of the default services
+ */
+extern unsigned int openais_service_defaults_link_and_init (
 	struct objdb_iface_ver0 *objdb);
 
-extern int openais_service_init_all (
-	int service_count,
-	struct objdb_iface_ver0 *objdb);
-
 extern struct openais_service_handler *ais_service[];
 
 #endif /* SERVICE_H_DEFINED */
Index: exec/clm.c
===================================================================
--- exec/clm.c	(revision 1527)
+++ exec/clm.c	(working copy)
@@ -142,6 +142,8 @@
 
 static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb);
 
+static int clm_exec_exit_fn (struct objdb_iface_ver0 *objdb);
+
 static int clm_lib_init_fn (void *conn);
 
 static int clm_lib_exit_fn (void *conn);
@@ -216,6 +218,7 @@
 	.lib_service		= clm_lib_service,
 	.lib_service_count	= sizeof (clm_lib_service) / sizeof (struct openais_lib_handler),
 	.exec_init_fn		= clm_exec_init_fn,
+	.exec_exit_fn		= clm_exec_exit_fn,
 	.exec_dump_fn		= NULL,
 	.exec_service		= clm_exec_service,
 	.exec_service_count	= sizeof (clm_exec_service) / sizeof (struct openais_exec_handler),
@@ -355,6 +358,11 @@
 	return (0);
 }
 
+static int clm_exec_exit_fn (struct objdb_iface_ver0 *objdb)
+{
+	return (0);
+}
+
 static int clm_lib_exit_fn (void *conn)
 {
 	struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
Index: exec/objdb.c
===================================================================
--- exec/objdb.c	(revision 1527)
+++ exec/objdb.c	(working copy)
@@ -73,6 +73,7 @@
 	.mutex		= PTHREAD_MUTEX_INITIALIZER
 };
 
+
 static int objdb_init (void)
 {
 	unsigned int handle;
@@ -448,7 +449,7 @@
 	instance->find_child_list = &instance->child_head;
 
 	hdb_handle_put (&object_instance_database, object_handle);
-	return (0);
+	return (found == 1 ? 0 : ENOENT);
 
 error_exit:
 	return (-1);
Index: exec/main.c
===================================================================
--- exec/main.c	(revision 1527)
+++ exec/main.c	(working copy)
@@ -500,7 +500,11 @@
 
 	objdb->objdb_init ();
 
-	/* User's bootstrap config service */
+	/*
+	 * Bootstrap in the default configuration parser or use
+	 * the openais default built in parser if the configuration parser
+	 * isn't overridden
+	 */
 	config_iface = getenv("OPENAIS_DEFAULT_CONFIG_IFACE");
 	if (!config_iface) {
 		config_iface = "aisparser";
@@ -537,14 +541,6 @@
 	if (config_iface)
 		free(config_iface);
 
-	openais_service_default_objdb_set (objdb);
-
-	res = openais_service_link_all (objdb);
-	if (res == -1) {
-		log_printf (LOG_LEVEL_ERROR, "Could not load services\n");
-		openais_exit_error (AIS_DONE_DYNAMICLOAD);
-	}
-
 	res = openais_main_config_read (objdb, &error_string, &main_config);
 	if (res == -1) {
 		log_printf (LOG_LEVEL_ERROR, error_string);
@@ -636,12 +632,13 @@
 	/*
 	 * This must occur after totempg is initialized because "this_ip" must be set
 	 */
-	res = openais_service_init_all (service_count, objdb);
+	res = openais_service_defaults_link_and_init (objdb);
 	if (res == -1) {
-		log_printf (LOG_LEVEL_ERROR, "Could not init services\n");
+		log_printf (LOG_LEVEL_ERROR, "Could not initialize default services\n");
 		openais_exit_error (AIS_DONE_INIT_SERVICES);
 	}
 
+
 	sync_register (openais_sync_callbacks_retrieve, openais_sync_completed,
 		totem_config.vsf_type);
 
Index: lib/cfg.c
===================================================================
--- lib/cfg.c	(revision 1527)
+++ lib/cfg.c	(working copy)
@@ -1,7 +1,6 @@
-
 /*
  * Copyright (c) 2002-2005 MontaVista Software, Inc.
- * Copyright (c) 2006 Red Hat, Inc.
+ * Copyright (c) 2006-2007 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -78,9 +77,9 @@
  * All instances in one database
  */
 static struct saHandleDatabase cfg_hdb = {
-	.handleCount				= 0,
-	.handles					= 0,
-	.mutex						= PTHREAD_MUTEX_INITIALIZER,
+	.handleCount			= 0,
+	.handles			= 0,
+	.mutex				= PTHREAD_MUTEX_INITIALIZER,
 	.handleInstanceDestructor	= cfg_handleInstanceDestructor
 };
 
@@ -459,6 +458,81 @@
 }
 
 SaAisErrorT
+openais_cfg_service_load (
+	openais_cfg_handle_t cfg_handle,
+	char *service_name,
+	unsigned int service_ver)
+{
+	struct cfg_instance *cfg_instance;
+	struct req_lib_cfg_serviceload req_lib_cfg_serviceload;
+	struct res_lib_cfg_serviceload res_lib_cfg_serviceload;
+	SaAisErrorT error;
+
+	error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
+	if (error != SA_AIS_OK) {
+		return (error);
+	}
+
+	req_lib_cfg_serviceload.header.size = sizeof (struct req_lib_cfg_serviceload);
+	req_lib_cfg_serviceload.header.id = MESSAGE_REQ_CFG_SERVICELOAD;
+	memset (&req_lib_cfg_serviceload.service_name, 0,
+		sizeof (req_lib_cfg_serviceload.service_name));
+	strncpy ((char *)req_lib_cfg_serviceload.service_name, service_name,
+		sizeof (req_lib_cfg_serviceload.service_name) - 1);
+	req_lib_cfg_serviceload.service_ver = service_ver;
+
+	pthread_mutex_lock (&cfg_instance->response_mutex);
+
+	error = saSendReceiveReply (cfg_instance->response_fd,
+		&req_lib_cfg_serviceload,
+		sizeof (struct req_lib_cfg_serviceload),
+		&res_lib_cfg_serviceload,
+		sizeof (struct res_lib_cfg_serviceload));
+
+	pthread_mutex_unlock (&cfg_instance->response_mutex);
+	saHandleInstancePut (&cfg_hdb, cfg_handle);
+
+	return (error);
+}
+
+SaAisErrorT
+openais_cfg_service_unload (
+	openais_cfg_handle_t cfg_handle,
+	char *service_name,
+	unsigned int service_ver)
+{
+	struct cfg_instance *cfg_instance;
+	struct req_lib_cfg_serviceunload req_lib_cfg_serviceunload;
+	struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload;
+	SaAisErrorT error;
+
+	error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
+	if (error != SA_AIS_OK) {
+		return (error);
+	}
+
+	req_lib_cfg_serviceunload.header.size = sizeof (struct req_lib_cfg_serviceunload);
+	req_lib_cfg_serviceunload.header.id = MESSAGE_REQ_CFG_SERVICEUNLOAD;
+	memset (&req_lib_cfg_serviceunload.service_name, 0,
+		sizeof (req_lib_cfg_serviceunload.service_name));
+	strncpy ((char *)req_lib_cfg_serviceunload.service_name, service_name,
+		sizeof (req_lib_cfg_serviceunload.service_name) - 1);
+	req_lib_cfg_serviceunload.service_ver = service_ver;
+
+	pthread_mutex_lock (&cfg_instance->response_mutex);
+
+	error = saSendReceiveReply (cfg_instance->response_fd,
+		&req_lib_cfg_serviceunload,
+		sizeof (struct req_lib_cfg_serviceunload),
+		&res_lib_cfg_serviceunload,
+		sizeof (struct res_lib_cfg_serviceunload));
+
+	pthread_mutex_unlock (&cfg_instance->response_mutex);
+	saHandleInstancePut (&cfg_hdb, cfg_handle);
+
+	return (error);
+}
+SaAisErrorT
 openais_cfg_state_track (
 	openais_cfg_handle_t cfg_handle,
 	SaUint8T trackFlags,
Index: lib/libcfg.versions
===================================================================
--- lib/libcfg.versions	(revision 1527)
+++ lib/libcfg.versions	(working copy)
@@ -1,6 +1,6 @@
 # Version and symbol export for libcfg.so
 
-OPENAIS_CFG_0.80 {
+OPENAIS_CFG_0.82 {
 	global:
 		openais_cfg_initialize;
 		openais_cfg_fd_get;
@@ -12,6 +12,8 @@
 		openais_cfg_track_stop;
 		openais_cfg_ring_status_get;
 		openais_cfg_ring_reenable;
+		openais_cfg_service_load;
+		openais_cfg_service_unload;
 		
 		
 	local:
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to