File pacemaker.diff of Package openais
--- whitetank-svn/Makefile
+++ whitetank-dev/Makefile
@@ -29,30 +29,30 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
-DESTDIR=/usr/local
-SBINDIR=/usr/sbin
-INCLUDEDIR=/usr/include/openais
-INCLUDEDIR_TOTEM=/usr/include/openais/totem
-INCLUDEDIR_LCR=/usr/include/openais/lcr
-INCLUDEDIR_SERVICE=/usr/include/openais/service
-MANDIR=/usr/share/man
+include Makefile.inc
+
+SBINDIR=$(PREFIX)/sbin
+INCLUDEDIR=$(PREFIX)/include/openais
+INCLUDEDIR_TOTEM=$(PREFIX)/include/openais/totem
+INCLUDEDIR_LCR=$(PREFIX)/include/openais/lcr
+INCLUDEDIR_SERVICE=$(PREFIX)/include/openais/service
+MANDIR=$(PREFIX)/share/man
ETCDIR=/etc/ais
-LCRSODIR=/usr/libexec/lcrso
ARCH=$(shell uname -p)
ifeq (,$(findstring 64,$(ARCH)))
-LIBDIR=/usr/lib/openais
+LIBDIR=$(PREFIX)/lib/openais
else
-LIBDIR=/usr/lib64/openais
+LIBDIR=$(PREFIX)/lib64/openais
endif
ifeq (s390,$(ARCH))
-LIBDIR=/usr/lib/openais
+LIBDIR=$(PREFIX)/lib/openais
endif
ifeq (s390x,$(ARCH))
-LIBDIR=/usr/lib64/openais
+LIBDIR=$(PREFIX)/lib64/openais
endif
ifeq (ia64,$(ARCH))
-LIBDIR=/usr/lib/openais
+LIBDIR=$(PREFIX)/lib/openais
endif
all:
@@ -106,29 +106,29 @@ install:
ln -sf libcfg.so.2.0.0 lib/libcfg.so.2
ln -sf libtotem_pg.so.2.0.0 exec/libtotem_pg.so.2
- cp -a lib/libais.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaAmf.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaClm.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaCkpt.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaEvt.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaLck.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaMsg.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libevs.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libcpg.so $(DESTDIR)$(LIBDIR)
- cp -a lib/libcfg.so $(DESTDIR)$(LIBDIR)
- cp -a exec/libtotem_pg.so $(DESTDIR)$(LIBDIR)
-
- cp -a lib/libais.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaAmf.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaClm.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaCkpt.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaEvt.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaLck.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libSaMsg.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libevs.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libcpg.so.2 $(DESTDIR)$(LIBDIR)
- cp -a lib/libcfg.so.2 $(DESTDIR)$(LIBDIR)
- cp -a exec/libtotem_pg.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libais.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaAmf.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaClm.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaCkpt.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaEvt.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaLck.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaMsg.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libevs.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libcpg.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libcfg.so $(DESTDIR)$(LIBDIR)
+ $(CP) -a exec/libtotem_pg.so $(DESTDIR)$(LIBDIR)
+
+ $(CP) -a lib/libais.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaAmf.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaClm.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaCkpt.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaEvt.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaLck.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libSaMsg.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libevs.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libcpg.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a lib/libcfg.so.2 $(DESTDIR)$(LIBDIR)
+ $(CP) -a exec/libtotem_pg.so.2 $(DESTDIR)$(LIBDIR)
install -m 755 lib/libais.so.2.* $(DESTDIR)$(LIBDIR)
install -m 755 lib/libSaAmf.so.2.* $(DESTDIR)$(LIBDIR)
@@ -158,7 +158,7 @@ ifneq "NO" "$(STATICLIBS)"
install -m 755 exec/libtotem_pg.a $(DESTDIR)$(LIBDIR)
endif
- echo $(LIBDIR) > $(DESTDIR)/etc/ld.so.conf.d/openais-$(ARCH).conf
+ echo $(LIBDIR) > "$(DESTDIR)/etc/ld.so.conf.d/openais-$(ARCH).conf"
install -m 755 exec/*lcrso $(DESTDIR)$(LCRSODIR)
--- whitetank-svn/Makefile.inc
+++ whitetank-dev/Makefile.inc
@@ -29,12 +29,17 @@
# THE POSSIBILITY OF SUCH DAMAGE.
# Basic OS detection
#
+CP=cp
+DESTDIR=
+PREFIX=/usr/local
UNAME=$(shell uname)
+LCRSODIR=$(PREFIX)/libexec/lcrso
ifeq "$(UNAME)" "Linux"
OPENAIS_COMPAT=LINUX
endif
ifeq "$(UNAME)" "Darwin"
+ CP=rsync
OPENAIS_COMPAT=DARWIN
endif
ifneq "" "$(findstring BSD,$(UNAME))"
--- whitetank-svn/conf/openais.conf
+++ whitetank-dev/conf/openais.conf
@@ -1,22 +1,66 @@
# Please read the openais.conf.5 manual page
+aisexec {
+ # Run as root - this is necessary to be able to manage resources with Pacemaker
+ user: root
+ group: root
+}
+
+service {
+ # Load the Pacemaker Cluster Resource Manager
+ name: pacemaker
+ ver: 0
+}
+
totem {
version: 2
+
+ # How long before declaring a token lost (ms)
+ token: 10000
+
+ # How many token retransmits before forming a new configuration
+ token_retransmits_before_loss_const: 20
+
+ # How long to wait for join messages in the membership protocol (ms)
+ join: 60
+
+ # How long to wait for consensus to be achieved before starting a new round of membership configuration (ms)
+ consensus: 4800
+
+ # Turn off the virtual synchrony filter
+ vsftype: none
+
+ # Number of messages that may be sent by one processor on receipt of the token
+ max_messages: 20
+
+ # Limit generated nodeids to 31-bits (positive signed integers)
+ clear_node_high_bit: yes
+
+ # Disable encryption
secauth: off
+
+ # How many threads to use for encryption/decryption
threads: 0
+
+ # Optionally assign a fixed node id (integer)
+ # nodeid: 1234
+
interface {
ringnumber: 0
- bindnetaddr: 192.168.2.0
- mcastaddr: 226.94.1.1
- mcastport: 5405
+
+ # The following values need to be set based on your environment
+ #bindnetaddr: 192.168.2.0
+ #mcastaddr: 226.94.1.1
+ #mcastport: 5405
}
}
logging {
- to_stderr: yes
- to_file: yes
- logfile: /tmp/ais
debug: off
+ fileline: off
+ to_syslog: yes
+ to_stderr: yes
+ syslog_facility: daemon
timestamp: on
}
--- whitetank-svn/exec/cfg.c
+++ whitetank-dev/exec/cfg.c
@@ -109,6 +109,14 @@ static void message_handler_req_lib_cfg_
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
*/
@@ -120,35 +128,47 @@ static struct openais_lib_handler cfg_li
.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
}
};
@@ -177,6 +197,8 @@ struct openais_service_handler cfg_servi
.confchg_fn = cfg_confchg_fn,
};
+static struct objdb_iface_ver0 *my_objdb;
+
/*
* Dynamic Loader definition
*/
@@ -226,6 +248,7 @@ struct req_exec_cfg_ringreenable {
static int cfg_exec_init_fn (struct objdb_iface_ver0 *objdb)
{
log_init ("CFG");
+ my_objdb = objdb;
return (0);
}
static void cfg_confchg_fn (
@@ -380,3 +403,49 @@ static void message_handler_req_lib_cfg_
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, 0);
+
+ 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_response_send (
+ 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_response_send (
+ conn,
+ &res_lib_cfg_serviceunload,
+ sizeof (struct res_lib_cfg_serviceunload));
+ LEAVE("");
+}
--- whitetank-svn/exec/clm.c
+++ whitetank-dev/exec/clm.c
@@ -134,6 +134,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);
@@ -208,6 +210,7 @@ struct openais_service_handler clm_servi
.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),
@@ -336,6 +339,11 @@ static int clm_exec_init_fn (struct objd
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);
--- whitetank-svn/exec/main.c
+++ whitetank-dev/exec/main.c
@@ -92,6 +92,8 @@ static struct totem_logging_configuratio
static char delivery_data[MESSAGE_SIZE_MAX];
+static struct objdb_iface_ver0 *objdb = NULL;
+
SaClmClusterNodeT *(*main_clm_get_by_nodeid) (unsigned int node_id);
static void sigusr2_handler (int num)
@@ -105,6 +107,50 @@ static void sigusr2_handler (int num)
}
}
+static void *aisexec_exit (void *arg)
+{
+ if(objdb) {
+ openais_service_unlink_all (objdb);
+ }
+
+#ifdef DEBUG_MEMPOOL
+ int stats_inuse[MEMPOOL_GROUP_SIZE];
+ int stats_avail[MEMPOOL_GROUP_SIZE];
+ int stats_memoryused[MEMPOOL_GROUP_SIZE];
+ int i;
+
+ mempool_getstats (stats_inuse, stats_avail, stats_memoryused);
+ log_printf (LOG_LEVEL_DEBUG, "Memory pools:\n");
+ for (i = 0; i < MEMPOOL_GROUP_SIZE; i++) {
+ log_printf (LOG_LEVEL_DEBUG, "order %d size %d inuse %d avail %d memory used %d\n",
+ i, 1<<i, stats_inuse[i], stats_avail[i], stats_memoryused[i]);
+ }
+#endif
+
+ totempg_finalize ();
+ log_flush ();
+
+ openais_exit_error (AIS_DONE_EXIT);
+
+ /* never reached */
+ return NULL;
+}
+
+pthread_t aisexec_exit_thread;
+static void init_shutdown(void *data)
+{
+ pthread_create (&aisexec_exit_thread, NULL, aisexec_exit, NULL);
+}
+
+
+static poll_timer_handle shutdown_handle;
+static void sigquit_handler (int num)
+{
+ /* avoid creating threads from within the interrupt context */
+ poll_timer_add (aisexec_poll_handle, 500, NULL, init_shutdown, &shutdown_handle);
+}
+
+
static void sigsegv_handler (int num)
{
signal (SIGSEGV, SIG_DFL);
@@ -131,23 +177,7 @@ struct totempg_group openais_group = {
void sigintr_handler (int signum)
{
-
-#ifdef DEBUG_MEMPOOL
- int stats_inuse[MEMPOOL_GROUP_SIZE];
- int stats_avail[MEMPOOL_GROUP_SIZE];
- int stats_memoryused[MEMPOOL_GROUP_SIZE];
- int i;
-
- mempool_getstats (stats_inuse, stats_avail, stats_memoryused);
- log_printf (LOG_LEVEL_DEBUG, "Memory pools:\n");
- for (i = 0; i < MEMPOOL_GROUP_SIZE; i++) {
- log_printf (LOG_LEVEL_DEBUG, "order %d size %d inuse %d avail %d memory used %d\n",
- i, 1<<i, stats_inuse[i], stats_avail[i], stats_memoryused[i]);
- }
-#endif
-
- totempg_finalize ();
- openais_exit_error (AIS_DONE_EXIT);
+ poll_timer_add (aisexec_poll_handle, 500, NULL, init_shutdown, &shutdown_handle);
}
@@ -273,6 +303,7 @@ static void aisexec_tty_detach (void)
/*
* Disconnect from TTY if this is not a debug run
*/
+
switch (fork ()) {
case -1:
openais_exit_error (AIS_DONE_FORK);
@@ -281,6 +312,10 @@ static void aisexec_tty_detach (void)
/*
* child which is disconnected, run this process
*/
+/* setset(); */
+ close (0);
+ close (1);
+ close (2);
break;
default:
exit (0);
@@ -373,6 +408,13 @@ static void deliver_fn (
*/
service = header->id >> 16;
fn_id = header->id & 0xffff;
+
+ if(service >= SERVICE_HANDLER_MAXIMUM_COUNT
+ || ais_service[service] == NULL) {
+ /* The component is no longer loaded */
+ return;
+ }
+
if (endian_conversion_required) {
ais_service[service]->exec_service[fn_id].exec_endian_convert_fn
(header);
@@ -390,7 +432,6 @@ int main (int argc, char **argv)
unsigned int objdb_handle;
unsigned int config_handle;
unsigned int config_version = 0;
- struct objdb_iface_ver0 *objdb;
void *objdb_p;
struct config_iface_ver0 *config;
void *config_p;
@@ -427,6 +468,7 @@ int main (int argc, char **argv)
signal (SIGUSR2, sigusr2_handler);
signal (SIGSEGV, sigsegv_handler);
signal (SIGABRT, sigabrt_handler);
+ signal (SIGQUIT, sigquit_handler);
openais_timer_init (
serialize_mutex_lock,
@@ -456,7 +498,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";
@@ -481,14 +527,6 @@ int main (int argc, char **argv)
openais_exit_error (AIS_DONE_MAINCONFIGREAD);
}
- 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);
@@ -568,12 +606,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);
--- whitetank-svn/exec/objdb.c
+++ whitetank-dev/exec/objdb.c
@@ -52,10 +52,13 @@ struct object_instance {
void *object_name;
int object_name_len;
unsigned int object_handle;
+ unsigned int parent_handle;
struct list_head key_head;
struct list_head child_head;
struct list_head child_list;
struct list_head *find_child_list;
+ struct list_head *iter_key_list;
+ struct list_head *iter_list;
void *priv;
struct object_valid *object_valid_list;
int object_valid_list_entries;
@@ -70,6 +73,7 @@ static struct hdb_handle_database object
.mutex = PTHREAD_MUTEX_INITIALIZER
};
+
static int objdb_init (void)
{
unsigned int handle;
@@ -179,9 +183,12 @@ static int object_create (
object_instance->object_handle = *object_handle;
object_instance->find_child_list = &object_instance->child_head;
+ object_instance->iter_key_list = &object_instance->key_head;
+ object_instance->iter_list = &object_instance->child_head;
object_instance->priv = NULL;
object_instance->object_valid_list = NULL;
object_instance->object_valid_list_entries = 0;
+ object_instance->parent_handle = parent_object_handle;
hdb_handle_put (&object_instance_database, *object_handle);
@@ -313,10 +320,66 @@ error_exit:
return (-1);
}
+
+static int _clear_object(struct object_instance *instance)
+{
+ struct list_head *list;
+ int res;
+ struct object_instance *find_instance = NULL;
+ struct object_key *object_key = NULL;
+
+ for (list = instance->key_head.next;
+ list != &instance->key_head; ) {
+
+ object_key = list_entry (list, struct object_key,
+ list);
+
+ list = list->next;
+
+ list_del(&object_key->list);
+ free(object_key->key_name);
+ free(object_key->value);
+ }
+
+ for (list = instance->child_head.next;
+ list != &instance->child_head; ) {
+
+ find_instance = list_entry (list, struct object_instance,
+ child_list);
+ res = _clear_object(find_instance);
+ if (res)
+ return res;
+
+ list = list->next;
+
+ list_del(&find_instance->child_list);
+ free(find_instance->object_name);
+ free(find_instance);
+ }
+
+ return 0;
+}
+
static int object_destroy (
unsigned int object_handle)
{
- return (0);
+ struct object_instance *instance;
+ unsigned int res;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ return (res);
+ }
+
+ /* Recursively clear sub-objects & keys */
+ res = _clear_object(instance);
+
+ list_del(&instance->child_list);
+ free(instance->object_name);
+ free(instance);
+
+ return (res);
}
static int object_valid_set (
@@ -478,6 +541,153 @@ error_exit:
return (-1);
}
+static int object_key_delete (
+ unsigned int object_handle,
+ void *key_name,
+ int key_len,
+ void *value,
+ int value_len)
+{
+ unsigned int res;
+ int ret = 0;
+ struct object_instance *instance;
+ struct object_key *object_key = NULL;
+ struct list_head *list;
+ int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ for (list = instance->key_head.next;
+ list != &instance->key_head; list = list->next) {
+
+ object_key = list_entry (list, struct object_key, list);
+
+ if ((object_key->key_len == key_len) &&
+ (memcmp (object_key->key_name, key_name, key_len) == 0) &&
+ (value == NULL ||
+ (object_key->value_len == value_len &&
+ (memcmp (object_key->value, value, value_len) == 0)))) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ list_del(&object_key->list);
+ free(object_key->key_name);
+ free(object_key->value);
+ free(object_key);
+ }
+ else {
+ ret = -1;
+ errno = ENOENT;
+ }
+
+ hdb_handle_put (&object_instance_database, object_handle);
+ return (ret);
+
+error_exit:
+ return (-1);
+}
+
+static int object_key_replace (
+ unsigned int object_handle,
+ void *key_name,
+ int key_len,
+ void *old_value,
+ int old_value_len,
+ void *new_value,
+ int new_value_len)
+{
+ unsigned int res;
+ int ret = 0;
+ struct object_instance *instance;
+ struct object_key *object_key = NULL;
+ struct list_head *list;
+ int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ for (list = instance->key_head.next;
+ list != &instance->key_head; list = list->next) {
+
+ object_key = list_entry (list, struct object_key, list);
+
+ if ((object_key->key_len == key_len) &&
+ (memcmp (object_key->key_name, key_name, key_len) == 0) &&
+ (old_value == NULL ||
+ (object_key->value_len == old_value_len &&
+ (memcmp (object_key->value, old_value, old_value_len) == 0)))) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ int i;
+
+ /*
+ * Do validation check if validation is configured for the parent object
+ */
+ if (instance->object_key_valid_list_entries) {
+ for (i = 0; i < instance->object_key_valid_list_entries; i++) {
+ if ((key_len ==
+ instance->object_key_valid_list[i].key_len) &&
+ (memcmp (key_name,
+ instance->object_key_valid_list[i].key_name,
+ key_len) == 0)) {
+
+ found = 1;
+ break;
+ }
+ }
+
+ /*
+ * Item not found in validation list
+ */
+ if (found == 0) {
+ goto error_put;
+ } else {
+ if (instance->object_key_valid_list[i].validate_callback) {
+ res = instance->object_key_valid_list[i].validate_callback (
+ key_name, key_len, new_value, new_value_len);
+ if (res != 0) {
+ goto error_put;
+ }
+ }
+ }
+ }
+
+ if (new_value_len != object_key->value_len) {
+ void *replacement_value;
+ replacement_value = malloc(new_value_len);
+ if (!replacement_value)
+ goto error_exit;
+ free(object_key->value);
+ object_key->value = replacement_value;
+ }
+ memcpy(object_key->value, new_value, new_value_len);
+ object_key->value_len = new_value_len;
+ }
+ else {
+ ret = -1;
+ errno = ENOENT;
+ }
+
+ hdb_handle_put (&object_instance_database, object_handle);
+ return (ret);
+
+error_put:
+ hdb_handle_put (&object_instance_database, object_handle);
+error_exit:
+ return (-1);
+}
+
static int object_priv_get (
unsigned int object_handle,
void **priv)
@@ -500,18 +710,276 @@ error_exit:
return (-1);
}
+static int _dump_object(struct object_instance *instance, FILE *file, int depth)
+{
+ struct list_head *list;
+ int res;
+ int i;
+ struct object_instance *find_instance = NULL;
+ struct object_key *object_key = NULL;
+ char stringbuf1[1024];
+ char stringbuf2[1024];
+
+ memcpy(stringbuf1, instance->object_name, instance->object_name_len);
+ stringbuf1[instance->object_name_len] = '\0';
+
+ for (i=0; i<depth; i++)
+ fprintf(file, " ");
+
+ if (instance->object_handle != OBJECT_PARENT_HANDLE)
+ fprintf(file, "%s {\n", stringbuf1);
+
+ for (list = instance->key_head.next;
+ list != &instance->key_head; list = list->next) {
+
+ object_key = list_entry (list, struct object_key,
+ list);
+
+ memcpy(stringbuf1, object_key->key_name, object_key->key_len);
+ stringbuf1[object_key->key_len] = '\0';
+ memcpy(stringbuf2, object_key->value, object_key->value_len);
+ stringbuf2[object_key->value_len] = '\0';
+
+ for (i=0; i<depth+1; i++)
+ fprintf(file, " ");
+
+ fprintf(file, "%s: %s\n", stringbuf1, stringbuf2);
+ }
+
+ for (list = instance->child_head.next;
+ list != &instance->child_head; list = list->next) {
+
+ find_instance = list_entry (list, struct object_instance,
+ child_list);
+ res = _dump_object(find_instance, file, depth+1);
+ if (res)
+ return res;
+ }
+ for (i=0; i<depth; i++)
+ fprintf(file, " ");
+
+ if (instance->object_handle != OBJECT_PARENT_HANDLE)
+ fprintf(file, "}\n");
+
+ return 0;
+}
+
+
+static int object_key_iter_reset(unsigned int object_handle)
+{
+ unsigned int res;
+ struct object_instance *instance;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ instance->iter_key_list = &instance->key_head;
+
+ hdb_handle_put (&object_instance_database, object_handle);
+ return (0);
+
+error_exit:
+ return (-1);
+}
+
+static int object_key_iter(unsigned int parent_object_handle,
+ void **key_name,
+ int *key_len,
+ void **value,
+ int *value_len)
+{
+ unsigned int res;
+ struct object_instance *instance;
+ struct object_key *find_key = NULL;
+ struct list_head *list;
+ unsigned int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ res = -ENOENT;
+ list = instance->iter_key_list->next;
+ if (list != &instance->key_head) {
+ find_key = list_entry (list, struct object_key, list);
+ found = 1;
+ }
+ instance->iter_key_list = list;
+ if (found) {
+ *key_name = find_key->key_name;
+ if (key_len)
+ *key_len = find_key->key_len;
+ *value = find_key->value;
+ if (value_len)
+ *value_len = find_key->value_len;
+ res = 0;
+ }
+ else {
+ res = -1;
+ }
+
+ hdb_handle_put (&object_instance_database, parent_object_handle);
+ return (res);
+
+error_exit:
+ return (-1);
+}
+
+static int object_iter_reset(unsigned int parent_object_handle)
+{
+ unsigned int res;
+ struct object_instance *instance;
+
+ res = hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ instance->iter_list = &instance->child_head;
+
+ hdb_handle_put (&object_instance_database, parent_object_handle);
+ return (0);
+
+error_exit:
+ return (-1);
+}
+
+static int object_iter(unsigned int parent_object_handle,
+ void **object_name,
+ int *name_len,
+ unsigned int *object_handle)
+{
+ unsigned int res;
+ struct object_instance *instance;
+ struct object_instance *find_instance = NULL;
+ struct list_head *list;
+ unsigned int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ res = -ENOENT;
+ list = instance->iter_list->next;
+ if (list != &instance->child_head) {
+
+ find_instance = list_entry (list, struct object_instance,
+ child_list);
+ found = 1;
+ }
+ instance->iter_list = list;
+
+ if (found) {
+ *object_handle = find_instance->object_handle;
+ *object_name = find_instance->object_name;
+ *name_len = find_instance->object_name_len;
+ res = 0;
+ }
+ else {
+ res = -1;
+ }
+
+ return (res);
+
+error_exit:
+ return (-1);
+}
+
+
+static int object_parent_get(unsigned int object_handle,
+ unsigned int *parent_handle)
+{
+ struct object_instance *instance;
+ unsigned int res;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ return (res);
+ }
+
+ if (object_handle == OBJECT_PARENT_HANDLE)
+ *parent_handle = 0;
+ else
+ *parent_handle = instance->parent_handle;
+
+ hdb_handle_put (&object_instance_database, object_handle);
+
+ return (0);
+}
+
+
+static int object_dump(unsigned int object_handle,
+ FILE *file)
+{
+ struct object_instance *instance;
+ unsigned int res;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ return (res);
+ }
+
+ res = _dump_object(instance, file, -1);
+
+ hdb_handle_put (&object_instance_database, object_handle);
+
+ return (res);
+}
+
+static struct list_head *last_result = NULL;
+static int save_search_iter (unsigned int parent_object_handle)
+{
+ struct object_instance *instance;
+ if(0 != hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance)) {
+ return -1;
+ }
+ last_result = instance->find_child_list;
+ hdb_handle_put (&object_instance_database, parent_object_handle);
+ return 0;
+}
+
+static int restore_search_iter (unsigned int parent_object_handle)
+{
+ struct object_instance *instance;
+ if(0 != hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance)) {
+ return -1;
+ }
+ instance->find_child_list = last_result;
+ hdb_handle_put (&object_instance_database, parent_object_handle);
+ return 0;
+}
+
+
struct objdb_iface_ver0 objdb_iface = {
.objdb_init = objdb_init,
.object_create = object_create,
.object_priv_set = object_priv_set,
.object_key_create = object_key_create,
+ .object_key_delete = object_key_delete,
+ .object_key_replace = object_key_replace,
.object_destroy = object_destroy,
.object_valid_set = object_valid_set,
.object_key_valid_set = object_key_valid_set,
.object_find_reset = object_find_reset,
.object_find = object_find,
.object_key_get = object_key_get,
- .object_priv_get = object_priv_get
+ .object_key_iter = object_key_iter,
+ .object_key_iter_reset = object_key_iter_reset,
+ .object_iter = object_iter,
+ .object_iter_reset = object_iter_reset,
+ .object_priv_get = object_priv_get,
+ .object_parent_get = object_parent_get,
+ .object_dump = object_dump,
+ .save_iter = save_search_iter,
+ .restore_iter = restore_search_iter
};
struct lcr_iface objdb_iface_ver0[1] = {
--- whitetank-svn/exec/objdb.h
+++ whitetank-dev/exec/objdb.h
@@ -38,6 +38,8 @@
#define OBJECT_PARENT_HANDLE 0
+#include <stdio.h>
+
struct object_valid {
char *object_name;
int object_len;
@@ -101,6 +103,51 @@ struct objdb_iface_ver0 {
int (*object_priv_get) (
unsigned int jobject_handle,
void **priv);
+
+ int (*object_key_replace) (
+ unsigned int object_handle,
+ void *key_name,
+ int key_len,
+ void *old_value,
+ int old_value_len,
+ void *new_value,
+ int new_value_len);
+
+ int (*object_key_delete) (
+ unsigned int object_handle,
+ void *key_name,
+ int key_len,
+ void *value,
+ int value_len);
+
+ int (*object_iter_reset) (
+ unsigned int parent_object_handle);
+
+ int (*object_iter) (
+ unsigned int parent_object_handle,
+ void **object_name,
+ int *name_len,
+ unsigned int *object_handle);
+
+ int (*object_key_iter_reset) (
+ unsigned int object_handle);
+
+ int (*object_key_iter) (
+ unsigned int parent_object_handle,
+ void **key_name,
+ int *key_len,
+ void **value,
+ int *value_len);
+
+ int (*object_parent_get) (
+ unsigned int object_handle,
+ unsigned int *parent_handle);
+
+ int (*object_dump) (
+ unsigned int object_handle,
+ FILE *file);
+ int (*save_iter) (unsigned int object_handle);
+ int (*restore_iter) (unsigned int object_handle);
};
#endif /* OBJDB_H_DEFINED */
--- whitetank-svn/exec/service.c
+++ whitetank-dev/exec/service.c
@@ -84,59 +84,19 @@ static struct default_service default_se
{
.name = "openais_cpg",
.ver = 0,
- }
+ },
};
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);
-}
+ unsigned int object_service_handle = 0;
+ char *value = NULL;
/*
- * adds the default services to the object database
+ * Don't link default services if they have been disabled
*/
-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,
@@ -158,25 +118,144 @@ int openais_service_default_objdb_set (s
log_init ("SERV");
- 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);
+ return (-1);
}
- return (0);
+
+unsigned int openais_service_link_and_init (
+ struct objdb_iface_ver0 *objdb,
+ char *service_name,
+ unsigned int service_ver, unsigned int object_handle)
+{
+ struct openais_service_handler_iface_ver0 *iface_ver0;
+ void *iface_ver0_p;
+ unsigned int handle;
+ struct openais_service_handler *service;
+ unsigned int res;
+
+ /*
+ * 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);
+ }
+
+
+ /*
+ * 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);
+ }
+
+ if(object_handle == 0) {
/*
- * Links dynamic services into the executive
+ * Store service in object database
*/
-int openais_service_link_all (struct objdb_iface_ver0 *objdb)
+ 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);
+}
+
+static int openais_service_unlink_common(
+ struct objdb_iface_ver0 *objdb,
+ unsigned int object_service_handle,
+ const char *service_name,
+ unsigned int service_version)
{
- 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;
+ unsigned int res;
+ unsigned short *service_id;
+ unsigned int *found_service_handle;
+ 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);
+
+ log_printf(LOG_LEVEL_NOTICE, "Unloading openais component: %s v%u (%d/%d)\n",
+ service_name, service_version, object_service_handle, *service_id);
+
+ if((*service_id) >= SERVICE_HANDLER_MAXIMUM_COUNT) {
+ log_printf(LOG_LEVEL_NOTICE, "Invalid component: %s v%u (%d)\n",
+ service_name, service_version, *service_id);
+ return 0;
+ }
+
+ if(ais_service[*service_id] == NULL) {
+ /* The component is no longer loaded */
+ log_printf(LOG_LEVEL_NOTICE, "Openais component is already unloaded: %s v%u (%d)\n",
+ service_name, service_version, *service_id);
+ return 0;
+
+ } else if (ais_service[*service_id]->exec_exit_fn) {
+ ais_service[*service_id]->exec_exit_fn (objdb);
+ }
+
+ ais_service[*service_id] = NULL;
+ return lcr_ifact_release (*found_service_handle);
+}
+
+extern unsigned int openais_service_unlink_and_exit (
+ struct objdb_iface_ver0 *objdb,
+ char *service_name,
+ unsigned int service_ver)
+{
+ unsigned int res = 0;
+ unsigned int object_service_handle = 0;
+ char *found_service_name = NULL;
+ unsigned int *found_service_ver = 0;
objdb->object_find_reset (OBJECT_PARENT_HANDLE);
while (objdb->object_find (
@@ -188,56 +267,120 @@ int openais_service_link_all (struct obj
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
*/
- 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)) {
+ res = openais_service_unlink_common(
+ objdb, object_service_handle, service_name, service_ver);
+ objdb->object_destroy (object_service_handle);
+ return res;
+ }
+ }
+ return (-1);
+}
- iface_ver0 = (struct openais_service_handler_iface_ver0 *)iface_ver0_p;
+extern unsigned int openais_service_unlink_all (
+ struct objdb_iface_ver0 *objdb)
+{
+ char *service_name = NULL;
+ unsigned int *service_ver = 0;
+ unsigned int object_service_handle = 0;
- 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);
- }
+ log_printf(LOG_LEVEL_NOTICE, "Unloading all openais components\n");
- service_handler_config (
- iface_ver0->openais_get_service_handler_ver0(), objdb);
+ objdb->object_find_reset (OBJECT_PARENT_HANDLE);
+ while (objdb->object_find (OBJECT_PARENT_HANDLE,
+ "service",
+ strlen ("service"),
+ &object_service_handle) == 0) {
+
+ objdb->object_key_get (object_service_handle,
+ "name",
+ strlen ("name"),
+ (void *)&service_name,
+ NULL);
+
+ objdb->object_key_get (object_service_handle,
+ "ver",
+ strlen ("ver"),
+ (void *)&service_ver,
+ NULL);
+
+ openais_service_unlink_common(
+ objdb, object_service_handle, service_name, *service_ver);
+
+ objdb->object_destroy (object_service_handle);
+ objdb->object_find_reset (OBJECT_PARENT_HANDLE);
}
+
return (0);
}
-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 = 0;
+ unsigned int object_service_handle = 0;
+ char *found_service_name = NULL;
+ char *found_service_ver = NULL;
+ unsigned int found_service_ver_atoi = 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;
- }
+ objdb->object_find_reset (OBJECT_PARENT_HANDLE);
+ while (objdb->object_find (
+ OBJECT_PARENT_HANDLE,
+ "service",
+ strlen ("service"),
+ &object_service_handle) == 0) {
+
+ objdb->object_key_get (object_service_handle,
+ "name",
+ strlen ("name"),
+ (void *)&found_service_name,
+ NULL);
+
+ objdb->object_key_get (object_service_handle,
+ "ver",
+ strlen ("ver"),
+ (void *)&found_service_ver,
+ NULL);
+
+ found_service_ver_atoi = atoi (found_service_ver);
+
+ /* Delete this so openais_service_link_and_init() can create it correctly */
+ objdb->object_key_delete(
+ object_service_handle, "ver", strlen ("ver"), NULL, 0);
+
+ objdb->save_iter (OBJECT_PARENT_HANDLE);
+ openais_service_link_and_init (
+ objdb,
+ found_service_name,
+ found_service_ver_atoi, object_service_handle);
+ objdb->restore_iter (OBJECT_PARENT_HANDLE);
+ }
+
+ if (default_services_requested (objdb)) {
+ 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, 0);
}
}
- return (res);
+
+ return (0);
}
--- whitetank-svn/exec/service.h
+++ whitetank-dev/exec/service.h
@@ -74,6 +74,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;
@@ -90,26 +91,37 @@ 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 (
+/*
+ * Link and initialize a service
+ */
+extern unsigned int openais_service_link_and_init (
struct objdb_iface_ver0 *objdb,
- char *name,
- int version);
-
-
-extern int openais_service_handler_register (
- struct openais_service_handler *handler);
-
-extern int openais_service_default_objdb_set (struct objdb_iface_ver0 *objdb);
+ char *service_name,
+ unsigned int service_ver,
+ unsigned int object_handle);
+
+/*
+ * 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_link_all (
+/*
+ * Unlink and exit all openais services
+ */
+extern unsigned int openais_service_unlink_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[];
--- whitetank-svn/exec/tlist.h
+++ whitetank-dev/exec/tlist.h
@@ -45,7 +45,7 @@
#include "../include/list.h"
-#if defined(OPENAIS_BSD) || defined(OPENAIS_DARWIN)
+#ifndef HZ
#define HZ 100 /* 10ms */
#endif
--- whitetank-svn/exec/totem.h
+++ whitetank-dev/exec/totem.h
@@ -44,26 +44,6 @@
#define SEND_THREADS_MAX 16
#define INTERFACE_MAX 2
-/*
- * Array location of various timeouts as
- * specified in openais.conf. The last enum
- * specifies the size of the timeouts array and
- * needs to remain the last item in the list.
- */
-enum {
- TOTEM_RETRANSMITS_BEFORE_LOSS,
- TOTEM_TOKEN,
- TOTEM_RETRANSMIT_TOKEN,
- TOTEM_HOLD_TOKEN,
- TOTEM_JOIN,
- TOTEM_CONSENSUS,
- TOTEM_MERGE,
- TOTEM_DOWNCHECK,
- TOTEM_FAIL_RECV_CONST,
-
- MAX_TOTEM_TIMEOUTS /* Last item */
-} totem_timeout_types;
-
struct totem_interface {
struct totem_ip_address bindnet;
struct totem_ip_address boundto;
--- whitetank-svn/exec/totemconfig.c
+++ whitetank-dev/exec/totemconfig.c
@@ -52,10 +52,7 @@
#include "totemconfig.h"
#include "print.h"
#include "objdb.h"
-
-#if defined(OPENAIS_BSD) || defined(OPENAIS_DARWIN)
- #define HZ 100 /* 10ms */
-#endif
+#include "tlist.h" /* for HZ */
#define TOKEN_RETRANSMITS_BEFORE_LOSS_CONST 4
#define TOKEN_TIMEOUT 1000
--- whitetank-svn/exec/totemip.c
+++ whitetank-dev/exec/totemip.c
@@ -516,7 +516,7 @@ int totemip_iface_check(struct totem_ip_
memcpy(&network, RTA_DATA(tb[IFA_BROADCAST]), sizeof(uint32_t));
memcpy(&addr, bindnet->addr, sizeof(uint32_t));
- if (addr == (network & netmask)) {
+ if ((addr & netmask) == (network & netmask)) {
memcpy(ipaddr.addr, RTA_DATA(tb[IFA_ADDRESS]), TOTEMIP_ADDRLEN);
found_if = 1;
}
--- whitetank-svn/exec/totemnet.c
+++ whitetank-dev/exec/totemnet.c
@@ -702,7 +702,12 @@ static int netif_determine (
* field is only 32 bits.
*/
if (bound_to->family == AF_INET && bound_to->nodeid == 0) {
- memcpy (&bound_to->nodeid, bound_to->addr, sizeof (int));
+ int32_t nodeid = 0;
+ memcpy (&nodeid, bound_to->addr, sizeof (int));
+ if(nodeid < 0 && instance->totem_config->clear_node_high_bit) {
+ nodeid = 0 - nodeid;
+ }
+ bound_to->nodeid = nodeid;
}
return (res);
@@ -1227,15 +1232,6 @@ int totemnet_initialize (
instance->totemnet_poll_handle = poll_handle;
- if(instance->totem_config->node_id == 0) {
- int32_t nodeid = 0;
- memcpy (&nodeid, instance->totem_interface->bindnet.addr, sizeof (int32_t));
- if(nodeid < 0 && instance->totem_config->clear_node_high_bit) {
- nodeid = 0 - nodeid;
- }
- instance->totem_config->node_id = nodeid;
- }
-
instance->totem_interface->bindnet.nodeid = instance->totem_config->node_id;
instance->context = context;
--- whitetank-svn/include/cfg.h
+++ whitetank-dev/include/cfg.h
@@ -140,6 +140,18 @@ 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,
OpenaisCfgAdministrativeTargetT administrativeTarget,
--- whitetank-svn/include/ipc_cfg.h
+++ whitetank-dev/include/ipc_cfg.h
@@ -47,6 +47,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 {
@@ -56,6 +58,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 {
@@ -117,6 +121,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,
--- whitetank-svn/init/generic 1970-01-01 01:00:00.000000000 +0100
+++ whitetank-dev/init/generic
@@ -0,0 +1,146 @@
+#!/bin/sh
+#
+# openais Start the openais cluster service
+#
+# Author: Andrew Beekhof <abeekhof@suse.de>
+# License: Revised BSD
+#
+# chkconfig: - 20 20
+# processname: aisexec
+# description: OpenAIS daemon
+#
+### BEGIN INIT INFO
+# Description: openais....
+#
+# Short-Description: openais cluster services.
+# Provides: openais
+# Required-Start: $network
+# Should-Start: $syslog
+# Required-Stop: $network
+# Default-Start: 3 5
+# Default-Stop: 0 6
+# Should-Stop: $null
+### END INIT INFO
+
+do_force=0
+prog="aisexec"
+lockfile="/var/lock/subsys/$prog"
+
+internal_status() {
+ killall -0 aisexec > /dev/null 2>&1
+ return $?
+}
+
+status() {
+ if
+ ! internal_status
+ then
+ echo "Stopped"
+ return 7
+ fi
+
+ echo "Running"
+ return 0
+}
+
+start() {
+ echo -n $"Starting OpenAIS daemon ($prog): "
+ if
+ ! internal_status
+ then
+ echo -n "starting... "
+ $prog 2>&1 > /dev/null 2>&1
+ echo -n "rc=$?: "
+ fi
+
+ sleep 2 # give it time to fail... $? isn't definitive
+
+ if
+ internal_status
+ then
+ echo "OK"
+ return 0
+ fi
+
+ echo "Failed"
+ return 1
+}
+
+do_force=0
+do_forever=1
+
+stop() {
+ echo -n $"Stopping OpenAIS daemon ($prog): "
+
+ killall -QUIT aisexec
+
+ if [ $do_forever = 0 ]; then
+ for i in 1 2 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20; do
+ if
+ internal_status
+ then
+ sleep 2
+ echo -n "."
+ else
+ rm -f "$lockfile"
+ echo "OK"
+ return 0
+ fi
+ done
+
+ if [ $do_force = 1 ]; then
+ echo -n "Escalating... "
+ killall -KILL aisexec
+ sleep 5
+
+ if
+ ! internal_status
+ then
+ rm -f "$lockfile"
+ echo "OK"
+ return 0
+ fi
+ fi
+
+ echo "Failed"
+ return 1
+ fi
+
+ while
+ internal_status
+ do
+ sleep 1
+ echo -n "."
+ done
+
+ rm -f "$lockfile"
+ echo "OK"
+ return 0
+}
+
+restart() {
+ stop
+ start
+}
+
+case "$1" in
+ start|stop|restart)
+ $1
+ ;;
+ force-stop)
+ do_force=1
+ stop
+ ;;
+ reload|force-reload)
+ restart
+ ;;
+ condrestart|try-restart)
+ [ ! -f "$lockfile" ] || restart
+ ;;
+ status)
+ status $prog
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|restart|try-restart|condrestart|reload|force-reload|force-stop|status}"
+ exit 2
+esac
--- whitetank-svn/lcr/Makefile
+++ whitetank-dev/lcr/Makefile
@@ -26,8 +26,8 @@
#
include ../Makefile.inc
-CFLAGS += -I../include
override LDFLAGS += ${DYFLAGS}
+override CFLAGS += -I../include -DLCRSODIR='"$(LCRSODIR)"'
ifeq (${OPENAIS_COMPAT}, LINUX)
LDFLAGS += -ldl
--- whitetank-svn/lcr/lcr_ifact.c
+++ whitetank-dev/lcr/lcr_ifact.c
@@ -174,7 +174,7 @@ static void defaults_path_build (void)
path_list[0] = strdup (cwd);
path_list_entries++;
}
- path_list[path_list_entries++] = "/usr/libexec/lcrso";
+ path_list[path_list_entries++] = LCRSODIR;
}
static void ld_library_path_build (void)
--- whitetank-svn/lib/Makefile
+++ whitetank-dev/lib/Makefile
@@ -55,35 +55,37 @@ libSaClm.a: util.o clm.o
ifeq (${OPENAIS_COMPAT}, DARWIN)
+DARWIN_OPTS=-dynamiclib -bind_at_load -current_version 2.0.0 -compatibility_version 2.0.0
+
libSaClm.so.2.0.0: util.o clm.o
- $(CC) $(LDFLAGS) -bundle -bind_at_load util.o clm.o -o $@
+ $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o clm.o -o $@
libSaAmf.so.2.0.0: util.o amf.o
- $(CC) $(LDFLAGS) -bundle -bind_at_load util.o amf.o -o $@
+ $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o amf.o -o $@
libSaCkpt.so.2.0.0: util.o ckpt.o
- $(CC) $(LDFLAGS) -bundle -bind_at_load util.o ckpt.o -o $@
+ $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o ckpt.o -o $@
libSaEvt.so.2.0.0: util.o evt.o
- $(CC) $(LDFLAGS) -bundle -bind_at_load util.o evt.o -o $@
+ $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o evt.o -o $@
libSaLck.so.2.0.0: util.o lck.o
- $(CC) $(LDFLAGS) -bundle -bind_at_load util.o lck.o -o $@
+ $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o lck.o -o $@
libSaMsg.so.2.0.0: util.o msg.o
- $(CC) $(LDFLAGS) -bundle -bind_at_load util.o msg.o -o $@
+ $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o msg.o -o $@
libais.so.2.0.0: util.o amf.o clm.o ckpt.o evt.o lck.o msg.o
- $(CC) $(LDFLAGS) -bundle -bind_at_load util.o amf.o clm.o ckpt.o evt.o -o $@
+ $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o amf.o clm.o ckpt.o evt.o -o $@
libevs.so.2.0.0: util.o evs.o
- $(CC) $(LDFLAGS) -bundle -bind_at_load util.o evs.o -o $@
+ $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o evs.o -o $@
libcpg.so.2.0.0: util.o cpg.o
- $(CC) -bundle -bind_at_load util.o cpg.o -o $@
+ $(CC) $(DARWIN_OPTS) util.o cpg.o -o $@
libcfg.so.2.0.0: util.o cfg.o
- $(CC) -bundle -bind_at_load util.o cfg.o -o $@
+ $(CC) $(DARWIN_OPTS) util.o cfg.o -o $@
else
--- whitetank-svn/lib/cfg.c
+++ whitetank-dev/lib/cfg.c
@@ -458,6 +458,81 @@ openais_cfg_ring_reenable (
}
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,
--- whitetank-svn/lib/libSaMsg.versions
+++ whitetank-dev/lib/libSaMsg.versions
@@ -24,18 +24,18 @@ OPENAIS_MSG_B.01.01 {
saMsgMessageCancel;
saMsgMessageReply;
saMsgMessageReplyAsync;
+ saSendReceiveReply;
+ saServiceConnect;
+ saRecvRetry;
+ saSendMsgReceiveReply;
+ saSendMsgRetry;
+ saSendRetry;
local:
saHandleCreate;
saHandleDestroy;
saHandleInstanceGet;
saHandleInstancePut;
saPollRetry;
- saRecvRetry;
- saSendMsgReceiveReply;
- saSendMsgRetry;
- saSendReceiveReply;
- saSendRetry;
- saServiceConnect;
saVersionVerify;
clustTimeNow;
};
--- whitetank-svn/lib/libcfg.versions
+++ whitetank-dev/lib/libcfg.versions
@@ -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:
--- whitetank-svn/lib/util.c
+++ whitetank-dev/lib/util.c
@@ -525,7 +525,7 @@ saHandleCreate (
{
uint32_t handle;
uint32_t check;
- void *newHandles;
+ void *newHandles = NULL;
int found = 0;
void *instance;
int i;
--- whitetank-svn/test/openais-cfgtool.c
+++ whitetank-dev/test/openais-cfgtool.c
@@ -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);
}