Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1842016
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
47 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/cman/daemon/ais.c b/cman/daemon/ais.c
index 0c1fe9972..76044c92b 100644
--- a/cman/daemon/ais.c
+++ b/cman/daemon/ais.c
@@ -1,318 +1,317 @@
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
/* corosync headers */
#include <corosync/ipc_gen.h>
#include <corosync/engine/coroapi.h>
#include <corosync/engine/logsys.h>
#include <corosync/lcr/lcr_comp.h>
#include "list.h"
#include "cnxman-socket.h"
#include "cnxman-private.h"
#include "commands.h"
#include "logging.h"
#include "ais.h"
#include "cman.h"
#define OBJDB_API struct corosync_api_v1
#include "nodelist.h"
#include "cmanconfig.h"
#include "daemon.h"
extern int our_nodeid();
extern char cluster_name[MAX_CLUSTER_NAME_LEN+1];
-extern char *key_filename;
extern unsigned int quorumdev_poll;
extern unsigned int ccsd_poll_interval;
extern unsigned int shutdown_timeout;
extern int init_config(struct corosync_api_v1 *api);
struct totem_ip_address mcast_addr[MAX_INTERFACES];
struct totem_ip_address ifaddrs[MAX_INTERFACES];
int num_interfaces;
uint64_t incarnation;
int num_ais_nodes;
extern unsigned int config_version;
static unsigned int cluster_parent_handle;
static int startup_pipe;
static unsigned int debug_mask;
static int first_trans = 1;
struct corosync_api_v1 *corosync;
static corosync_tpg_handle group_handle;
static struct corosync_tpg_group cman_group[1] = {
{ .group = "CMAN", .group_len = 4},
};
LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO);
/* This structure is tacked onto the start of a cluster message packet for our
* own nefarious purposes. */
struct cl_protheader {
unsigned char tgtport; /* Target port number */
unsigned char srcport; /* Source (originating) port number */
unsigned short pad;
unsigned int flags;
int srcid; /* Node ID of the sender */
int tgtid; /* Node ID of the target */
};
/* Plugin-specific code */
/* Need some better way of determining these.... */
#define CMAN_SERVICE 9
static int cman_exit_fn(void *conn_info);
static int cman_exec_init_fn(struct corosync_api_v1 *api);
static void cman_confchg_fn(enum totem_configuration_type configuration_type,
unsigned int *member_list, int member_list_entries,
unsigned int *left_list, int left_list_entries,
unsigned int *joined_list, int joined_list_entries,
struct memb_ring_id *ring_id);
static void cman_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len,
int endian_conversion_required);
/*
* Exports the interface for the service
*/
static struct corosync_service_engine cman_service_handler = {
.name = (char *)"corosync CMAN membership service 2.90",
.id = CMAN_SERVICE,
.flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED,
.lib_exit_fn = cman_exit_fn,
.exec_init_fn = cman_exec_init_fn,
.config_init_fn = NULL,
};
static struct corosync_service_engine *cman_get_handler_ver0(void)
{
return (&cman_service_handler);
}
static struct corosync_service_engine_iface_ver0 cman_service_handler_iface = {
.corosync_get_service_engine_ver0 = cman_get_handler_ver0
};
static struct lcr_iface ifaces_ver0[1] = {
{
.name = "corosync_cman",
.version = 0,
.versions_replace = 0,
.versions_replace_count = 0,
.dependencies = 0,
.dependency_count = 0,
.constructor = NULL,
.destructor = NULL,
.interfaces = NULL,
}
};
static struct lcr_comp cman_comp_ver0 = {
.iface_count = 1,
.ifaces = ifaces_ver0,
};
__attribute__ ((constructor)) static void cman_comp_register(void) {
lcr_interfaces_set(&ifaces_ver0[0], &cman_service_handler_iface);
lcr_component_register(&cman_comp_ver0);
}
/* ------------------------------- */
static int cman_exec_init_fn(struct corosync_api_v1 *api)
{
unsigned int object_handle;
unsigned int find_handle;
char pipe_msg[256];
corosync = api;
if (getenv("CMAN_PIPE"))
startup_pipe = atoi(getenv("CMAN_PIPE"));
/* Get our config variables */
corosync->object_find_create(OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &find_handle);
corosync->object_find_next(find_handle, &cluster_parent_handle);
corosync->object_find_destroy(find_handle);
corosync->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
if (corosync->object_find_next(find_handle, &object_handle) == 0)
{
objdb_get_int(api, object_handle, "quorum_dev_poll", &quorumdev_poll, DEFAULT_QUORUMDEV_POLL);
objdb_get_int(api, object_handle, "shutdown_timeout", &shutdown_timeout, DEFAULT_SHUTDOWN_TIMEOUT);
objdb_get_int(api, object_handle, "ccsd_poll", &ccsd_poll_interval, DEFAULT_CCSD_POLL);
objdb_get_int(api, object_handle, "debug_mask", &debug_mask, 0);
/* All other debugging options should already have been set in preconfig */
set_debuglog(debug_mask);
}
corosync->object_find_destroy(find_handle);
P_DAEMON(CMAN_NAME " starting");
/* Open local sockets and initialise I/O queues */
if (read_cman_config(api, &config_version)) {
/* An error message will have been written to cman_pipe */
exit(9);
}
cman_init();
/* Let cman_tool know we are running and our PID */
sprintf(pipe_msg,"SUCCESS: %d", getpid());
write_cman_pipe(pipe_msg);
close(startup_pipe);
startup_pipe = 0;
/* Start totem */
api->tpg_init(&group_handle, cman_deliver_fn, cman_confchg_fn);
api->tpg_join(group_handle, cman_group, 1);
return 0;
}
int cman_exit_fn(void *conn_info)
{
cman_finish();
return 0;
}
/* END Plugin-specific code */
int comms_send_message(void *buf, int len,
unsigned char toport, unsigned char fromport,
int nodeid,
unsigned int flags)
{
struct iovec iov[2];
struct cl_protheader header;
int totem_flags = TOTEM_AGREED;
P_AIS("comms send message %p len = %d\n", buf,len);
header.tgtport = toport;
header.srcport = fromport;
header.flags = flags;
header.srcid = our_nodeid();
header.tgtid = nodeid;
iov[0].iov_base = &header;
iov[0].iov_len = sizeof(header);
iov[1].iov_base = buf;
iov[1].iov_len = len;
if (flags & MSG_TOTEM_SAFE)
totem_flags = TOTEM_SAFE;
return corosync->tpg_joined_mcast(group_handle, iov, 2, totem_flags);
}
// This assumes the iovec has only one element ... is it true ??
static void cman_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len,
int endian_conversion_required)
{
struct cl_protheader *header = iovec->iov_base;
char *buf = iovec->iov_base;
P_AIS("deliver_fn source nodeid = %d, len=%d, endian_conv=%d\n",
nodeid, (int)iovec->iov_len, endian_conversion_required);
if (endian_conversion_required) {
header->srcid = swab32(header->srcid);
header->tgtid = swab32(header->tgtid);
header->flags = swab32(header->flags);
}
/* Only pass on messages for us or everyone */
if (header->tgtid == our_nodeid() ||
header->tgtid == 0) {
send_to_userport(header->srcport, header->tgtport,
header->srcid, header->tgtid,
buf + sizeof(struct cl_protheader), iovec->iov_len - sizeof(struct cl_protheader),
endian_conversion_required);
}
}
static void cman_confchg_fn(enum totem_configuration_type configuration_type,
unsigned int *member_list, int member_list_entries,
unsigned int *left_list, int left_list_entries,
unsigned int *joined_list, int joined_list_entries,
struct memb_ring_id *ring_id)
{
int i;
static int last_memb_count = 0;
static int saved_left_list_entries;
static int saved_left_list_size;
static unsigned int *saved_left_list = NULL;
P_AIS("confchg_fn called type = %d, seq=%lld\n", configuration_type, ring_id->seq);
incarnation = ring_id->seq;
num_ais_nodes = member_list_entries;
/* Tell the cman membership layer */
for (i=0; i<left_list_entries; i++)
del_ais_node(left_list[i]);
/* Joining nodes are only added after a valid TRANSITION message
* is received.
*/
/* Save the left list for later so we can do a consolidated confchg message */
if (configuration_type == TOTEM_CONFIGURATION_TRANSITIONAL) {
if (saved_left_list == NULL) {
saved_left_list_size = left_list_entries*2;
saved_left_list = malloc(sizeof(int) * saved_left_list_size);
if (!saved_left_list) {
log_printf(LOG_LEVEL_CRIT, "cannot allocate memory for confchg message");
exit(3);
}
}
if (saved_left_list_size < left_list_entries) {
saved_left_list_size = left_list_entries*2;
saved_left_list = realloc(saved_left_list, sizeof(int) * saved_left_list_size);
if (!saved_left_list) {
log_printf(LOG_LEVEL_CRIT, "cannot reallocate memory for confchg message");
exit(3);
}
}
saved_left_list_entries = left_list_entries;
memcpy(saved_left_list, left_list, left_list_entries * sizeof(int));
}
if (configuration_type == TOTEM_CONFIGURATION_REGULAR) {
P_AIS("last memb_count = %d, current = %d\n", last_memb_count, member_list_entries);
send_transition_msg(last_memb_count, first_trans);
last_memb_count = member_list_entries;
first_trans = 0;
cman_send_confchg(member_list, member_list_entries,
saved_left_list, saved_left_list_entries,
joined_list, joined_list_entries);
}
}
/* Write an error message down the CMAN startup pipe so
that cman_tool can display it */
int write_cman_pipe(char *message)
{
if (startup_pipe)
return write(startup_pipe, message, strlen(message)+1);
return 0;
}
diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c
index 9d3f8f86d..a7ddea7db 100644
--- a/cman/daemon/cman-preconfig.c
+++ b/cman/daemon/cman-preconfig.c
@@ -1,1076 +1,1076 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <netdb.h>
#define SYSLOG_NAMES
#include <sys/syslog.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
/* corosync headers */
#include <corosync/engine/logsys.h>
#include <corosync/lcr/lcr_comp.h>
#include <corosync/engine/objdb.h>
#include <corosync/engine/config.h>
#include "cman.h"
#define OBJDB_API struct objdb_iface_ver0
#include "cnxman-socket.h"
#include "nodelist.h"
#include "logging.h"
#define MAX_PATH_LEN PATH_MAX
static unsigned int debug_mask;
static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, char **error_string);
static char *nodename_env;
static int expected_votes;
static int votes;
static int num_interfaces;
static int startup_pipe;
static unsigned int cluster_id;
static char nodename[MAX_CLUSTER_MEMBER_NAME_LEN];
static int nodeid;
static int two_node;
static unsigned int disable_openais;
static unsigned int portnum;
static int num_nodenames;
-static char *key_filename;
+static char *key_filename=NULL;
static char *mcast_name;
static char *cluster_name;
static char error_reason[1024] = { '\0' };
static unsigned int cluster_parent_handle;
/*
* Exports the interface for the service
*/
static struct config_iface_ver0 cmanpreconfig_iface_ver0 = {
.config_readconfig = cmanpre_readconfig
};
static struct lcr_iface ifaces_ver0[2] = {
{
.name = "cmanpreconfig",
.version = 0,
.versions_replace = 0,
.versions_replace_count = 0,
.dependencies = 0,
.dependency_count = 0,
.constructor = NULL,
.destructor = NULL,
.interfaces = NULL,
}
};
static struct lcr_comp cmanpre_comp_ver0 = {
.iface_count = 1,
.ifaces = ifaces_ver0,
};
__attribute__ ((constructor)) static void cmanpre_comp_register(void) {
lcr_interfaces_set(&ifaces_ver0[0], &cmanpreconfig_iface_ver0);
lcr_component_register(&cmanpre_comp_ver0);
}
static char *facility_name_get (unsigned int facility)
{
unsigned int i;
for (i = 0; facilitynames[i].c_name != NULL; i++) {
if (facility == facilitynames[i].c_val) {
return (facilitynames[i].c_name);
}
}
return (NULL);
}
static char *priority_name_get (unsigned int priority)
{
unsigned int i;
for (i = 0; prioritynames[i].c_name != NULL; i++) {
if (priority == prioritynames[i].c_val) {
return (prioritynames[i].c_name);
}
}
return (NULL);
}
#define LOCALHOST_IPV4 "127.0.0.1"
#define LOCALHOST_IPV6 "::1"
/* Compare two addresses */
static int ipaddr_equal(struct sockaddr_storage *addr1, struct sockaddr_storage *addr2)
{
int addrlen = 0;
struct sockaddr *saddr1 = (struct sockaddr *)addr1;
struct sockaddr *saddr2 = (struct sockaddr *)addr2;
if (saddr1->sa_family != saddr2->sa_family)
return 0;
if (saddr1->sa_family == AF_INET) {
addrlen = sizeof(struct sockaddr_in);
}
if (saddr1->sa_family == AF_INET6) {
addrlen = sizeof(struct sockaddr_in6);
}
assert(addrlen);
if (memcmp(saddr1, saddr2, addrlen) == 0)
return 1;
else
return 0;
}
/* Build a localhost ip_address */
static int get_localhost(int family, struct sockaddr_storage *localhost)
{
char *addr_text;
struct addrinfo *ainfo;
struct addrinfo ahints;
int ret;
if (family == AF_INET) {
addr_text = LOCALHOST_IPV4;
} else {
addr_text = LOCALHOST_IPV6;
}
memset(&ahints, 0, sizeof(ahints));
ahints.ai_socktype = SOCK_DGRAM;
ahints.ai_protocol = IPPROTO_UDP;
ahints.ai_family = family;
/* Lookup the nodename address */
ret = getaddrinfo(addr_text, NULL, &ahints, &ainfo);
if (ret)
return -1;
memset(localhost, 0, sizeof(struct sockaddr_storage));
memcpy(localhost, ainfo->ai_addr, ainfo->ai_addrlen);
freeaddrinfo(ainfo);
return 0;
}
/* Return the address family of an IP[46] name */
static int address_family(char *addr, struct sockaddr_storage *ssaddr)
{
struct addrinfo *ainfo;
struct addrinfo ahints;
int family;
int ret;
memset(&ahints, 0, sizeof(ahints));
ahints.ai_socktype = SOCK_DGRAM;
ahints.ai_protocol = IPPROTO_UDP;
/* Lookup the nodename address */
ret = getaddrinfo(addr, NULL, &ahints, &ainfo);
if (ret)
return -1;
memset(ssaddr, 0, sizeof(struct sockaddr_storage));
memcpy(ssaddr, ainfo->ai_addr, ainfo->ai_addrlen);
family = ainfo->ai_family;
freeaddrinfo(ainfo);
return family;
}
/* Find the "CMAN" logger_subsys object. Or create one if it does not
exist
*/
static unsigned int find_cman_logger(struct objdb_iface_ver0 *objdb, unsigned int object_handle)
{
unsigned int subsys_handle;
unsigned int find_handle;
char *str;
objdb->object_find_create(object_handle, "logger_subsys", strlen("logger_subsys"), &find_handle);
while (!objdb->object_find_next(object_handle, &subsys_handle)) {
if (objdb_get_string(objdb, subsys_handle, "subsys", &str)) {
continue;
}
if (strcmp(str, CMAN_NAME) == 0)
return subsys_handle;
}
objdb->object_find_destroy(find_handle);
/* We can't find it ... create one */
if (objdb->object_create(object_handle, &subsys_handle,
"logger_subsys", strlen("logger_subsys")) == 0) {
objdb->object_key_create(subsys_handle, "subsys", strlen("subsys"),
CMAN_NAME, strlen(CMAN_NAME)+1);
}
return subsys_handle;
}
static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int portnum)
{
unsigned int totem_object_handle;
unsigned int find_handle;
unsigned int interface_object_handle;
struct sockaddr_storage if_addr, localhost, mcast_addr;
char tmp[132];
int ret = 0;
/* Check the families match */
if (address_family(mcast, &mcast_addr) !=
address_family(ifaddr, &if_addr)) {
sprintf(error_reason, "Node address family does not match multicast address family");
return -1;
}
/* Check it's not bound to localhost, sigh */
get_localhost(if_addr.ss_family, &localhost);
if (ipaddr_equal(&localhost, &if_addr)) {
sprintf(error_reason, "Node address is localhost, please choose a real host address");
return -1;
}
objdb->object_find_create(OBJECT_PARENT_HANDLE, "totem", strlen("totem"), &find_handle);
if (objdb->object_find_next(find_handle, &totem_object_handle)) {
objdb->object_create(OBJECT_PARENT_HANDLE, &totem_object_handle,
"totem", strlen("totem"));
}
objdb->object_find_destroy(find_handle);
if (objdb->object_create(totem_object_handle, &interface_object_handle,
"interface", strlen("interface")) == 0) {
sprintf(tmp, "%d", num_interfaces);
objdb->object_key_create(interface_object_handle, "ringnumber", strlen("ringnumber"),
tmp, strlen(tmp)+1);
objdb->object_key_create(interface_object_handle, "bindnetaddr", strlen("bindnetaddr"),
ifaddr, strlen(ifaddr)+1);
objdb->object_key_create(interface_object_handle, "mcastaddr", strlen("mcastaddr"),
mcast, strlen(mcast)+1);
sprintf(tmp, "%d", portnum);
objdb->object_key_create(interface_object_handle, "mcastport", strlen("mcastport"),
tmp, strlen(tmp)+1);
num_interfaces++;
}
return ret;
}
static uint16_t generate_cluster_id(char *name)
{
int i;
int value = 0;
for (i=0; i<strlen(name); i++) {
value <<= 1;
value += name[i];
}
sprintf(error_reason, "Generated cluster id for '%s' is %d\n", name, value & 0xFFFF);
return value & 0xFFFF;
}
static char *default_mcast(char *nodename, uint16_t cluster_id)
{
struct addrinfo *ainfo;
struct addrinfo ahints;
int ret;
int family;
static char addr[132];
memset(&ahints, 0, sizeof(ahints));
/* Lookup the the nodename address and use it's IP type to
default a multicast address */
ret = getaddrinfo(nodename, NULL, &ahints, &ainfo);
if (ret) {
sprintf(error_reason, "Can't determine address family of nodename %s\n", nodename);
write_cman_pipe("Can't determine address family of nodename");
return NULL;
}
family = ainfo->ai_family;
freeaddrinfo(ainfo);
if (family == AF_INET) {
snprintf(addr, sizeof(addr), "239.192.%d.%d", cluster_id >> 8, cluster_id % 0xFF);
return addr;
}
if (family == AF_INET6) {
snprintf(addr, sizeof(addr), "ff15::%x", cluster_id);
return addr;
}
return NULL;
}
static int verify_nodename(struct objdb_iface_ver0 *objdb, char *nodename)
{
char nodename2[MAX_CLUSTER_MEMBER_NAME_LEN+1];
char nodename3[MAX_CLUSTER_MEMBER_NAME_LEN+1];
char *str, *dot = NULL;
struct ifaddrs *ifa, *ifa_list;
struct sockaddr *sa;
unsigned int nodes_handle;
unsigned int find_handle = 0;
int error;
/* nodename is either from commandline or from uname */
if (nodelist_byname(objdb, cluster_parent_handle, nodename))
return 0;
/* If nodename was from uname, try a domain-less version of it */
strcpy(nodename2, nodename);
dot = strchr(nodename2, '.');
if (dot) {
*dot = '\0';
if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
strcpy(nodename, nodename2);
return 0;
}
}
/* If nodename (from uname) is domain-less, try to match against
cluster.conf names which may have domainname specified */
nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
do {
int len;
if (objdb_get_string(objdb, nodes_handle, "name", &str)) {
sprintf(error_reason, "Cannot get node name");
nodes_handle = nodeslist_next(objdb, find_handle);
continue;
}
strcpy(nodename3, str);
dot = strchr(nodename3, '.');
if (dot)
len = dot-nodename3;
else
len = strlen(nodename3);
if (strlen(nodename2) == len &&
!strncmp(nodename2, nodename3, len)) {
strcpy(nodename, str);
return 0;
}
nodes_handle = nodeslist_next(objdb, find_handle);
} while (nodes_handle);
objdb->object_find_destroy(find_handle);
/* The cluster.conf names may not be related to uname at all,
they may match a hostname on some network interface.
NOTE: This is IPv4 only */
error = getifaddrs(&ifa_list);
if (error)
return -1;
for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
/* Restore this */
strcpy(nodename2, nodename);
sa = ifa->ifa_addr;
if (!sa || sa->sa_family != AF_INET)
continue;
error = getnameinfo(sa, sizeof(*sa), nodename2,
sizeof(nodename2), NULL, 0, 0);
if (error)
goto out;
if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
strcpy(nodename, nodename2);
goto out;
}
/* truncate this name and try again */
dot = strchr(nodename2, '.');
if (!dot)
continue;
*dot = '\0';
if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
strcpy(nodename, nodename2);
goto out;
}
/* See if it's the IP address that's in cluster.conf */
error = getnameinfo(sa, sizeof(*sa), nodename2,
sizeof(nodename2), NULL, 0, NI_NUMERICHOST);
if (error)
goto out;
if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
strcpy(nodename, nodename2);
goto out;
}
}
error = -1;
out:
freeifaddrs(ifa_list);
return error;
}
/* Get any environment variable overrides */
static int get_env_overrides()
{
if (getenv("CMAN_CLUSTER_NAME")) {
cluster_name = strdup(getenv("CMAN_CLUSTER_NAME"));
}
nodename_env = getenv("CMAN_NODENAME");
expected_votes = 0;
if (getenv("CMAN_EXPECTEDVOTES")) {
expected_votes = atoi(getenv("CMAN_EXPECTEDVOTES"));
if (expected_votes < 1) {
expected_votes = 0;
}
}
/* optional port */
if (getenv("CMAN_IP_PORT")) {
portnum = atoi(getenv("CMAN_IP_PORT"));
}
/* optional security key filename */
if (getenv("CMAN_KEYFILE")) {
key_filename = strdup(getenv("CMAN_KEYFILE"));
if (key_filename == NULL) {
write_cman_pipe("Cannot allocate memory for key filename");
return -1;
}
}
/* find our own number of votes */
if (getenv("CMAN_VOTES")) {
votes = atoi(getenv("CMAN_VOTES"));
}
/* nodeid */
if (getenv("CMAN_NODEID")) {
nodeid = atoi(getenv("CMAN_NODEID"));
}
if (getenv("CMAN_MCAST_ADDR")) {
mcast_name = getenv("CMAN_MCAST_ADDR");
}
if (getenv("CMAN_2NODE")) {
two_node = 1;
expected_votes = 1;
votes = 1;
}
if (getenv("CMAN_DEBUGLOG")) {
debug_mask = atoi(getenv("CMAN_DEBUGLOG"));
}
return 0;
}
static int get_nodename(struct objdb_iface_ver0 *objdb)
{
char *nodeid_str = NULL;
unsigned int object_handle;
unsigned int find_handle;
unsigned int node_object_handle;
unsigned int alt_object;
int error;
if (!getenv("CMAN_NOCONFIG")) {
/* our nodename */
if (nodename_env != NULL) {
if (strlen(nodename_env) >= sizeof(nodename)) {
sprintf(error_reason, "Overridden node name %s is too long", nodename);
write_cman_pipe("Overridden node name is too long");
error = -1;
goto out;
}
strcpy(nodename, nodename_env);
if (!(node_object_handle = nodelist_byname(objdb, cluster_parent_handle, nodename))) {
sprintf(error_reason, "Overridden node name %s is not in CCS", nodename);
write_cman_pipe("Overridden node name is not in CCS");
error = -1;
goto out;
}
} else {
struct utsname utsname;
error = uname(&utsname);
if (error) {
sprintf(error_reason, "cannot get node name, uname failed");
write_cman_pipe("Can't determine local node name");
error = -1;
goto out;
}
if (strlen(utsname.nodename) >= sizeof(nodename)) {
sprintf(error_reason, "node name from uname is too long");
write_cman_pipe("Can't determine local node name");
error = -1;
goto out;
}
strcpy(nodename, utsname.nodename);
}
if (verify_nodename(objdb, nodename))
return -1;
}
/* Add <cman> bits to pass down to the main module*/
if ( (node_object_handle = nodelist_byname(objdb, cluster_parent_handle, nodename))) {
if (objdb_get_string(objdb, node_object_handle, "nodeid", &nodeid_str)) {
sprintf(error_reason, "This node has no nodeid in cluster.conf");
write_cman_pipe("This node has no nodeid in cluster.conf");
return -1;
}
}
objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle) == 0) {
unsigned int mcast_handle;
unsigned int find_handle2;
if (!mcast_name) {
objdb->object_find_create(object_handle, "multicast", strlen("multicast"), &find_handle2);
if (objdb->object_find_next(find_handle2, &mcast_handle) == 0) {
objdb_get_string(objdb, mcast_handle, "addr", &mcast_name);
}
objdb->object_find_destroy(find_handle2);
}
if (!mcast_name) {
mcast_name = default_mcast(nodename, cluster_id);
}
/* See if the user wants our default set of openais services (default=yes) */
objdb_get_int(objdb, object_handle, "disable_openais", &disable_openais, 0);
objdb->object_key_create(object_handle, "nodename", strlen("nodename"),
nodename, strlen(nodename)+1);
}
objdb->object_find_destroy(find_handle);
nodeid = atoi(nodeid_str);
error = 0;
/* optional port */
if (!portnum) {
objdb_get_int(objdb, object_handle, "port", &portnum, DEFAULT_PORT);
}
if (add_ifaddr(objdb, mcast_name, nodename, portnum))
return -1;
/* Get all alternative node names */
num_nodenames = 1;
objdb->object_find_create(node_object_handle,"altname", strlen("altname"), &find_handle);
while (objdb->object_find_next(find_handle, &alt_object) == 0) {
unsigned int port;
char *nodename;
char *mcast;
if (objdb_get_string(objdb, alt_object, "name", &nodename)) {
continue;
}
objdb_get_int(objdb, alt_object, "port", &port, portnum);
if (objdb_get_string(objdb, alt_object, "mcast", &mcast)) {
mcast = mcast_name;
}
if (add_ifaddr(objdb, mcast, nodename, portnum))
return -1;
num_nodenames++;
}
objdb->object_find_destroy(find_handle);
out:
return error;
}
/* These are basically cman overrides to the totem config bits */
static void add_cman_overrides(struct objdb_iface_ver0 *objdb)
{
unsigned int logger_object_handle;
char *logstr;
char *logfacility;
unsigned int object_handle;
unsigned int find_handle;
char tmp[256];
/* "totem" key already exists, because we have added the interfaces by now */
objdb->object_find_create(OBJECT_PARENT_HANDLE,"totem", strlen("totem"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle) == 0)
{
char *value;
objdb->object_key_create(object_handle, "version", strlen("version"),
"2", 2);
sprintf(tmp, "%d", nodeid);
objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"),
tmp, strlen(tmp)+1);
objdb->object_key_create(object_handle, "vsftype", strlen("vsftype"),
"none", strlen("none")+1);
/* Set the token timeout is 10 seconds, but don't overrride anything that
might be in cluster.conf */
if (objdb_get_string(objdb, object_handle, "token", &value)) {
objdb->object_key_create(object_handle, "token", strlen("token"),
"10000", strlen("10000")+1);
}
if (objdb_get_string(objdb, object_handle, "token_retransmits_before_loss_const", &value)) {
objdb->object_key_create(object_handle, "token_retransmits_before_loss_const",
strlen("token_retransmits_before_loss_const"),
"20", strlen("20")+1);
}
/* Extend consensus & join timeouts per bz#214290 */
if (objdb_get_string(objdb, object_handle, "join", &value)) {
objdb->object_key_create(object_handle, "join", strlen("join"),
"60", strlen("60")+1);
}
if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
objdb->object_key_create(object_handle, "consensus", strlen("consensus"),
"4800", strlen("4800")+1);
}
/* Set RRP mode appropriately */
if (objdb_get_string(objdb, object_handle, "rrp_mode", &value)) {
if (num_interfaces > 1) {
objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"),
"active", strlen("active")+1);
}
else {
objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"),
"none", strlen("none")+1);
}
}
if (objdb_get_string(objdb, object_handle, "secauth", &value)) {
sprintf(tmp, "%d", 1);
objdb->object_key_create(object_handle, "secauth", strlen("secauth"),
tmp, strlen(tmp)+1);
}
/* optional security key filename */
if (!key_filename) {
objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
}
else {
objdb->object_key_create(object_handle, "keyfile", strlen("keyfile"),
key_filename, strlen(key_filename)+1);
}
if (!key_filename) {
/* Use the cluster name as key,
* This isn't a good isolation strategy but it does make sure that
* clusters on the same port/multicast by mistake don't actually interfere
* and that we have some form of encryption going.
*/
int keylen;
memset(tmp, 0, sizeof(tmp));
strcpy(tmp, cluster_name);
/* Key length must be a multiple of 4 */
keylen = (strlen(cluster_name)+4) & 0xFC;
objdb->object_key_create(object_handle, "key", strlen("key"),
tmp, keylen);
}
}
objdb->object_find_destroy(find_handle);
/* Make sure mainconfig doesn't stomp on our logging options */
objdb->object_find_create(OBJECT_PARENT_HANDLE, "logging", strlen("logging"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle)) {
objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
"logging", strlen("logging"));
}
objdb->object_find_destroy(find_handle);
logfacility = facility_name_get(SYSLOGFACILITY);
logger_object_handle = find_cman_logger(objdb, object_handle);
if (objdb_get_string(objdb, object_handle, "syslog_facility", &logstr)) {
objdb->object_key_create(object_handle, "syslog_facility", strlen("syslog_facility"),
logfacility, strlen(logfacility)+1);
}
if (objdb_get_string(objdb, object_handle, "to_file", &logstr)) {
objdb->object_key_create(object_handle, "to_file", strlen("to_file"),
"yes", strlen("yes")+1);
}
if (objdb_get_string(objdb, object_handle, "logfile", &logstr)) {
objdb->object_key_create(object_handle, "logfile", strlen("logfile"),
LOGDIR "/cman.log", strlen(LOGDIR "/cman.log")+1);
}
if (debug_mask) {
objdb->object_key_create(object_handle, "to_stderr", strlen("to_stderr"),
"yes", strlen("yes")+1);
objdb->object_key_create(logger_object_handle, "debug", strlen("debug"),
"on", strlen("on")+1);
objdb->object_key_create(logger_object_handle, "syslog_level", strlen("syslog_level"),
"debug", strlen("debug")+1);
}
else {
char *loglevel;
loglevel = priority_name_get(SYSLOGLEVEL);
objdb->object_key_create(logger_object_handle, "syslog_level", strlen("syslog_level"),
loglevel, strlen(loglevel)+1);
}
/* Don't run under user "ais" */
objdb->object_find_create(OBJECT_PARENT_HANDLE, "aisexec", strlen("aisexec"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle) != 0) {
objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
"aisexec", strlen("aisexec"));
}
objdb->object_find_destroy(find_handle);
objdb->object_key_create(object_handle, "user", strlen("user"),
"root", strlen("root") + 1);
objdb->object_key_create(object_handle, "group", strlen("group"),
"root", strlen("root") + 1);
objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle) == 0)
{
char str[255];
sprintf(str, "%d", cluster_id);
objdb->object_key_create(object_handle, "cluster_id", strlen("cluster_id"),
str, strlen(str) + 1);
if (two_node) {
sprintf(str, "%d", 1);
objdb->object_key_create(object_handle, "two_node", strlen("two_node"),
str, strlen(str) + 1);
}
if (debug_mask) {
sprintf(str, "%d", debug_mask);
objdb->object_key_create(object_handle, "debug_mask", strlen("debug_mask"),
str, strlen(str) + 1);
}
}
objdb->object_find_destroy(find_handle);
/* Make sure we load our alter-ego - the main cman module */
objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
"service", strlen("service"));
objdb->object_key_create(object_handle, "name", strlen("name"),
"corosync_cman", strlen("corosync_cman") + 1);
objdb->object_key_create(object_handle, "ver", strlen("ver"),
"0", 2);
}
/* If ccs is not available then use some defaults */
static int set_noccs_defaults(struct objdb_iface_ver0 *objdb)
{
char tmp[255];
unsigned int object_handle;
unsigned int find_handle;
/* Enforce key */
key_filename = NOCCS_KEY_FILENAME;
if (!cluster_name)
cluster_name = DEFAULT_CLUSTER_NAME;
if (!cluster_id)
cluster_id = generate_cluster_id(cluster_name);
if (!nodename_env) {
int error;
struct utsname utsname;
error = uname(&utsname);
if (error) {
sprintf(error_reason, "cannot get node name, uname failed");
write_cman_pipe("Can't determine local node name");
return -1;
}
nodename_env = (char *)&utsname.nodename;
}
strcpy(nodename, nodename_env);
num_nodenames = 1;
if (!mcast_name) {
mcast_name = default_mcast(nodename, cluster_id);
}
/* This will increase as nodes join the cluster */
if (!expected_votes)
expected_votes = 1;
if (!votes)
votes = 1;
if (!portnum)
portnum = DEFAULT_PORT;
/* Invent a node ID */
if (!nodeid) {
struct addrinfo *ainfo;
struct addrinfo ahints;
int ret;
memset(&ahints, 0, sizeof(ahints));
ret = getaddrinfo(nodename, NULL, &ahints, &ainfo);
if (ret) {
sprintf(error_reason, "Can't determine address family of nodename %s\n", nodename);
write_cman_pipe("Can't determine address family of nodename");
return -1;
}
if (ainfo->ai_family == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *)ainfo->ai_addr;
memcpy(&nodeid, &addr->sin_addr, sizeof(int));
}
if (ainfo->ai_family == AF_INET6) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ainfo->ai_addr;
memcpy(&nodeid, &addr->sin6_addr.s6_addr32[3], sizeof(int));
}
freeaddrinfo(ainfo);
}
/* Write a local <clusternode> entry to keep the rest of the code happy */
objdb->object_create(cluster_parent_handle, &object_handle,
"clusternodes", strlen("clusternodes"));
objdb->object_create(object_handle, &object_handle,
"clusternode", strlen("clusternode"));
objdb->object_key_create(object_handle, "name", strlen("name"),
nodename, strlen(nodename)+1);
sprintf(tmp, "%d", votes);
objdb->object_key_create(object_handle, "votes", strlen("votes"),
tmp, strlen(tmp)+1);
sprintf(tmp, "%d", nodeid);
objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"),
tmp, strlen(tmp)+1);
/* Write the default cluster name & ID in here too */
objdb->object_key_create(cluster_parent_handle, "name", strlen("name"),
cluster_name, strlen(cluster_name)+1);
objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle) == 0) {
objdb->object_create(cluster_parent_handle, &object_handle,
"cman", strlen("cman"));
}
sprintf(tmp, "%d", cluster_id);
objdb->object_key_create(object_handle, "cluster_id", strlen("cluster_id"),
tmp, strlen(tmp)+1);
sprintf(tmp, "%d", expected_votes);
objdb->object_key_create(object_handle, "expected_votes", strlen("expected_votes"),
tmp, strlen(tmp)+1);
objdb->object_find_destroy(find_handle);
return 0;
}
/* Move an object/key tree */
static int move_config_tree(struct objdb_iface_ver0 *objdb, unsigned int source_object, unsigned int target_parent_object)
{
unsigned int object_handle;
unsigned int new_object;
unsigned int find_handle;
char object_name[1024];
int object_name_len;
void *key_name;
int key_name_len;
void *key_value;
int key_value_len;
int res;
/* Create new parent object if necessary */
objdb->object_name_get(source_object, object_name, &object_name_len);
objdb->object_find_create(target_parent_object, object_name, strlen(object_name), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle))
objdb->object_create(target_parent_object, &new_object, object_name, object_name_len);
objdb->object_find_destroy(find_handle);
/* Copy the keys */
objdb->object_key_iter_reset(new_object);
while (!objdb->object_key_iter(source_object, &key_name, &key_name_len,
&key_value, &key_value_len)) {
objdb->object_key_create(new_object, key_name, key_name_len,
key_value, key_value_len);
}
/* Create sub-objects */
res = objdb->object_find_create(source_object, NULL, 0, &find_handle);
if (res) {
sprintf(error_reason, "error resetting object iterator for object %d: %d\n", source_object, res);
return -1;
}
while ( (res = objdb->object_find_next(find_handle, &object_handle) == 0)) {
/* Down we go ... */
move_config_tree(objdb, object_handle, new_object);
}
objdb->object_find_destroy(find_handle);
return 0;
}
/*
* Move trees from /cluster where they live in cluster.conf, into the root
* of the config tree where corosync expects to find them.
*/
static int move_tree_to_root(struct objdb_iface_ver0 *objdb, char *name)
{
unsigned int find_handle;
unsigned int object_handle;
int res=0;
objdb->object_find_create(cluster_parent_handle, name, strlen(name), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle) == 0) {
res = move_config_tree(objdb, object_handle, OBJECT_PARENT_HANDLE);
}
objdb->object_find_destroy(find_handle);
// TODO Destroy original ??
// objdb->object_destroy(object_handle);
return res;
}
static int get_cman_globals(struct objdb_iface_ver0 *objdb)
{
unsigned int object_handle;
unsigned int find_handle;
objdb_get_string(objdb, cluster_parent_handle, "name", &cluster_name);
/* Get the <cman> bits that override <totem> bits */
objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle) == 0) {
if (!portnum)
objdb_get_int(objdb, object_handle, "port", &portnum, DEFAULT_PORT);
if (!key_filename)
objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
if (!cluster_id)
objdb_get_int(objdb, object_handle, "cluster_id", &cluster_id, 0);
if (!cluster_id)
cluster_id = generate_cluster_id(cluster_name);
}
objdb->object_find_destroy(find_handle);
return 0;
}
static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, char **error_string)
{
int ret = 0;
unsigned int object_handle;
unsigned int find_handle;
if (getenv("CMAN_PIPE"))
startup_pipe = atoi(getenv("CMAN_PIPE"));
objdb->object_find_create(OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &find_handle);
objdb->object_find_next(find_handle, &cluster_parent_handle);
objdb->object_find_destroy(find_handle);
/* Move these to a place where corosync expects to find them */
ret = move_tree_to_root(objdb, "totem");
ret = move_tree_to_root(objdb, "logging");
ret = move_tree_to_root(objdb, "event");
ret = move_tree_to_root(objdb, "amf");
ret = move_tree_to_root(objdb, "aisexec");
objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
if (objdb->object_find_next(find_handle, &object_handle)) {
objdb->object_create(cluster_parent_handle, &object_handle,
"cman", strlen("cman"));
}
objdb->object_find_destroy(find_handle);
get_env_overrides();
if (getenv("CMAN_NOCONFIG"))
ret = set_noccs_defaults(objdb);
else
ret = get_cman_globals(objdb);
if (!ret) {
ret = get_nodename(objdb);
add_cman_overrides(objdb);
}
if (!ret) {
sprintf (error_reason, "%s", "Successfully parsed cman config\n");
}
else {
if (error_reason[0] == '\0')
sprintf (error_reason, "%s", "Error parsing cman config\n");
}
*error_string = error_reason;
return ret;
}
/* Write an error message down the CMAN startup pipe so
that cman_tool can display it */
int write_cman_pipe(char *message)
{
if (startup_pipe)
return write(startup_pipe, message, strlen(message)+1);
return 0;
}
diff --git a/config/plugins/xml/config.c b/config/plugins/xml/config.c
index 8ba290bf5..a20bf00da 100644
--- a/config/plugins/xml/config.c
+++ b/config/plugins/xml/config.c
@@ -1,303 +1,311 @@
#include <string.h>
#include <limits.h>
#include <syslog.h>
#include <arpa/inet.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <corosync/lcr/lcr_comp.h>
#include <corosync/engine/objdb.h>
#include <corosync/engine/config.h>
#include "logging.h"
static int xml_readconfig(struct objdb_iface_ver0 *objdb, char **error_string);
+static int xml_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, char **error_string);
static int init_config(struct objdb_iface_ver0 *objdb, char *configfile, char *error_string);
static char error_reason[1024];
static int xmllistindex = 0;
static char previous_query[PATH_MAX];
#define DEFAULT_CONFIG DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE
/*
* Exports the interface for the service
*/
static struct config_iface_ver0 xmlconfig_iface_ver0 = {
- .config_readconfig = xml_readconfig
+ .config_readconfig = xml_readconfig,
+ .config_reloadconfig = xml_reloadconfig
};
static struct lcr_iface ifaces_ver0[2] = {
{
.name = "xmlconfig",
.version = 0,
.versions_replace = 0,
.versions_replace_count = 0,
.dependencies = 0,
.dependency_count = 0,
.constructor = NULL,
.destructor = NULL,
.interfaces = NULL,
}
};
static struct lcr_comp xml_comp_ver0 = {
.iface_count = 1,
.ifaces = ifaces_ver0,
};
__attribute__ ((constructor)) static void xml_comp_register(void) {
lcr_interfaces_set(&ifaces_ver0[0], &xmlconfig_iface_ver0);
lcr_component_register(&xml_comp_ver0);
};
static char *do_xml_query(xmlXPathContextPtr ctx, char *query, int list) {
xmlXPathObjectPtr obj = NULL;
xmlNodePtr node = NULL;
char *rtn = NULL;
int size = 0, nnv = 0, child = 0;
if (list && !strcmp(query, previous_query))
xmllistindex++;
else {
memset(previous_query, 0, PATH_MAX);
xmllistindex = 0;
}
obj = xmlXPathEvalExpression((xmlChar *)query, ctx);
if (obj && obj->nodesetval && (obj->nodesetval->nodeNr > 0)) {
if (xmllistindex >= obj->nodesetval->nodeNr) {
memset(previous_query, 0, PATH_MAX);
xmllistindex = 0;
goto fail;
}
node = obj->nodesetval->nodeTab[xmllistindex];
if (!node)
goto fail;
if (((node->type == XML_ATTRIBUTE_NODE) && strstr(query, "@*")) ||
((node->type == XML_ELEMENT_NODE) && strstr(query, "child::*"))) {
if (node->children && node->children->content) {
size = strlen((char *)node->children->content) +
strlen((char *)node->name)+2;
child = 1;
} else
size = strlen((char *)node->name)+2;
nnv = 1;
} else {
if (node->children && node->children->content)
size = strlen((char *)node->children->content)+1;
else
goto fail;
}
rtn = malloc(size);
if (!rtn)
goto fail;
memset(rtn, 0, size);
if (nnv) {
if (child)
sprintf(rtn, "%s=%s", node->name, (char *)node->children->content);
else
sprintf(rtn, "%s=", node->name);
} else
sprintf(rtn, "%s", node->children ? node->children->content : node->name);
if(list)
strncpy(previous_query, query, PATH_MAX-1);
}
fail:
if (obj)
xmlXPathFreeObject(obj);
return rtn;
}
static int should_alloc(xmlXPathContextPtr ctx, char *key)
{
int keyerror = 1, childerr = 1;
char path[256];
char *str = NULL;
sprintf(path, "%s/@*", key);
str = do_xml_query(ctx, path, 1);
if (str) {
keyerror = 0;
free(str);
str = NULL;
}
sprintf(path, "%s/child::*", key);
str = do_xml_query(ctx, path, 1);
if(str) {
childerr = 0;
free(str);
str = NULL;
}
if (childerr && keyerror)
return 0;
return 1;
}
static int read_config_for(xmlXPathContextPtr ctx, struct objdb_iface_ver0 *objdb, unsigned int parent,
char *object, char *key, int always_create)
{
char *str;
unsigned int object_handle = 0;
char path[256];
int gotcount = 0;
char *subkeys[52];
int subkeycount = 0;
int i;
if (should_alloc(ctx, key) || always_create) {
objdb->object_create(parent, &object_handle, object, strlen(object));
}
memset(previous_query, 0, PATH_MAX);
sprintf(path, "%s/@*", key);
/* Get the keys */
for (;;)
{
char *equal;
str = do_xml_query(ctx, path, 1);
if (!str)
break;
equal = strchr(str, '=');
if (equal)
{
*equal = 0;
objdb->object_key_create(object_handle, str, strlen(str),
equal+1, strlen(equal+1)+1);
gotcount++;
}
free(str);
}
/* Now look for sub-objects.
CCS can't cope with recursive queries so we have to store the result of
the subkey search */
memset(previous_query, 0, PATH_MAX);
memset(subkeys, 0, sizeof(subkeys));
sprintf(path, "%s/child::*", key);
for (;;)
{
char *equal;
str = do_xml_query(ctx, path, 1);
if (!str)
break;
/* CCS returns duplicate values for the numbered entries we use below.
eg. if there are 4 <clusternode/> entries it will return
clusternode=
clusternode=
clusternode=
clusternode=
which is not helpful to us cos we retrieve them as
clusternode[1]
clusternode[2]
clusternode[3]
clusternode[4]
so we just store unique keys.
*/
equal = strchr(str, '=');
if (equal)
*equal = 0;
if (subkeycount > 0 && strcmp(str, subkeys[subkeycount-1]) == 0)
{
free(str);
break;
}
subkeys[subkeycount++] = str;
}
for (i=0; i<subkeycount; i++)
{
int count = 0;
str = subkeys[i];
gotcount++;
for (;;)
{
char subpath[1024];
/* Found a subkey, iterate through it's sub sections */
sprintf(subpath, "%s/%s[%d]", key, str, ++count);
if (!read_config_for(ctx, objdb, object_handle, str, subpath, 0))
break;
}
free(str);
}
return gotcount;
}
+static int xml_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, char **error_string)
+{
+ fprintf(stderr, "CC: xml_reloadconfig\n");
+ return xml_readconfig(objdb, error_string);
+}
+
static int xml_readconfig(struct objdb_iface_ver0 *objdb, char **error_string)
{
int ret = 0;
char *configfile = DEFAULT_CONFIG;
/* We need to set this up to internal defaults too early */
openlog("corosync", LOG_CONS|LOG_PID, SYSLOGFACILITY);
if(getenv("COROSYNC_CLUSTER_CONFIG_FILE"))
configfile = getenv("COROSYNC_CLUSTER_CONFIG_FILE");
/* Read low-level totem/aisexec etc config from cluster.conf */
if ( !(ret = init_config(objdb, configfile, error_reason)) )
sprintf (error_reason, "Successfully read config from %s\n", configfile);
else
sprintf (error_reason, "Unable to read config from %s\n", configfile);
*error_string = error_reason;
return ret;
}
static int init_config(struct objdb_iface_ver0 *objdb, char *configfile, char *error_string)
{
int err = 0;
xmlDocPtr doc = NULL;
xmlXPathContextPtr ctx = NULL;
/* openfile */
doc = xmlParseFile(configfile);
if (!doc) {
err = -1;
goto fail;
}
ctx = xmlXPathNewContext(doc);
if (!ctx) {
err = -1;
goto fail;
}
/* load it in objdb */
read_config_for(ctx, objdb, OBJECT_PARENT_HANDLE, "cluster", "/cluster", 1);
fail:
if (ctx)
xmlXPathFreeContext(ctx);
if (doc)
xmlFreeDoc(doc);
return err;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 11:07 AM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018638
Default Alt Text
(47 KB)
Attached To
Mode
rR Resource Agents
Attached
Detach File
Event Timeline
Log In to Comment