Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/crm/cib/main.c b/crm/cib/main.c
index 982c0dc4dd..c5eab4f473 100644
--- a/crm/cib/main.c
+++ b/crm/cib/main.c
@@ -1,479 +1,477 @@
-/* $Id: main.c,v 1.41 2006/04/03 10:01:35 andrew Exp $ */
+/* $Id: main.c,v 1.42 2006/04/10 16:18:08 andrew Exp $ */
/*
* Copyright (C) 2004 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <portability.h>
#include <sys/param.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <hb_api.h>
#include <heartbeat.h>
#include <clplumbing/cl_misc.h>
#include <clplumbing/uids.h>
#include <clplumbing/coredumps.h>
#include <clplumbing/Gmain_timeout.h>
/* #include <portability.h> */
#include <ocf/oc_event.h>
/* #include <ocf/oc_membership.h> */
#include <crm/crm.h>
#include <crm/cib.h>
#include <crm/msg_xml.h>
#include <crm/common/ipc.h>
#include <crm/common/ctrl.h>
#include <crm/common/xml.h>
#include <crm/common/msg.h>
#include <cibio.h>
#include <callbacks.h>
#include <crm/dmalloc_wrapper.h>
gboolean cib_shutdown_flag = FALSE;
extern void oc_ev_special(const oc_ev_t *, oc_ev_class_t , int );
GMainLoop* mainloop = NULL;
const char* crm_system_name = CRM_SYSTEM_CIB;
char *cib_our_uname = NULL;
oc_ev_t *cib_ev_token;
gboolean cib_writes_enabled = TRUE;
void usage(const char* cmd, int exit_status);
int init_start(void);
gboolean cib_register_ha(ll_cluster_t *hb_cluster, const char *client_name);
gboolean cib_shutdown(int nsig, gpointer unused);
void cib_ha_connection_destroy(gpointer user_data);
gboolean startCib(const char *filename);
extern gboolean cib_msg_timeout(gpointer data);
extern int write_cib_contents(gpointer p);
ll_cluster_t *hb_conn = NULL;
GTRIGSource *cib_writer = NULL;
#define OPTARGS "hV"
static void
cib_diskwrite_complete(gpointer userdata, int status, int signo, int exitcode)
{
if(exitcode != LSB_EXIT_OK || signo != 0 || status != 0) {
crm_err("Disk write failed: status=%d, signo=%d, exitcode=%d",
status, signo, exitcode);
if(cib_writes_enabled) {
crm_err("Disabling disk writes after write failure");
cib_writes_enabled = FALSE;
}
} else {
crm_debug_2("Disk write passed");
}
}
int
main(int argc, char ** argv)
{
int flag;
int argerr = 0;
crm_log_init(crm_system_name);
G_main_add_SignalHandler(
G_PRIORITY_HIGH, SIGTERM, cib_shutdown, NULL, NULL);
cib_writer = G_main_add_tempproc_trigger(
G_PRIORITY_LOW, write_cib_contents, "write_cib_contents",
NULL, NULL, NULL, cib_diskwrite_complete);
EnableProcLogging();
set_sigchld_proctrack(G_PRIORITY_HIGH);
client_list = g_hash_table_new(g_str_hash, g_str_equal);
peer_hash = g_hash_table_new(g_str_hash, g_str_equal);
while ((flag = getopt(argc, argv, OPTARGS)) != EOF) {
switch(flag) {
case 'V':
cl_log_enable_stderr(1);
alter_debug(DEBUG_INC);
break;
case 'h': /* Help message */
usage(crm_system_name, LSB_EXIT_OK);
break;
default:
++argerr;
break;
}
}
if (optind > argc) {
++argerr;
}
if (argerr) {
usage(crm_system_name,LSB_EXIT_GENERIC);
}
/* read local config file */
return init_start();
}
unsigned long cib_num_ops = 0;
const char *cib_stat_interval = "10min";
unsigned long cib_num_local = 0, cib_num_updates = 0, cib_num_fail = 0;
unsigned long cib_bad_connects = 0, cib_num_timeouts = 0;
longclock_t cib_call_time = 0;
gboolean cib_stats(gpointer data);
gboolean
cib_stats(gpointer data)
{
int local_log_level = LOG_DEBUG;
static unsigned long last_stat = 0;
unsigned int cib_calls_ms = 0;
static unsigned long cib_stat_interval_ms = 0;
if(cib_stat_interval_ms == 0) {
cib_stat_interval_ms = crm_get_msec(cib_stat_interval);
}
cib_calls_ms = longclockto_ms(cib_call_time);
if((cib_num_ops - last_stat) > 0) {
unsigned long calls_diff = cib_num_ops - last_stat;
double stat_1 = (1000*cib_calls_ms)/calls_diff;
local_log_level = LOG_INFO;
crm_log_maybe(local_log_level,
"Processed %lu operations"
" (%.2fus average, %lu%% utilization) in the last %s",
calls_diff, stat_1,
(100*cib_calls_ms)/cib_stat_interval_ms,
cib_stat_interval);
}
crm_log_maybe(local_log_level+1,
"\tDetail: %lu operations (%ums total)"
" (%lu local, %lu updates, %lu failures,"
" %lu timeouts, %lu bad connects)",
cib_num_ops, cib_calls_ms, cib_num_local, cib_num_updates,
cib_num_fail, cib_bad_connects, cib_num_timeouts);
last_stat = cib_num_ops;
cib_call_time = 0;
return TRUE;
}
int
init_start(void)
{
gboolean was_error = FALSE;
hb_conn = ll_cluster_new("heartbeat");
if(cib_register_ha(hb_conn, CRM_SYSTEM_CIB) == FALSE) {
crm_crit("Cannot sign in to heartbeat... terminating");
fprintf(stderr, "Cannot sign in to heartbeat... terminating");
exit(1);
}
if(startCib(CIB_FILENAME) == FALSE){
crm_crit("Cannot start CIB... terminating");
exit(1);
}
was_error = init_server_ipc_comms(
crm_strdup(cib_channel_callback), cib_client_connect_null,
default_ipc_connection_destroy);
was_error = was_error || init_server_ipc_comms(
crm_strdup(cib_channel_ro), cib_client_connect_rw_ro,
default_ipc_connection_destroy);
was_error = was_error || init_server_ipc_comms(
crm_strdup(cib_channel_rw), cib_client_connect_rw_ro,
default_ipc_connection_destroy);
was_error = was_error || init_server_ipc_comms(
crm_strdup(cib_channel_rw_synchronous), cib_client_connect_rw_synch,
default_ipc_connection_destroy);
was_error = was_error || init_server_ipc_comms(
crm_strdup(cib_channel_ro_synchronous), cib_client_connect_ro_synch,
default_ipc_connection_destroy);
if(was_error == FALSE) {
crm_debug_3("Be informed of CRM Client Status changes");
if (HA_OK != hb_conn->llc_ops->set_cstatus_callback(
hb_conn, cib_client_status_callback, hb_conn)) {
crm_err("Cannot set cstatus callback: %s",
hb_conn->llc_ops->errmsg(hb_conn));
was_error = TRUE;
} else {
crm_debug_3("Client Status callback set");
}
}
if(was_error == FALSE) {
gboolean did_fail = TRUE;
int num_ccm_fails = 0;
int max_ccm_fails = 30;
int ret;
int cib_ev_fd;
while(did_fail && was_error == FALSE) {
did_fail = FALSE;
crm_debug_3("Registering with CCM");
ret = oc_ev_register(&cib_ev_token);
if (ret != 0) {
crm_warn("CCM registration failed");
did_fail = TRUE;
}
if(did_fail == FALSE) {
crm_debug_3("Setting up CCM callbacks");
ret = oc_ev_set_callback(
cib_ev_token, OC_EV_MEMB_CLASS,
cib_ccm_msg_callback, NULL);
if (ret != 0) {
crm_warn("CCM callback not set");
did_fail = TRUE;
}
}
if(did_fail == FALSE) {
oc_ev_special(cib_ev_token, OC_EV_MEMB_CLASS, 0);
crm_debug_3("Activating CCM token");
ret = oc_ev_activate(cib_ev_token, &cib_ev_fd);
if (ret != 0){
crm_warn("CCM Activation failed");
did_fail = TRUE;
}
}
if(did_fail) {
num_ccm_fails++;
oc_ev_unregister(cib_ev_token);
if(num_ccm_fails < max_ccm_fails){
crm_warn("CCM Connection failed"
" %d times (%d max)",
num_ccm_fails, max_ccm_fails);
sleep(1);
} else {
crm_err("CCM Activation failed"
" %d (max) times",
num_ccm_fails);
was_error = TRUE;
}
}
}
crm_debug_3("CCM Activation passed... all set to go!");
G_main_add_fd(G_PRIORITY_HIGH, cib_ev_fd, FALSE,
cib_ccm_dispatch, cib_ev_token,
default_ipc_connection_destroy);
}
if(was_error == FALSE) {
/* Async get client status information in the cluster */
crm_debug_3("Requesting an initial dump of CIB client_status");
hb_conn->llc_ops->client_status(
hb_conn, NULL, CRM_SYSTEM_CIB, -1);
/* Create the mainloop and run it... */
mainloop = g_main_new(FALSE);
crm_info("Starting %s mainloop", crm_system_name);
Gmain_timeout_add(crm_get_msec("10s"), cib_msg_timeout, NULL);
Gmain_timeout_add(
crm_get_msec(cib_stat_interval), cib_stats, NULL);
g_main_run(mainloop);
return_to_orig_privs();
} else {
crm_err("Couldnt start all communication channels, exiting.");
}
return 0;
}
void
usage(const char* cmd, int exit_status)
{
FILE* stream;
stream = exit_status ? stderr : stdout;
fprintf(stream, "usage: %s [-srkh]"
"[-c configure file]\n", cmd);
/* fprintf(stream, "\t-d\tsets debug level\n"); */
/* fprintf(stream, "\t-s\tgets daemon status\n"); */
/* fprintf(stream, "\t-r\trestarts daemon\n"); */
/* fprintf(stream, "\t-k\tstops daemon\n"); */
/* fprintf(stream, "\t-h\thelp message\n"); */
fflush(stream);
exit(exit_status);
}
gboolean
cib_register_ha(ll_cluster_t *hb_cluster, const char *client_name)
{
const char *uname = NULL;
crm_info("Signing in with Heartbeat");
if (hb_cluster->llc_ops->signon(hb_cluster, client_name)!= HA_OK) {
crm_err("Cannot sign on with heartbeat: %s",
hb_cluster->llc_ops->errmsg(hb_cluster));
return FALSE;
}
- crm_set_ha_options(hb_cluster);
-
crm_debug_3("Be informed of CIB messages");
if (HA_OK != hb_cluster->llc_ops->set_msg_callback(
hb_cluster, T_CIB, cib_peer_callback, hb_cluster)){
crm_err("Cannot set msg callback: %s",
hb_cluster->llc_ops->errmsg(hb_cluster));
return FALSE;
}
crm_debug_3("Finding our node name");
if ((uname = hb_cluster->llc_ops->get_mynodeid(hb_cluster)) == NULL) {
crm_err("get_mynodeid() failed");
return FALSE;
}
cib_our_uname = crm_strdup(uname);
crm_info("FSA Hostname: %s", cib_our_uname);
crm_debug_3("Adding channel to mainloop");
G_main_add_IPC_Channel(
G_PRIORITY_DEFAULT, hb_cluster->llc_ops->ipcchan(hb_cluster),
FALSE, cib_ha_dispatch, hb_cluster /* userdata */,
cib_ha_connection_destroy);
return TRUE;
}
void
cib_ha_connection_destroy(gpointer user_data)
{
if(cib_shutdown_flag) {
crm_info("Heartbeat disconnection complete... exiting");
} else {
crm_err("Heartbeat connection lost! Exiting.");
}
if (mainloop != NULL && g_main_is_running(mainloop)) {
g_main_quit(mainloop);
} else {
exit(LSB_EXIT_OK);
}
}
static void
disconnect_cib_client(gpointer key, gpointer value, gpointer user_data)
{
cib_client_t *a_client = value;
crm_debug_2("Processing client %s/%s... send=%d, recv=%d",
a_client->name, a_client->channel_name,
(int)a_client->channel->send_queue->current_qlen,
(int)a_client->channel->recv_queue->current_qlen);
if(a_client->channel->ch_status == IPC_CONNECT) {
a_client->channel->ops->resume_io(a_client->channel);
if(a_client->channel->send_queue->current_qlen != 0
|| a_client->channel->recv_queue->current_qlen != 0) {
crm_info("Flushed messages to/from %s/%s... send=%d, recv=%d",
a_client->name, a_client->channel_name,
(int)a_client->channel->send_queue->current_qlen,
(int)a_client->channel->recv_queue->current_qlen);
}
}
if(a_client->channel->ch_status == IPC_CONNECT) {
crm_warn("Disconnecting %s/%s...",
a_client->name, a_client->channel_name);
a_client->channel->ops->disconnect(a_client->channel);
}
}
extern gboolean cib_process_disconnect(
IPC_Channel *channel, cib_client_t *cib_client);
gboolean
cib_shutdown(int nsig, gpointer unused)
{
if(cib_shutdown_flag == FALSE) {
cib_shutdown_flag = TRUE;
crm_debug("Disconnecting %d clients",
g_hash_table_size(client_list));
g_hash_table_foreach(client_list, disconnect_cib_client, NULL);
crm_info("Disconnected %d clients",
g_hash_table_size(client_list));
cib_process_disconnect(NULL, NULL);
} else {
crm_info("Waiting for %d clients to disconnect...",
g_hash_table_size(client_list));
}
return TRUE;
}
gboolean
startCib(const char *filename)
{
crm_data_t *cib = readCibXmlFile(filename);
if(cib == NULL) {
crm_warn("Cluster configuration not found: %s."
" Creating an empty one.", filename);
cib = createEmptyCib();
crm_xml_add(cib, XML_ATTR_GENERATION_ADMIN, "0");
crm_xml_add(cib, XML_ATTR_GENERATION, "0");
crm_xml_add(cib, XML_ATTR_NUMUPDATES, "0");
}
if(activateCibXml(cib, filename) != 0) {
return FALSE;
}
crm_info("CIB Initialization completed successfully");
return TRUE;
}
diff --git a/crm/crmd/control.c b/crm/crmd/control.c
index 8a0a9a8039..a274634493 100644
--- a/crm/crmd/control.c
+++ b/crm/crmd/control.c
@@ -1,768 +1,766 @@
/*
* Copyright (C) 2004 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <portability.h>
#include <sys/param.h>
#include <heartbeat.h>
#include <crm/crm.h>
#include <crm/cib.h>
#include <crm/msg_xml.h>
#include <crm/common/ctrl.h>
#include <crmd.h>
#include <crmd_fsa.h>
#include <fsa_proto.h>
#include <crmd_messages.h>
#include <crmd_callbacks.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <crm/dmalloc_wrapper.h>
extern void crmd_ha_connection_destroy(gpointer user_data);
extern gboolean stop_all_resources(void);
gboolean crm_shutdown(int nsig, gpointer unused);
gboolean register_with_ha(ll_cluster_t *hb_cluster, const char *client_name);
void populate_cib_nodes(ll_cluster_t *hb_cluster, gboolean with_client_status);
GHashTable *ipc_clients = NULL;
GTRIGSource *fsa_source = NULL;
/* A_HA_CONNECT */
enum crmd_fsa_input
do_ha_control(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
gboolean registered = FALSE;
if(action & A_HA_DISCONNECT) {
if(fsa_cluster_conn != NULL) {
set_bit_inplace(fsa_input_register, R_HA_DISCONNECTED);
fsa_cluster_conn->llc_ops->signoff(
fsa_cluster_conn, FALSE);
fsa_cluster_conn->llc_ops->delete(fsa_cluster_conn);
fsa_cluster_conn = NULL;
}
crm_info("Disconnected from Heartbeat");
}
if(action & A_HA_CONNECT) {
if(fsa_cluster_conn == NULL) {
fsa_cluster_conn = ll_cluster_new("heartbeat");
}
/* make sure we are disconnected first */
fsa_cluster_conn->llc_ops->signoff(fsa_cluster_conn, FALSE);
registered = register_with_ha(
fsa_cluster_conn, crm_system_name);
if(registered == FALSE) {
register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
return I_NULL;
}
clear_bit_inplace(fsa_input_register, R_HA_DISCONNECTED);
crm_info("Connected to Heartbeat");
}
if(action & ~(A_HA_CONNECT|A_HA_DISCONNECT)) {
crm_err("Unexpected action %s in %s",
fsa_action2string(action), __FUNCTION__);
}
return I_NULL;
}
/* A_SHUTDOWN */
enum crmd_fsa_input
do_shutdown(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
int lpc = 0;
gboolean continue_shutdown = TRUE;
struct crm_subsystem_s *subsystems[] = {
pe_subsystem,
te_subsystem
};
/* just in case */
set_bit_inplace(fsa_input_register, R_SHUTDOWN);
for(lpc = 0; lpc < DIMOF(subsystems); lpc++) {
struct crm_subsystem_s *a_subsystem = subsystems[lpc];
if(is_set(fsa_input_register, a_subsystem->flag_connected)) {
crm_info("Terminating the %s", a_subsystem->name);
if(stop_subsystem(a_subsystem, TRUE) == FALSE) {
/* its gone... */
crm_err("Faking %s exit", a_subsystem->name);
clear_bit_inplace(fsa_input_register,
a_subsystem->flag_connected);
}
continue_shutdown = FALSE;
}
}
if(continue_shutdown == FALSE) {
crm_info("Waiting for subsystems to exit");
crmd_fsa_stall(NULL);
} else {
register_fsa_input(C_FSA_INTERNAL, I_TERMINATE, NULL);
}
return I_NULL;
}
/* A_SHUTDOWN_REQ */
enum crmd_fsa_input
do_shutdown_req(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
HA_Message *msg = NULL;
crm_info("Sending shutdown request to DC: %s", crm_str(fsa_our_dc));
msg = create_request(
CRM_OP_SHUTDOWN_REQ, NULL, NULL,
CRM_SYSTEM_DC, CRM_SYSTEM_CRMD, NULL);
/* set_bit_inplace(fsa_input_register, R_STAYDOWN); */
if(send_request(msg, NULL) == FALSE) {
if(AM_I_DC) {
crm_info("Processing shutdown locally");
} else {
register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
}
}
return I_NULL;
}
/* A_EXIT_0, A_EXIT_1 */
enum crmd_fsa_input
do_exit(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
int exit_code = 0;
int log_level = LOG_INFO;
const char *exit_type = "gracefully";
if(action & A_EXIT_1) {
exit_code = 1;
log_level = LOG_ERR;
exit_type = "forcefully";
}
crm_log_maybe(log_level, "Performing %s - %s exiting the CRMd",
fsa_action2string(action), exit_type);
if(is_set(fsa_input_register, R_IN_RECOVERY)) {
crm_err("Could not recover from internal error");
exit_code = 2;
} else if(is_set(fsa_input_register, R_STAYDOWN)) {
crm_warn("Inhibiting respawn by Heartbeat");
exit_code = 100;
}
crm_info("[%s] stopped (%d)", crm_system_name, exit_code);
exit(exit_code);
return I_NULL;
}
/* A_STARTUP */
enum crmd_fsa_input
do_startup(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
int was_error = 0;
int interval = 1; /* seconds between DC heartbeats */
crm_debug("Registering Signal Handlers");
G_main_add_SignalHandler(
G_PRIORITY_HIGH, SIGTERM, crm_shutdown, NULL, NULL);
fsa_source = G_main_add_TriggerHandler(
G_PRIORITY_HIGH, crm_fsa_trigger, NULL, NULL);
ipc_clients = g_hash_table_new(g_str_hash, g_str_equal);
if(was_error == 0) {
crm_debug("Init server comms");
was_error = init_server_ipc_comms(
crm_strdup(CRM_SYSTEM_CRMD), crmd_client_connect,
default_ipc_connection_destroy);
}
if(was_error == 0) {
crm_debug("Creating CIB object");
fsa_cib_conn = cib_new();
}
/* set up the timers */
crm_malloc0(integration_timer, sizeof(fsa_timer_t));
crm_malloc0(finalization_timer, sizeof(fsa_timer_t));
crm_malloc0(election_trigger, sizeof(fsa_timer_t));
crm_malloc0(election_timeout, sizeof(fsa_timer_t));
crm_malloc0(shutdown_escalation_timer, sizeof(fsa_timer_t));
crm_malloc0(wait_timer, sizeof(fsa_timer_t));
crm_malloc0(recheck_timer, sizeof(fsa_timer_t));
interval = interval * 1000;
if(election_trigger != NULL) {
election_trigger->source_id = 0;
election_trigger->period_ms = -1;
election_trigger->fsa_input = I_DC_TIMEOUT;
election_trigger->callback = crm_timer_popped;
election_trigger->repeat = FALSE;
} else {
was_error = TRUE;
}
if(election_timeout != NULL) {
election_timeout->source_id = 0;
election_timeout->period_ms = -1;
election_timeout->fsa_input = I_ELECTION_DC;
election_timeout->callback = crm_timer_popped;
election_timeout->repeat = FALSE;
} else {
was_error = TRUE;
}
if(integration_timer != NULL) {
integration_timer->source_id = 0;
integration_timer->period_ms = -1;
integration_timer->fsa_input = I_INTEGRATED;
integration_timer->callback = crm_timer_popped;
integration_timer->repeat = FALSE;
} else {
was_error = TRUE;
}
if(finalization_timer != NULL) {
finalization_timer->source_id = 0;
finalization_timer->period_ms = -1;
finalization_timer->fsa_input = I_FINALIZED;
finalization_timer->callback = crm_timer_popped;
finalization_timer->repeat = FALSE;
/* for possible enabling... a bug in the join protocol left
* a slave in S_PENDING while we think its in S_NOT_DC
*
* raising I_FINALIZED put us into a transition loop which is
* never resolved.
* in this loop we continually send probes which the node
* NACK's because its in S_PENDING
*
* if we have nodes where heartbeat is active but the
* CRM is not... then this will be handled in the
* integration phase
*/
finalization_timer->fsa_input = I_ELECTION;
} else {
was_error = TRUE;
}
if(shutdown_escalation_timer != NULL) {
shutdown_escalation_timer->source_id = 0;
shutdown_escalation_timer->period_ms = -1;
shutdown_escalation_timer->fsa_input = I_STOP;
shutdown_escalation_timer->callback = crm_timer_popped;
shutdown_escalation_timer->repeat = FALSE;
} else {
was_error = TRUE;
}
if(wait_timer != NULL) {
wait_timer->source_id = 0;
wait_timer->period_ms = 500;
wait_timer->fsa_input = I_NULL;
wait_timer->callback = crm_timer_popped;
wait_timer->repeat = FALSE;
} else {
was_error = TRUE;
}
if(recheck_timer != NULL) {
recheck_timer->source_id = 0;
recheck_timer->period_ms = -1;
recheck_timer->fsa_input = I_PE_CALC;
recheck_timer->callback = crm_timer_popped;
recheck_timer->repeat = FALSE;
} else {
was_error = TRUE;
}
/* set up the sub systems */
crm_malloc0(cib_subsystem, sizeof(struct crm_subsystem_s));
crm_malloc0(te_subsystem, sizeof(struct crm_subsystem_s));
crm_malloc0(pe_subsystem, sizeof(struct crm_subsystem_s));
if(cib_subsystem != NULL) {
cib_subsystem->pid = -1;
cib_subsystem->path = BIN_DIR;
cib_subsystem->name = CRM_SYSTEM_CIB;
cib_subsystem->command = BIN_DIR"/"CRM_SYSTEM_CIB;
cib_subsystem->args = "-VVc";
cib_subsystem->flag_connected = R_CIB_CONNECTED;
cib_subsystem->flag_required = R_CIB_REQUIRED;
} else {
was_error = TRUE;
}
if(te_subsystem != NULL) {
te_subsystem->pid = -1;
te_subsystem->path = BIN_DIR;
te_subsystem->name = CRM_SYSTEM_TENGINE;
te_subsystem->command = BIN_DIR"/"CRM_SYSTEM_TENGINE;
te_subsystem->args = NULL;
te_subsystem->flag_connected = R_TE_CONNECTED;
te_subsystem->flag_required = R_TE_REQUIRED;
} else {
was_error = TRUE;
}
if(pe_subsystem != NULL) {
pe_subsystem->pid = -1;
pe_subsystem->path = BIN_DIR;
pe_subsystem->name = CRM_SYSTEM_PENGINE;
pe_subsystem->command = BIN_DIR"/"CRM_SYSTEM_PENGINE;
pe_subsystem->args = NULL;
pe_subsystem->flag_connected = R_PE_CONNECTED;
pe_subsystem->flag_required = R_PE_REQUIRED;
} else {
was_error = TRUE;
}
if(was_error) {
register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
}
welcomed_nodes = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
integrated_nodes = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
finalized_nodes = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
confirmed_nodes = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
crmd_peer_state = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
set_sigchld_proctrack(G_PRIORITY_HIGH);
return I_NULL;
}
extern GHashTable *shutdown_ops;
/* A_STOP */
enum crmd_fsa_input
do_stop(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
crm_debug_2("Stopping all remaining local resources");
if(is_set(fsa_input_register, R_LRM_CONNECTED)) {
stop_all_resources();
} else {
crm_err("Exiting with no LRM connection..."
" resources may be active!");
}
if(g_hash_table_size(shutdown_ops) > 0) {
crm_info("Waiting on %d stop operations to complete",
g_hash_table_size(shutdown_ops));
crmd_fsa_stall(NULL);
return I_NULL;
}
return I_NULL;
}
/* A_STARTED */
enum crmd_fsa_input
do_started(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
if(is_set(fsa_input_register, R_CCM_DATA) == FALSE) {
crm_info("Delaying start, CCM (%.16llx) not connected",
R_CCM_DATA);
crmd_fsa_stall(NULL);
return I_NULL;
} else if(is_set(fsa_input_register, R_LRM_CONNECTED) == FALSE) {
crm_info("Delaying start, LRM (%.16llx) not connected",
R_LRM_CONNECTED);
crmd_fsa_stall(NULL);
return I_NULL;
} else if(is_set(fsa_input_register, R_CIB_CONNECTED) == FALSE) {
crm_info("Delaying start, CIB (%.16llx) not connected",
R_CIB_CONNECTED);
crmd_fsa_stall(NULL);
return I_NULL;
} else if(is_set(fsa_input_register, R_READ_CONFIG) == FALSE) {
crm_info("Delaying start, Config not read (%.16llx)",
R_READ_CONFIG);
crmd_fsa_stall(NULL);
return I_NULL;
} else if(is_set(fsa_input_register, R_PEER_DATA) == FALSE) {
HA_Message * msg = NULL;
/* try reading from HA */
crm_info("Delaying start, Peer data (%.16llx) not recieved",
R_PEER_DATA);
crm_debug_3("Looking for a HA message");
msg = fsa_cluster_conn->llc_ops->readmsg(fsa_cluster_conn, 0);
if(msg != NULL) {
crm_debug_3("There was a HA message");
crm_msg_del(msg);
}
crm_timer_start(wait_timer);
crmd_fsa_stall(NULL);
return I_NULL;
}
crm_info("The local CRM is operational");
clear_bit_inplace(fsa_input_register, R_STARTING);
register_fsa_input(msg_data->fsa_cause, I_PENDING, NULL);
return I_NULL;
}
/* A_RECOVER */
enum crmd_fsa_input
do_recover(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
set_bit_inplace(fsa_input_register, R_IN_RECOVERY);
crm_err("Action %s (%.16llx) not supported",
fsa_action2string(action), action);
register_fsa_input(C_FSA_INTERNAL, I_STOP, NULL);
return I_NULL;
}
static void
config_query_callback(const HA_Message *msg, int call_id, int rc,
crm_data_t *output, void *user_data)
{
crm_debug("Call %d : Parsing CIB options", call_id);
if(rc != cib_ok) {
fsa_data_t *msg_data = NULL;
crm_err("Local CIB query resulted in an error: %s",
cib_error2string(rc));
register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
return;
}
#if 0
/* disable until we can do it properly
* - most people use the defaults anyway
*/
crm_data_t *config = output;
xml_child_iter_filter(
config, iter, XML_CIB_TAG_NVPAIR,
const char *name = crm_element_value(iter, XML_NVPAIR_ATTR_NAME);
const char *value = crm_element_value(iter, XML_NVPAIR_ATTR_VALUE);
if(name == NULL || value == NULL) {
continue;
} else if(safe_str_eq(name, XML_CONFIG_ATTR_DC_DEADTIME)) {
election_trigger->period_ms = crm_get_msec(value);
} else if(safe_str_eq(name, XML_CONFIG_ATTR_FORCE_QUIT)) {
shutdown_escalation_timer->period_ms = crm_get_msec(value);
} else if(safe_str_eq(name, XML_CONFIG_ATTR_RECHECK)) {
recheck_timer->period_ms = crm_get_msec(value);
}
);
#endif
set_bit_inplace(fsa_input_register, R_READ_CONFIG);
crm_debug_3("Triggering FSA: %s", __FUNCTION__);
G_main_set_trigger(fsa_source);
}
/* A_READCONFIG */
enum crmd_fsa_input
do_read_config(long long action,
enum crmd_fsa_cause cause,
enum crmd_fsa_state cur_state,
enum crmd_fsa_input current_input,
fsa_data_t *msg_data)
{
char *param_val = NULL;
const char *param_name = NULL;
int call_id = fsa_cib_conn->cmds->query(
fsa_cib_conn, XML_CIB_TAG_CRMCONFIG, NULL, cib_scope_local);
add_cib_op_callback(call_id, FALSE, NULL, config_query_callback);
crm_debug_2("Querying the CIB... call %d", call_id);
/* defaults */
election_trigger->period_ms = crm_get_msec("5s");
election_timeout->period_ms = crm_get_msec("2min");
integration_timer->period_ms = crm_get_msec("3min");
finalization_timer->period_ms = crm_get_msec("3min");
shutdown_escalation_timer->period_ms = crm_get_msec("10min");
/* apparently we're not allowed to free the result of getenv */
param_name = ENV_PREFIX "" KEY_INITDEAD;
param_val = getenv(param_name);
if(param_val != NULL) {
int tmp = crm_get_msec(param_val) / 2;
if(tmp > election_trigger->period_ms) {
election_trigger->period_ms = tmp;
}
crm_debug("%s = %s", param_name, param_val);
param_val = NULL;
}
return I_NULL;
}
gboolean
crm_shutdown(int nsig, gpointer unused)
{
if (crmd_mainloop != NULL && g_main_is_running(crmd_mainloop)) {
if(is_set(fsa_input_register, R_SHUTDOWN)) {
crm_err("Escalating the shutdown");
register_fsa_input_before(C_SHUTDOWN, I_ERROR, NULL);
} else {
crm_info("Requesting shutdown");
set_bit_inplace(fsa_input_register, R_SHUTDOWN);
register_fsa_input(C_SHUTDOWN,I_SHUTDOWN,NULL);
/* cant rely on this... */
crm_timer_start(shutdown_escalation_timer);
}
} else {
crm_info("exit from shutdown");
exit(LSB_EXIT_OK);
}
return TRUE;
}
static void
default_cib_update_callback(const HA_Message *msg, int call_id, int rc,
crm_data_t *output, void *user_data)
{
if(rc != cib_ok) {
fsa_data_t *msg_data = NULL;
crm_err("CIB Update failed: %s", cib_error2string(rc));
crm_log_xml_warn(output, "update:failed");
register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
}
}
void
populate_cib_nodes(ll_cluster_t *hb_cluster, gboolean with_client_status)
{
int call_id = 0;
const char *ha_node = NULL;
crm_data_t *cib_node_list = NULL;
/* Async get client status information in the cluster */
crm_debug_2("Invoked");
if(with_client_status) {
crm_debug_3("Requesting an initial dump of CRMD client_status");
fsa_cluster_conn->llc_ops->client_status(
fsa_cluster_conn, NULL, CRM_SYSTEM_CRMD, -1);
}
crm_info("Requesting the list of configured nodes");
fsa_cluster_conn->llc_ops->init_nodewalk(fsa_cluster_conn);
cib_node_list = create_xml_node(NULL, XML_CIB_TAG_NODES);
do {
const char *ha_node_type = NULL;
const char *ha_node_uuid = NULL;
crm_data_t *cib_new_node = NULL;
ha_node = fsa_cluster_conn->llc_ops->nextnode(fsa_cluster_conn);
if(ha_node == NULL) {
continue;
}
ha_node_type = fsa_cluster_conn->llc_ops->node_type(
fsa_cluster_conn, ha_node);
if(safe_str_neq(NORMALNODE, ha_node_type)) {
crm_debug("Node %s: skipping '%s'",
ha_node, ha_node_type);
continue;
}
ha_node_uuid = get_uuid(fsa_cluster_conn, ha_node);
if(ha_node_uuid == NULL) {
crm_warn("Node %s: no uuid found", ha_node);
continue;
}
crm_notice("Node: %s (uuid: %s)", ha_node, ha_node_uuid);
cib_new_node = create_xml_node(cib_node_list, XML_CIB_TAG_NODE);
crm_xml_add(cib_new_node, XML_ATTR_ID, ha_node_uuid);
crm_xml_add(cib_new_node, XML_ATTR_UNAME, ha_node);
crm_xml_add(cib_new_node, XML_ATTR_TYPE, ha_node_type);
} while(ha_node != NULL);
fsa_cluster_conn->llc_ops->end_nodewalk(fsa_cluster_conn);
/* Now update the CIB with the list of nodes */
call_id = fsa_cib_conn->cmds->update(
fsa_cib_conn, XML_CIB_TAG_NODES, cib_node_list, NULL,
cib_scope_local|cib_quorum_override|cib_inhibit_bcast);
add_cib_op_callback(call_id, FALSE, NULL, default_cib_update_callback);
free_xml(cib_node_list);
crm_debug_2("Complete");
}
gboolean
register_with_ha(ll_cluster_t *hb_cluster, const char *client_name)
{
crm_debug("Signing in with Heartbeat");
if (hb_cluster->llc_ops->signon(hb_cluster, client_name)!= HA_OK) {
crm_err("Cannot sign on with heartbeat: %s",
hb_cluster->llc_ops->errmsg(hb_cluster));
return FALSE;
}
- crm_set_ha_options(hb_cluster);
-
crm_debug_3("Be informed of CRM messages");
if (HA_OK != hb_cluster->llc_ops->set_msg_callback(
hb_cluster, T_CRM, crmd_ha_msg_callback, hb_cluster)){
crm_err("Cannot set msg callback: %s",
hb_cluster->llc_ops->errmsg(hb_cluster));
return FALSE;
}
#if 0
crm_debug_3("Be informed of Node Status changes");
if (HA_OK != hb_cluster->llc_ops->set_nstatus_callback(
hb_cluster, crmd_ha_status_callback, hb_cluster)){
crm_err("Cannot set nstatus callback: %s",
hb_cluster->llc_ops->errmsg(hb_cluster));
return FALSE;
}
#endif
crm_debug_3("Be informed of CRM Client Status changes");
if (HA_OK != hb_cluster->llc_ops->set_cstatus_callback(
hb_cluster, crmd_client_status_callback, hb_cluster)) {
crm_err("Cannot set cstatus callback: %s",
hb_cluster->llc_ops->errmsg(hb_cluster));
return FALSE;
}
crm_debug_3("Adding channel to mainloop");
G_main_add_IPC_Channel(
G_PRIORITY_HIGH, hb_cluster->llc_ops->ipcchan(hb_cluster),
FALSE, crmd_ha_msg_dispatch, hb_cluster /* userdata */,
crmd_ha_connection_destroy);
crm_debug_3("Finding our node name");
if ((fsa_our_uname =
hb_cluster->llc_ops->get_mynodeid(hb_cluster)) == NULL) {
crm_err("get_mynodeid() failed");
return FALSE;
}
crm_info("Hostname: %s", fsa_our_uname);
crm_debug_3("Finding our node uuid");
fsa_our_uuid = get_uuid(fsa_cluster_conn, fsa_our_uname);
if(fsa_our_uuid == NULL) {
crm_err("get_uuid_by_name() failed");
return FALSE;
}
/* copy it so that unget_uuid() doesn't trash the value on us */
fsa_our_uuid = crm_strdup(fsa_our_uuid);
crm_info("UUID: %s", fsa_our_uuid);
populate_cib_nodes(hb_cluster, TRUE);
return TRUE;
}
diff --git a/include/crm/common/util.h b/include/crm/common/util.h
index 3bb3b735d5..d1a0e2043f 100644
--- a/include/crm/common/util.h
+++ b/include/crm/common/util.h
@@ -1,138 +1,136 @@
-/* $Id: util.h,v 1.32 2006/04/10 12:49:15 andrew Exp $ */
+/* $Id: util.h,v 1.33 2006/04/10 16:18:25 andrew Exp $ */
/*
* Copyright (C) 2004 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CRM_COMMON_UTIL__H
#define CRM_COMMON_UTIL__H
#include <signal.h>
#include <crm/common/xml.h>
#include <hb_api.h>
#include <ocf/oc_event.h>
#include <lrm/lrm_api.h>
#define DEBUG_INC SIGUSR1
#define DEBUG_DEC SIGUSR2
extern unsigned int crm_log_level;
extern gboolean crm_log_init(const char *entity);
extern void do_crm_log(int log_level, const char *file, const char *function,
const char *format, ...) G_GNUC_PRINTF(4,5);
/* returns the old value */
extern unsigned int set_crm_log_level(unsigned int level);
extern unsigned int get_crm_log_level(void);
extern char *crm_itoa(int an_int);
extern char *crm_strdup(const char *a);
extern char *generate_hash_key(const char *crm_msg_reference, const char *sys);
extern char *generate_hash_value(const char *src_node, const char *src_subsys);
extern gboolean decode_hash_value(gpointer value, char **node, char **subsys);
extern gboolean decodeNVpair(const char *srcstring,
char separator, char **name, char **value);
extern int compare_version(const char *version1, const char *version2);
extern char *generateReference(const char *custom1, const char *custom2);
extern void alter_debug(int nsig);
extern void g_hash_destroy_str(gpointer data);
extern const char *get_uuid(ll_cluster_t *hb, const char *uname);
extern const char *get_uname(ll_cluster_t *hb, const char *uuid);
extern void unget_uuid(const char *uname);
extern void set_uuid(
ll_cluster_t* hb, crm_data_t *node, const char *attr, const char *uname);
-extern void crm_set_ha_options(ll_cluster_t *hb_cluster);
-
extern gboolean crm_is_true(const char * s);
extern int crm_str_to_boolean(const char * s, int * ret);
extern long crm_get_msec(const char * input);
extern gboolean ccm_have_quorum(oc_ed_t event);
extern const char *ccm_event_name(oc_ed_t event);
extern const char *op_status2text(op_status_t status);
extern char *generate_op_key(
const char *rsc_id, const char *op_type, int interval);
extern char *generate_notify_key(
const char *rsc_id, const char *notify_type, const char *op_type);
extern gboolean crm_mem_stats(volatile cl_mem_stats_t *mem_stats);
extern void crm_zero_mem_stats(volatile cl_mem_stats_t *stats);
extern char *generate_transition_magic_v202(
const char *transition_key, int op_status);
extern char *generate_transition_magic(
const char *transition_key, int op_status, int op_rc);
extern gboolean decode_transition_magic(
const char *magic, char **uuid,
int *transition_id, int *op_status, int *op_rc);
extern char *generate_transition_key(int transition_id, const char *node);
extern gboolean decode_transition_key(
const char *key, char **uuid, int *transition_id);
extern char *crm_concat(const char *prefix, const char *suffix, char join);
extern gboolean decode_op_key(
const char *key, char **rsc_id, char **op_type, int *interval);
extern void filter_action_parameters(crm_data_t *param_set);
extern gboolean safe_str_eq(const char *a, const char *b);
extern gboolean safe_str_neq(const char *a, const char *b);
extern int crm_parse_int(const char *text, const char *default_text);
extern int crm_int_helper(const char *text, char **end_text);
#define crm_atoi(text, default_text) crm_parse_int(text, default_text)
extern void crm_abort(const char *file, const char *function, int line,
const char *condition, gboolean do_fork);
extern char *generate_series_filename(
const char *directory, const char *series, int sequence, gboolean bzip);
extern int get_last_sequence(const char *directory, const char *series);
extern void write_last_sequence(
const char *directory, const char *series, int sequence, int max);
extern void crm_make_daemon(
const char *name, gboolean daemonize, const char *pidfile);
#endif
diff --git a/lib/crm/common/utils.c b/lib/crm/common/utils.c
index 1a17fd6d14..b649d1feb4 100644
--- a/lib/crm/common/utils.c
+++ b/lib/crm/common/utils.c
@@ -1,1427 +1,1348 @@
-/* $Id: utils.c,v 1.45 2006/04/10 12:49:15 andrew Exp $ */
+/* $Id: utils.c,v 1.46 2006/04/10 16:18:08 andrew Exp $ */
/*
* Copyright (C) 2004 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.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <portability.h>
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <sys/param.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <heartbeat.h>
#include <ha_msg.h>
#include <clplumbing/cl_log.h>
#include <clplumbing/cl_signal.h>
#include <clplumbing/cl_syslog.h>
#include <clplumbing/cl_misc.h>
#include <clplumbing/coredumps.h>
#include <clplumbing/lsb_exitcodes.h>
#include <clplumbing/cl_pidfile.h>
#include <time.h>
#include <clplumbing/Gmain_timeout.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
#include <crm/common/util.h>
#include <crm/dmalloc_wrapper.h>
#ifndef MAXLINE
# define MAXLINE 512
#endif
static uint ref_counter = 0;
gboolean crm_assert_failed = FALSE;
unsigned int crm_log_level = LOG_INFO;
void crm_set_env_options(void);
char *
generateReference(const char *custom1, const char *custom2)
{
const char *local_cust1 = custom1;
const char *local_cust2 = custom2;
int reference_len = 4;
char *since_epoch = NULL;
reference_len += 20; /* too big */
reference_len += 40; /* too big */
if(local_cust1 == NULL) { local_cust1 = "_empty_"; }
reference_len += strlen(local_cust1);
if(local_cust2 == NULL) { local_cust2 = "_empty_"; }
reference_len += strlen(local_cust2);
crm_malloc0(since_epoch, reference_len*(sizeof(char)));
if(since_epoch != NULL) {
sprintf(since_epoch, "%s-%s-%ld-%u",
local_cust1, local_cust2,
(unsigned long)time(NULL), ref_counter++);
}
return since_epoch;
}
gboolean
decodeNVpair(const char *srcstring, char separator, char **name, char **value)
{
int lpc = 0;
int len = 0;
const char *temp = NULL;
CRM_ASSERT(name != NULL && value != NULL);
*name = NULL;
*value = NULL;
crm_debug_4("Attempting to decode: [%s]", srcstring);
if (srcstring != NULL) {
len = strlen(srcstring);
while(lpc <= len) {
if (srcstring[lpc] == separator) {
crm_malloc0(*name, sizeof(char)*lpc+1);
if(*name == NULL) {
break; /* and return FALSE */
}
strncpy(*name, srcstring, lpc);
(*name)[lpc] = '\0';
/* this sucks but as the strtok manpage says..
* it *is* a bug
*/
len = len-lpc; len--;
if(len <= 0) {
*value = NULL;
} else {
crm_malloc0(*value, sizeof(char)*len+1);
if(*value == NULL) {
crm_free(*name);
break; /* and return FALSE */
}
temp = srcstring+lpc+1;
strncpy(*value, temp, len);
(*value)[len] = '\0';
}
return TRUE;
}
lpc++;
}
}
if(*name != NULL) {
crm_free(*name);
}
*name = NULL;
*value = NULL;
return FALSE;
}
char *
crm_concat(const char *prefix, const char *suffix, char join)
{
int len = 0;
char *new_str = NULL;
CRM_ASSERT(prefix != NULL);
CRM_ASSERT(suffix != NULL);
len = strlen(prefix) + strlen(suffix) + 2;
crm_malloc0(new_str, sizeof(char)*(len));
sprintf(new_str, "%s%c%s", prefix, join, suffix);
new_str[len-1] = 0;
return new_str;
}
char *
generate_hash_key(const char *crm_msg_reference, const char *sys)
{
char *hash_key = crm_concat(sys?sys:"none", crm_msg_reference, '_');
crm_debug_3("created hash key: (%s)", hash_key);
return hash_key;
}
char *
generate_hash_value(const char *src_node, const char *src_subsys)
{
char *hash_value = NULL;
if (src_node == NULL || src_subsys == NULL) {
return NULL;
}
if (strcmp(CRM_SYSTEM_DC, src_subsys) == 0) {
hash_value = crm_strdup(src_subsys);
if (!hash_value) {
crm_err("memory allocation failed in "
"generate_hash_value()");
}
return hash_value;
}
hash_value = crm_concat(src_node, src_subsys, '_');
crm_info("created hash value: (%s)", hash_value);
return hash_value;
}
gboolean
decode_hash_value(gpointer value, char **node, char **subsys)
{
char *char_value = (char*)value;
int value_len = strlen(char_value);
CRM_CHECK(value != NULL, return FALSE);
CRM_CHECK(node != NULL, return FALSE);
CRM_CHECK(subsys != NULL, return FALSE);
*node = NULL;
*subsys = NULL;
crm_info("Decoding hash value: (%s:%d)", char_value, value_len);
if (strcmp(CRM_SYSTEM_DC, (char*)value) == 0) {
*node = NULL;
*subsys = (char*)crm_strdup(char_value);
CRM_CHECK(*subsys != NULL, return FALSE);
crm_info("Decoded value: (%s:%d)", *subsys,
(int)strlen(*subsys));
return TRUE;
} else if (decodeNVpair(char_value, '_', node, subsys)) {
return TRUE;
}
crm_free(*node);
crm_free(*subsys);
*node = NULL;
*subsys = NULL;
return FALSE;
}
char *
crm_itoa(int an_int)
{
int len = 32;
char *buffer = NULL;
crm_malloc0(buffer, sizeof(char)*(len+1));
if(buffer != NULL) {
snprintf(buffer, len, "%d", an_int);
}
return buffer;
}
extern int LogToLoggingDaemon(int priority, const char * buf, int bstrlen, gboolean use_pri_str);
gboolean
crm_log_init(const char *entity)
{
/* const char *test = "Testing log daemon connection"; */
/* Redirect messages from glib functions to our handler */
/* cl_malloc_forced_for_glib(); */
g_log_set_handler(NULL,
G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL
| G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE
| G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG
| G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL,
cl_glib_msg_handler, NULL);
/* and for good measure... - this enum is a bit field (!) */
g_log_set_always_fatal((GLogLevelFlags)0); /*value out of range*/
cl_log_set_entity(entity);
cl_log_set_facility(LOG_LOCAL7);
cl_set_corerootdir(HA_COREDIR);
cl_cdtocoredir();
crm_set_env_options();
CL_SIGNAL(DEBUG_INC, alter_debug);
CL_SIGNAL(DEBUG_DEC, alter_debug);
return TRUE;
}
/* returns the old value */
unsigned int
set_crm_log_level(unsigned int level)
{
unsigned int old = crm_log_level;
while(crm_log_level < level) {
alter_debug(DEBUG_INC);
}
while(crm_log_level > level) {
alter_debug(DEBUG_DEC);
}
return old;
}
unsigned int
get_crm_log_level(void)
{
return crm_log_level;
}
void
crm_log_message_adv(int level, const char *prefix, const HA_Message *msg)
{
if((int)crm_log_level >= level) {
do_crm_log(level, NULL, NULL, "#========= %s message start ==========#", prefix?prefix:"");
if(level > LOG_DEBUG) {
cl_log_message(LOG_DEBUG, msg);
} else {
cl_log_message(level, msg);
}
}
}
void
do_crm_log(int log_level, const char *file, const char *function,
const char *fmt, ...)
{
int log_as = log_level;
gboolean do_log = FALSE;
if(log_level <= (int)crm_log_level) {
do_log = TRUE;
if(log_level > LOG_INFO) {
log_as = LOG_DEBUG;
}
}
if(do_log) {
va_list ap;
int nbytes;
char buf[MAXLINE];
va_start(ap, fmt);
nbytes=vsnprintf(buf, MAXLINE, fmt, ap);
va_end(ap);
log_level -= LOG_INFO;
if(log_level > 1) {
if(file == NULL && function == NULL) {
cl_log(log_as, "[%d] %s", log_level, buf);
} else {
cl_log(log_as, "mask(%s%s%s [%d]): %s",
file?file:"",
(file !=NULL && function !=NULL)?":":"",
function?function:"", log_level, buf);
}
} else {
if(file == NULL && function == NULL) {
cl_log(log_as, "%s", buf);
} else {
cl_log(log_as, "mask(%s%s%s): %s",
file?file:"",
(file !=NULL && function !=NULL)?":":"",
function?function:"", buf);
}
}
if(nbytes > MAXLINE) {
cl_log(LOG_WARNING, "Log from %s() was truncated",
crm_str(function));
}
}
}
int
compare_version(const char *version1, const char *version2)
{
int lpc = 0;
char *step1 = NULL, *step2 = NULL;
char *rest1 = NULL, *rest2 = NULL;
if(version1 == NULL && version2 == NULL) {
return 0;
} else if(version1 == NULL) {
return -1;
} else if(version2 == NULL) {
return 1;
}
rest1 = crm_strdup(version1);
rest2 = crm_strdup(version2);
while(1) {
int cmp = 0;
int step1_i = 0;
int step2_i = 0;
char *tmp1 = NULL, *tmp2 = NULL;
decodeNVpair(rest1, '.', &step1, &tmp1);
decodeNVpair(rest2, '.', &step2, &tmp2);
if(step1 != NULL) {
step1_i = crm_parse_int(step1, NULL);
}
if(step2 != NULL) {
step2_i = crm_parse_int(step2, NULL);
}
if(step1_i < step2_i){
cmp = -1;
} else if (step1_i > step2_i){
cmp = 1;
}
crm_debug_4("compare[%d (%d)]: %d(%s) %d(%s)",
lpc++, cmp,
step1_i, crm_str(step1),
step2_i, crm_str(step2));
crm_free(rest1);
crm_free(rest2);
rest1 = tmp1;
rest2 = tmp2;
if(step1 == NULL && step2 == NULL) {
break;
}
crm_free(step1);
crm_free(step2);
if(cmp < 0) {
crm_debug_3("%s < %s", version1, version2);
return -1;
} else if(cmp > 0) {
crm_debug_3("%s > %s", version1, version2);
return 1;
}
}
crm_debug_3("%s == %s", version1, version2);
return 0;
}
gboolean do_stderr = FALSE;
void
alter_debug(int nsig)
{
CL_SIGNAL(DEBUG_INC, alter_debug);
CL_SIGNAL(DEBUG_DEC, alter_debug);
switch(nsig) {
case DEBUG_INC:
crm_log_level++;
break;
case DEBUG_DEC:
crm_log_level--;
break;
default:
fprintf(stderr, "Unknown signal %d\n", nsig);
cl_log(LOG_ERR, "Unknown signal %d", nsig);
break;
}
}
void g_hash_destroy_str(gpointer data)
{
crm_free(data);
}
int
crm_int_helper(const char *text, char **end_text)
{
int atoi_result = -1;
char *local_end_text = NULL;
errno = 0;
if(text != NULL) {
if(end_text != NULL) {
atoi_result = (int)strtol(text, end_text, 10);
} else {
atoi_result = (int)strtol(text, &local_end_text, 10);
}
/* CRM_CHECK(errno != EINVAL); */
if(errno == EINVAL) {
crm_err("Conversion of %s failed", text);
atoi_result = -1;
} else {
if(errno == ERANGE) {
crm_err("Conversion of %s was clipped", text);
}
if(end_text == NULL && local_end_text[0] != '\0') {
crm_err("Characters left over after parsing "
"\"%s\": \"%s\"", text, local_end_text);
}
}
}
return atoi_result;
}
int
crm_parse_int(const char *text, const char *default_text)
{
int atoi_result = -1;
if(text != NULL) {
atoi_result = crm_int_helper(text, NULL);
if(errno == 0) {
return atoi_result;
}
}
if(default_text != NULL) {
atoi_result = crm_int_helper(default_text, NULL);
if(errno == 0) {
return atoi_result;
}
} else {
crm_err("No default conversion value supplied");
}
return -1;
}
gboolean
safe_str_eq(const char *a, const char *b)
{
if(a == b) {
return TRUE;
} else if(a == NULL || b == NULL) {
return FALSE;
} else if(strcmp(a, b) == 0) {
return TRUE;
}
return FALSE;
}
gboolean
safe_str_neq(const char *a, const char *b)
{
if(a == b) {
return FALSE;
} else if(a==NULL || b==NULL) {
return TRUE;
} else if(strcmp(a, b) == 0) {
return FALSE;
}
return TRUE;
}
char *
crm_strdup(const char *a)
{
char *ret = NULL;
CRM_CHECK(a != NULL, return NULL);
if(a != NULL) {
ret = cl_strdup(a);
} else {
crm_warn("Cannot dup NULL string");
}
return ret;
}
static GHashTable *crm_uuid_cache = NULL;
static GHashTable *crm_uname_cache = NULL;
void
unget_uuid(const char *uname)
{
if(crm_uuid_cache == NULL) {
return;
}
g_hash_table_remove(crm_uuid_cache, uname);
}
const char *
get_uuid(ll_cluster_t *hb, const char *uname)
{
cl_uuid_t uuid_raw;
char *uuid_calc = NULL;
const char *unknown = "00000000-0000-0000-0000-000000000000";
if(crm_uuid_cache == NULL) {
crm_uuid_cache = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
}
CRM_CHECK(uname != NULL, return NULL);
/* avoid blocking calls where possible */
uuid_calc = g_hash_table_lookup(crm_uuid_cache, uname);
if(uuid_calc != NULL) {
return uuid_calc;
}
if(hb->llc_ops->get_uuid_by_name(hb, uname, &uuid_raw) == HA_FAIL) {
crm_err("get_uuid_by_name() call failed for host %s", uname);
crm_free(uuid_calc);
return NULL;
}
crm_malloc0(uuid_calc, sizeof(char)*50);
if(uuid_calc == NULL) {
return NULL;
}
cl_uuid_unparse(&uuid_raw, uuid_calc);
if(safe_str_eq(uuid_calc, unknown)) {
crm_warn("Could not calculate UUID for %s", uname);
crm_free(uuid_calc);
return NULL;
}
g_hash_table_insert(crm_uuid_cache, crm_strdup(uname), uuid_calc);
uuid_calc = g_hash_table_lookup(crm_uuid_cache, uname);
return uuid_calc;
}
const char *
get_uname(ll_cluster_t *hb, const char *uuid)
{
char *uname = NULL;
if(crm_uuid_cache == NULL) {
crm_uname_cache = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
}
CRM_CHECK(uuid != NULL, return NULL);
/* avoid blocking calls where possible */
uname = g_hash_table_lookup(crm_uname_cache, uuid);
if(uname != NULL) {
return uname;
}
if(uuid != NULL) {
cl_uuid_t uuid_raw;
char *uuid_copy = crm_strdup(uuid);
cl_uuid_parse(uuid_copy, &uuid_raw);
if(hb->llc_ops->get_name_by_uuid(
hb, &uuid_raw, uname, 256) == HA_FAIL) {
crm_err("Could not calculate UUID for %s", uname);
uname = NULL;
crm_free(uuid_copy);
} else {
g_hash_table_insert(
crm_uuid_cache,
uuid_copy, crm_strdup(uname));
uname = g_hash_table_lookup(crm_uname_cache, uuid);
}
return uname;
}
return NULL;
}
void
set_uuid(ll_cluster_t *hb,crm_data_t *node,const char *attr,const char *uname)
{
const char *uuid_calc = get_uuid(hb, uname);
crm_xml_add(node, attr, uuid_calc);
return;
}
-void
-crm_set_ha_options(ll_cluster_t *hb_cluster)
-{
-#if 0
- int facility;
- char *param_val = NULL;
- const char *param_name = NULL;
-
- if(hb_cluster == NULL) {
- crm_set_env_options();
- return;
- }
-
- /* change the logging facility to the one used by heartbeat daemon */
- crm_debug("Switching to Heartbeat logger");
- if (( facility =
- hb_cluster->llc_ops->get_logfacility(hb_cluster)) > 0) {
- cl_log_set_facility(facility);
- }
- crm_debug_2("Facility: %d", facility);
-
- param_name = KEY_LOGFILE;
- param_val = hb_cluster->llc_ops->get_parameter(hb_cluster, param_name);
- crm_debug_3("%s = %s", param_name, param_val);
- if(param_val != NULL) {
- cl_log_set_logfile(param_val);
- cl_free(param_val);
- param_val = NULL;
- }
-
- param_name = KEY_DBGFILE;
- param_val = hb_cluster->llc_ops->get_parameter(hb_cluster, param_name);
- crm_debug_3("%s = %s", param_name, param_val);
- if(param_val != NULL) {
- cl_log_set_debugfile(param_val);
- cl_free(param_val);
- param_val = NULL;
- }
-
- param_name = KEY_DEBUGLEVEL;
- param_val = hb_cluster->llc_ops->get_parameter(hb_cluster, param_name);
- crm_debug_3("%s = %s", param_name, param_val);
- if(param_val != NULL) {
- int debug_level = crm_parse_int(param_val, NULL);
- if(debug_level > 0 && (debug_level+LOG_INFO) > (int)crm_log_level) {
- set_crm_log_level(LOG_INFO + debug_level);
- }
- cl_free(param_val);
- param_val = NULL;
- }
-
- param_name = KEY_LOGDAEMON;
- param_val = hb_cluster->llc_ops->get_parameter(hb_cluster, param_name);
- crm_debug_3("%s = %s", param_name, param_val);
- if(param_val != NULL) {
- int uselogd;
- cl_str_to_boolean(param_val, &uselogd);
- cl_log_set_uselogd(uselogd);
- if(cl_log_get_uselogd()) {
- cl_set_logging_wqueue_maxlen(500);
- }
- cl_free(param_val);
- param_val = NULL;
- }
-
- param_name = KEY_CONNINTVAL;
- param_val = hb_cluster->llc_ops->get_parameter(hb_cluster, param_name);
- crm_debug_3("%s = %s", param_name, param_val);
- if(param_val != NULL) {
- int logdtime;
- logdtime = crm_get_msec(param_val);
- cl_log_set_logdtime(logdtime);
- cl_free(param_val);
- param_val = NULL;
- }
-#endif
-}
-
-
#define ENV_PREFIX "HA_"
void
crm_set_env_options(void)
{
char *param_val = NULL;
const char *param_name = NULL;
/* apparently we're not allowed to free the result of getenv */
param_name = ENV_PREFIX "" KEY_DEBUGLEVEL;
param_val = getenv(param_name);
if(param_val != NULL) {
int debug_level = crm_parse_int(param_val, NULL);
if(debug_level > 0 && (debug_level+LOG_INFO) > (int)crm_log_level) {
set_crm_log_level(LOG_INFO + debug_level);
}
crm_debug("%s = %s", param_name, param_val);
param_val = NULL;
}
param_name = ENV_PREFIX "" KEY_FACILITY;
param_val = getenv(param_name);
crm_debug("%s = %s", param_name, param_val);
if(param_val != NULL) {
int facility = cl_syslogfac_str2int(param_val);
if(facility > 0) {
cl_log_set_facility(facility);
}
param_val = NULL;
}
param_name = ENV_PREFIX "" KEY_LOGFILE;
param_val = getenv(param_name);
crm_debug("%s = %s", param_name, param_val);
if(param_val != NULL) {
if(safe_str_eq("/dev/null", param_val)) {
param_val = NULL;
}
cl_log_set_logfile(param_val);
param_val = NULL;
}
param_name = ENV_PREFIX "" KEY_DBGFILE;
param_val = getenv(param_name);
crm_debug("%s = %s", param_name, param_val);
if(param_val != NULL) {
if(safe_str_eq("/dev/null", param_val)) {
param_val = NULL;
}
cl_log_set_debugfile(param_val);
param_val = NULL;
}
param_name = ENV_PREFIX "" KEY_LOGDAEMON;
param_val = getenv(param_name);
crm_debug("%s = %s", param_name, param_val);
if(param_val != NULL) {
int uselogd;
cl_str_to_boolean(param_val, &uselogd);
cl_log_set_uselogd(uselogd);
if(uselogd) {
cl_set_logging_wqueue_maxlen(500);
cl_log_set_logd_channel_source(NULL, NULL);
}
param_val = NULL;
}
param_name = ENV_PREFIX "" KEY_CONNINTVAL;
param_val = getenv(param_name);
crm_debug("%s = %s", param_name, param_val);
if(param_val != NULL) {
int logdtime;
logdtime = crm_get_msec(param_val);
cl_log_set_logdtime(logdtime);
param_val = NULL;
}
inherit_compress();
}
gboolean
crm_is_true(const char * s)
{
gboolean ret = FALSE;
if(s != NULL) {
cl_str_to_boolean(s, &ret);
}
return ret;
}
int
crm_str_to_boolean(const char * s, int * ret)
{
if(s == NULL) {
return -1;
} else if (strcasecmp(s, "true") == 0
|| strcasecmp(s, "on") == 0
|| strcasecmp(s, "yes") == 0
|| strcasecmp(s, "y") == 0
|| strcasecmp(s, "1") == 0){
*ret = TRUE;
return 1;
} else if (strcasecmp(s, "false") == 0
|| strcasecmp(s, "off") == 0
|| strcasecmp(s, "no") == 0
|| strcasecmp(s, "n") == 0
|| strcasecmp(s, "0") == 0){
*ret = FALSE;
return 1;
}
return -1;
}
#ifndef NUMCHARS
# define NUMCHARS "0123456789."
#endif
#ifndef WHITESPACE
# define WHITESPACE " \t\n\r\f"
#endif
long
crm_get_msec(const char * input)
{
const char * cp = input;
const char * units;
long multiplier = 1000;
long divisor = 1;
long ret = -1;
double dret;
if(input == NULL) {
return 0;
}
cp += strspn(cp, WHITESPACE);
units = cp + strspn(cp, NUMCHARS);
units += strspn(units, WHITESPACE);
if (strchr(NUMCHARS, *cp) == NULL) {
return ret;
}
if (strncasecmp(units, "ms", 2) == 0
|| strncasecmp(units, "msec", 4) == 0) {
multiplier = 1;
divisor = 1;
}else if (strncasecmp(units, "us", 2) == 0
|| strncasecmp(units, "usec", 4) == 0) {
multiplier = 1;
divisor = 1000;
}else if (strncasecmp(units, "s", 1) == 0
|| strncasecmp(units, "sec", 3) == 0) {
multiplier = 1000;
divisor = 1;
}else if (strncasecmp(units, "m", 1) == 0
|| strncasecmp(units, "min", 3) == 0) {
multiplier = 60*1000;
divisor = 1;
}else if (*units != EOS && *units != '\n'
&& *units != '\r') {
return ret;
}
dret = atof(cp);
dret *= (double)multiplier;
dret /= (double)divisor;
dret += 0.5;
ret = (long)dret;
return(ret);
}
gboolean
ccm_have_quorum(oc_ed_t event)
{
if(event==OC_EV_MS_NEW_MEMBERSHIP) {
return TRUE;
}
return FALSE;
}
const char *
ccm_event_name(oc_ed_t event)
{
if(event==OC_EV_MS_NEW_MEMBERSHIP) {
return "NEW MEMBERSHIP";
} else if(event==OC_EV_MS_NOT_PRIMARY) {
return "NOT PRIMARY";
} else if(event==OC_EV_MS_PRIMARY_RESTORED) {
return "PRIMARY RESTORED";
} else if(event==OC_EV_MS_EVICTED) {
return "EVICTED";
} else if(event==OC_EV_MS_INVALID) {
return "INVALID";
}
return "NO QUORUM MEMBERSHIP";
}
const char *
op_status2text(op_status_t status)
{
switch(status) {
case LRM_OP_PENDING:
return "pending";
break;
case LRM_OP_DONE:
return "complete";
break;
case LRM_OP_ERROR:
return "Error";
break;
case LRM_OP_TIMEOUT:
return "Timed Out";
break;
case LRM_OP_NOTSUPPORTED:
return "NOT SUPPORTED";
break;
case LRM_OP_CANCELLED:
return "Cancelled";
break;
}
CRM_CHECK(status >= LRM_OP_PENDING && status <= LRM_OP_CANCELLED,
crm_err("Unknown status: %d", status));
return "UNKNOWN!";
}
char *
generate_op_key(const char *rsc_id, const char *op_type, int interval)
{
int len = 35;
char *op_id = NULL;
CRM_CHECK(rsc_id != NULL, return NULL);
CRM_CHECK(op_type != NULL, return NULL);
len += strlen(op_type);
len += strlen(rsc_id);
crm_malloc0(op_id, sizeof(char)*len);
CRM_CHECK(op_id != NULL, return NULL);
sprintf(op_id, "%s_%s_%d", rsc_id, op_type, interval);
return op_id;
}
char *
generate_notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
{
int len = 12;
char *op_id = NULL;
CRM_CHECK(rsc_id != NULL, return NULL);
CRM_CHECK(op_type != NULL, return NULL);
CRM_CHECK(notify_type != NULL, return NULL);
len += strlen(op_type);
len += strlen(rsc_id);
len += strlen(notify_type);
crm_malloc0(op_id, sizeof(char)*len);
if(op_id != NULL) {
sprintf(op_id, "%s_%s_notify_%s_0", rsc_id, notify_type, op_type);
}
return op_id;
}
char *
generate_transition_magic_v202(const char *transition_key, int op_status)
{
int len = 80;
char *fail_state = NULL;
CRM_CHECK(transition_key != NULL, return NULL);
len += strlen(transition_key);
crm_malloc0(fail_state, sizeof(char)*len);
if(fail_state != NULL) {
snprintf(fail_state, len, "%d:%s", op_status,transition_key);
}
return fail_state;
}
char *
generate_transition_magic(const char *transition_key, int op_status, int op_rc)
{
int len = 80;
char *fail_state = NULL;
CRM_CHECK(transition_key != NULL, return NULL);
len += strlen(transition_key);
crm_malloc0(fail_state, sizeof(char)*len);
if(fail_state != NULL) {
snprintf(fail_state, len, "%d:%d;%s",
op_status, op_rc, transition_key);
}
return fail_state;
}
gboolean
decode_transition_magic(
const char *magic, char **uuid, int *transition_id,
int *op_status, int *op_rc)
{
char *rc = NULL;
char *key = NULL;
char *magic2 = NULL;
char *status = NULL;
if(decodeNVpair(magic, ':', &status, &magic2) == FALSE) {
crm_err("Couldn't find ':' in: %s", magic);
return FALSE;
}
if(decodeNVpair(magic2, ';', &rc, &key) == FALSE) {
crm_err("Couldn't find ';' in: %s", magic2);
return FALSE;
}
CRM_CHECK(decode_transition_key(key, uuid, transition_id), return FALSE);
*op_rc = crm_parse_int(rc, NULL);
*op_status = crm_parse_int(status, NULL);
crm_free(rc);
crm_free(key);
crm_free(magic2);
crm_free(status);
return TRUE;
}
char *
generate_transition_key(int transition_id, const char *node)
{
int len = 40;
char *fail_state = NULL;
CRM_CHECK(node != NULL, return NULL);
len += strlen(node);
crm_malloc0(fail_state, sizeof(char)*len);
if(fail_state != NULL) {
snprintf(fail_state, len, "%d:%s", transition_id, node);
}
return fail_state;
}
gboolean
decode_transition_key(const char *key, char **uuid, int *transition_id)
{
char *transition = NULL;
if(decodeNVpair(key, ':', &transition, uuid) == FALSE) {
crm_err("Couldn't find ':' in: %s", key);
return FALSE;
}
*transition_id = crm_parse_int(transition, NULL);
crm_free(transition);
return TRUE;
}
void
filter_action_parameters(crm_data_t *param_set)
{
const char *attr_filter[] = {
XML_ATTR_ID,
XML_LRM_ATTR_OP_DIGEST,
XML_ATTR_TE_TARGET_RC,
XML_ATTR_LRM_PROBE,
XML_RSC_ATTR_START,
XML_RSC_ATTR_NOTIFY,
XML_RSC_ATTR_UNIQUE,
XML_RSC_ATTR_MANAGED,
XML_ATTR_CRM_VERSION,
XML_RSC_ATTR_PRIORITY,
XML_RSC_ATTR_MULTIPLE,
XML_RSC_ATTR_STICKINESS,
XML_RSC_ATTR_FAIL_STICKINESS,
XML_RSC_ATTR_TARGET_ROLE,
/* ignore clone fields */
XML_RSC_ATTR_INCARNATION,
XML_RSC_ATTR_INCARNATION_MAX,
XML_RSC_ATTR_INCARNATION_NODEMAX,
XML_RSC_ATTR_MASTER_MAX,
XML_RSC_ATTR_MASTER_NODEMAX,
/* ignore master fields */
"crm_role",
/* ignore notify fields */
"notify_stop_resource",
"notify_stop_uname",
"notify_start_resource",
"notify_start_uname",
"notify_active_resource",
"notify_active_uname",
"notify_inactive_resource",
"notify_inactive_uname",
"notify_promote_resource",
"notify_promote_uname",
"notify_demote_resource",
"notify_demote_uname",
"notify_master_resource",
"notify_master_uname",
"notify_slave_resource",
"notify_slave_uname",
};
int lpc = 0;
if(param_set == NULL) {
return;
}
for(lpc = 0; lpc < DIMOF(attr_filter); lpc++) {
xml_remove_prop(param_set, attr_filter[lpc]);
}
}
gboolean
crm_mem_stats(volatile cl_mem_stats_t *mem_stats)
{
volatile cl_mem_stats_t *active_stats = mem_stats;
if(active_stats == NULL) {
active_stats = cl_malloc_getstats();
}
CRM_CHECK(active_stats != NULL, ;);
#ifndef CRM_USE_MALLOC
if(active_stats->numalloc > active_stats->numfree) {
crm_warn("Potential memory leak detected:"
" %lu alloc's vs. %lu free's (%lu)"
" (%lu bytes not freed: req=%lu, alloc'd=%lu)",
active_stats->numalloc, active_stats->numfree,
active_stats->numalloc - active_stats->numfree,
active_stats->nbytes_alloc, active_stats->nbytes_req,
active_stats->mallocbytes);
return TRUE;
} else if(active_stats->numalloc < active_stats->numfree) {
crm_debug("Process shrank: %lu alloc's vs. %lu free's (%lu)",
active_stats->numalloc, active_stats->numfree,
active_stats->numalloc - active_stats->numfree);
}
#endif
return FALSE;
}
void
crm_zero_mem_stats(volatile cl_mem_stats_t *stats)
{
volatile cl_mem_stats_t *active_stats = NULL;
if(stats != NULL) {
cl_malloc_setstats(stats);
}
active_stats = cl_malloc_getstats();
active_stats->numalloc = 0;
active_stats->numfree = 0;
active_stats->numrealloc = 0;
active_stats->nbytes_req = 0;
active_stats->nbytes_alloc = 0;
active_stats->mallocbytes = 0;
active_stats->arena = 0;
}
void
crm_abort(const char *file, const char *function, int line,
const char *assert_condition, gboolean do_fork)
{
int pid = 0;
do_crm_log(LOG_ERR, file, function,
"Triggered %sfatal assert at %s:%d : %s",
do_fork?"non-":"", file, line, assert_condition);
if(do_fork) {
pid=fork();
}
switch(pid) {
case -1:
crm_err("Cannot fork!");
return;
default: /* Parent */
crm_debug("Child %d forked to record assert failure", pid);
return;
case 0: /* Child */
abort();
break;
}
}
char *
generate_series_filename(
const char *directory, const char *series, int sequence, gboolean bzip)
{
int len = 40;
char *filename = NULL;
const char *ext = "raw";
CRM_CHECK(directory != NULL, return NULL);
CRM_CHECK(series != NULL, return NULL);
len += strlen(directory);
len += strlen(series);
crm_malloc0(filename, sizeof(char)*len);
CRM_CHECK(filename != NULL, return NULL);
if(bzip) {
ext = "bz2";
}
sprintf(filename, "%s/%s-%d.%s", directory, series, sequence, ext);
return filename;
}
int
get_last_sequence(const char *directory, const char *series)
{
FILE *file_strm = NULL;
int start = 0, length = 0, read_len = 0;
char *series_file = NULL;
char *buffer = NULL;
int seq = 0;
int len = 36;
CRM_CHECK(directory != NULL, return 0);
CRM_CHECK(series != NULL, return 0);
len += strlen(directory);
len += strlen(series);
crm_malloc0(series_file, sizeof(char)*len);
CRM_CHECK(series_file != NULL, return 0);
sprintf(series_file, "%s/%s.last", directory, series);
file_strm = fopen(series_file, "r");
if(file_strm == NULL) {
crm_debug("%s does not exist", series_file);
crm_free(series_file);
return 0;
}
/* see how big the file is */
start = ftell(file_strm);
fseek(file_strm, 0L, SEEK_END);
length = ftell(file_strm);
fseek(file_strm, 0L, start);
CRM_ASSERT(start == ftell(file_strm));
crm_debug_3("Reading %d bytes from file", length);
crm_malloc0(buffer, sizeof(char) * (length+1));
read_len = fread(buffer, sizeof(char), length, file_strm);
if(read_len != length) {
crm_err("Calculated and read bytes differ: %d vs. %d",
length, read_len);
crm_free(buffer);
buffer = NULL;
} else if(length <= 0) {
crm_info("%s was not valid", series_file);
crm_free(buffer);
buffer = NULL;
}
crm_free(series_file);
seq = crm_parse_int(buffer, "0");
crm_free(buffer);
fclose(file_strm);
return seq;
}
void
write_last_sequence(
const char *directory, const char *series, int sequence, int max)
{
int rc = 0;
int len = 36;
char *buffer = NULL;
FILE *file_strm = NULL;
char *series_file = NULL;
CRM_CHECK(directory != NULL, return);
CRM_CHECK(series != NULL, return);
if(max == 0) {
return;
}
while(max > 0 && sequence > max) {
sequence -= max;
}
buffer = crm_itoa(sequence);
len += strlen(directory);
len += strlen(series);
crm_malloc0(series_file, sizeof(char)*len);
CRM_CHECK(series_file != NULL, return);
sprintf(series_file, "%s/%s.last", directory, series);
file_strm = fopen(series_file, "w");
if(file_strm == NULL) {
crm_err("%s does not exist", series_file);
crm_free(series_file);
return;
}
rc = fprintf(file_strm, "%s", buffer);
if(rc < 0) {
cl_perror("Cannot write output to %s", series_file);
}
fflush(file_strm);
fclose(file_strm);
crm_free(series_file);
crm_free(buffer);
}
void
crm_make_daemon(const char *name, gboolean daemonize, const char *pidfile)
{
long pid;
const char *devnull = "/dev/null";
if(daemonize == FALSE) {
return;
}
pid = fork();
if (pid < 0) {
fprintf(stderr, "%s: could not start daemon\n", name);
cl_perror("fork");
exit(LSB_EXIT_GENERIC);
} else if (pid > 0) {
exit(LSB_EXIT_OK);
}
if (cl_lock_pidfile(pidfile) < 0 ) {
pid = cl_read_pidfile_no_checking(pidfile);
crm_warn("%s: already running [pid %ld] (%s).\n",
name, pid, pidfile);
exit(LSB_EXIT_OK);
}
umask(022);
close(FD_STDIN);
(void)open(devnull, O_RDONLY); /* Stdin: fd 0 */
close(FD_STDOUT);
(void)open(devnull, O_WRONLY); /* Stdout: fd 1 */
close(FD_STDERR);
(void)open(devnull, O_WRONLY); /* Stderr: fd 2 */
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Jan 25, 11:32 AM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1320472
Default Alt Text
(71 KB)

Event Timeline