]> git.proxmox.com Git - mirror_corosync.git/commitdiff
load and unload service engines at runtime.
authorSteven Dake <sdake@redhat.com>
Mon, 28 Apr 2008 16:25:47 +0000 (16:25 +0000)
committerSteven Dake <sdake@redhat.com>
Mon, 28 Apr 2008 16:25:47 +0000 (16:25 +0000)
git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1528 fd59a12c-fef9-0310-b244-a6a79926bd2f

exec/cfg.c
exec/clm.c
exec/main.c
exec/objdb.c
exec/service.c
exec/service.h
include/cfg.h
include/ipc_cfg.h
lib/cfg.c
lib/libcfg.versions
test/openais-cfgtool.c

index a439dac880574d537d3c7d64da6a5fefc2774065..6a43952b9c55af495b217aeab15721580a5bb4b5 100644 (file)
@@ -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 @@ static void message_handler_req_lib_cfg_administrativestateget (
        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 @@ static struct openais_lib_handler cfg_lib_service[] =
                .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 @@ struct openais_service_handler cfg_service_handler = {
        .confchg_fn                             = cfg_confchg_fn,
 };
 
+static struct objdb_iface_ver0 *my_objdb;
+
 /*
  * Dynamic Loader definition
  */
@@ -231,6 +253,7 @@ struct req_exec_cfg_ringreenable {
 
 static int cfg_exec_init_fn (struct objdb_iface_ver0 *objdb)
 {
+       my_objdb = objdb;
        return (0);
 }
 
@@ -386,3 +409,49 @@ static void message_handler_req_lib_cfg_administrativestateget (
        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 16d9004566737ed0a75cf4a5841f29b0794cf65d..16b4ca12547933e1b62c6f6c3cc155a0fc7c4da2 100644 (file)
@@ -142,6 +142,8 @@ static void clm_sync_abort (void);
 
 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 @@ struct openais_service_handler clm_service_handler = {
        .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 @@ static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb)
        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 68a265683302dde0092571bdf8b7d1a842e4fa75..e85ea6d4988a31996db98ba79917ef574bc4d79e 100644 (file)
@@ -500,7 +500,11 @@ int main (int argc, char **argv)
 
        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 @@ int main (int argc, char **argv)
        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 @@ int main (int argc, char **argv)
        /*
         * 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 fe2540d77c34b2b7e2041da6df29c0a257a63073..07b92a20d66a3284d7212fced474ac022e2df9b2 100644 (file)
@@ -73,6 +73,7 @@ static struct hdb_handle_database object_instance_database = {
        .mutex          = PTHREAD_MUTEX_INITIALIZER
 };
 
+
 static int objdb_init (void)
 {
        unsigned int handle;
@@ -448,7 +449,7 @@ static int object_find_reset (
        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 7899f6b806afd81c8d8836e848b739911d1c0c18..119e9271c1b32abd0d4e1a69e673a85d984f2678 100644 (file)
@@ -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 (sdake@mvista.com)
+ * Author: Steven Dake (sdake@redhat.com)
  *
  * This software licensed under BSD license, the text of which follows:
  *
@@ -99,54 +98,14 @@ static struct default_service default_services[] = {
 
 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)
-{
-       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)
+static unsigned int default_services_requested (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 @@ int openais_service_default_objdb_set (struct objdb_iface_ver0 *objdb)
                &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 @@ int openais_service_link_all (struct objdb_iface_ver0 *objdb)
                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);
-
-               iface_ver0 = (struct openais_service_handler_iface_ver0 *)iface_ver0_p;
-
-               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);
-               }
+               if ((strcmp (service_name, found_service_name) == 0) &&
+                       (service_ver == *found_service_ver)) {
 
-               service_handler_config (
-                       iface_ver0->openais_get_service_handler_ver0(), objdb);
+                       res = objdb->object_key_get (object_service_handle,
+                               "handle",
+                               strlen ("handle"),
+                               (void *)&found_service_handle,
+                               NULL);
+
+                       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);
+               }
        }
-       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;
-
-       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;
-                       }
-               }
+       unsigned int i;
+
+       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 e693db6837ec5280d2ae65769737a673eb3db2fd..d5de6497425602276f1e029ea09f1d7e67398448 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2007 Red Hat, Inc.
  *
  * All rights reserved.
  *
- * Author: Steven Dake (sdake@mvista.com)
+ * Author: Steven Dake (sdake@redhat.com)
  *
  * This software licensed under BSD license, the text of which follows:
  *
@@ -65,6 +66,7 @@ struct openais_service_handler {
        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,26 +83,36 @@ struct openais_service_handler {
 };
 
 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);
 
-extern int openais_service_handler_register (
-       struct openais_service_handler *handler);
+/*
+ * 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_default_objdb_set (struct objdb_iface_ver0 *objdb);
+/*
+ * Unlink and exit all openais services
+ */
+extern unsigned int openais_service_unlink_all (
+    struct objdb_iface_ver0 *objdb);
 
-extern int openais_service_link_all (
-       struct objdb_iface_ver0 *objdb);
 
-extern int openais_service_init_all (
-       int service_count,
+/*
+ * Load all of the default services
+ */
+extern unsigned int openais_service_defaults_link_and_init (
        struct objdb_iface_ver0 *objdb);
 
 extern struct openais_service_handler *ais_service[];
index 77dfd54ab5e87110395b2f945bd5920b0f8ea2cf..d5cd41d4bbb491668f4a80ed18e62efcf2eeced4 100644 (file)
@@ -139,6 +139,18 @@ SaAisErrorT
 openais_cfg_ring_reenable (
        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,
index 2e1a3d9be8a72733bf4d114a2ebf3346228312c8..e6cc1c794ddd1ca075436da9740bfc045d692e11 100644 (file)
@@ -46,6 +46,8 @@ enum req_lib_cfg_types {
         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 @@ enum res_lib_cfg_types {
         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 @@ struct res_lib_cfg_ringreenable {
        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 3d8a97883ab2b7e34d6c7c38f9b315ecf1241758..119eeeb610ec7b680497ed9e904b4cbc348562d9 100644 (file)
--- a/lib/cfg.c
+++ b/lib/cfg.c
@@ -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 @@ static void cfg_handleInstanceDestructor (void *);
  * 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
 };
 
@@ -458,6 +457,81 @@ openais_cfg_ring_reenable (
        return (error);
 }
 
+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,
index d56772f37f08bfabdd782fee78921bf03fa1be15..a13fc6c52d24380c22aa2bc999b7a0cc3c5d51b1 100644 (file)
@@ -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_0.80 {
                openais_cfg_track_stop;
                openais_cfg_ring_status_get;
                openais_cfg_ring_reenable;
+               openais_cfg_service_load;
+               openais_cfg_service_unload;
                
                
        local:
index a11f2f838257aeccac3dadeda343cf9cfb07603e..9a7d11531d0fa35ab17a37f4d1664fbb32afad23 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Red Hat Inc
+ * Copyright (c) 2006-2007 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -98,19 +98,61 @@ static void ringreenable_do (void)
        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 @@ int main (int argc, char *argv[]) {
                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);
 }