This is a patch that adds some standalone code to libconfdb, so it can
examine and ultimately change, the configuration without aisexec running.
A small number of things I'm unsure about..
- it automatically falls back to standalone if it can't connect to
aisexec. That might not be the right thing to do, opinions welcome.
- any program accessing confdb needs to be linked -rdynamic so that
several objdb/config symbols can be resolved. There might be ways around
this though I'm not sure how nice they are!
- Some config options I haven't got to work yet. In particular the new
cman preconfig module calls logsys, and I'm undecided about the best way
to tackle this. I think maybe the callers ought also to link with
logsys, but a quite test seems to make this difficult for some reason.
--
Chrissie
Index: lib/sa-confdb.h
===================================================================
--- lib/sa-confdb.h (revision 0)
+++ lib/sa-confdb.h (revision 0)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield ([EMAIL PROTECTED])
+ *
+ * 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.
+ */
+
+extern int confdb_sa_init(void);
+extern int confdb_sa_object_create(unsigned int parent_object_handle, void *object_name, int object_name_len, unsigned int *object_handle);
+extern int confdb_sa_object_destroy(unsigned int object_handle);
+extern int confdb_sa_object_parent_get(unsigned int object_handle, unsigned int *parent_object_handle);
+extern int confdb_sa_key_create(unsigned int parent_object_handle, void *key_name, int key_name_len, void *value, int value_len);
+extern int confdb_sa_key_get(unsigned int parent_object_handle, void *key_name, int key_name_len, void *value, int *value_len);
+extern int confdb_sa_key_replace(unsigned int parent_object_handle, void *key_name, int key_name_len, void *old_value, int old_value_len, void *new_value, int new_value_len);
+extern int confdb_sa_object_find(unsigned int parent_object_handle, unsigned int start_pos, void *object_name, int object_name_len, unsigned int *object_handle, unsigned int *next_pos);
+extern int confdb_sa_object_iter(unsigned int parent_object_handle, unsigned int start_pos, unsigned int *object_handle, void *object_name, int *object_name_len);
+extern int confdb_sa_key_iter(unsigned int parent_object_handle, unsigned int start_pos, void *key_name, int *key_name_len, void *value, int *value_len);
Index: lib/confdb.c
===================================================================
--- lib/confdb.c (revision 1519)
+++ lib/confdb.c (working copy)
@@ -49,6 +49,8 @@
#include <ais_util.h>
#include <list.h>
+#include "sa-confdb.h"
+
/* Hold the information for iterators so that
callers can do recursive tree traversals.
each object_handle can have its own iterator */
@@ -62,6 +64,7 @@
int response_fd;
int dispatch_fd;
int finalize;
+ int standalone;
confdb_callbacks_t callbacks;
void *context;
pthread_mutex_t response_mutex;
@@ -149,7 +152,11 @@
&confdb_inst->response_fd,
CONFDB_SERVICE);
if (error != SA_AIS_OK) {
- goto error_put_destroy;
+
+ /* If we can't connect to aisexec then load the config ourself. */
+ /* CC: should we really do this automatically ?? */
+ confdb_sa_init();
+ confdb_inst->standalone = 1;
}
memcpy (&confdb_inst->callbacks, callbacks, sizeof (confdb_callbacks_t));
@@ -206,17 +213,19 @@
free_context_list(&confdb_inst->object_iter_head);
free_context_list(&confdb_inst->key_iter_head);
- /*
- * Disconnect from the server
- */
- if (confdb_inst->response_fd != -1) {
- shutdown(confdb_inst->response_fd, 0);
- close(confdb_inst->response_fd);
+ if (!confdb_inst->standalone) {
+ /*
+ * Disconnect from the server
+ */
+ if (confdb_inst->response_fd != -1) {
+ shutdown(confdb_inst->response_fd, 0);
+ close(confdb_inst->response_fd);
+ }
+ if (confdb_inst->dispatch_fd != -1) {
+ shutdown(confdb_inst->dispatch_fd, 0);
+ close(confdb_inst->dispatch_fd);
+ }
}
- if (confdb_inst->dispatch_fd != -1) {
- shutdown(confdb_inst->dispatch_fd, 0);
- close(confdb_inst->dispatch_fd);
- }
saHandleInstancePut (&confdb_handle_t_db, handle);
return (CONFDB_OK);
@@ -304,6 +313,11 @@
return (error);
}
+ if (confdb_inst->standalone) {
+ error = CONFDB_ERR_NOT_SUPPORTED;
+ goto error_unlock;
+ }
+
/*
* Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and
* wait indefinately for SA_DISPATCH_BLOCKING
@@ -450,6 +464,16 @@
return (error);
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_object_create(parent_object_handle,
+ object_name, object_name_len,
+ object_handle))
+ error = SA_AIS_ERR_ACCESS;
+ goto error_exit;
+ }
+
req_lib_confdb_object_create.header.size = sizeof (struct req_lib_confdb_object_create);
req_lib_confdb_object_create.header.id = MESSAGE_REQ_CONFDB_OBJECT_CREATE;
req_lib_confdb_object_create.parent_object_handle = parent_object_handle;
@@ -493,6 +517,14 @@
return (error);
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_object_destroy(object_handle))
+ error = SA_AIS_ERR_ACCESS;
+ goto error_exit;
+ }
+
req_lib_confdb_object_destroy.header.size = sizeof (struct req_lib_confdb_object_destroy);
req_lib_confdb_object_destroy.header.id = MESSAGE_REQ_CONFDB_OBJECT_DESTROY;
req_lib_confdb_object_destroy.object_handle = object_handle;
@@ -534,6 +566,14 @@
return (error);
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_object_parent_get(object_handle, parent_object_handle))
+ error = SA_AIS_ERR_ACCESS;
+ goto error_exit;
+ }
+
req_lib_confdb_object_parent_get.header.size = sizeof (struct req_lib_confdb_object_parent_get);
req_lib_confdb_object_parent_get.header.id = MESSAGE_REQ_CONFDB_OBJECT_PARENT_GET;
req_lib_confdb_object_parent_get.object_handle = object_handle;
@@ -579,6 +619,16 @@
return (error);
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_key_create(parent_object_handle,
+ key_name, key_name_len,
+ value, value_len))
+ error = SA_AIS_ERR_ACCESS;
+ goto error_exit;
+ }
+
req_lib_confdb_key_create.header.size = sizeof (struct req_lib_confdb_key_create);
req_lib_confdb_key_create.header.id = MESSAGE_REQ_CONFDB_KEY_CREATE;
req_lib_confdb_key_create.object_handle = parent_object_handle;
@@ -627,6 +677,16 @@
return (error);
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_key_get(parent_object_handle,
+ key_name, key_name_len,
+ value, value_len))
+ error = SA_AIS_ERR_ACCESS;
+ goto error_exit;
+ }
+
req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_GET;
req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
@@ -680,6 +740,16 @@
return (error);
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_key_replace(parent_object_handle,
+ key_name, key_name_len,
+ old_value, old_value_len,
+ new_value, new_value_len))
+ error = SA_AIS_ERR_ACCESS;
+ goto error_exit;
+ }
req_lib_confdb_key_replace.header.size = sizeof (struct req_lib_confdb_key_replace);
req_lib_confdb_key_replace.header.id = MESSAGE_REQ_CONFDB_KEY_REPLACE;
req_lib_confdb_key_replace.object_handle = parent_object_handle;
@@ -833,6 +903,18 @@
goto error_exit;
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_object_find(parent_object_handle,
+ context->context,
+ object_name, object_name_len,
+ object_handle,
+ &context->context))
+ error = SA_AIS_ERR_ACCESS;
+ goto error_exit;
+ }
+
req_lib_confdb_object_find.header.size = sizeof (struct req_lib_confdb_object_find);
req_lib_confdb_object_find.header.id = MESSAGE_REQ_CONFDB_OBJECT_FIND;
req_lib_confdb_object_find.parent_object_handle = parent_object_handle;
@@ -890,6 +972,17 @@
goto error_exit;
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_object_iter(parent_object_handle,
+ context->context,
+ object_handle,
+ object_name, object_name_len))
+ error = SA_AIS_ERR_ACCESS;
+ goto sa_exit;
+ }
+
req_lib_confdb_object_iter.header.size = sizeof (struct req_lib_confdb_object_iter);
req_lib_confdb_object_iter.header.id = MESSAGE_REQ_CONFDB_OBJECT_ITER;
req_lib_confdb_object_iter.parent_object_handle = parent_object_handle;
@@ -914,7 +1007,7 @@
memcpy(object_name, res_lib_confdb_object_iter.object_name.value, *object_name_len);
*object_handle = res_lib_confdb_object_iter.object_handle;
}
-
+sa_exit:
context->context++;
error_exit:
@@ -950,6 +1043,17 @@
goto error_exit;
}
+ if (confdb_inst->standalone) {
+ error = SA_AIS_OK;
+
+ if (confdb_sa_key_iter(parent_object_handle,
+ context->context,
+ key_name, key_name_len,
+ value, value_len))
+ error = SA_AIS_ERR_ACCESS;
+ goto sa_exit;
+ }
+
req_lib_confdb_key_iter.header.size = sizeof (struct req_lib_confdb_key_iter);
req_lib_confdb_key_iter.header.id = MESSAGE_REQ_CONFDB_KEY_ITER;
req_lib_confdb_key_iter.parent_object_handle = parent_object_handle;
@@ -976,6 +1080,7 @@
memcpy(value, res_lib_confdb_key_iter.value.value, *value_len);
}
+sa_exit:
context->context++;
error_exit:
Index: lib/Makefile
===================================================================
--- lib/Makefile (revision 1519)
+++ lib/Makefile (working copy)
@@ -90,8 +90,8 @@
libcpg.so.2.0.0: util.o cpg.o
$(CC) -bundle -bind_at_load util.o cpg.o -o $@
-libconfdb.so.2.0.0: util.o confdb.o
- $(CC) -bundle -bind_at_load util.o confdb.o -o $@
+libconfdb.so.2.0.0: util.o confdb.o sa-confdb.o ../lcr/liblcr.a
+ $(CC) -bundle -bind_at_load util.o confdb.o sa-confdb.o ../lcr/liblcr.a -o $@
libcfg.so.2.0.0: util.o cfg.o
$(CC) -bundle -bind_at_load util.o cfg.o -o $@
@@ -128,8 +128,8 @@
libcpg.so.2.0.0: util.o cpg.o
$(CC) -shared -Wl,-soname,libcpg.so.2,-version-script=$(srcdir)$(subdir)libcpg.versions util.o cpg.o -o $@
-libconfdb.so.2.0.0: util.o confdb.o
- $(CC) -shared -Wl,-soname,libconfdb.so.2,-version-script=$(srcdir)$(subdir)libconfdb.versions util.o confdb.o -o $@
+libconfdb.so.2.0.0: util.o confdb.o sa-confdb.o ../lcr/liblcr.a
+ $(CC) -shared -Wl,-soname,libconfdb.so.2,-version-script=$(srcdir)$(subdir)libconfdb.versions util.o confdb.o sa-confdb.o ../lcr/liblcr.a -o $@
libcfg.so.2.0.0: util.o cfg.o
$(CC) -shared -Wl,-soname,libcfg.so.2,-version-script=$(srcdir)$(subdir)libcfg.versions util.o cfg.o -o $@
@@ -160,8 +160,8 @@
libcpg.a: util.o cpg.o
$(AR) -rc libcpg.a util.o cpg.o
-libconfdb.a: util.o confdb.o
- $(AR) -rc libconfdb.a util.o confdb.o
+libconfdb.a: util.o confdb.o sa-confdb.o
+ $(AR) -rc libconfdb.a util.o confdb.o sa-confdb.o ../lcr/lcr_ifact.o
libcfg.a: util.o cfg.o
$(AR) -rc libcfg.a util.o cfg.o
Index: lib/sa-confdb.c
===================================================================
--- lib/sa-confdb.c (revision 0)
+++ lib/sa-confdb.c (revision 0)
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield ([EMAIL PROTECTED])
+ *
+ * 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.
+ */
+/*
+ * Provides stand-alone access to data in the openais object database
+ * when aisexec is not running.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include <saAis.h>
+#include <ais_util.h>
+#include "../exec/objdb.h"
+#include "../exec/config.h"
+#include "../lcr/lcr_comp.h"
+#include "../lcr/lcr_ifact.h"
+#include "../exec/logsys.h"
+
+static struct objdb_iface_ver0 *objdb;
+
+static int num_config_modules;
+
+static struct config_iface_ver0 *config_modules[128];
+
+
+static int load_objdb()
+{
+ unsigned int objdb_handle;
+ void *objdb_p;
+ int res;
+
+ /*
+ * Load the object database interface
+ */
+ res = lcr_ifact_reference (
+ &objdb_handle,
+ "objdb",
+ 0,
+ &objdb_p,
+ 0);
+ if (res == -1) {
+ return -1;
+ }
+
+ objdb = (struct objdb_iface_ver0 *)objdb_p;
+
+ objdb->objdb_init ();
+ return 0;
+}
+
+static int load_config()
+{
+ char *config_iface;
+ char *iface;
+ int res;
+ unsigned int config_handle;
+ unsigned int config_version = 0;
+ void *config_p;
+ struct config_iface_ver0 *config;
+ char *error_string;
+
+ /* User's bootstrap config service */
+ config_iface = getenv("OPENAIS_DEFAULT_CONFIG_IFACE");
+ if (!config_iface) {
+ config_iface = "aisparser";
+ }
+
+ /* Make a copy so we can deface it with strtok */
+ config_iface = strdup(config_iface);
+
+ iface = strtok(config_iface, ":");
+ while (iface)
+ {
+ res = lcr_ifact_reference (
+ &config_handle,
+ iface,
+ config_version,
+ &config_p,
+ 0);
+
+ config = (struct config_iface_ver0 *)config_p;
+ if (res == -1) {
+ return -1;
+ }
+
+ res = config->config_readconfig(objdb, &error_string);
+ if (res == -1) {
+ return -1;
+ }
+
+ config_modules[num_config_modules++] = config;
+
+ iface = strtok(NULL, ":");
+ }
+ if (config_iface)
+ free(config_iface);
+
+ return 0;
+}
+
+/* Needed by objdb when it writes back the configuration */
+void main_get_config_modules(struct config_iface_ver0 ***modules, int *num)
+{
+ *modules = config_modules;
+ *num = num_config_modules;
+}
+
+/* Needed by some modules ... */
+char *strstr_rs (const char *haystack, const char *needle)
+{
+ char *end_address;
+ char *new_needle;
+
+ new_needle = (char *)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');
+ }
+
+ free (new_needle);
+ return (end_address);
+}
+
+int confdb_sa_init (void)
+{
+ int res;
+
+ res = load_objdb();
+ if (res)
+ return res;
+
+ res = load_config();
+
+ return res;
+}
+
+
+int confdb_sa_object_create (
+ unsigned int parent_object_handle,
+ void *object_name,
+ int object_name_len,
+ unsigned int *object_handle)
+{
+ return objdb->object_create(parent_object_handle,
+ object_handle,
+ object_name, object_name_len);
+}
+
+int confdb_sa_object_destroy (
+ unsigned int object_handle)
+{
+ return objdb->object_destroy(object_handle);
+}
+
+int confdb_sa_object_parent_get (
+ unsigned int object_handle,
+ unsigned int *parent_object_handle)
+{
+ return objdb->object_parent_get(object_handle, parent_object_handle);
+}
+
+int confdb_sa_key_create (
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *value,
+ int value_len)
+{
+ return objdb->object_key_create(parent_object_handle,
+ key_name, key_name_len,
+ value, value_len);
+}
+
+int confdb_sa_key_get (
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *value,
+ int *value_len)
+{
+ int res;
+ void *kvalue;
+
+ res = objdb->object_key_get(parent_object_handle,
+ key_name, key_name_len,
+ &kvalue, value_len);
+ if (!res) {
+ memcpy(value, kvalue, *value_len);
+ }
+ return res;
+}
+
+
+int confdb_sa_key_replace (
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *old_value,
+ int old_value_len,
+ void *new_value,
+ int new_value_len)
+{
+ return objdb->object_key_replace(parent_object_handle,
+ key_name, key_name_len,
+ old_value, old_value_len,
+ new_value, new_value_len);
+}
+
+int confdb_sa_object_find (
+ unsigned int parent_object_handle,
+ unsigned int start_pos,
+ void *object_name,
+ int object_name_len,
+ unsigned int *object_handle,
+ unsigned int *next_pos)
+{
+ return objdb->object_find_from(parent_object_handle,
+ start_pos,
+ object_name,
+ object_name_len,
+ object_handle,
+ next_pos);
+}
+
+
+int confdb_sa_object_iter (
+ unsigned int parent_object_handle,
+ unsigned int start_pos,
+ unsigned int *object_handle,
+ void *object_name,
+ int *object_name_len)
+{
+ int res;
+ void *objname;
+
+ res = objdb->object_iter_from(parent_object_handle,
+ start_pos,
+ &objname, object_name_len,
+ object_handle);
+ if (!res) {
+ memcpy(object_name, objname, *object_name_len);
+ }
+ return res;
+}
+
+int confdb_sa_key_iter (
+ unsigned int parent_object_handle,
+ unsigned int start_pos,
+ void *key_name,
+ int *key_name_len,
+ void *value,
+ int *value_len)
+{
+ int res;
+ void *kname, *kvalue;
+
+ res = objdb->object_key_iter_from(parent_object_handle,
+ start_pos,
+ &kname, key_name_len,
+ &kvalue, value_len);
+
+ if (!res) {
+ memcpy(key_name, kname, *key_name_len);
+ memcpy(value, kvalue, *value_len);
+ }
+ return res;
+}
Index: test/Makefile
===================================================================
--- test/Makefile (revision 1519)
+++ test/Makefile (working copy)
@@ -155,7 +155,7 @@
$(CC) $(LDFLAGS) -o cpgbench cpgbench.o $(LIBS)
testconfdb: testconfdb.o $(LIBRARIES)
- $(CC) $(LDFLAGS) -o testconfdb testconfdb.o $(LIBS)
+ $(CC) $(LDFLAGS) -o testconfdb testconfdb.o $(LIBS) -rdynamic
openais-cfgtool: openais-cfgtool.o $(LIBRARIES)
$(CC) $(LDFLAGS) -o openais-cfgtool openais-cfgtool.o $(LIBS)
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais