Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3686779
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
62 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment