Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/mcp/corosync.c b/mcp/corosync.c
index cd500e5ff4..3acb1a3dd7 100644
--- a/mcp/corosync.c
+++ b/mcp/corosync.c
@@ -1,593 +1,599 @@
/*
* Copyright (C) 2010 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <crm_internal.h>
#include <pacemaker.h>
#include <sys/utsname.h>
-#include <sys/stat.h> /* for calls to stat() */
-#include <libgen.h> /* For basename() and dirname() */
+#include <sys/stat.h> /* for calls to stat() */
+#include <libgen.h> /* For basename() and dirname() */
#include <sys/types.h>
-#include <pwd.h> /* For getpwname() */
+#include <pwd.h> /* For getpwname() */
#include <corosync/cfg.h>
#include <corosync/cpg.h>
#include <corosync/confdb.h>
#include <crm/common/cluster.h>
#ifdef SUPPORT_CMAN
#include <libcman.h>
#endif
static struct cpg_name cpg_group = {
.length = 0,
.value[0] = 0,
};
gboolean use_cman = FALSE;
static cpg_handle_t cpg_handle;
static corosync_cfg_handle_t cfg_handle;
static corosync_cfg_state_notification_t cfg_buffer;
/* =::=::=::= CFG - Shutdown stuff =::=::=::= */
-static void cfg_shutdown_callback(corosync_cfg_handle_t h,
- corosync_cfg_shutdown_flags_t flags)
+static void
+cfg_shutdown_callback(corosync_cfg_handle_t h, corosync_cfg_shutdown_flags_t flags)
{
crm_info("Corosync wants to shut down: %s",
- (flags==COROSYNC_CFG_SHUTDOWN_FLAG_IMMEDIATE)?"immediate":
- (flags==COROSYNC_CFG_SHUTDOWN_FLAG_REGARDLESS)?"forced":"optional"
- );
+ (flags == COROSYNC_CFG_SHUTDOWN_FLAG_IMMEDIATE) ? "immediate" :
+ (flags == COROSYNC_CFG_SHUTDOWN_FLAG_REGARDLESS) ? "forced" : "optional");
/* Never allow corosync to shut down while we're running */
corosync_cfg_replyto_shutdown(h, COROSYNC_CFG_SHUTDOWN_FLAG_NO);
}
-static corosync_cfg_callbacks_t cfg_callbacks =
-{
+static corosync_cfg_callbacks_t cfg_callbacks = {
.corosync_cfg_shutdown_callback = cfg_shutdown_callback,
.corosync_cfg_state_track_callback = NULL,
};
-static gboolean pcmk_cfg_dispatch(int sender, gpointer user_data)
+static gboolean
+pcmk_cfg_dispatch(int sender, gpointer user_data)
{
- corosync_cfg_handle_t *handle = (corosync_cfg_handle_t*)user_data;
+ corosync_cfg_handle_t *handle = (corosync_cfg_handle_t *) user_data;
cs_error_t rc = corosync_cfg_dispatch(*handle, CS_DISPATCH_ALL);
+
if (rc != CS_OK) {
- return FALSE;
+ return FALSE;
}
return TRUE;
}
static void
cfg_connection_destroy(gpointer user_data)
{
crm_err("Connection destroyed");
cfg_handle = 0;
pcmk_shutdown(SIGTERM);
return;
}
-gboolean cluster_disconnect_cfg(void)
+gboolean
+cluster_disconnect_cfg(void)
{
- if(cfg_handle) {
- corosync_cfg_finalize(cfg_handle);
- cfg_handle = 0;
+ if (cfg_handle) {
+ corosync_cfg_finalize(cfg_handle);
+ cfg_handle = 0;
}
pcmk_shutdown(SIGTERM);
return TRUE;
}
#define cs_repeat(counter, max, code) do { \
code; \
if(rc == CS_ERR_TRY_AGAIN) { \
counter++; \
crm_debug("Retrying operation after %ds", counter); \
sleep(counter); \
} \
} while(rc == CS_ERR_TRY_AGAIN && counter < max)
-gboolean cluster_connect_cfg(uint32_t *nodeid)
+gboolean
+cluster_connect_cfg(uint32_t * nodeid)
{
cs_error_t rc;
int fd = 0, retries = 0;
- cs_repeat(
- retries, 30, rc = corosync_cfg_initialize(&cfg_handle, &cfg_callbacks));
-
+ cs_repeat(retries, 30, rc = corosync_cfg_initialize(&cfg_handle, &cfg_callbacks));
+
if (rc != CS_OK) {
- crm_err("corosync cfg init error %d", rc);
- return FALSE;
+ crm_err("corosync cfg init error %d", rc);
+ return FALSE;
}
rc = corosync_cfg_fd_get(cfg_handle, &fd);
if (rc != CS_OK) {
- crm_err("corosync cfg fd_get error %d", rc);
- goto bail;
+ crm_err("corosync cfg fd_get error %d", rc);
+ goto bail;
}
retries = 0;
cs_repeat(retries, 30, rc = corosync_cfg_local_get(cfg_handle, nodeid));
if (rc != CS_OK) {
- crm_err("corosync cfg local_get error %d", rc);
- goto bail;
+ crm_err("corosync cfg local_get error %d", rc);
+ goto bail;
}
crm_debug("Our nodeid: %d", *nodeid);
retries = 0;
- cs_repeat(
- retries, 30, rc = corosync_cfg_state_track (cfg_handle, 0, &cfg_buffer));
-
+ cs_repeat(retries, 30, rc = corosync_cfg_state_track(cfg_handle, 0, &cfg_buffer));
+
if (rc != CS_OK) {
- crm_err("corosync cfg stack_track error %d", rc);
- goto bail;
+ crm_err("corosync cfg stack_track error %d", rc);
+ goto bail;
}
-
+
crm_debug("Adding fd=%d to mainloop", fd);
- G_main_add_fd(
- G_PRIORITY_HIGH, fd, FALSE, pcmk_cfg_dispatch, &cfg_handle, cfg_connection_destroy);
-
+ G_main_add_fd(G_PRIORITY_HIGH, fd, FALSE, pcmk_cfg_dispatch, &cfg_handle,
+ cfg_connection_destroy);
+
return TRUE;
- bail:
+ bail:
corosync_cfg_finalize(cfg_handle);
return FALSE;
}
/* =::=::=::= CPG - Closed Process Group Messaging =::=::=::= */
-static gboolean pcmk_cpg_dispatch(int sender, gpointer user_data)
+static gboolean
+pcmk_cpg_dispatch(int sender, gpointer user_data)
{
- cpg_handle_t *handle = (cpg_handle_t*)user_data;
+ cpg_handle_t *handle = (cpg_handle_t *) user_data;
cs_error_t rc = cpg_dispatch(*handle, CS_DISPATCH_ALL);
+
if (rc != CS_OK) {
- return FALSE;
+ return FALSE;
}
return TRUE;
}
static void
cpg_connection_destroy(gpointer user_data)
{
crm_err("Connection destroyed");
cpg_handle = 0;
return;
}
-static void pcmk_cpg_deliver (
- cpg_handle_t handle,
- const struct cpg_name *groupName,
- uint32_t nodeid,
- uint32_t pid,
- void *msg,
- size_t msg_len)
+static void
+pcmk_cpg_deliver(cpg_handle_t handle,
+ const struct cpg_name *groupName,
+ uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
{
- if(nodeid != local_nodeid) {
- uint32_t procs = 0;
- xmlNode *xml = string2xml(msg);
- const char *uname = crm_element_value(xml, "uname");
-
- crm_element_value_int(xml, "proclist", (int*)&procs);
- /* crm_debug("Got proclist %.32x from %s", procs, uname); */
- if(update_node_processes(nodeid, uname, procs)) {
- update_process_clients();
- }
+ if (nodeid != local_nodeid) {
+ uint32_t procs = 0;
+ xmlNode *xml = string2xml(msg);
+ const char *uname = crm_element_value(xml, "uname");
+
+ crm_element_value_int(xml, "proclist", (int *)&procs);
+ /* crm_debug("Got proclist %.32x from %s", procs, uname); */
+ if (update_node_processes(nodeid, uname, procs)) {
+ update_process_clients();
+ }
}
}
-static void pcmk_cpg_membership(
- cpg_handle_t handle,
- const struct cpg_name *groupName,
- const struct cpg_address *member_list, size_t member_list_entries,
- const struct cpg_address *left_list, size_t left_list_entries,
- const struct cpg_address *joined_list, size_t joined_list_entries)
+static void
+pcmk_cpg_membership(cpg_handle_t handle,
+ const struct cpg_name *groupName,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
{
/* Don't care about CPG membership */
update_process_peers();
}
cpg_callbacks_t cpg_callbacks = {
- .cpg_deliver_fn = pcmk_cpg_deliver,
- .cpg_confchg_fn = pcmk_cpg_membership,
+ .cpg_deliver_fn = pcmk_cpg_deliver,
+ .cpg_confchg_fn = pcmk_cpg_membership,
};
-gboolean cluster_disconnect_cpg(void)
+gboolean
+cluster_disconnect_cpg(void)
{
- if(cpg_handle) {
- cpg_finalize(cpg_handle);
- cpg_handle = 0;
+ if (cpg_handle) {
+ cpg_finalize(cpg_handle);
+ cpg_handle = 0;
}
return TRUE;
}
-gboolean cluster_connect_cpg(void)
+gboolean
+cluster_connect_cpg(void)
{
cs_error_t rc;
unsigned int nodeid;
int fd;
int retries = 0;
-
+
strcpy(cpg_group.value, "pcmk");
- cpg_group.length = strlen(cpg_group.value)+1;
-
+ cpg_group.length = strlen(cpg_group.value) + 1;
+
retries = 0;
cs_repeat(retries, 30, rc = cpg_initialize(&cpg_handle, &cpg_callbacks));
if (rc != CS_OK) {
- crm_err("corosync cpg init error %d", rc);
- return FALSE;
+ crm_err("corosync cpg init error %d", rc);
+ return FALSE;
}
rc = cpg_fd_get(cpg_handle, &fd);
if (rc != CS_OK) {
- crm_err("corosync cpg fd_get error %d", rc);
- goto bail;
+ crm_err("corosync cpg fd_get error %d", rc);
+ goto bail;
}
retries = 0;
cs_repeat(retries, 30, rc = cpg_local_get(cpg_handle, &nodeid));
if (rc != CS_OK) {
- crm_err("corosync cpg local_get error %d", rc);
- goto bail;
+ crm_err("corosync cpg local_get error %d", rc);
+ goto bail;
}
crm_debug("Our nodeid: %d", nodeid);
retries = 0;
cs_repeat(retries, 30, rc = cpg_join(cpg_handle, &cpg_group));
-
+
if (rc != CS_OK) {
- crm_err("Could not join the CPG group '%s': %d", crm_system_name, rc);
- goto bail;
+ crm_err("Could not join the CPG group '%s': %d", crm_system_name, rc);
+ goto bail;
}
-
+
crm_debug("Adding fd=%d to mainloop", fd);
- G_main_add_fd(
- G_PRIORITY_HIGH, fd, FALSE, pcmk_cpg_dispatch, &cpg_handle, cpg_connection_destroy);
-
+ G_main_add_fd(G_PRIORITY_HIGH, fd, FALSE, pcmk_cpg_dispatch, &cpg_handle,
+ cpg_connection_destroy);
+
return TRUE;
- bail:
+ bail:
cpg_finalize(cpg_handle);
return FALSE;
}
-gboolean send_cpg_message(struct iovec *iov)
+gboolean
+send_cpg_message(struct iovec * iov)
{
int rc = CS_OK;
int retries = 0;
errno = 0;
-
- do {
- rc = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 1);
- if(rc == CS_ERR_TRY_AGAIN) {
- cpg_flow_control_state_t fc_state = CPG_FLOW_CONTROL_DISABLED;
- int rc2 = cpg_flow_control_state_get (cpg_handle, &fc_state);
-
- if (rc2 == CS_OK && fc_state == CPG_FLOW_CONTROL_ENABLED) {
- crm_debug("Attempting to clear cpg dispatch queue");
- rc2 = cpg_dispatch(cpg_handle, CS_DISPATCH_ALL);
- }
-
- if (rc2 != CS_OK) {
- crm_warn("Could not check/clear the cpg connection");
- goto bail;
-
- } else {
- retries++;
- crm_debug("Retrying operation after %ds", retries);
- sleep(retries);
- }
- }
-
- /* 5 retires is plenty, we'll resend once the membership reforms anyway */
- } while(rc == CS_ERR_TRY_AGAIN && retries < 5);
-
- bail:
- if(rc != CS_OK) {
- crm_err("Sending message via cpg FAILED: (rc=%d) %s", rc, ais_error2text(rc));
+
+ do {
+ rc = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 1);
+ if (rc == CS_ERR_TRY_AGAIN) {
+ cpg_flow_control_state_t fc_state = CPG_FLOW_CONTROL_DISABLED;
+ int rc2 = cpg_flow_control_state_get(cpg_handle, &fc_state);
+
+ if (rc2 == CS_OK && fc_state == CPG_FLOW_CONTROL_ENABLED) {
+ crm_debug("Attempting to clear cpg dispatch queue");
+ rc2 = cpg_dispatch(cpg_handle, CS_DISPATCH_ALL);
+ }
+
+ if (rc2 != CS_OK) {
+ crm_warn("Could not check/clear the cpg connection");
+ goto bail;
+
+ } else {
+ retries++;
+ crm_debug("Retrying operation after %ds", retries);
+ sleep(retries);
+ }
+ }
+
+ /* 5 retires is plenty, we'll resend once the membership reforms anyway */
+ } while (rc == CS_ERR_TRY_AGAIN && retries < 5);
+
+ bail:
+ if (rc != CS_OK) {
+ crm_err("Sending message via cpg FAILED: (rc=%d) %s", rc, ais_error2text(rc));
}
return (rc == CS_OK);
}
-
/* =::=::=::= Configuration =::=::=::= */
-static int get_config_opt(
- confdb_handle_t config,
- hdb_handle_t object_handle,
- const char *key, char **value, const char *fallback)
+static int
+get_config_opt(confdb_handle_t config,
+ hdb_handle_t object_handle, const char *key, char **value, const char *fallback)
{
size_t len = 0;
char *env_key = NULL;
const char *env_value = NULL;
char buffer[256];
- if(*value) {
- crm_free(*value);
- *value = NULL;
+ if (*value) {
+ crm_free(*value);
+ *value = NULL;
}
- if(object_handle > 0) {
- if(CS_OK == confdb_key_get(config, object_handle, key, strlen(key), &buffer, &len)) {
- *value = crm_strdup(buffer);
- }
+ if (object_handle > 0) {
+ if (CS_OK == confdb_key_get(config, object_handle, key, strlen(key), &buffer, &len)) {
+ *value = crm_strdup(buffer);
+ }
}
-
+
if (*value) {
- crm_info("Found '%s' for option: %s", *value, key);
- return 0;
+ crm_info("Found '%s' for option: %s", *value, key);
+ return 0;
}
env_key = crm_concat("HA", key, '_');
env_value = getenv(env_key);
crm_free(env_key);
if (*value) {
- crm_info("Found '%s' in ENV for option: %s", *value, key);
- *value = crm_strdup(env_value);
- return 0;
+ crm_info("Found '%s' in ENV for option: %s", *value, key);
+ *value = crm_strdup(env_value);
+ return 0;
}
- if(fallback) {
- crm_info("Defaulting to '%s' for option: %s", fallback, key);
- *value = crm_strdup(fallback);
+ if (fallback) {
+ crm_info("Defaulting to '%s' for option: %s", fallback, key);
+ *value = crm_strdup(fallback);
} else {
- crm_info("No default for option: %s", key);
+ crm_info("No default for option: %s", key);
}
-
+
return -1;
}
-static confdb_handle_t config_find_init(confdb_handle_t config)
+static confdb_handle_t
+config_find_init(confdb_handle_t config)
{
- cs_error_t rc = CS_OK;
+ cs_error_t rc = CS_OK;
confdb_handle_t local_handle = OBJECT_PARENT_HANDLE;
rc = confdb_object_find_start(config, local_handle);
- if(rc == CS_OK) {
- return local_handle;
+ if (rc == CS_OK) {
+ return local_handle;
} else {
- crm_err("Couldn't create search context: %d", rc);
+ crm_err("Couldn't create search context: %d", rc);
}
return 0;
}
-static hdb_handle_t config_find_next(
- confdb_handle_t config, const char *name, confdb_handle_t top_handle)
+static hdb_handle_t
+config_find_next(confdb_handle_t config, const char *name, confdb_handle_t top_handle)
{
cs_error_t rc = CS_OK;
hdb_handle_t local_handle = 0;
- if(top_handle == 0) {
- crm_err("Couldn't search for %s: no valid context", name);
- return 0;
+ if (top_handle == 0) {
+ crm_err("Couldn't search for %s: no valid context", name);
+ return 0;
}
-
- crm_debug_2("Searching for %s in "HDB_X_FORMAT, name, top_handle);
+
+ crm_debug_2("Searching for %s in " HDB_X_FORMAT, name, top_handle);
rc = confdb_object_find(config, top_handle, name, strlen(name), &local_handle);
- if(rc != CS_OK) {
- crm_info("No additional configuration supplied for: %s", name);
- local_handle = 0;
+ if (rc != CS_OK) {
+ crm_info("No additional configuration supplied for: %s", name);
+ local_handle = 0;
} else {
- crm_info("Processing additional %s options...", name);
+ crm_info("Processing additional %s options...", name);
}
return local_handle;
}
-char *get_local_node_name(void)
+char *
+get_local_node_name(void)
{
char *name = NULL;
struct utsname res;
-
- if(use_cman) {
+
+ if (use_cman) {
#ifdef SUPPORT_CMAN
- cman_node_t us;
- cman_handle_t cman;
-
- cman = cman_init(NULL);
- if(cman != NULL && cman_is_active(cman)) {
- us.cn_name[0] = 0;
- cman_get_node(cman, CMAN_NODEID_US, &us);
- name = crm_strdup(us.cn_name);
- crm_info("Using CMAN node name: %s", name);
-
- } else {
- crm_err("Couldn't determin node name from CMAN");
- }
-
- cman_finish(cman);
+ cman_node_t us;
+ cman_handle_t cman;
+
+ cman = cman_init(NULL);
+ if (cman != NULL && cman_is_active(cman)) {
+ us.cn_name[0] = 0;
+ cman_get_node(cman, CMAN_NODEID_US, &us);
+ name = crm_strdup(us.cn_name);
+ crm_info("Using CMAN node name: %s", name);
+
+ } else {
+ crm_err("Couldn't determin node name from CMAN");
+ }
+
+ cman_finish(cman);
#endif
-
- } else if(uname(&res) < 0) {
- crm_perror(LOG_ERR,"Could not determin the current host");
- exit(100);
-
+
+ } else if (uname(&res) < 0) {
+ crm_perror(LOG_ERR, "Could not determin the current host");
+ exit(100);
+
} else {
- name = crm_strdup(res.nodename);
+ name = crm_strdup(res.nodename);
}
return name;
}
-gboolean read_config(void)
+gboolean
+read_config(void)
{
confdb_handle_t config;
int rc;
char *value = NULL;
gboolean have_log = FALSE;
confdb_handle_t top_handle = 0;
hdb_handle_t local_handle = 0;
- static confdb_callbacks_t callbacks = {};
+ static confdb_callbacks_t callbacks = { };
enum cluster_type_e stack = get_cluster_type();
crm_info("Reading configure for stack: %s", name_for_cluster_type(stack));
- rc = confdb_initialize (&config, &callbacks);
+ rc = confdb_initialize(&config, &callbacks);
if (rc != CS_OK) {
- printf ("Could not initialize Cluster Configuration Database API instance error %d\n", rc);
- return FALSE;
+ printf("Could not initialize Cluster Configuration Database API instance error %d\n", rc);
+ return FALSE;
}
/* =::=::= Should we be here =::=::= */
- if(stack == pcmk_cluster_corosync) {
- setenv("HA_cluster_type", "corosync", 1);
-
- } else if(stack == pcmk_cluster_cman) {
- setenv("HA_cluster_type", "cman", 1);
- enable_crmd_as_root(TRUE);
- use_cman = TRUE;
-
- } else if(stack == pcmk_cluster_classic_ais) {
- setenv("HA_cluster_type", "openais", 1);
-
- /* Look for a service block to indicate our plugin is loaded */
- top_handle = config_find_init(config);
- local_handle = config_find_next(config, "service", top_handle);
-
- while(local_handle) {
- crm_free(value);
- get_config_opt(config, local_handle, "name", &value, NULL);
- if(safe_str_eq("pacemaker", value)) {
- crm_free(value);
- get_config_opt(config, local_handle, "ver", &value, "0");
- if(safe_str_eq(value, "1")) {
- crm_free(value);
- get_config_opt(config, local_handle, "use_logd", &value, "no");
- setenv("HA_use_logd", value, 1);
-
- crm_free(value);
- get_config_opt(config, local_handle, "use_mgmtd", &value, "no");
- enable_mgmtd(crm_is_true(value));
-
- } else {
- crm_err("We can only start Pacemaker from init if using version 1"
- " of the Pacemaker plugin for Corosync. Terminating.");
- exit(100);
- }
- break;
- }
- local_handle = config_find_next(config, "service", top_handle);
- }
- crm_free(value);
+ if (stack == pcmk_cluster_corosync) {
+ setenv("HA_cluster_type", "corosync", 1);
+
+ } else if (stack == pcmk_cluster_cman) {
+ setenv("HA_cluster_type", "cman", 1);
+ enable_crmd_as_root(TRUE);
+ use_cman = TRUE;
+
+ } else if (stack == pcmk_cluster_classic_ais) {
+ setenv("HA_cluster_type", "openais", 1);
+
+ /* Look for a service block to indicate our plugin is loaded */
+ top_handle = config_find_init(config);
+ local_handle = config_find_next(config, "service", top_handle);
+
+ while (local_handle) {
+ crm_free(value);
+ get_config_opt(config, local_handle, "name", &value, NULL);
+ if (safe_str_eq("pacemaker", value)) {
+ crm_free(value);
+ get_config_opt(config, local_handle, "ver", &value, "0");
+ if (safe_str_eq(value, "1")) {
+ crm_free(value);
+ get_config_opt(config, local_handle, "use_logd", &value, "no");
+ setenv("HA_use_logd", value, 1);
+
+ crm_free(value);
+ get_config_opt(config, local_handle, "use_mgmtd", &value, "no");
+ enable_mgmtd(crm_is_true(value));
+
+ } else {
+ crm_err("We can only start Pacemaker from init if using version 1"
+ " of the Pacemaker plugin for Corosync. Terminating.");
+ exit(100);
+ }
+ break;
+ }
+ local_handle = config_find_next(config, "service", top_handle);
+ }
+ crm_free(value);
} else {
- crm_err("Unsupported stack type: %s", name_for_cluster_type(stack));
- return FALSE;
+ crm_err("Unsupported stack type: %s", name_for_cluster_type(stack));
+ return FALSE;
}
-
+
/* =::=::= Logging =::=::= */
top_handle = config_find_init(config);
local_handle = config_find_next(config, "logging", top_handle);
-
+
get_config_opt(config, local_handle, "debug", &value, "on");
- if(crm_is_true(value) && crm_log_level < LOG_DEBUG) {
- crm_log_level = LOG_DEBUG;
- }
-
- if(crm_log_level >= LOG_DEBUG) {
- char *level = crm_itoa(crm_log_level - LOG_INFO);
- setenv("HA_debug", level, 1);
- crm_free(level);
+ if (crm_is_true(value) && crm_log_level < LOG_DEBUG) {
+ crm_log_level = LOG_DEBUG;
+ }
+
+ if (crm_log_level >= LOG_DEBUG) {
+ char *level = crm_itoa(crm_log_level - LOG_INFO);
+
+ setenv("HA_debug", level, 1);
+ crm_free(level);
}
-
+
get_config_opt(config, local_handle, "to_logfile", &value, "off");
- if(crm_is_true(value)) {
- get_config_opt(config, local_handle, "logfile", &value, NULL);
-
- if(value == NULL) {
- crm_err("Logging to a file requested but no log file specified");
-
- } else {
- struct stat parent;
- FILE *logfile = NULL;
- char *parent_dir = dirname(strdup(value));
- struct passwd *pcmk_user = getpwnam(CRM_DAEMON_USER);
- uid_t pcmk_uid = pcmk_user->pw_uid;
- uid_t pcmk_gid = getegid();
-
- rc = stat(parent_dir, &parent);
-
- if(rc != 0) {
- crm_err("Directory '%s' does not exist for logfile '%s'", parent_dir, value);
-
- } else if(parent.st_uid == pcmk_uid && (parent.st_mode & (S_IRUSR|S_IWUSR))) {
- /* all good - user */
- logfile = fopen(value, "a");
-
- } else if(parent.st_gid == pcmk_gid && (parent.st_mode & S_IXGRP)) {
- /* all good - group */
- logfile = fopen(value, "a");
-
- } else {
- crm_err("Daemons running as %s do not have permission to access '%s'. Logging to '%s' is disabled",
- CRM_DAEMON_USER, parent_dir, value);
- }
-
- if(logfile) {
- int logfd = fileno(logfile);
-
- setenv("HA_debugfile", value, 1);
-
- /* Ensure the file has the correct permissions */
- fchown(logfd, pcmk_uid, pcmk_gid);
- fchmod(logfd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
-
- fprintf(logfile, "Set r/w permissions for uid=%d, gid=%d on %s\n",
- pcmk_uid, pcmk_gid, value);
- fflush(logfile);
- fsync(logfd);
- fclose(logfile);
- have_log = TRUE;
-
- } else {
- crm_err("Couldn't create logfile: %s", value);
- }
- crm_free(parent_dir);
- }
+ if (crm_is_true(value)) {
+ get_config_opt(config, local_handle, "logfile", &value, NULL);
+
+ if (value == NULL) {
+ crm_err("Logging to a file requested but no log file specified");
+
+ } else {
+ struct stat parent;
+ FILE *logfile = NULL;
+ char *parent_dir = dirname(strdup(value));
+ struct passwd *pcmk_user = getpwnam(CRM_DAEMON_USER);
+ uid_t pcmk_uid = pcmk_user->pw_uid;
+ uid_t pcmk_gid = getegid();
+
+ rc = stat(parent_dir, &parent);
+
+ if (rc != 0) {
+ crm_err("Directory '%s' does not exist for logfile '%s'", parent_dir, value);
+
+ } else if (parent.st_uid == pcmk_uid && (parent.st_mode & (S_IRUSR | S_IWUSR))) {
+ /* all good - user */
+ logfile = fopen(value, "a");
+
+ } else if (parent.st_gid == pcmk_gid && (parent.st_mode & S_IXGRP)) {
+ /* all good - group */
+ logfile = fopen(value, "a");
+
+ } else {
+ crm_err
+ ("Daemons running as %s do not have permission to access '%s'. Logging to '%s' is disabled",
+ CRM_DAEMON_USER, parent_dir, value);
+ }
+
+ if (logfile) {
+ int logfd = fileno(logfile);
+
+ setenv("HA_debugfile", value, 1);
+
+ /* Ensure the file has the correct permissions */
+ fchown(logfd, pcmk_uid, pcmk_gid);
+ fchmod(logfd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
+ fprintf(logfile, "Set r/w permissions for uid=%d, gid=%d on %s\n",
+ pcmk_uid, pcmk_gid, value);
+ fflush(logfile);
+ fsync(logfd);
+ fclose(logfile);
+ have_log = TRUE;
+
+ } else {
+ crm_err("Couldn't create logfile: %s", value);
+ }
+ crm_free(parent_dir);
+ }
}
get_config_opt(config, local_handle, "to_syslog", &value, "on");
- if(have_log && crm_is_true(value) == FALSE) {
- crm_info("User configured file based logging and explicitly disabled syslog.");
- crm_free(value);
- value = NULL;
+ if (have_log && crm_is_true(value) == FALSE) {
+ crm_info("User configured file based logging and explicitly disabled syslog.");
+ crm_free(value);
+ value = NULL;
} else {
- if(crm_is_true(value) == FALSE) {
- crm_err("Please enable some sort of logging, either 'to_file: on' or 'to_syslog: on'.");
- crm_err("If you use file logging, be sure to also define a value for 'logfile'");
- }
- get_config_opt(config, local_handle, "syslog_facility", &value, "daemon");
+ if (crm_is_true(value) == FALSE) {
+ crm_err
+ ("Please enable some sort of logging, either 'to_file: on' or 'to_syslog: on'.");
+ crm_err("If you use file logging, be sure to also define a value for 'logfile'");
+ }
+ get_config_opt(config, local_handle, "syslog_facility", &value, "daemon");
}
-
- setenv("HA_logfacility", value?value:"none", 1);
- setenv("HA_LOGFACILITY", value?value:"none", 1);
-
- confdb_finalize (config);
+
+ setenv("HA_logfacility", value ? value : "none", 1);
+ setenv("HA_LOGFACILITY", value ? value : "none", 1);
+
+ confdb_finalize(config);
crm_free(value);
return TRUE;
}
diff --git a/mcp/pacemaker.c b/mcp/pacemaker.c
index 734ca29e00..4e64e688f5 100644
--- a/mcp/pacemaker.c
+++ b/mcp/pacemaker.c
@@ -1,791 +1,808 @@
/*
* Copyright (C) 2010 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <crm_internal.h>
#include <pacemaker.h>
#include <pwd.h>
#include <crm/common/ipc.h>
#include <clplumbing/proctrack.h>
-
GMainLoop *mainloop = NULL;
GHashTable *client_list = NULL;
GHashTable *peers = NULL;
char ipc_name[] = "pcmk";
char *local_name = NULL;
uint32_t local_nodeid = 0;
-crm_trigger_t *shutdown_trigger = NULL;
+crm_trigger_t *shutdown_trigger = NULL;
const char *pid_file = "/var/run/pacemaker.pid";
/* *INDENT-OFF* */
enum crm_proc_flag {
crm_proc_none = 0x00000001,
crm_proc_ais = 0x00000002,
crm_proc_lrmd = 0x00000010,
crm_proc_cib = 0x00000100,
crm_proc_crmd = 0x00000200,
crm_proc_attrd = 0x00001000,
crm_proc_stonithd = 0x00002000,
crm_proc_pe = 0x00010000,
crm_proc_te = 0x00020000,
crm_proc_mgmtd = 0x00040000,
crm_proc_stonith_ng = 0x00100000,
};
/* *INDENT-ON* */
typedef struct pcmk_child_s {
- int pid;
- long flag;
- int start_seq;
- int respawn_count;
- gboolean respawn;
- const char *name;
- const char *uid;
- const char *command;
-
+ int pid;
+ long flag;
+ int start_seq;
+ int respawn_count;
+ gboolean respawn;
+ const char *name;
+ const char *uid;
+ const char *command;
+
} pcmk_child_t;
/* Index into the array below */
#define pcmk_child_crmd 4
#define pcmk_child_mgmtd 8
/* *INDENT-OFF* */
static pcmk_child_t pcmk_children[] = {
{ 0, crm_proc_none, 0, 0, FALSE, "none", NULL, NULL },
{ 0, crm_proc_ais, 0, 0, FALSE, "ais", NULL, NULL },
{ 0, crm_proc_lrmd, 3, 0, TRUE, "lrmd", NULL, HB_DAEMON_DIR"/lrmd" },
{ 0, crm_proc_cib, 2, 0, TRUE, "cib", CRM_DAEMON_USER, CRM_DAEMON_DIR"/cib" },
{ 0, crm_proc_crmd, 6, 0, TRUE, "crmd", CRM_DAEMON_USER, CRM_DAEMON_DIR"/crmd" },
{ 0, crm_proc_attrd, 4, 0, TRUE, "attrd", CRM_DAEMON_USER, CRM_DAEMON_DIR"/attrd" },
{ 0, crm_proc_stonithd, 0, 0, TRUE, "stonithd", NULL, NULL },
{ 0, crm_proc_pe, 5, 0, TRUE, "pengine", CRM_DAEMON_USER, CRM_DAEMON_DIR"/pengine" },
{ 0, crm_proc_mgmtd, 0, 0, TRUE, "mgmtd", NULL, HB_DAEMON_DIR"/mgmtd" },
{ 0, crm_proc_stonith_ng, 1, 0, TRUE, "stonith-ng", NULL, CRM_DAEMON_DIR"/stonithd" },
};
/* *INDENT-ON* */
-static gboolean start_child(pcmk_child_t *child);
+static gboolean start_child(pcmk_child_t * child);
-void enable_crmd_as_root(gboolean enable)
+void
+enable_crmd_as_root(gboolean enable)
{
- if(enable) {
- pcmk_children[pcmk_child_crmd].uid = NULL;
+ if (enable) {
+ pcmk_children[pcmk_child_crmd].uid = NULL;
} else {
- pcmk_children[pcmk_child_crmd].uid = CRM_DAEMON_USER;
+ pcmk_children[pcmk_child_crmd].uid = CRM_DAEMON_USER;
}
}
-void enable_mgmtd(gboolean enable)
+void
+enable_mgmtd(gboolean enable)
{
- if(enable) {
- pcmk_children[pcmk_child_mgmtd].start_seq = 7;
+ if (enable) {
+ pcmk_children[pcmk_child_mgmtd].start_seq = 7;
} else {
- pcmk_children[pcmk_child_mgmtd].start_seq = 0;
+ pcmk_children[pcmk_child_mgmtd].start_seq = 0;
}
}
-static uint32_t get_process_list(void)
+static uint32_t
+get_process_list(void)
{
int lpc = 0;
uint32_t procs = crm_proc_ais;
+
for (lpc = 0; lpc < SIZEOF(pcmk_children); lpc++) {
- if(pcmk_children[lpc].pid != 0) {
- procs |= pcmk_children[lpc].flag;
- }
+ if (pcmk_children[lpc].pid != 0) {
+ procs |= pcmk_children[lpc].flag;
+ }
}
return procs;
}
-static int pcmk_user_lookup(const char *name, uid_t *uid, gid_t *gid)
+static int
+pcmk_user_lookup(const char *name, uid_t * uid, gid_t * gid)
{
int rc = -1;
char *buffer = NULL;
struct passwd pwd;
struct passwd *pwentry = NULL;
crm_malloc0(buffer, PW_BUFFER_LEN);
getpwnam_r(name, &pwd, buffer, PW_BUFFER_LEN, &pwentry);
- if(pwentry) {
- rc = 0;
- if(uid) { *uid = pwentry->pw_uid; }
- if(gid) { *gid = pwentry->pw_gid; }
- crm_debug_2("Cluster user %s has uid=%d gid=%d",
- name, pwentry->pw_uid, pwentry->pw_gid);
+ if (pwentry) {
+ rc = 0;
+ if (uid) {
+ *uid = pwentry->pw_uid;
+ }
+ if (gid) {
+ *gid = pwentry->pw_gid;
+ }
+ crm_debug_2("Cluster user %s has uid=%d gid=%d", name, pwentry->pw_uid, pwentry->pw_gid);
} else {
- crm_err("Cluster user %s does not exist", name);
+ crm_err("Cluster user %s does not exist", name);
}
crm_free(buffer);
return rc;
}
static void
-pcmk_child_exit(
- ProcTrack* p, int status, int signo, int exitcode, int waslogged)
+pcmk_child_exit(ProcTrack * p, int status, int signo, int exitcode, int waslogged)
{
pcmk_child_t *child = p->privatedata;
+
p->privatedata = NULL;
- if(signo) {
- crm_notice("Child process %s terminated with signal %d (pid=%d, rc=%d)",
- child->name, signo, child->pid, exitcode);
+ if (signo) {
+ crm_notice("Child process %s terminated with signal %d (pid=%d, rc=%d)",
+ child->name, signo, child->pid, exitcode);
} else {
- do_crm_log(exitcode==0?LOG_NOTICE:LOG_ERR,
- "Child process %s exited (pid=%d, rc=%d)", child->name, child->pid, exitcode);
+ do_crm_log(exitcode == 0 ? LOG_NOTICE : LOG_ERR,
+ "Child process %s exited (pid=%d, rc=%d)", child->name, child->pid, exitcode);
}
-
+
child->pid = 0;
- if(exitcode == 100) {
- crm_notice("Child process %s no longer wishes"
- " to be respawned", child->name);
- child->respawn = FALSE;
+ if (exitcode == 100) {
+ crm_notice("Child process %s no longer wishes" " to be respawned", child->name);
+ child->respawn = FALSE;
}
/* Broadcast the fact that one of our processes died ASAP
*
* Try to get some logging of the cause out first though
* because we're probably about to get fenced
*
* Potentially do this only if respawn_count > N
* to allow for local recovery
*/
update_node_processes(local_nodeid, NULL, get_process_list());
-
+
child->respawn_count += 1;
- if(child->respawn_count > MAX_RESPAWN) {
- crm_err("Child respawn count exceeded by %s", child->name);
- child->respawn = FALSE;
+ if (child->respawn_count > MAX_RESPAWN) {
+ crm_err("Child respawn count exceeded by %s", child->name);
+ child->respawn = FALSE;
}
- if(shutdown_trigger) {
- mainloop_set_trigger(shutdown_trigger);
- update_node_processes(local_nodeid, NULL, get_process_list());
+ if (shutdown_trigger) {
+ mainloop_set_trigger(shutdown_trigger);
+ update_node_processes(local_nodeid, NULL, get_process_list());
- } else if(child->respawn) {
- crm_notice("Respawning failed child process: %s", child->name);
- start_child(child);
- }
+ } else if (child->respawn) {
+ crm_notice("Respawning failed child process: %s", child->name);
+ start_child(child);
+ }
}
static void
-pcmkManagedChildRegistered(ProcTrack* p)
+pcmkManagedChildRegistered(ProcTrack * p)
{
pcmk_child_t *child = p->privatedata;
+
child->pid = p->pid;
}
static const char *
-pcmkManagedChildName(ProcTrack* p)
+pcmkManagedChildName(ProcTrack * p)
{
pcmk_child_t *child = p->privatedata;
+
return child->name;
}
static ProcTrack_ops pcmk_managed_child_ops = {
pcmk_child_exit,
pcmkManagedChildRegistered,
pcmkManagedChildName
};
static gboolean
-stop_child(pcmk_child_t *child, int signal)
+stop_child(pcmk_child_t * child, int signal)
{
- if(signal == 0) {
- signal = SIGTERM;
+ if (signal == 0) {
+ signal = SIGTERM;
}
-
- if(child->command == NULL) {
- crm_debug("Nothing to do for child \"%s\"", child->name);
- return TRUE;
+
+ if (child->command == NULL) {
+ crm_debug("Nothing to do for child \"%s\"", child->name);
+ return TRUE;
}
-
+
if (child->pid <= 0) {
- crm_debug_2("Client %s not running", child->name);
- return TRUE;
+ crm_debug_2("Client %s not running", child->name);
+ return TRUE;
}
-
+
errno = 0;
- if(kill(child->pid, signal) == 0) {
- crm_notice("Stopping %s: Sent -%d to process %d", child->name, signal, child->pid);
-
+ if (kill(child->pid, signal) == 0) {
+ crm_notice("Stopping %s: Sent -%d to process %d", child->name, signal, child->pid);
+
} else {
- crm_perror(LOG_ERR, "Stopping %s: Could not send -%d to process %d failed",
- child->name, signal, child->pid);
+ crm_perror(LOG_ERR, "Stopping %s: Could not send -%d to process %d failed",
+ child->name, signal, child->pid);
}
-
+
return TRUE;
}
static char *opts_default[] = { NULL, NULL };
-static char *opts_vgrind[] = { NULL, NULL, NULL, NULL, NULL };
+static char *opts_vgrind[] = { NULL, NULL, NULL, NULL, NULL };
static gboolean
-start_child(pcmk_child_t *child)
+start_child(pcmk_child_t * child)
{
int lpc = 0;
uid_t uid = 0;
struct rlimit oflimits;
gboolean use_valgrind = FALSE;
gboolean use_callgrind = FALSE;
const char *devnull = "/dev/null";
const char *env_valgrind = getenv("PCMK_valgrind_enabled");
const char *env_callgrind = getenv("PCMK_callgrind_enabled");
-
- if(child->command == NULL) {
- crm_info("Nothing to do for child \"%s\"", child->name);
- return TRUE;
+
+ if (child->command == NULL) {
+ crm_info("Nothing to do for child \"%s\"", child->name);
+ return TRUE;
}
-
- if(env_callgrind != NULL && crm_is_true(env_callgrind)) {
- use_callgrind = TRUE;
- use_valgrind = TRUE;
- } else if(env_callgrind != NULL && strstr(env_callgrind, child->name)) {
- use_callgrind = TRUE;
- use_valgrind = TRUE;
+ if (env_callgrind != NULL && crm_is_true(env_callgrind)) {
+ use_callgrind = TRUE;
+ use_valgrind = TRUE;
- } else if(env_valgrind != NULL && crm_is_true(env_valgrind)) {
- use_valgrind = TRUE;
+ } else if (env_callgrind != NULL && strstr(env_callgrind, child->name)) {
+ use_callgrind = TRUE;
+ use_valgrind = TRUE;
- } else if(env_valgrind != NULL && strstr(env_valgrind, child->name)) {
- use_valgrind = TRUE;
+ } else if (env_valgrind != NULL && crm_is_true(env_valgrind)) {
+ use_valgrind = TRUE;
+
+ } else if (env_valgrind != NULL && strstr(env_valgrind, child->name)) {
+ use_valgrind = TRUE;
}
-
- if(use_valgrind && strlen(VALGRIND_BIN) == 0) {
- crm_warn("Cannot enable valgrind for %s:"
- " The location of the valgrind binary is unknown", child->name);
- use_valgrind = FALSE;
+
+ if (use_valgrind && strlen(VALGRIND_BIN) == 0) {
+ crm_warn("Cannot enable valgrind for %s:"
+ " The location of the valgrind binary is unknown", child->name);
+ use_valgrind = FALSE;
}
child->pid = fork();
CRM_ASSERT(child->pid != -1);
- if(child->pid > 0) {
- /* parent */
- NewTrackedProc(child->pid, 0, PT_LOGNORMAL, child, &pcmk_managed_child_ops);
- crm_info("Forked child %d for process %s%s", child->pid, child->name,
- use_valgrind?" (valgrind enabled: "VALGRIND_BIN")":"");
- update_node_processes(local_nodeid, NULL, get_process_list());
- return TRUE;
+ if (child->pid > 0) {
+ /* parent */
+ NewTrackedProc(child->pid, 0, PT_LOGNORMAL, child, &pcmk_managed_child_ops);
+ crm_info("Forked child %d for process %s%s", child->pid, child->name,
+ use_valgrind ? " (valgrind enabled: " VALGRIND_BIN ")" : "");
+ update_node_processes(local_nodeid, NULL, get_process_list());
+ return TRUE;
} else {
- /* Start a new session */
- (void)setsid();
-
- /* Setup the two alternate arg arrarys */
- opts_vgrind[0] = crm_strdup(VALGRIND_BIN);
- if(use_callgrind) {
- opts_vgrind[1] = crm_strdup("--tool=callgrind");
- opts_vgrind[2] = crm_strdup("--callgrind-out-file="CRM_STATE_DIR"/callgrind.out.%p");
- opts_vgrind[3] = crm_strdup(child->command);
- opts_vgrind[4] = NULL;
- } else {
- opts_vgrind[1] = crm_strdup(child->command);
- opts_vgrind[2] = NULL;
- opts_vgrind[3] = NULL;
- opts_vgrind[4] = NULL;
- }
- opts_default[0] = crm_strdup(child->command);;
-
+ /* Start a new session */
+ (void)setsid();
+
+ /* Setup the two alternate arg arrarys */
+ opts_vgrind[0] = crm_strdup(VALGRIND_BIN);
+ if (use_callgrind) {
+ opts_vgrind[1] = crm_strdup("--tool=callgrind");
+ opts_vgrind[2] = crm_strdup("--callgrind-out-file=" CRM_STATE_DIR "/callgrind.out.%p");
+ opts_vgrind[3] = crm_strdup(child->command);
+ opts_vgrind[4] = NULL;
+ } else {
+ opts_vgrind[1] = crm_strdup(child->command);
+ opts_vgrind[2] = NULL;
+ opts_vgrind[3] = NULL;
+ opts_vgrind[4] = NULL;
+ }
+ opts_default[0] = crm_strdup(child->command);;
+
#if 0
- /* Dont set the group for now - it prevents connection to the cluster */
- if(gid && setgid(gid) < 0) {
- crm_perror("Could not set group to %d", gid);
- }
+ /* Dont set the group for now - it prevents connection to the cluster */
+ if (gid && setgid(gid) < 0) {
+ crm_perror("Could not set group to %d", gid);
+ }
#endif
- if(child->uid) {
- if(pcmk_user_lookup(child->uid, &uid, NULL) < 0) {
- crm_err("Invalid uid (%s) specified for %s",
- child->uid, child->name);
- return TRUE;
- }
- }
-
- if(uid && setuid(uid) < 0) {
- crm_perror(LOG_ERR, "Could not set user to %d (%s)", uid, child->uid);
- }
-
- /* Close all open file descriptors */
- getrlimit(RLIMIT_NOFILE, &oflimits);
- for (lpc = 0; lpc < oflimits.rlim_cur; lpc++) {
- close(lpc);
- }
-
- (void)open(devnull, O_RDONLY); /* Stdin: fd 0 */
- (void)open(devnull, O_WRONLY); /* Stdout: fd 1 */
- (void)open(devnull, O_WRONLY); /* Stderr: fd 2 */
-
- if(use_valgrind) {
- (void)execvp(VALGRIND_BIN, opts_vgrind);
- } else {
- (void)execvp(child->command, opts_default);
- }
- crm_perror(LOG_ERR, "FATAL: Cannot exec %s", child->command);
- exit(100);
- }
- return TRUE; /* never reached */
+ if (child->uid) {
+ if (pcmk_user_lookup(child->uid, &uid, NULL) < 0) {
+ crm_err("Invalid uid (%s) specified for %s", child->uid, child->name);
+ return TRUE;
+ }
+ }
+
+ if (uid && setuid(uid) < 0) {
+ crm_perror(LOG_ERR, "Could not set user to %d (%s)", uid, child->uid);
+ }
+
+ /* Close all open file descriptors */
+ getrlimit(RLIMIT_NOFILE, &oflimits);
+ for (lpc = 0; lpc < oflimits.rlim_cur; lpc++) {
+ close(lpc);
+ }
+
+ (void)open(devnull, O_RDONLY); /* Stdin: fd 0 */
+ (void)open(devnull, O_WRONLY); /* Stdout: fd 1 */
+ (void)open(devnull, O_WRONLY); /* Stderr: fd 2 */
+
+ if (use_valgrind) {
+ (void)execvp(VALGRIND_BIN, opts_vgrind);
+ } else {
+ (void)execvp(child->command, opts_default);
+ }
+ crm_perror(LOG_ERR, "FATAL: Cannot exec %s", child->command);
+ exit(100);
+ }
+ return TRUE; /* never reached */
}
static gboolean
escalate_shutdown(gpointer data)
{
-
+
pcmk_child_t *child = data;
- if(child->pid) {
- /* Use SIGSEGV instead of SIGKILL to create a core so we can see what it was up to */
- crm_err("Child %s not terminating in a timely manner, forcing", child->name);
- stop_child(child, SIGSEGV);
+
+ if (child->pid) {
+ /* Use SIGSEGV instead of SIGKILL to create a core so we can see what it was up to */
+ crm_err("Child %s not terminating in a timely manner, forcing", child->name);
+ stop_child(child, SIGSEGV);
}
return FALSE;
}
static gboolean
-pcmk_shutdown_worker(gpointer user_data)
+pcmk_shutdown_worker(gpointer user_data)
{
static int phase = 0;
static time_t next_log = 0;
static int max = SIZEOF(pcmk_children);
int lpc = 0;
-
- if(phase == 0) {
- crm_notice("Shuting down Pacemaker");
- phase = max;
+
+ if (phase == 0) {
+ crm_notice("Shuting down Pacemaker");
+ phase = max;
}
-
+
for (; phase > 0; phase--) {
- /* dont stop anything with start_seq < 1 */
-
- for (lpc = max - 1; lpc >= 0; lpc--) {
- pcmk_child_t *child = &(pcmk_children[lpc]);
- if(phase != child->start_seq) {
- continue;
- }
-
- if(child->pid) {
- time_t now = time(NULL);
-
- if(child->respawn) {
- next_log = now + 30;
- child->respawn = FALSE;
- stop_child(child, SIGTERM);
- if(phase < pcmk_children[pcmk_child_crmd].start_seq) {
- g_timeout_add(180000/* 3m */, escalate_shutdown, child);
- }
-
- } else if(now >= next_log) {
- next_log = now + 30;
- crm_notice("Still waiting for %s (pid=%d, seq=%d) to terminate...",
- child->name, child->pid, child->start_seq);
- }
- return TRUE;
- }
-
- /* cleanup */
- crm_notice("%s confirmed stopped", child->name);
- child->pid = 0;
- }
- }
-
+ /* dont stop anything with start_seq < 1 */
+
+ for (lpc = max - 1; lpc >= 0; lpc--) {
+ pcmk_child_t *child = &(pcmk_children[lpc]);
+
+ if (phase != child->start_seq) {
+ continue;
+ }
+
+ if (child->pid) {
+ time_t now = time(NULL);
+
+ if (child->respawn) {
+ next_log = now + 30;
+ child->respawn = FALSE;
+ stop_child(child, SIGTERM);
+ if (phase < pcmk_children[pcmk_child_crmd].start_seq) {
+ g_timeout_add(180000 /* 3m */ , escalate_shutdown, child);
+ }
+
+ } else if (now >= next_log) {
+ next_log = now + 30;
+ crm_notice("Still waiting for %s (pid=%d, seq=%d) to terminate...",
+ child->name, child->pid, child->start_seq);
+ }
+ return TRUE;
+ }
+
+ /* cleanup */
+ crm_notice("%s confirmed stopped", child->name);
+ child->pid = 0;
+ }
+ }
+
/* send_cluster_id(); */
crm_notice("Shutdown complete");
g_main_loop_quit(mainloop);
- return TRUE;
+ return TRUE;
}
void
pcmk_shutdown(int nsig)
{
- if(shutdown_trigger == NULL) {
- shutdown_trigger = mainloop_add_trigger(G_PRIORITY_HIGH, pcmk_shutdown_worker, NULL);
+ if (shutdown_trigger == NULL) {
+ shutdown_trigger = mainloop_add_trigger(G_PRIORITY_HIGH, pcmk_shutdown_worker, NULL);
}
mainloop_set_trigger(shutdown_trigger);
}
-
-static void build_path(const char *path_c, mode_t mode)
+static void
+build_path(const char *path_c, mode_t mode)
{
int offset = 1, len = 0;
char *path = crm_strdup(path_c);
CRM_CHECK(path != NULL, return);
- for(len = strlen(path); offset < len; offset++) {
- if(path[offset] == '/') {
- path[offset] = 0;
- if(mkdir(path, mode) < 0 && errno != EEXIST) {
- crm_perror(LOG_ERR, "Could not create directory '%s'", path);
- break;
- }
- path[offset] = '/';
- }
- }
- if(mkdir(path, mode) < 0 && errno != EEXIST) {
- crm_perror(LOG_ERR, "Could not create directory '%s'", path);
+ for (len = strlen(path); offset < len; offset++) {
+ if (path[offset] == '/') {
+ path[offset] = 0;
+ if (mkdir(path, mode) < 0 && errno != EEXIST) {
+ crm_perror(LOG_ERR, "Could not create directory '%s'", path);
+ break;
+ }
+ path[offset] = '/';
+ }
+ }
+ if (mkdir(path, mode) < 0 && errno != EEXIST) {
+ crm_perror(LOG_ERR, "Could not create directory '%s'", path);
}
crm_free(path);
}
static void
pcmk_server_destroy(gpointer user_data)
{
crm_info("Server destroyed");
return;
}
static void
pcmk_client_destroy(gpointer user_data)
{
crm_debug("Client %p disconnected", user_data);
g_hash_table_remove(client_list, user_data);
return;
}
static gboolean
-pcmk_client_msg(IPC_Channel *client, gpointer user_data)
+pcmk_client_msg(IPC_Channel * client, gpointer user_data)
{
xmlNode *msg = NULL;
gboolean stay_connected = TRUE;
-
- while(IPC_ISRCONN(client)) {
- if(client->ops->is_message_pending(client) == 0) {
- break;
- }
- msg = xmlfromIPC(client, MAX_IPC_DELAY);
- free_xml(msg);
+ while (IPC_ISRCONN(client)) {
+ if (client->ops->is_message_pending(client) == 0) {
+ break;
+ }
+
+ msg = xmlfromIPC(client, MAX_IPC_DELAY);
+ free_xml(msg);
- if(client->ch_status != IPC_CONNECT) {
- break;
- }
+ if (client->ch_status != IPC_CONNECT) {
+ break;
+ }
}
-
+
if (client->ch_status != IPC_CONNECT) {
- stay_connected = FALSE;
+ stay_connected = FALSE;
}
return stay_connected;
}
static gboolean
-pcmk_client_connect(IPC_Channel *ch, gpointer user_data)
+pcmk_client_connect(IPC_Channel * ch, gpointer user_data)
{
if (ch == NULL) {
- crm_err("Channel was invalid");
+ crm_err("Channel was invalid");
} else if (ch->ch_status == IPC_DISCONNECT) {
- crm_err("Channel was disconnected");
+ crm_err("Channel was disconnected");
} else {
- ch->ops->set_recv_qlen(ch, 1024);
- ch->ops->set_send_qlen(ch, 1024);
+ ch->ops->set_recv_qlen(ch, 1024);
+ ch->ops->set_send_qlen(ch, 1024);
- g_hash_table_insert(client_list, ch, user_data);
- crm_debug("Channel %p connected: %d children", ch, g_hash_table_size(client_list));
- update_process_clients();
-
- G_main_add_IPC_Channel(
- G_PRIORITY_LOW, ch, FALSE, pcmk_client_msg, ch, pcmk_client_destroy);
+ g_hash_table_insert(client_list, ch, user_data);
+ crm_debug("Channel %p connected: %d children", ch, g_hash_table_size(client_list));
+ update_process_clients();
+
+ G_main_add_IPC_Channel(G_PRIORITY_LOW, ch, FALSE, pcmk_client_msg, ch, pcmk_client_destroy);
}
return TRUE;
}
static gboolean
ghash_send_proc_details(gpointer key, gpointer value, gpointer data)
{
- if(send_ipc_message(key, data) == FALSE) {
- /* remove it */
- return TRUE;
+ if (send_ipc_message(key, data) == FALSE) {
+ /* remove it */
+ return TRUE;
}
return FALSE;
}
-static void peer_loop_fn(gpointer key, gpointer value, gpointer user_data)
+static void
+peer_loop_fn(gpointer key, gpointer value, gpointer user_data)
{
pcmk_peer_t *node = value;
- xmlNode *update = user_data;
+ xmlNode *update = user_data;
xmlNode *xml = create_xml_node(update, "node");
crm_xml_add_int(xml, "id", node->id);
crm_xml_add(xml, "uname", node->uname);
crm_xml_add_int(xml, "processes", node->processes);
}
-void update_process_clients(void)
+void
+update_process_clients(void)
{
xmlNode *update = create_xml_node(NULL, "nodes");
-
+
crm_debug_2("Sending process list to %d children", g_hash_table_size(client_list));
g_hash_table_foreach(peers, peer_loop_fn, update);
g_hash_table_foreach_remove(client_list, ghash_send_proc_details, update);
-
+
free_xml(update);
}
-void update_process_peers(void)
+void
+update_process_peers(void)
{
char buffer[1024];
struct iovec iov;
int rc = 0;
memset(buffer, 0, SIZEOF(buffer));
- if(local_name) {
- rc = snprintf(buffer, SIZEOF(buffer) - 1, "<node uname=\"%s\" proclist=\"%u\"/>", local_name, get_process_list());
+ if (local_name) {
+ rc = snprintf(buffer, SIZEOF(buffer) - 1, "<node uname=\"%s\" proclist=\"%u\"/>",
+ local_name, get_process_list());
} else {
- rc = snprintf(buffer, SIZEOF(buffer) - 1, "<node proclist=\"%u\"/>", get_process_list());
+ rc = snprintf(buffer, SIZEOF(buffer) - 1, "<node proclist=\"%u\"/>", get_process_list());
}
-
+
iov.iov_base = buffer;
iov.iov_len = rc + 1;
-
+
send_cpg_message(&iov);
}
-gboolean update_node_processes(uint32_t id, const char *uname, uint32_t procs)
+gboolean
+update_node_processes(uint32_t id, const char *uname, uint32_t procs)
{
gboolean changed = FALSE;
- pcmk_peer_t *node = g_hash_table_lookup(peers, GUINT_TO_POINTER(id));
- if(node == NULL) {
- changed = TRUE;
-
- crm_malloc0(node, sizeof(pcmk_peer_t));
- node->id = id;
-
- g_hash_table_insert(peers, GUINT_TO_POINTER(id), node);
- node = g_hash_table_lookup(peers, GUINT_TO_POINTER(id));
- CRM_ASSERT(node != NULL);
- }
-
- if(uname != NULL) {
- if(node->uname == NULL || safe_str_eq(node->uname, uname) == FALSE) {
- crm_info("%p Node %u now known as %s (was: %s)",
- node, id, uname, node->uname);
- crm_free(node->uname);
- node->uname = crm_strdup(uname);
- changed = TRUE;
- }
- }
-
- if(procs != 0 && procs != node->processes) {
- crm_info("Node %s now has process list: %.32x (was %.32x)",
- node->uname, procs, node->processes);
- node->processes = procs;
- changed = TRUE;
- }
-
- if(changed && id == local_nodeid) {
- update_process_clients();
- update_process_peers();
+ pcmk_peer_t *node = g_hash_table_lookup(peers, GUINT_TO_POINTER(id));
+
+ if (node == NULL) {
+ changed = TRUE;
+
+ crm_malloc0(node, sizeof(pcmk_peer_t));
+ node->id = id;
+
+ g_hash_table_insert(peers, GUINT_TO_POINTER(id), node);
+ node = g_hash_table_lookup(peers, GUINT_TO_POINTER(id));
+ CRM_ASSERT(node != NULL);
+ }
+
+ if (uname != NULL) {
+ if (node->uname == NULL || safe_str_eq(node->uname, uname) == FALSE) {
+ crm_info("%p Node %u now known as %s (was: %s)", node, id, uname, node->uname);
+ crm_free(node->uname);
+ node->uname = crm_strdup(uname);
+ changed = TRUE;
+ }
+ }
+
+ if (procs != 0 && procs != node->processes) {
+ crm_info("Node %s now has process list: %.32x (was %.32x)",
+ node->uname, procs, node->processes);
+ node->processes = procs;
+ changed = TRUE;
+ }
+
+ if (changed && id == local_nodeid) {
+ update_process_clients();
+ update_process_peers();
}
return changed;
}
+/* *INDENT-OFF* */
static struct crm_option long_options[] = {
/* Top-level Options */
{"help", 0, 0, '?', "\tThis text"},
{"version", 0, 0, '$', "\tVersion information" },
{"verbose", 0, 0, 'V', "\tIncrease debug output"},
{"features", 0, 0, 'F', "\tDisplay the full version and list of features Pacemaker was built with"},
{"-spacer-", 1, 0, '-', "\nAdditional Options:"},
{"foreground", 0, 0, 'f', "\tRun in the foreground instead of as a daemon"},
{"pid-file", 1, 0, 'p', "\t(Advanced) Daemon pid file location"},
{NULL, 0, 0, 0}
};
+/* *INDENT-ON* */
int
main(int argc, char **argv)
{
int rc;
int flag;
int argerr = 0;
- int option_index = 0;
+ int option_index = 0;
gboolean daemonize = TRUE;
int start_seq = 1, lpc = 0;
static int max = SIZEOF(pcmk_children);
-
+
uid_t pcmk_uid = 0;
gid_t pcmk_gid = 0;
struct rlimit cores;
+/* *INDENT-OFF* */
/* =::=::= Default Environment =::=::= */
setenv("HA_mcp", "true", 1);
setenv("HA_COMPRESSION", "bz2", 1);
setenv("HA_debug", "0", 1);
setenv("HA_logfacility", "daemon", 1);
setenv("HA_LOGFACILITY", "daemon", 1);
setenv("HA_use_logd", "off", 1);
-
+/* *INDENT-ON* */
+
crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv);
- crm_set_options(NULL, "mode [options]", long_options,
- "Start/Stop Pacemaker\n");
+ crm_set_options(NULL, "mode [options]", long_options, "Start/Stop Pacemaker\n");
#ifndef ON_DARWIN
/* prevent zombies */
signal(SIGCLD, SIG_IGN);
#endif
-
+
while (1) {
- flag = crm_get_option(argc, argv, &option_index);
- if (flag == -1)
- break;
-
- switch(flag) {
- case 'V':
- cl_log_enable_stderr(TRUE);
- alter_debug(DEBUG_INC);
- break;
- case 'f':
- daemonize = FALSE;
- break;
- case 'p':
- pid_file = optarg;
- break;
- case '$':
- case '?':
- crm_help(flag, LSB_EXIT_OK);
- break;
- case 'F':
- printf("Pacemaker %s (Build: %s)\n Supporting: %s\n", VERSION, BUILD_VERSION, CRM_FEATURES);
- exit (0);
- default:
- printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
- ++argerr;
- break;
- }
+ flag = crm_get_option(argc, argv, &option_index);
+ if (flag == -1)
+ break;
+
+ switch (flag) {
+ case 'V':
+ cl_log_enable_stderr(TRUE);
+ alter_debug(DEBUG_INC);
+ break;
+ case 'f':
+ daemonize = FALSE;
+ break;
+ case 'p':
+ pid_file = optarg;
+ break;
+ case '$':
+ case '?':
+ crm_help(flag, LSB_EXIT_OK);
+ break;
+ case 'F':
+ printf("Pacemaker %s (Build: %s)\n Supporting: %s\n", VERSION, BUILD_VERSION,
+ CRM_FEATURES);
+ exit(0);
+ default:
+ printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
+ ++argerr;
+ break;
+ }
}
if (optind < argc) {
- printf("non-option ARGV-elements: ");
- while (optind < argc)
- printf("%s ", argv[optind++]);
- printf("\n");
+ printf("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf("%s ", argv[optind++]);
+ printf("\n");
}
if (argerr) {
- crm_help('?', LSB_EXIT_GENERIC);
+ crm_help('?', LSB_EXIT_GENERIC);
}
-
- if(read_config() == FALSE) {
- return 1;
+
+ if (read_config() == FALSE) {
+ return 1;
}
- if(daemonize) {
- cl_log_enable_stderr(FALSE);
- crm_make_daemon(crm_system_name, TRUE, pid_file);
+ if (daemonize) {
+ cl_log_enable_stderr(FALSE);
+ crm_make_daemon(crm_system_name, TRUE, pid_file);
- /* Only Re-init if we're running daemonized */
- crm_log_init(NULL, LOG_INFO, TRUE, FALSE, 0, NULL);
+ /* Only Re-init if we're running daemonized */
+ crm_log_init(NULL, LOG_INFO, TRUE, FALSE, 0, NULL);
}
- crm_info("Starting Pacemaker %s (Build: %s): %s\n", VERSION, BUILD_VERSION, CRM_FEATURES);
+ crm_info("Starting Pacemaker %s (Build: %s): %s\n", VERSION, BUILD_VERSION, CRM_FEATURES);
mainloop = g_main_new(FALSE);
rc = getrlimit(RLIMIT_CORE, &cores);
- if(rc < 0) {
- crm_perror(LOG_ERR, "Cannot determine current maximum core size.");
+ if (rc < 0) {
+ crm_perror(LOG_ERR, "Cannot determine current maximum core size.");
} else {
- if (cores.rlim_max == 0 && geteuid() == 0) {
- cores.rlim_max = RLIM_INFINITY;
- } else {
- crm_info("Maximum core file size is: %lu", (unsigned long)cores.rlim_max);
- }
- cores.rlim_cur = cores.rlim_max;
-
- rc = setrlimit(RLIMIT_CORE, &cores);
- if(rc < 0) {
- crm_perror(LOG_ERR,
- "Core file generation will remain disabled."
- " Core files are an important diagnositic tool,"
- " please consider enabling them by default.");
- }
+ if (cores.rlim_max == 0 && geteuid() == 0) {
+ cores.rlim_max = RLIM_INFINITY;
+ } else {
+ crm_info("Maximum core file size is: %lu", (unsigned long)cores.rlim_max);
+ }
+ cores.rlim_cur = cores.rlim_max;
+
+ rc = setrlimit(RLIMIT_CORE, &cores);
+ if (rc < 0) {
+ crm_perror(LOG_ERR,
+ "Core file generation will remain disabled."
+ " Core files are an important diagnositic tool,"
+ " please consider enabling them by default.");
+ }
#if 0
- /* system() is not thread-safe, can't call from here
- * Actually, its a pretty hacky way to try and achieve this anyway
- */
- if(system("echo 1 > /proc/sys/kernel/core_uses_pid") != 0) {
- crm_perror(LOG_ERR, "Could not enable /proc/sys/kernel/core_uses_pid");
- }
+ /* system() is not thread-safe, can't call from here
+ * Actually, its a pretty hacky way to try and achieve this anyway
+ */
+ if (system("echo 1 > /proc/sys/kernel/core_uses_pid") != 0) {
+ crm_perror(LOG_ERR, "Could not enable /proc/sys/kernel/core_uses_pid");
+ }
#endif
}
- if(pcmk_user_lookup(CRM_DAEMON_USER, &pcmk_uid, &pcmk_gid) < 0) {
- crm_err("Cluster user %s does not exist, aborting Pacemaker startup", CRM_DAEMON_USER);
- return TRUE;
+ if (pcmk_user_lookup(CRM_DAEMON_USER, &pcmk_uid, &pcmk_gid) < 0) {
+ crm_err("Cluster user %s does not exist, aborting Pacemaker startup", CRM_DAEMON_USER);
+ return TRUE;
}
-
+
mkdir(CRM_STATE_DIR, 0750);
chown(CRM_STATE_DIR, pcmk_uid, pcmk_gid);
-
+
/* Used by stonithd */
- build_path(HA_STATE_DIR"/heartbeat", 0755);
+ build_path(HA_STATE_DIR "/heartbeat", 0755);
/* Used by RAs - Leave owned by root */
- build_path(CRM_RSCTMP_DIR, 0755);
+ build_path(CRM_RSCTMP_DIR, 0755);
client_list = g_hash_table_new(g_direct_hash, g_direct_equal);
peers = g_hash_table_new(g_direct_hash, g_direct_equal);
- if(init_server_ipc_comms(ipc_name, pcmk_client_connect, pcmk_server_destroy)) {
- crm_err("Couldn't start IPC server");
- return 1;
+ if (init_server_ipc_comms(ipc_name, pcmk_client_connect, pcmk_server_destroy)) {
+ crm_err("Couldn't start IPC server");
+ return 1;
}
- if(cluster_connect_cfg(&local_nodeid) == FALSE) {
- return 1;
+ if (cluster_connect_cfg(&local_nodeid) == FALSE) {
+ return 1;
}
- if(cluster_connect_cpg() == FALSE) {
- return 1;
+ if (cluster_connect_cpg() == FALSE) {
+ return 1;
}
local_name = get_local_node_name();
- update_node_processes(local_nodeid, local_name, get_process_list());
-
+ update_node_processes(local_nodeid, local_name, get_process_list());
+
mainloop_add_signal(SIGTERM, pcmk_shutdown);
mainloop_add_signal(SIGINT, pcmk_shutdown);
set_sigchld_proctrack(G_PRIORITY_HIGH, DEFAULT_MAXDISPATCHTIME);
-
+
for (start_seq = 1; start_seq < max; start_seq++) {
- /* dont start anything with start_seq < 1 */
- for (lpc = 0; lpc < max; lpc++) {
- if(start_seq == pcmk_children[lpc].start_seq) {
- start_child(&(pcmk_children[lpc]));
- }
- }
+ /* dont start anything with start_seq < 1 */
+ for (lpc = 0; lpc < max; lpc++) {
+ if (start_seq == pcmk_children[lpc].start_seq) {
+ start_child(&(pcmk_children[lpc]));
+ }
+ }
}
- crm_info("Starting mainloop");
+ crm_info("Starting mainloop");
g_main_run(mainloop);
g_main_destroy(mainloop);
cluster_disconnect_cpg();
cluster_disconnect_cfg();
-
- crm_info("Exiting %s", crm_system_name);
+
+ crm_info("Exiting %s", crm_system_name);
return 0;
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Apr 21, 5:56 PM (1 d, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1665012
Default Alt Text
(62 KB)

Event Timeline