diff --git a/exec/Makefile b/exec/Makefile index fd606ef1..40591997 100644 --- a/exec/Makefile +++ b/exec/Makefile @@ -48,19 +48,19 @@ endif CFLAGS += -DOPENAIS_USER=\"${OPENAIS_USER}\" -DOPENAIS_GROUP=\"${OPENAIS_GROUP}\" -DOPENAIS_CONFDIR=\"${OPENAIS_CONFDIR}\" # Totem objects -TOTEM_SRC = aispoll.c totemip.c totemnet.c totemrrp.c totemsrp.c totemmrp.c totempg.c totemconfig.c tlist.c crypto.c wthread.c -TOTEM_OBJS = aispoll.o totemip.o totemnet.o totemrrp.o totemsrp.o totemmrp.o totempg.o totemconfig.o tlist.o crypto.o wthread.o +TOTEM_SRC = aispoll.c totemip.c totemnet.c totemrrp.c totemsrp.c totemmrp.c totempg.c tlist.c crypto.c wthread.c +TOTEM_OBJS = aispoll.o totemip.o totemnet.o totemrrp.o totemsrp.o totemmrp.o totempg.o tlist.o crypto.o wthread.o EXEC_LIBS = libtotem_pg.a # service handler objects -SERV_SRC = evs.c clm.c amf.c ckpt.c evt.c lck.c msg.c cfg.c cpg.c -SERV_OBJS = evs.o clm.o amf.o ckpt.o evt.o lck.o msg.o cfg.o cpg.o +SERV_SRC = evs.c clm.c amf.c ckpt.c evt.c lck.c msg.c cfg.c cpg.c aisparser.c +SERV_OBJS = evs.o clm.o amf.o ckpt.o evt.o lck.o msg.o cfg.o cpg.o aisparser.o # main executive objects MAIN_SRC = main.c print.c mempool.c \ - util.c sync.c ykd.c mainconfig.c amfconfig.c service.c + util.c sync.c ykd.c service.c totemconfig.c mainconfig.c MAIN_OBJS = main.o print.o mempool.o \ - util.o sync.o ykd.o mainconfig.o amfconfig.o service.o ../lcr/lcr_ifact.o + util.o sync.o ykd.o service.o totemconfig.o mainconfig.o ../lcr/lcr_ifact.o OTHER_OBJS = objdb.o ifeq (${BUILD_DYNAMIC}, 1) @@ -72,7 +72,7 @@ all:libtotem_pg.a libtotem_pg.so.1.0 ../lcr/lcr_ifact.o \ service_evs.lcrso service_clm.lcrso service_amf.lcrso \ service_ckpt.lcrso service_evt.lcrso service_lck.lcrso \ service_msg.lcrso service_cfg.lcrso service_cpg.lcrso \ - objdb.lcrso keygen openais-instantiate + objdb.lcrso aisparser.lcrso keygen openais-instantiate else EXEC_OBJS = $(TOTEM_OBJS) $(MAIN_OBJS) $(OTHER_OBJS) $(SERV_OBJS) all: libtotem_pg.a aisexec keygen openais-instantiate @@ -87,8 +87,8 @@ service_evs.lcrso: evs.o service_clm.lcrso: clm.o $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load clm.o -o $@ -service_amf.lcrso: amf.o - $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load amf.o -o $@ +service_amf.lcrso: amf.o amfconfig.o + $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load amf.o amfconfig.o -o $@ service_ckpt.lcrso: ckpt.o $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load ckpt.o -o $@ @@ -106,7 +106,10 @@ service_cfg.lcrso: cfg.o $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load cfg.o -o $@ service_cpg.lcrso: cpg.o - $(CC) -bundle -bundle_loader ./aisexec -bind_at_load cpg.o -o $@ + $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load cpg.o -o $@ + +aisparser.lcrso: aisparser.o + $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load aisparser.o -o $@ objdb.lcrso: objdb.o $(CC) -bundle -bundle_loader ./aisexec -bind_at_load objdb.o -o $@ @@ -119,8 +122,8 @@ service_evs.lcrso: evs.o service_clm.lcrso: clm.o $(CC) -shared -Wl,-soname,service_clm.lcrso clm.o -o $@ -service_amf.lcrso: amf.o - $(CC) -shared -Wl,-soname,service_amf.lcrso amf.o -o $@ +service_amf.lcrso: amf.o amfconfig.o + $(CC) -shared -Wl,-soname,service_amf.lcrso amf.o amfconfig.o -o $@ service_ckpt.lcrso: ckpt.o $(CC) -shared -Wl,-soname,service_ckpt.lcrso ckpt.o -o $@ @@ -140,6 +143,9 @@ service_cfg.lcrso: cfg.o service_cpg.lcrso: cpg.o $(CC) -shared -Wl,-soname,service_cpg.lcrso cpg.o -o $@ +aisparser.lcrso: aisparser.o + $(CC) -shared -Wl,-soname,aisparser.lcrso aisparser.o -o $@ + objdb.lcrso: objdb.o $(CC) -shared -Wl,-soname,objdb.lcrso objdb.o -o $@ @@ -209,6 +215,9 @@ msg.o: msg.c cfg.o: cfg.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $(*F).c +aisparser.o: aisparser.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $(*F).c + cpg.o: cpg.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $(*F).c diff --git a/exec/aisparser.c b/exec/aisparser.c new file mode 100644 index 00000000..d333abd4 --- /dev/null +++ b/exec/aisparser.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2006 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Patrick Caulfield (pcaulfie@redhat.com) + * + * This software licensed under BSD license, the text of which follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the MontaVista Software, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../lcr/lcr_comp.h" +#include "objdb.h" +#include "config.h" +#include "mempool.h" + +static int read_config_file_into_objdb( + struct objdb_iface_ver0 *objdb, + char **error_string); +static char error_string_response[512]; + + +static int aisparser_readconfig (struct objdb_iface_ver0 *objdb, char **error_string) +{ + if (read_config_file_into_objdb(objdb, error_string)) { + return -1; + } + + return 0; +} + + +char *remove_whitespace(char *string) +{ + char *start = string+strspn(string, " \t"); + char *end = start+(strlen(start))-1; + + while ((*end == ' ' || *end == '\t' || *end == ':' || *end == '{') && end > start) + end--; + if (end != start) + *(end+1) = '\0'; + + return start; +} + +char *strstr_rs (const char *haystack, const char *needle) +{ + char *end_address; + char *new_needle; + + new_needle = (char *)mempool_strdup (needle); + new_needle[strlen(new_needle) - 1] = '\0'; + + end_address = strstr (haystack, new_needle); + if (end_address) { + end_address += strlen (new_needle); + end_address = strstr (end_address, needle + strlen (new_needle)); + } + if (end_address) { + end_address += 1; /* skip past { or = */ + do { + if (*end_address == '\t' || *end_address == ' ') { + end_address++; + } else { + break; + } + } while (*end_address != '\0'); + } + + mempool_free (new_needle); + return (end_address); +} + +static int parse_section(FILE *fp, + struct objdb_iface_ver0 *objdb, + unsigned int parent_key, + char **error_string) +{ + char line[512]; + int i; + char *loc; + + while (fgets (line, 255, fp)) { + line[strlen(line) - 1] = '\0'; + /* + * Clear out white space and tabs + */ + for (i = strlen (line) - 1; i > -1; i--) { + if (line[i] == '\t' || line[i] == ' ') { + line[i] = '\0'; + } else { + break; + } + } + /* + * Clear out comments and empty lines + */ + if (line[0] == '#' || line[0] == '\0') { + continue; + } + + /* New section ? */ + if ((loc = strstr_rs (line, "{"))) { + unsigned int new_parent; + char *section = remove_whitespace(line); + + loc--; + *loc = '\0'; + objdb->object_create (OBJECT_PARENT_HANDLE, &new_parent, + section, strlen (section)); + if (parse_section(fp, objdb, new_parent, error_string)) + return -1; + } + + /* New key/value */ + if ((loc = strstr_rs (line, ":"))) { + char *key; + char *value; + + *(loc-1) = '\0'; + key = remove_whitespace(line); + value = remove_whitespace(loc); + objdb->object_key_create (parent_key, key, strlen (key), + value, strlen (value) + 1); + } + + if ((loc = strstr_rs (line, "}"))) { + return 0; + } + } + + if (parent_key != OBJECT_PARENT_HANDLE) { + *error_string = "Missing closing brace"; + return -1; + } + + return 0; +} + + + +/* Read config file and load into objdb */ +static int read_config_file_into_objdb( + struct objdb_iface_ver0 *objdb, + char **error_string) +{ + FILE *fp; + char *error_reason = error_string_response; + int res; + + fp = fopen (OPENAIS_CONFDIR "/openais.conf", "r"); + if (fp == 0) { + sprintf (error_reason, "Can't read file %s/openais.conf reason = (%s)\n", + OPENAIS_CONFDIR, strerror (errno)); + *error_string = error_reason; + return -1; + } + + res = parse_section(fp, objdb, OBJECT_PARENT_HANDLE, error_string); + + fclose(fp); + + return res; +} + +/* + * Dynamic Loader definition + */ + +struct config_iface_ver0 aisparser_iface_ver0 = { + .config_readconfig = aisparser_readconfig +}; + +struct lcr_iface openais_aisparser_ver0[1] = { + { + .name = "aisparser", + .version = 0, + .versions_replace = 0, + .versions_replace_count = 0, + .dependencies = 0, + .dependency_count = 0, + .constructor = NULL, + .destructor = NULL, + .interfaces = (void **)(void *)&aisparser_iface_ver0, + } +}; + +struct openais_service_handler *aisparser_get_handler_ver0 (void); + +struct lcr_comp aisparser_comp_ver0 = { + .iface_count = 1, + .ifaces = openais_aisparser_ver0 +}; + + +__attribute__ ((constructor)) static void aisparser_comp_register (void) { + lcr_component_register (&aisparser_comp_ver0); +} + + diff --git a/exec/amf.c b/exec/amf.c index 41575d40..f7d8ce5c 100644 --- a/exec/amf.c +++ b/exec/amf.c @@ -63,6 +63,7 @@ #include "amfconfig.h" #include "main.h" #include "service.h" +#include "objdb.h" #define LOG_SERVICE LOG_SERVICE_AMF #include "print.h" @@ -136,7 +137,7 @@ static void amf_confchg_fn ( static int amf_lib_exit_fn (void *conn); -static int amf_exec_init_fn (struct openais_config *); +static int amf_exec_init_fn (struct objdb_iface_ver0 *objdb); static int amf_lib_init_fn (void *conn); @@ -837,9 +838,43 @@ int clc_cleanup (struct amf_comp *comp) /* IMPL */ -static int amf_exec_init_fn (struct openais_config *openais_config) +static int amf_exec_init_fn (struct objdb_iface_ver0 *objdb) { - if (openais_config->amf_enabled) { + int res; + char *error_string; + unsigned int object_service_handle; + int enabled = 0; + char *value; + + objdb->object_find_reset (OBJECT_PARENT_HANDLE); + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "amf", + strlen ("amf"), + &object_service_handle) == 0) { + + value = NULL; + if ( !objdb->object_key_get (object_service_handle, + "mode", + strlen ("mode"), + (void *)&value, + NULL) && value) { + if (strcmp (value, "enabled") == 0) { + enabled = 1; + } else + if (strcmp (value, "disabled") == 0) { + enabled = 0; + } + } + } + + if (enabled) { + res = openais_amf_config_read (&error_string); + if (res == -1) { + log_printf (LOG_LEVEL_ERROR, error_string); + return res; + } + clc_instantiate_all (); } return (0); diff --git a/exec/amfconfig.c b/exec/amfconfig.c index 3f99bc74..bae2f820 100644 --- a/exec/amfconfig.c +++ b/exec/amfconfig.c @@ -46,7 +46,6 @@ #include "../include/list.h" #include "util.h" #include "amfconfig.h" -#include "mainconfig.h" #include "mempool.h" #include "print.h" #include "totem.h" @@ -213,6 +212,35 @@ struct amf_unit *find_unit (SaNameT *name) } } +static char *strstr_rs (const char *haystack, const char *needle) +{ + char *end_address; + char *new_needle; + + new_needle = (char *)mempool_strdup (needle); + new_needle[strlen(new_needle) - 1] = '\0'; + + end_address = strstr (haystack, new_needle); + if (end_address) { + end_address += strlen (new_needle); + end_address = strstr (end_address, needle + strlen (new_needle)); + } + if (end_address) { + end_address += 1; /* skip past { or = */ + do { + if (*end_address == '\t' || *end_address == ' ') { + end_address++; + } else { + break; + } + } while (*end_address != '\0'); + } + + mempool_free (new_needle); + return (end_address); +} + + extern int openais_amf_config_read (char **error_string) { char line[255]; diff --git a/exec/amfconfig.h b/exec/amfconfig.h index 8e52fed4..d6ad6120 100644 --- a/exec/amfconfig.h +++ b/exec/amfconfig.h @@ -194,4 +194,6 @@ extern struct amf_unit *find_unit (SaNameT *name); extern struct amf_healthcheck *find_healthcheck (SaAmfHealthcheckKeyT *key); +extern int openais_amf_config_read (char **error_string); + #endif /* AMFCONFIG_H_DEFINED */ diff --git a/exec/cfg.c b/exec/cfg.c index 4abbbddc..e0c5ecdb 100644 --- a/exec/cfg.c +++ b/exec/cfg.c @@ -71,7 +71,7 @@ static void cfg_confchg_fn ( struct totem_ip_address *joined_list, int joined_list_entries, struct memb_ring_id *ring_id); -static int cfg_exec_init_fn (struct openais_config *); +static int cfg_exec_init_fn (struct objdb_iface_ver0 *objdb); static int cfg_lib_init_fn (void *conn); @@ -184,7 +184,7 @@ __attribute__ ((constructor)) static void register_this_component (void) { /* IMPL */ -static int cfg_exec_init_fn (struct openais_config *openais_config) +static int cfg_exec_init_fn (struct objdb_iface_ver0 *objdb) { return (0); } diff --git a/exec/clm.c b/exec/clm.c index c0e91d75..74b947a0 100644 --- a/exec/clm.c +++ b/exec/clm.c @@ -127,7 +127,7 @@ static void clm_sync_activate (void); static void clm_sync_abort (void); -static int clm_exec_init_fn (struct openais_config *); +static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb); static int clm_lib_init_fn (void *conn); @@ -254,7 +254,7 @@ struct req_exec_clm_nodejoin { SaClmClusterNodeT clusterNode; }; -static int clm_exec_init_fn (struct openais_config *openais_config) +static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb) { memset (clusterNodes, 0, sizeof (SaClmClusterNodeT) * NODE_MAX); diff --git a/exec/config.h b/exec/config.h new file mode 100644 index 00000000..dc8e4c33 --- /dev/null +++ b/exec/config.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Patrick Caulfield (pcaulfie@redhat.com) + * + * This software licensed under BSD license, the text of which follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the MontaVista Software, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CONFIG_H_DEFINED +#define CONFIG_H_DEFINED + +struct config_iface_ver0 { + int (*config_readconfig) (struct objdb_iface_ver0 *objdb, char **error_string); +}; + + + +#endif /* CONFIG_H_DEFINED */ diff --git a/exec/cpg.c b/exec/cpg.c index 47b01311..4d936751 100644 --- a/exec/cpg.c +++ b/exec/cpg.c @@ -122,7 +122,7 @@ static void cpg_confchg_fn ( struct totem_ip_address *joined_list, int joined_list_entries, struct memb_ring_id *ring_id); -static int cpg_exec_init_fn (struct openais_config *); +static int cpg_exec_init_fn (struct objdb_iface_ver0 *objdb); static int cpg_lib_init_fn (void *conn); @@ -393,7 +393,7 @@ static void remove_group(struct group_info *gi) } -static int cpg_exec_init_fn (struct openais_config *openais_config) +static int cpg_exec_init_fn (struct objdb_iface_ver0 *objdb) { int i; diff --git a/exec/evt.c b/exec/evt.c index 9d341361..ffae1a43 100644 --- a/exec/evt.c +++ b/exec/evt.c @@ -119,7 +119,7 @@ static void evt_conf_change( static int evt_lib_init(void *conn); static int evt_lib_exit(void *conn); -static int evt_exec_init(struct openais_config *openais_config); +static int evt_exec_init(struct objdb_iface_ver0 *objdb); /* * Recovery sync functions @@ -3017,22 +3017,42 @@ static int evt_lib_exit(void *conn) /* * Called at service start time. */ -static int evt_exec_init(struct openais_config *openais_config) +static int evt_exec_init(struct objdb_iface_ver0 *objdb) { + unsigned int object_service_handle; + char *value; + log_printf(LOG_LEVEL_DEBUG, "Evt exec init request\n"); - if (openais_config->evt_delivery_queue_size) { - evt_delivery_queue_size = openais_config->evt_delivery_queue_size; - log_printf(LOG_LEVEL_NOTICE, - "event delivery_queue_size set to %u\n", - evt_delivery_queue_size); - } + objdb->object_find_reset (OBJECT_PARENT_HANDLE); + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "event", + strlen ("event"), + &object_service_handle) == 0) { - if (openais_config->evt_delivery_queue_resume) { - evt_delivery_queue_resume = openais_config->evt_delivery_queue_resume; - log_printf(LOG_LEVEL_NOTICE, - "event delivery_queue_resume set to %u\n", - evt_delivery_queue_resume); + value = NULL; + if ( !objdb->object_key_get (object_service_handle, + "delivery_queue_size", + strlen ("delivery_queue_size"), + (void *)&value, + NULL) && value) { + evt_delivery_queue_size = atoi(value); + log_printf(LOG_LEVEL_NOTICE, + "event delivery_queue_size set to %u\n", + evt_delivery_queue_size); + } + value = NULL; + if ( !objdb->object_key_get (object_service_handle, + "delivery_queue_resume", + strlen ("delivery_queue_resume"), + (void *)&value, + NULL) && value) { + evt_delivery_queue_resume = atoi(value); + log_printf(LOG_LEVEL_NOTICE, + "event delivery_queue_resume set to %u\n", + evt_delivery_queue_size); + } } /* diff --git a/exec/lck.c b/exec/lck.c index 0612f0e7..d67bfd86 100644 --- a/exec/lck.c +++ b/exec/lck.c @@ -109,7 +109,7 @@ struct resource_cleanup { DECLARE_LIST_INIT(resource_list_head); -static int lck_exec_init_fn (struct openais_config *); +static int lck_exec_init_fn (struct objdb_iface_ver0 *objdb); static int lck_lib_exit_fn (void *conn); @@ -574,7 +574,7 @@ void lck_resource_cleanup_remove ( } -static int lck_exec_init_fn (struct openais_config *openais_config) +static int lck_exec_init_fn (struct objdb_iface_ver0 *objdb) { /* * Initialize the saved ring ID. diff --git a/exec/main.c b/exec/main.c index d5f07429..a6c250b1 100644 --- a/exec/main.c +++ b/exec/main.c @@ -8,7 +8,7 @@ * Author: Steven Dake (sdake@mvista.com) * * This software licensed under BSD license, the text of which follows: - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -65,7 +65,6 @@ #include "totemsrp.h" #include "mempool.h" #include "mainconfig.h" -#include "amfconfig.h" #include "totemconfig.h" #include "main.h" #include "service.h" @@ -73,6 +72,7 @@ #include "ykd.h" #include "swab.h" #include "objdb.h" +#include "config.h" #define LOG_SERVICE LOG_SERVICE_MAIN #include "print.h" @@ -127,7 +127,6 @@ static int (*ais_init_service[]) (struct conn_info *conn_info, void *message) = static int poll_handler_libais_deliver (poll_handle handle, int fd, int revent, void *data, unsigned int *prio); -extern int openais_amf_config_read (char **error_string); static inline struct conn_info *conn_info_create (int fd) { struct conn_info *conn_info; @@ -151,7 +150,7 @@ static inline struct conn_info *conn_info_create (int fd) { free (conn_info); return (0); } - + conn_info->state = CONN_STATE_ACTIVE; conn_info->fd = fd; conn_info->service = SOCKET_SERVICE_INIT; @@ -179,7 +178,7 @@ struct totem_ip_address this_non_loopback_ip; #define LOCALHOST_IP inet_addr("127.0.0.1") #if defined(OPENAIS_LINUX) -/* SUN_LEN is broken for abstract namespace +/* SUN_LEN is broken for abstract namespace */ #define AIS_SUN_LEN(a) sizeof(*(a)) @@ -223,7 +222,7 @@ static int libais_disconnect (struct conn_info *conn_info) /* * Call library exit handler and free private data */ - if (conn_info->conn_info_partner && + if (conn_info->conn_info_partner && conn_info->conn_info_partner->should_exit_fn && ais_service[conn_info->conn_info_partner->service]->lib_exit_fn) { @@ -439,7 +438,7 @@ retry_sendmsg: * Send requested message */ if (queue_empty) { - + iov_send.iov_base = msg; iov_send.iov_len = mlen; retry_sendmsg_two: @@ -484,7 +483,7 @@ retry_sendmsg_two: } return (0); } - + static int poll_handler_libais_accept ( poll_handle handle, int fd, @@ -513,14 +512,14 @@ retry_accept: log_printf (LOG_LEVEL_ERROR, "ERROR: Could not accept Library connection: %s\n", strerror (errno)); return (0); /* This is an error, but -1 would indicate disconnect from poll loop */ } - + totemip_nosigpipe(new_fd); res = fcntl (new_fd, F_SETFL, O_NONBLOCK); if (res == -1) { log_printf (LOG_LEVEL_ERROR, "Could not set non-blocking operation on library connection: %s\n", strerror (errno)); close (new_fd); return (0); /* This is an error, but -1 would indicate disconnect from poll loop */ - } + } /* * Valid accept @@ -587,7 +586,7 @@ static int dispatch_init_send_response (struct conn_info *conn_info, void *messa res_lib_dispatch_init.header.size = sizeof (struct res_lib_dispatch_init); res_lib_dispatch_init.header.id = MESSAGE_RES_INIT; res_lib_dispatch_init.header.error = error; - + openais_conn_send_response ( conn_info, &res_lib_dispatch_init, @@ -817,9 +816,9 @@ retry_recv: /* * Overload, tell library to retry */ - res_overlay.header.size = + res_overlay.header.size = ais_service[service]->lib_service[header->id].response_size; - res_overlay.header.id = + res_overlay.header.id = ais_service[service]->lib_service[header->id].response_id; res_overlay.header.error = SA_AIS_ERR_TRY_AGAIN; openais_conn_send_response ( @@ -833,7 +832,7 @@ retry_recv: if (conn_info->inb_inuse == 0) { conn_info->inb_start = 0; - } else + } else // BUG if (connections[fd].inb_start + connections[fd].inb_inuse >= SIZEINB) { if (conn_info->inb_start >= SIZEINB) { /* @@ -844,7 +843,7 @@ retry_recv: sizeof (char) * conn_info->inb_inuse); conn_info->inb_start = conn_info->inb_inuse; } - + return (0); error_disconnect: @@ -977,24 +976,24 @@ static void confchg_fn ( } } -static void aisexec_uid_determine (void) +static void aisexec_uid_determine (struct openais_config *openais_config) { struct passwd *passwd; - passwd = getpwnam(OPENAIS_USER); + passwd = getpwnam(openais_config->user); if (passwd == 0) { - log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' user is not found in /etc/passwd, please read the documentation.\n", OPENAIS_USER); + log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' user is not found in /etc/passwd, please read the documentation.\n", openais_config->user); openais_exit_error (AIS_DONE_UID_DETERMINE); } ais_uid = passwd->pw_uid; } -static void aisexec_gid_determine (void) +static void aisexec_gid_determine (struct openais_config *openais_config) { struct group *group; - group = getgrnam (OPENAIS_GROUP); + group = getgrnam (openais_config->group); if (group == 0) { - log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' group is not found in /etc/group, please read the documentation.\n", OPENAIS_GROUP); + log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' group is not found in /etc/group, please read the documentation.\n", group); openais_exit_error (AIS_DONE_GID_DETERMINE); } gid_valid = group->gr_gid; @@ -1097,7 +1096,7 @@ static void aisexec_setscheduler (void) sched_param.sched_priority = res; res = sched_setscheduler (0, SCHED_RR, &sched_param); if (res == -1) { - log_printf (LOG_LEVEL_WARNING, "Could not set SCHED_RR at priority %d: %s\n", + log_printf (LOG_LEVEL_WARNING, "Could not set SCHED_RR at priority %d: %s\n", sched_param.sched_priority, strerror (errno)); } } else @@ -1138,7 +1137,7 @@ int message_source_is_local(struct message_source *source) ||(totemip_equal(&source->addr, &this_non_loopback_ip)))) { ret = 1; } - return ret; + return ret; } void message_source_set ( @@ -1158,17 +1157,17 @@ int main (int argc, char **argv) char *error_string; struct openais_config openais_config; unsigned int objdb_handle; + unsigned int config_handle; + unsigned int config_version = 0; struct objdb_iface_ver0 *objdb; + struct config_iface_ver0 *config; + char *config_iface; int res; memset(&this_non_loopback_ip, 0, sizeof(struct totem_ip_address)); totemip_localhost(AF_INET, &this_non_loopback_ip); - aisexec_uid_determine (); - - aisexec_gid_determine (); - aisexec_poll_handle = poll_create (); //TODO signal (SIGUSR2, sigusr2_handler); @@ -1182,9 +1181,39 @@ int main (int argc, char **argv) 0, (void **)&objdb, 0); - + objdb->objdb_init (); + + /* User's bootstrap config service */ + config_iface = getenv("OPENAIS_DEFAULT_CONFIG_IFACE"); + if (!config_iface) { + config_iface = "aisparser"; + } + + res = lcr_ifact_reference ( + &config_handle, + config_iface, + config_version, + (void **)&config, + 0); + + if (res == -1) { + log_printf (LOG_LEVEL_NOTICE, "AIS Executive Service: Copyright (C) 2002-2006 MontaVista Software, Inc and contributors.\n"); + + log_printf (LOG_LEVEL_ERROR, "can't open configuration module\n"); + openais_exit_error (AIS_DONE_MAINCONFIGREAD); + } + + res = config->config_readconfig(objdb, &error_string); + if (res == -1) { + log_printf (LOG_LEVEL_NOTICE, "AIS Executive Service: Copyright (C) 2002-2006 MontaVista Software, Inc and contributors.\n"); + + log_printf (LOG_LEVEL_ERROR, error_string); + openais_exit_error (AIS_DONE_MAINCONFIGREAD); + } + openais_service_default_objdb_set (objdb); + openais_service_link_all (objdb, &openais_config); res = openais_main_config_read (objdb, &error_string, &openais_config, 1); @@ -1195,14 +1224,8 @@ int main (int argc, char **argv) openais_exit_error (AIS_DONE_MAINCONFIGREAD); } - res = openais_amf_config_read (&error_string); - if (res == -1) { - log_printf (LOG_LEVEL_ERROR, error_string); - openais_exit_error (AIS_DONE_AMFCONFIGREAD); - } - if (!openais_config.totem_config.interface_count) { - res = totem_config_read (&openais_config.totem_config, &error_string, 1); + res = totem_config_read (objdb, &openais_config.totem_config, &error_string, 1); if (res == -1) { log_printf (LOG_LEVEL_NOTICE, "AIS Executive Service: Copyright (C) 2002-2006 MontaVista Software, Inc and contributors.\n"); log_printf (LOG_LEVEL_ERROR, error_string); @@ -1210,7 +1233,7 @@ int main (int argc, char **argv) } } - res = totem_config_keyread (OPENAIS_CONFDIR "/authkey", &openais_config.totem_config, &error_string); + res = totem_config_keyread (objdb, &openais_config.totem_config, &error_string); if (res == -1) { log_printf (LOG_LEVEL_ERROR, error_string); openais_exit_error (AIS_DONE_MAINCONFIGREAD); @@ -1228,6 +1251,10 @@ int main (int argc, char **argv) openais_exit_error (AIS_DONE_LOGSETUP); } + aisexec_uid_determine (&openais_config); + + aisexec_gid_determine (&openais_config); + log_printf (LOG_LEVEL_NOTICE, "AIS Executive Service: Copyright (C) 2002-2006 MontaVista Software, Inc. and contributors.\n"); /* @@ -1262,7 +1289,7 @@ int main (int argc, char **argv) &openais_group_handle, deliver_fn, confchg_fn); - + totempg_groups_join ( openais_group_handle, &openais_group, @@ -1272,8 +1299,8 @@ int main (int argc, char **argv) * This must occur after totempg is initialized because "this_ip" must be set */ this_ip = &openais_config.totem_config.interfaces[0].boundto; - openais_service_init_all (service_count, &openais_config); - + openais_service_init_all (service_count, objdb); + sync_register (openais_sync_callbacks_retrieve, openais_sync_completed); diff --git a/exec/mainconfig.c b/exec/mainconfig.c index 48a360ea..10c9c812 100644 --- a/exec/mainconfig.c +++ b/exec/mainconfig.c @@ -6,7 +6,7 @@ * Author: Steven Dake (sdake@mvista.com) * * This software licensed under BSD license, the text of which follows: - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -49,8 +49,6 @@ #include "totem.h" #include "service.h" -DECLARE_LIST_INIT (saAmfGroupHead); - static char error_string_response[512]; typedef enum { @@ -61,58 +59,22 @@ typedef enum { MAIN_COMPONENTS } main_parse_t; -char *strstr_rs (const char *haystack, const char *needle) +/* This just makes the code below a little neater */ +static inline int objdb_get_string(struct objdb_iface_ver0 *objdb, unsigned int object_service_handle, + char *key, char **value) { - char *end_address; - char *new_needle; + int res; - new_needle = (char *)mempool_strdup (needle); - new_needle[strlen(new_needle) - 1] = '\0'; - - end_address = strstr (haystack, new_needle); - if (end_address) { - end_address += strlen (new_needle); - end_address = strstr (end_address, needle + strlen (new_needle)); + *value = NULL; + if ( !(res = objdb->object_key_get (object_service_handle, + key, + strlen (key), + (void *)value, + NULL))) { + if (*value) + return 0; } - if (end_address) { - end_address += 1; /* skip past { or = */ - do { - if (*end_address == '\t' || *end_address == ' ') { - end_address++; - } else { - break; - } - } while (*end_address != '\0'); - } - - mempool_free (new_needle); - return (end_address); -} - -/* 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; + return -1; } extern int openais_main_config_read ( @@ -121,186 +83,126 @@ extern int openais_main_config_read ( struct openais_config *openais_config, int interface_max) { - FILE *fp; - int line_number = 0; - main_parse_t parse = MAIN_HEAD; - int logging_parsed = 0; - int event_parsed = 0; - int amf_parsed = 0; - int components_parsed = 0; - char *loc; - int i; - int parse_done = 0; - char line[512]; + unsigned int object_service_handle; + char *value; char *error_reason = error_string_response; memset (openais_config, 0, sizeof (struct openais_config)); - fp = fopen (OPENAIS_CONFDIR "/openais.conf", "r"); - if (fp == 0) { - parse_done = 1; - sprintf (error_reason, "Can't read file %s/openais.conf reason = (%s)\n", - OPENAIS_CONFDIR, strerror (errno)); - *error_string = error_reason; - return -1; - } - while (fgets (line, 255, fp)) { - line_number += 1; - line[strlen(line) - 1] = '\0'; - /* - * Clear out white space and tabs - */ - for (i = strlen (line) - 1; i > -1; i--) { - if (line[i] == '\t' || line[i] == ' ') { - line[i] = '\0'; + objdb->object_find_reset (OBJECT_PARENT_HANDLE); + + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "logging", + strlen ("logging"), + &object_service_handle) == 0) { + + if (!objdb_get_string (objdb,object_service_handle, "logoutput", &value)) { + if (strcmp (value, "file") == 0) { + openais_config->logmode |= LOG_MODE_FILE; + } else + if (strcmp (value, "syslog") == 0) { + openais_config->logmode |= LOG_MODE_SYSLOG; + } else + if (strcmp (value, "stderr") == 0) { + openais_config->logmode |= LOG_MODE_STDERR; } else { - break; + goto parse_error; } } - /* - * Clear out comments and empty lines - */ - if (line[0] == '#' || line[0] == '\0') { - continue; + if (!objdb_get_string (objdb,object_service_handle, "debug", &value)) { + if (strcmp (value, "on") == 0) { + openais_config->logmode |= LOG_MODE_DEBUG; + } else + if (strcmp (value, "off") == 0) { + openais_config->logmode &= ~LOG_MODE_DEBUG; + } else { + goto parse_error; + } } - - switch (parse) { - case MAIN_HEAD: - if (logging_parsed == 0 && strstr_rs (line, "logging{")) { - logging_parsed = 1; - parse = MAIN_LOGGING; + if (!objdb_get_string (objdb,object_service_handle, "timestamp", &value)) { + if (strcmp (value, "on") == 0) { + openais_config->logmode |= LOG_MODE_TIMESTAMP; } else - if (event_parsed == 0 && strstr_rs (line, "event{")) { - event_parsed = 1; - parse = MAIN_EVENT; - } else - 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; - } - break; - - case MAIN_LOGGING: - if ((loc = strstr_rs (line, "logoutput:"))) { - if (strcmp (loc, "file") == 0) { - openais_config->logmode |= LOG_MODE_FILE; - } else - if (strcmp (loc, "syslog") == 0) { - openais_config->logmode |= LOG_MODE_SYSLOG; - } else - if (strcmp (loc, "stderr") == 0) { - openais_config->logmode |= LOG_MODE_STDERR; - } else { - goto parse_error; - } - } else - if ((loc = strstr_rs (line, "debug:"))) { - if (strcmp (loc, "on") == 0) { - openais_config->logmode |= LOG_MODE_DEBUG; - } else - if (strcmp (loc, "off") == 0) { - openais_config->logmode &= ~LOG_MODE_DEBUG; - } else { - goto parse_error; - } - } else - if ((loc = strstr_rs (line, "timestamp:"))) { - if (strcmp (loc, "on") == 0) { - openais_config->logmode |= LOG_MODE_TIMESTAMP; - } else - if (strcmp (loc, "off") == 0) { - openais_config->logmode &= ~LOG_MODE_TIMESTAMP; - } else { - goto parse_error; - } - } else - if ((loc = strstr_rs (line, "logfile:"))) { - openais_config->logfile = strdup (loc); - } else - if ((loc = strstr_rs (line, "}"))) { - parse = MAIN_HEAD; + if (strcmp (value, "off") == 0) { + openais_config->logmode &= ~LOG_MODE_TIMESTAMP; } else { goto parse_error; } - break; - - case MAIN_EVENT: - if ((loc = strstr_rs (line, "delivery_queue_size:"))) { - openais_config->evt_delivery_queue_size = atoi(loc); - } else if ((loc = strstr_rs (line, "delivery_queue_resume:"))) { - openais_config->evt_delivery_queue_resume = atoi(loc); - } else if ((loc = strstr_rs (line, "}"))) { - parse = MAIN_HEAD; - } else { - goto parse_error; - } - break; - - case MAIN_AMF: - if ((loc = strstr_rs (line, "mode:"))) { - if (strcmp (loc, "enabled") == 0) { - openais_config->amf_enabled = 1; - } else - if (strcmp (loc, "disabled") == 0) { - openais_config->amf_enabled = 0; - } else { - goto parse_error; - } - } else - if ((loc = strstr_rs (line, "}"))) { - parse = MAIN_HEAD; - } else { - goto parse_error; - } - break; - case MAIN_COMPONENTS: - if ((loc = strstr_rs (line, "}"))) { - parse = MAIN_HEAD; - } - else { - int version; - char *name = get_component(line, &version); - if (name) { - openais_service_objdb_add (objdb, name, version); - } - } - break; - default: - assert (0 == 1); /* SHOULDN'T HAPPEN */ - break; + } + if (!objdb_get_string (objdb,object_service_handle, "logfile", &value)) { + openais_config->logfile = strdup (value); } } + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "event", + strlen ("event"), + &object_service_handle) == 0) { + + if (!objdb_get_string (objdb,object_service_handle, "delivery_queue_size", &value)) { + openais_config->evt_delivery_queue_size = atoi(value); + } + if (!objdb_get_string (objdb,object_service_handle, "delivery_queue_resume", &value)) { + openais_config->evt_delivery_queue_resume = atoi(value); + } + } + + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "amf", + strlen ("amf"), + &object_service_handle) == 0) { + + if (!objdb_get_string (objdb,object_service_handle, "mode", &value)) { + if (strcmp (value, "enabled") == 0) { + openais_config->amf_enabled = 1; + } else + if (strcmp (value, "disabled") == 0) { + openais_config->amf_enabled = 0; + } else { + goto parse_error; + } + } + } + + openais_config->user = NULL; + openais_config->group = NULL; + + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "aisexec", + strlen ("aisexec"), + &object_service_handle) == 0) { + + if (!objdb_get_string (objdb,object_service_handle, "user", &value)) { + openais_config->user = strdup(value); + } + if (!objdb_get_string (objdb,object_service_handle, "group", &value)) { + openais_config->group = strdup(value); + } + } + + /* Default user/group */ + if (!openais_config->user) + openais_config->user = OPENAIS_USER; + + if (!openais_config->group) + openais_config->group = OPENAIS_GROUP; + if ((openais_config->logmode & LOG_MODE_FILE) && openais_config->logfile == 0) { error_reason = "logmode set to 'file' but no logfile specified"; goto parse_error; } - if (parse == MAIN_HEAD) { - fclose (fp); - return (0); - } else { - error_reason = "Missing closing brace"; - goto parse_error; - } + return 0; parse_error: - if (parse_done) { - sprintf (error_string_response, - "parse error in %s/openais.conf: %s.\n", - OPENAIS_CONFDIR, error_reason); - } else { - sprintf (error_string_response, - "parse error in %s/openais.conf: %s (line %d).\n", - OPENAIS_CONFDIR, error_reason, line_number); - } + sprintf (error_string_response, + "parse error in config: %s.\n", + error_reason); + *error_string = error_string_response; - fclose (fp); return (-1); } diff --git a/exec/mainconfig.h b/exec/mainconfig.h index c82c4c13..62e3dfd8 100644 --- a/exec/mainconfig.h +++ b/exec/mainconfig.h @@ -60,6 +60,10 @@ struct openais_config { int logmode; char *logfile; + /* user/group to run as */ + char *user; + char *group; + /* * Event service */ diff --git a/exec/msg.c b/exec/msg.c index 60f0eae1..deab7c41 100644 --- a/exec/msg.c +++ b/exec/msg.c @@ -109,7 +109,7 @@ struct queue_cleanup { DECLARE_LIST_INIT(queue_list_head); DECLARE_LIST_INIT(queue_group_list_head); -static int msg_exec_init_fn (struct openais_config *); +static int msg_exec_init_fn (struct objdb_iface_ver0 *objdb); static int msg_lib_exit_fn (void *conn); @@ -666,7 +666,7 @@ static struct queue_group_entry *queue_group_entry_find ( return (0); } -static int msg_exec_init_fn (struct openais_config *openais_config) +static int msg_exec_init_fn (struct objdb_iface_ver0 *objdb) { /* * Initialize the saved ring ID. diff --git a/exec/service.c b/exec/service.c index 2e68b360..a6b08abe 100644 --- a/exec/service.c +++ b/exec/service.c @@ -113,14 +113,18 @@ int openais_service_objdb_add ( static int service_handler_config ( struct openais_service_handler *handler, - struct openais_config *config) + struct objdb_iface_ver0 *objdb) { int res = 0; - assert (ais_service[handler->id] == NULL); + + /* 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 (config); + res = ais_service[handler->id]->config_init_fn (objdb); } return (res); } @@ -131,6 +135,28 @@ static int service_handler_config ( int openais_service_default_objdb_set (struct objdb_iface_ver0 *objdb) { int i; + unsigned int object_service_handle; + char *value = NULL; + + /* Load default services unless they have been explicitly disabled */ + objdb->object_find_reset (OBJECT_PARENT_HANDLE); + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "aisexec", + strlen ("aisexec"), + &object_service_handle) == 0) { + + if ( ! objdb->object_key_get (object_service_handle, + "defaultservices", + strlen ("defaultservices"), + (void *)&value, + NULL)) { + + if (value && strcmp (value, "no") == 0) { + return 0; + } + } + } 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); @@ -191,13 +217,13 @@ int openais_service_link_all (struct objdb_iface_ver0 *objdb, } service_handler_config ( - iface_ver0->openais_get_service_handler_ver0(), openais_config); + iface_ver0->openais_get_service_handler_ver0(), objdb); } return (0); } int openais_service_init_all (int service_count, - struct openais_config *openais_config) + struct objdb_iface_ver0 *objdb) { int i; int res=0; @@ -205,7 +231,7 @@ int openais_service_init_all (int service_count, 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 (openais_config); + res = ais_service[i]->exec_init_fn (objdb); } } return (res); diff --git a/exec/service.h b/exec/service.h index 2d35ffbd..df4a1305 100644 --- a/exec/service.h +++ b/exec/service.h @@ -69,8 +69,8 @@ struct openais_service_handler { struct openais_lib_handler *lib_service; int lib_service_count; struct openais_exec_handler *exec_service; - int (*exec_init_fn) (struct openais_config *); - int (*config_init_fn) (struct openais_config *); + int (*exec_init_fn) (struct objdb_iface_ver0 *); + int (*config_init_fn) (struct objdb_iface_ver0 *); void (*exec_dump_fn) (void); int exec_service_count; void (*confchg_fn) ( @@ -108,7 +108,7 @@ extern int openais_service_link_all ( extern int openais_service_init_all ( int service_count, - struct openais_config *openais_config); + struct objdb_iface_ver0 *objdb); extern struct openais_service_handler *ais_service[]; diff --git a/exec/totemconfig.c b/exec/totemconfig.c index 439f2305..fdbe727c 100644 --- a/exec/totemconfig.c +++ b/exec/totemconfig.c @@ -7,7 +7,7 @@ * Author: Steven Dake (sdake@mvista.com) * * This software licensed under BSD license, the text of which follows: - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -51,6 +51,7 @@ #include "totem.h" #include "totemconfig.h" #include "print.h" +#include "objdb.h" #define LOG_SERVICE LOG_SERVICE_GMI @@ -75,75 +76,51 @@ static char error_string_response[512]; -typedef enum { - MAIN_HEAD, - MAIN_TOTEM, -} main_parse_t; - -static inline char * -strstr_rs (const char *haystack, const char *needle) +/* These just makes the code below a little neater */ +static inline int objdb_get_string(struct objdb_iface_ver0 *objdb, unsigned int object_service_handle, + char *key, char **value) { - char *end_address; - char *new_needle; - char *token = (char *)(needle + strlen (needle) - 1); /* last char is always the token */ + int res; - - new_needle = (char *)strdup (needle); - new_needle[strlen(new_needle) - 1] = '\0'; /* remove token */ - - end_address = strstr (haystack, new_needle); - if (end_address == 0) { - goto not_found; + *value = NULL; + if ( !(res = objdb->object_key_get (object_service_handle, + key, + strlen (key), + (void *)value, + NULL))) { + if (*value) + return 0; } - - end_address += strlen (new_needle); - - /* - * Parse all tabs and spaces until token is found - * if other character found besides token, its not a match - */ - do { - if (*end_address == '\t' || *end_address == ' ') { - end_address++; - } else { - break; - } - } while (*end_address != '\0' && *end_address != token[0]); - - if (*end_address != token[0]) { - end_address = 0; - goto not_found; - } - - end_address++; /* skip past token */ - - do { - if (*end_address == '\t' || *end_address == ' ') { - end_address++; - } else { - break; - } - } while (*end_address != '\0'); - -not_found: - free (new_needle); - return (end_address); + return -1; } +static inline void objdb_get_int(struct objdb_iface_ver0 *objdb, unsigned int object_service_handle, + char *key, unsigned int *intvalue) +{ + char *value = NULL; + + if (!objdb->object_key_get (object_service_handle, + key, + strlen (key), + (void *)&value, + NULL)) { + if (value) { + *intvalue = atoi(value); + } + } +} + + extern int totem_config_read ( + struct objdb_iface_ver0 *objdb, struct totem_config *totem_config, char **error_string, int interface_max) { - FILE *fp; int res = 0; - int line_number = 0; - main_parse_t parse = MAIN_HEAD; - int totem_parsed = 0; - char *loc; - int i; int parse_done = 0; - char line[512]; + unsigned int object_service_handle; + char *value; char *error_reason = error_string_response; memset (totem_config, 0, sizeof (struct totem_config)); @@ -159,151 +136,98 @@ extern int totem_config_read ( totem_config->secauth = 1; - fp = fopen (OPENAIS_CONFDIR "/openais.conf", "r"); + objdb->object_find_reset (OBJECT_PARENT_HANDLE); - if (fp == 0) { - parse_done = 1; - sprintf (error_reason, "Can't read file %s reason = (%s)\n", - OPENAIS_CONFDIR, strerror (errno)); - *error_string = error_reason; - return -1; - } + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "network", + strlen ("network"), + &object_service_handle) == 0 || + objdb->object_find ( + OBJECT_PARENT_HANDLE, + "totem", + strlen ("totem"), + &object_service_handle) == 0) { - while (fgets (line, 255, fp)) { - line_number += 1; - line[strlen(line) - 1] = '\0'; - /* - * Clear out white space and tabs - */ - for (i = strlen (line) - 1; i > -1; i--) { - if (line[i] == '\t' || line[i] == ' ') { - line[i] = '\0'; - } else { - break; + if (!objdb_get_string (objdb,object_service_handle, "version", &value)) { + if (strcmp (value, "1") == 0) { + totem_config->version = 1; } } - /* - * Clear out comments and empty lines - */ - if (line[0] == '#' || line[0] == '\0') { - continue; - } - - switch (parse) { - case MAIN_HEAD: - if (totem_parsed == 0 && strstr_rs (line, "network{")) { - totem_parsed = 1; - parse = MAIN_TOTEM; - } else - if (totem_parsed == 0 && strstr_rs (line, "totem{")) { - totem_parsed = 1; - parse = MAIN_TOTEM; - } else { - continue; + if (!objdb_get_string (objdb,object_service_handle, "secauth", &value)) { + if (strcmp (value, "on") == 0) { + totem_config->secauth = 1; } - break; + if (strcmp (value, "off") == 0) { + totem_config->secauth = 0; + } + } + objdb_get_int (objdb,object_service_handle, "threads", &totem_config->threads); - case MAIN_TOTEM: - if ((loc = strstr_rs (line, "version:"))) { - if (strcmp (loc, "1") == 0) { - totem_config->version = 1; - } - } else - if ((loc = strstr_rs (line, "secauth:"))) { - if (strcmp (loc, "on") == 0) { - totem_config->secauth = 1; - } else - if (strcmp (loc, "off") == 0) { - totem_config->secauth = 0; - } - } else - if ((loc = strstr_rs (line, "threads:"))) { - totem_config->threads = atoi (loc); - } else - if ((loc = strstr_rs (line, "nodeid:"))) { - res = totem_config->node_id = atoi (loc); - } else - if ((loc = strstr_rs (line, "netmtu:"))) { - totem_config->net_mtu = atoi (loc); - } else - if ((loc = strstr_rs (line, "mcastaddr:"))) { - res = totemip_parse (&totem_config->mcast_addr, loc); - } else - if ((loc = strstr_rs (line, "mcastport:"))) { - res = totem_config->ip_port = htons (atoi (loc)); - } else - if ((loc = strstr_rs (line, "bindnetaddr:"))) { - if (interface_max == totem_config->interface_count) { - sprintf (error_reason, - "%d is too many interfaces in %s/network.conf", - totem_config->interface_count, OPENAIS_CONFDIR); - goto parse_error; - } - res = totemip_parse (&totem_config->interfaces[totem_config->interface_count].bindnet, loc); - totem_config->interface_count += 1; - } else - if ((loc = strstr_rs (line, "token:"))) { - totem_config->token_timeout = atoi(loc); - } else if ((loc = strstr_rs (line, "token_retransmit:"))) { - totem_config->token_retransmit_timeout = atoi(loc); - } else if ((loc = strstr_rs (line, "hold:"))) { - totem_config->token_hold_timeout = atoi(loc); - } else if ((loc = strstr_rs (line, "token_retransmits_before_loss_const:"))) { - totem_config->token_retransmits_before_loss_const = atoi(loc); - } else if ((loc = strstr_rs (line, "join:"))) { - totem_config->join_timeout = atoi(loc); - } else if ((loc = strstr_rs (line, "consensus:"))) { - totem_config->consensus_timeout = atoi(loc); - } else if ((loc = strstr_rs (line, "merge:"))) { - totem_config->merge_timeout = atoi(loc); - } else if ((loc = strstr_rs (line, "downcheck:"))) { - totem_config->downcheck_timeout = atoi(loc); - } else if ((loc = strstr_rs (line, "fail_recv_const:"))) { - totem_config->fail_to_recv_const = atoi(loc); - } else if ((loc = strstr_rs (line, "seqno_unchanged_const:"))) { - totem_config->seqno_unchanged_const = atoi(loc); - } else if ((loc = strstr_rs (line, "heartbeat_failures_allowed:"))) { - totem_config->heartbeat_failures_allowed = atoi(loc); - } else if ((loc = strstr_rs (line, "max_network_delay:"))) { - totem_config->max_network_delay = atoi(loc); - } else if ((loc = strstr_rs (line, "window_size:"))) { - totem_config->window_size = atoi(loc); - } else if ((loc = strstr_rs (line, "max_messages:"))) { - totem_config->max_messages = atoi(loc); - } else - if ((loc = strstr_rs (line, "}"))) { - parse = MAIN_HEAD; - } else { + objdb_get_int (objdb,object_service_handle, "nodeid", &totem_config->node_id); + + objdb_get_int (objdb,object_service_handle, "netmtu", &totem_config->net_mtu); + + if (!objdb_get_string (objdb,object_service_handle, "mcastaddr", &value)) { + res = totemip_parse (&totem_config->mcast_addr, value); + } + + if (!objdb_get_string (objdb,object_service_handle, "mcastport", &value)) { + totem_config->ip_port = htons (atoi (value)); + } + + // TODO This really expects a list....copy stuff from services ? + if (!objdb_get_string (objdb,object_service_handle, "bindnetaddr", &value)) { + + if (interface_max == totem_config->interface_count) { + sprintf (error_reason, + "%d is too many interfaces in %s/network.conf", + totem_config->interface_count, OPENAIS_CONFDIR); goto parse_error; } - break; - default: - assert (0 == 1); /* SHOULDN'T HAPPEN */ - break; + res = totemip_parse (&totem_config->interfaces[totem_config->interface_count].bindnet, value); + totem_config->interface_count += 1; } + + objdb_get_int (objdb,object_service_handle, "token", &totem_config->token_timeout); + + objdb_get_int (objdb,object_service_handle, "token_retransmit", &totem_config->token_retransmit_timeout); + + objdb_get_int (objdb,object_service_handle, "hold", &totem_config->token_hold_timeout); + + objdb_get_int (objdb,object_service_handle, "token_retransmits_before_loss_const", &totem_config->token_retransmits_before_loss_const); + + objdb_get_int (objdb,object_service_handle, "join", &totem_config->join_timeout); + + objdb_get_int (objdb,object_service_handle, "consensus", &totem_config->consensus_timeout); + + objdb_get_int (objdb,object_service_handle, "merge", &totem_config->merge_timeout); + + objdb_get_int (objdb,object_service_handle, "downcheck", &totem_config->downcheck_timeout); + + objdb_get_int (objdb,object_service_handle, "fail_recv_const", &totem_config->fail_to_recv_const); + + objdb_get_int (objdb,object_service_handle, "seqno_unchanged_const", &totem_config->seqno_unchanged_const); + + objdb_get_int (objdb,object_service_handle, "heartbeat_failures_allowed", &totem_config->heartbeat_failures_allowed); + + objdb_get_int (objdb,object_service_handle, "max_network_delay", &totem_config->max_network_delay); + + objdb_get_int (objdb,object_service_handle, "window_size", &totem_config->window_size); + + objdb_get_int (objdb,object_service_handle, "max_messages", &totem_config->max_messages); } - - if (parse == MAIN_HEAD) { - fclose (fp); - return (0); - } else { - error_reason = "Missing closing brace"; - goto parse_error; - } + return 0; parse_error: - if (parse_done) { - sprintf (error_string_response, - "parse error in %s/openais.conf: %s.\n", - OPENAIS_CONFDIR, error_reason); - } else { - sprintf (error_string_response, - "parse error in %s/openais.conf: %s (line %d).\n", - OPENAIS_CONFDIR, error_reason, line_number); - } + + sprintf (error_string_response, + "parse error in config %s.\n", + error_reason); + *error_string = error_string_response; - fclose (fp); + return (-1); } @@ -340,7 +264,7 @@ int totem_config_validate ( } if (totem_config->version != 1) { - error_reason = "This totem parser can only parse version 1 configuration files."; + error_reason = "This totem parser can only parse version 1 configurations."; goto parse_error; } @@ -487,32 +411,28 @@ int totem_config_validate ( error_reason = "This net_mtu parameter is greater then the maximum frame size"; goto parse_error; } - + return (0); parse_error: sprintf (error_string_response, - "parse error in %s/openais.conf: %s\n", OPENAIS_CONFDIR, error_reason); + "parse error in config: %s\n", error_reason); *error_string = error_string_response; return (-1); } -int totem_config_keyread ( +static int read_keyfile ( char *key_location, struct totem_config *totem_config, char **error_string) { int fd; int res; - int i; - if (totem_config->secauth == 0) { - return (0); - } fd = open (key_location, O_RDONLY); if (fd == -1) { sprintf (error_string_response, "Could not open %s: %s\n", - key_location, strerror (errno)); + key_location, strerror (errno)); goto parse_error; } @@ -520,7 +440,7 @@ int totem_config_keyread ( if (res == -1) { close (fd); sprintf (error_string_response, "Could not read %s: %s\n", - key_location, strerror (errno)); + key_location, strerror (errno)); goto parse_error; } @@ -529,9 +449,74 @@ int totem_config_keyread ( if (res != 128) { close (fd); sprintf (error_string_response, "Could only read %d bits of 1024 bits from %s.\n", - res * 8, key_location); + res * 8, key_location); goto parse_error; } + return 0; + +parse_error: + *error_string = error_string_response; + return (-1); +} + +int totem_config_keyread ( + struct objdb_iface_ver0 *objdb, + struct totem_config *totem_config, + char **error_string) +{ + int got_key = 0; + char *key_location = NULL; + unsigned int object_service_handle; + int res; + int i; + + if (totem_config->secauth == 0) { + return (0); + } + + if (objdb->object_find ( + OBJECT_PARENT_HANDLE, + "network", + strlen ("network"), + &object_service_handle) == 0 || + objdb->object_find ( + OBJECT_PARENT_HANDLE, + "totem", + strlen ("totem"), + &object_service_handle) == 0) { + + /* objdb may store the location of the key file */ + if (!objdb_get_string (objdb,object_service_handle, "keyfile", &key_location) + && key_location) { + res = read_keyfile(key_location, totem_config, error_string); + if (res) + goto key_error; + got_key = 1; + } + else { /* Or the key itself may be in the objdb */ + char *key = NULL; + int key_len; + res = objdb->object_key_get (object_service_handle, + "key", + strlen ("key"), + (void *)&key, + &key_len); + if (res == 0 && key) { + memcpy(totem_config->private_key, key, key_len); + totem_config->private_key_len = key_len; + got_key = 1; + } + } + } + + /* In desperation we read the default filename */ + if (!got_key) { + res = read_keyfile(OPENAIS_CONFDIR "/authkey", totem_config, error_string); + if (res) + goto key_error; + + } + if (totem_config->mcast_addr.family != totem_config->interfaces[0].bindnet.family) { strcpy (error_string_response, "Multicast address family does not match bind address family"); goto parse_error; @@ -546,5 +531,7 @@ int totem_config_keyread ( parse_error: *error_string = error_string_response; +key_error: return (-1); + } diff --git a/exec/totemconfig.h b/exec/totemconfig.h index eb6753d6..b568a771 100644 --- a/exec/totemconfig.h +++ b/exec/totemconfig.h @@ -37,11 +37,13 @@ #include "aispoll.h" #include "totemsrp.h" #include "totempg.h" +#include "objdb.h" #ifndef TOTEMCONFIG_H_DEFINED #define TOTEMCONFIG_H_DEFINED extern int totem_config_read ( + struct objdb_iface_ver0 *objdb, struct totem_config *totem_config, char **error_string, int interface_max); @@ -51,7 +53,7 @@ extern int totem_config_validate ( char **error_string); int totem_config_keyread ( - char *key_location, + struct objdb_iface_ver0 *objdb, struct totem_config *totem_config, char **error_string);