Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/crm/crmd/cib.c b/crm/crmd/cib.c
index 8f9d4c7e6c..c0233be0af 100644
--- a/crm/crmd/cib.c
+++ b/crm/crmd/cib.c
@@ -1,281 +1,281 @@
/*
* 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 <sys/param.h>
#include <crm/crm.h>
#include <crmd_fsa.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h> /* for access */
#include <clplumbing/cl_signal.h>
#include <clplumbing/realtime.h>
#include <sys/types.h> /* for calls to open */
#include <sys/stat.h> /* for calls to open */
#include <fcntl.h> /* for calls to open */
#include <pwd.h> /* for getpwuid */
#include <grp.h> /* for initgroups */
#include <sys/time.h> /* for getrlimit */
#include <sys/resource.h>/* for getrlimit */
#include <errno.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
#include <crmd_messages.h>
#include <crmd_callbacks.h>
#include <crm/cib.h>
#include <crmd.h>
#include <crm/dmalloc_wrapper.h>
struct crm_subsystem_s *cib_subsystem = NULL;
/* A_CIB_STOP, A_CIB_START, A_CIB_RESTART, */
enum crmd_fsa_input
do_cib_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)
{
enum crmd_fsa_input result = I_NULL;
struct crm_subsystem_s *this_subsys = cib_subsystem;
long long stop_actions = A_CIB_STOP;
long long start_actions = A_CIB_START;
if(action & stop_actions) {
/* dont do anything, its embedded now */
}
if(action & start_actions) {
if(cur_state != S_STOPPING) {
if(startCib(CIB_FILENAME) == FALSE)
result = I_FAIL;
} else {
crm_info("Ignoring request to start %s after shutdown",
- this_subsys->command);
+ this_subsys->name);
}
}
return result;
}
/* A_CIB_INVOKE, A_CIB_BUMPGEN, A_UPDATE_NODESTATUS */
enum crmd_fsa_input
do_cib_invoke(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)
{
xmlNodePtr cib_msg = NULL;
xmlNodePtr answer = NULL;
xmlNodePtr new_options = NULL;
const char *section = NULL;
enum crmd_fsa_input result = I_NULL;
if(msg_data->data != NULL) {
cib_msg = (xmlNodePtr)msg_data->data;
}
if(action & A_CIB_INVOKE || action & A_CIB_INVOKE_LOCAL) {
/* gboolean is_update = FALSE; */
xmlNodePtr msg_copy = copy_xml_node_recursive(cib_msg);
xmlNodePtr options = find_xml_node(msg_copy, XML_TAG_OPTIONS);
const char *sys_from = xmlGetProp(msg_copy, XML_ATTR_SYSFROM);
const char *host_from= xmlGetProp(msg_copy, XML_ATTR_HOSTFROM);
const char *type = xmlGetProp(options, XML_ATTR_MSGTYPE);
const char *op = xmlGetProp(options, XML_ATTR_OP);
crm_xml_devel(msg_copy, "[CIB update]");
if(cib_msg == NULL) {
crm_err("No message for CIB command");
return I_NULL; /* I_ERROR */
} else if(op == NULL) {
crm_xml_devel(msg_copy, "Invalid CIB Message");
return I_NULL; /* I_ERROR */
}
if(AM_I_DC
&& safe_str_eq(op, CRM_OP_RETRIVE_CIB)
&& safe_str_eq(type, XML_ATTR_RESPONSE)) {
/* we actually need to process this as a REPLACE,
* not pretty, but fake the op type...
*/
crm_debug("Mapping %s reply to a %s request",
CRM_OP_RETRIVE_CIB, CRM_OP_REPLACE);
set_xml_property_copy(
options, XML_ATTR_OP, CRM_OP_REPLACE);
crm_xml_devel(msg_copy, "[CIB revised update]");
} else if(safe_str_eq(op, CRM_OP_RETRIVE_CIB)) {
crm_debug("is dc? %d, type=%s", AM_I_DC, type);
}
set_xml_property_copy(msg_copy, XML_ATTR_SYSTO, "cib");
answer = process_cib_message(msg_copy, TRUE);
if(action & A_CIB_INVOKE) {
if(AM_I_DC == FALSE) {
if(relay_message(answer, TRUE) == FALSE) {
crm_err("Confused what to do with cib result");
crm_xml_devel(answer, "Couldnt route: ");
result = I_ERROR;
}
} else if(strcmp(op, CRM_OP_CREATE) == 0
|| strcmp(op, CRM_OP_UPDATE) == 0
|| strcmp(op, CRM_OP_DELETE) == 0
|| strcmp(op, CRM_OP_REPLACE) == 0
|| strcmp(op, CRM_OP_RETRIVE_CIB) == 0
|| strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) {
register_fsa_input(
C_IPC_MESSAGE, I_CIB_UPDATE, cib_msg);
} else if(strcmp(op, CRM_OP_RETRIVE_CIB) == 0) {
crm_info("Retrieved latest CIB from %s",
host_from);
set_bit_inplace(fsa_input_register,R_HAVE_CIB);
} else if(strcmp(op, CRM_OP_ERASE) == 0) {
/* regenerate everyone's state and our node entry */
register_fsa_input(
C_UNKNOWN, I_ELECTION_DC, NULL);
}
/* the TENGINE will get CC'd by other means. */
if(AM_I_DC
&& sys_from != NULL
&& safe_str_neq(sys_from, CRM_SYSTEM_TENGINE)
&& safe_str_neq(sys_from, CRM_SYSTEM_CRMD)
&& safe_str_neq(sys_from, CRM_SYSTEM_DC)
&& relay_message(answer, TRUE) == FALSE) {
crm_err("Confused what to do with cib result");
crm_xml_devel(answer, "Couldnt route: ");
result = I_ERROR;
}
/* } else { */
/* put_message(answer); */
/* return I_REQUEST; */
}
return result;
} else if(action & A_CIB_BUMPGEN) {
/* xmlNodePtr options = find_xml_node(cib_msg, XML_TAG_OPTIONS); */
/* const char *op = xmlGetProp(options, XML_ATTR_OP); */
if(AM_I_DC == FALSE) {
return I_NULL;
}
/* check if the response was ok before next bit */
/* if(safe_str_neq(op, CRM_OP_WELCOME)) { */
/* set the section so that we dont always send the
* whole thing
*/
section = get_xml_attr(
cib_msg, XML_TAG_OPTIONS,
XML_ATTR_FILTER_TYPE, FALSE);
/* } */
if(section != NULL) {
new_options = set_xml_attr(
NULL, XML_TAG_OPTIONS, XML_ATTR_FILTER_TYPE,
section, TRUE);
}
answer = process_cib_request(
CRM_OP_BUMP, new_options, NULL);
free_xml(new_options);
if(answer == NULL) {
crm_err("Result of BUMP in %s was NULL",
__FUNCTION__);
return I_FAIL;
}
send_request(NULL, answer, CRM_OP_REPLACE,
NULL, CRM_SYSTEM_CRMD, NULL);
free_xml(answer);
} else {
crm_err("Unexpected action %s in %s",
fsa_action2string(action), __FUNCTION__);
}
return I_NULL;
}
enum crmd_fsa_input
invoke_local_cib(xmlNodePtr msg_options,
xmlNodePtr msg_data,
const char *operation)
{
enum crmd_fsa_input result = I_NULL;
xmlNodePtr request = NULL;
fsa_data_t *fsa_data = NULL;
msg_options = set_xml_attr(msg_options, XML_TAG_OPTIONS,
XML_ATTR_OP, operation, TRUE);
request = create_request(msg_options,
msg_data,
NULL,
CRM_SYSTEM_CIB,
AM_I_DC?CRM_SYSTEM_DC:CRM_SYSTEM_CRMD,
NULL,
NULL);
crm_malloc(fsa_data, sizeof(fsa_data_t));
fsa_data->fsa_input = I_CIB_UPDATE;
fsa_data->fsa_cause = C_IPC_MESSAGE;
fsa_data->data = request;
result = do_cib_invoke(
A_CIB_INVOKE_LOCAL, C_FSA_INTERNAL, fsa_state,
I_CIB_OP, fsa_data);
crm_free(fsa_data);
free_xml(request);
return I_NULL;
}
diff --git a/crm/crmd/control.c b/crm/crmd/control.c
index eb0f425a2a..0174e99032 100644
--- a/crm/crmd/control.c
+++ b/crm/crmd/control.c
@@ -1,623 +1,631 @@
/*
* 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 <sys/param.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);
void crm_shutdown(int nsig);
IPC_WaitConnection *wait_channel_init(char daemonsocket[]);
gboolean register_with_ha(ll_cluster_t *hb_cluster, const char *client_name);
int init_server_ipc_comms(
const char *child,
gboolean (*channel_client_connect)(
IPC_Channel *newclient, gpointer user_data),
void (*channel_connection_destroy)(gpointer user_data));
GHashTable *ipc_clients = 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) {
fsa_cluster_conn->llc_ops->signoff(fsa_cluster_conn);
}
}
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);
registered = register_with_ha(
fsa_cluster_conn, crm_system_name);
if(registered == FALSE) {
return I_FAIL;
}
}
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)
{
enum crmd_fsa_input next_input = I_NULL;
enum crmd_fsa_input tmp = I_NULL;
/* just in case */
set_bit_inplace(fsa_input_register, R_SHUTDOWN);
/* last attempt to shut these down */
if(is_set(fsa_input_register, R_PE_CONNECTED)) {
crm_warn("Last attempt to shutdown the PolicyEngine");
tmp = do_pe_control(A_PE_STOP, cause, cur_state,
current_input, msg_data);
if(tmp != I_NULL) {
next_input = I_ERROR;
crm_err("Failed to shutdown the PolicyEngine");
}
}
if(is_set(fsa_input_register, R_TE_CONNECTED)) {
crm_warn("Last attempt to shutdown the Transitioner");
tmp = do_pe_control(A_TE_STOP, cause, cur_state,
current_input, msg_data);
if(tmp != I_NULL) {
next_input = I_ERROR;
crm_err("Failed to shutdown the Transitioner");
}
}
crm_info("Stopping all remaining local resources");
stop_all_resources();
return next_input;
}
/* 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)
{
enum crmd_fsa_input next_input = I_NULL;
if(send_request(NULL, NULL, CRM_OP_SHUTDOWN_REQ,
NULL, CRM_SYSTEM_DC, NULL) == FALSE){
next_input = I_ERROR;
}
return next_input;
}
/* 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)
{
if(action & A_EXIT_0) {
crm_info("Performing %s - gracefully exiting the CRMd\n",
fsa_action2string(action));
g_main_quit(crmd_mainloop);
} else {
crm_warn("Performing %s - forcefully exiting the CRMd\n",
fsa_action2string(action));
exit(1);
}
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_info("Register PID");
register_pid(PID_FILE, FALSE, crm_shutdown);
- /* Async get client status information in the cluster */
- fsa_cluster_conn->llc_ops->client_status(
- fsa_cluster_conn, NULL, CRM_SYSTEM_CRMD, -1);
-
ipc_clients = g_hash_table_new(&g_str_hash, &g_str_equal);
if(was_error == 0) {
crm_info("Init server comms");
was_error = init_server_ipc_comms(
CRM_SYSTEM_CRMD, crmd_client_connect,
default_ipc_connection_destroy);
}
/* set up the timers */
crm_malloc(dc_heartbeat, sizeof(fsa_timer_t));
crm_malloc(integration_timer, sizeof(fsa_timer_t));
crm_malloc(finalization_timer, sizeof(fsa_timer_t));
crm_malloc(election_trigger, sizeof(fsa_timer_t));
crm_malloc(election_timeout, sizeof(fsa_timer_t));
crm_malloc(shutdown_escalation_timer, sizeof(fsa_timer_t));
crm_malloc(wait_timer, sizeof(fsa_timer_t));
interval = interval * 1000;
if(election_trigger != NULL) {
election_trigger->source_id = -1;
election_trigger->period_ms = -1;
election_trigger->fsa_input = I_DC_TIMEOUT;
election_trigger->callback = timer_popped;
} else {
was_error = TRUE;
}
if(dc_heartbeat != NULL) {
dc_heartbeat->source_id = -1;
dc_heartbeat->period_ms = -1;
dc_heartbeat->fsa_input = I_NULL;
dc_heartbeat->callback = do_dc_heartbeat;
} else {
was_error = TRUE;
}
if(election_timeout != NULL) {
election_timeout->source_id = -1;
election_timeout->period_ms = -1;
election_timeout->fsa_input = I_ELECTION_DC;
election_timeout->callback = timer_popped;
} else {
was_error = TRUE;
}
if(integration_timer != NULL) {
integration_timer->source_id = -1;
integration_timer->period_ms = -1;
integration_timer->fsa_input = I_INTEGRATED;
integration_timer->callback = timer_popped;
} else {
was_error = TRUE;
}
if(finalization_timer != NULL) {
finalization_timer->source_id = -1;
finalization_timer->period_ms = -1;
finalization_timer->fsa_input = I_FINALIZED;
finalization_timer->callback = timer_popped;
} else {
was_error = TRUE;
}
if(shutdown_escalation_timer != NULL) {
shutdown_escalation_timer->source_id = -1;
shutdown_escalation_timer->period_ms = -1;
shutdown_escalation_timer->fsa_input = I_TERMINATE;
shutdown_escalation_timer->callback = timer_popped;
} else {
was_error = TRUE;
}
if(wait_timer != NULL) {
wait_timer->source_id = -1;
wait_timer->period_ms = 3*1000;
wait_timer->fsa_input = I_NULL;
wait_timer->callback = timer_popped;
} else {
was_error = TRUE;
}
/* set up the sub systems */
crm_malloc(cib_subsystem, sizeof(struct crm_subsystem_s));
crm_malloc(te_subsystem, sizeof(struct crm_subsystem_s));
crm_malloc(pe_subsystem, sizeof(struct crm_subsystem_s));
if(cib_subsystem != NULL) {
- cib_subsystem->pid = 0;
- cib_subsystem->path = crm_strdup(BIN_DIR);
- cib_subsystem->name = crm_strdup(CRM_SYSTEM_CIB);
- cib_subsystem->command = BIN_DIR"/cib";
- cib_subsystem->flag = R_CIB_CONNECTED;
+ cib_subsystem->pid = -1;
+ cib_subsystem->flag = R_CIB_CONNECTED;
+ cib_subsystem->path = BIN_DIR;
+ cib_subsystem->name = CRM_SYSTEM_CIB;
+ cib_subsystem->command = BIN_DIR"/"CRM_SYSTEM_CIB;
+ cib_subsystem->args = "-VVc";
+
} else {
was_error = TRUE;
}
if(te_subsystem != NULL) {
- te_subsystem->pid = 0;
- te_subsystem->path = crm_strdup(BIN_DIR);
- te_subsystem->name = crm_strdup(CRM_SYSTEM_TENGINE);
- te_subsystem->command = BIN_DIR"/tengine";
- te_subsystem->flag = R_TE_CONNECTED;
+ te_subsystem->pid = -1;
+ te_subsystem->flag = R_TE_CONNECTED;
+ te_subsystem->path = BIN_DIR;
+ te_subsystem->name = CRM_SYSTEM_TENGINE;
+ te_subsystem->command = BIN_DIR"/"CRM_SYSTEM_TENGINE;
+ te_subsystem->args = "-VVc";
+
} else {
was_error = TRUE;
}
if(pe_subsystem != NULL) {
- pe_subsystem->pid = 0;
- pe_subsystem->path = crm_strdup(BIN_DIR);
- pe_subsystem->name = crm_strdup(CRM_SYSTEM_PENGINE);
- pe_subsystem->command = BIN_DIR"/pengine";
- pe_subsystem->flag = R_PE_CONNECTED;
+ pe_subsystem->pid = -1;
+ pe_subsystem->flag = R_PE_CONNECTED;
+ pe_subsystem->path = BIN_DIR;
+ pe_subsystem->name = CRM_SYSTEM_PENGINE;
+ pe_subsystem->command = BIN_DIR"/"CRM_SYSTEM_PENGINE;
+ pe_subsystem->args = "-VVc";
+
} else {
was_error = TRUE;
}
if(was_error)
return I_FAIL;
return I_NULL;
}
/* 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)
{
/* nothing to do yet */
/* todo: shut down any remaining CRM resources */
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
/* || is_set(fsa_input_register, R_PE_CONNECTED) == FALSE */
/* || is_set(fsa_input_register, R_TE_CONNECTED) == FALSE */
|| is_set(fsa_input_register, R_LRM_CONNECTED) == FALSE
) {
crm_info("Delaying start, some systems not connected %.16llx (%.16llx)",
fsa_input_register, (long long)R_CCM_DATA|R_LRM_CONNECTED);
crmd_fsa_stall();
return I_NULL;
} else if(is_set(fsa_input_register, R_PEER_DATA) == FALSE) {
struct ha_msg* msg = NULL;
/* try reading from HA */
crm_info("Delaying start, some systems not connected %.16llx (%.16llx)",
fsa_input_register, (long long)R_PEER_DATA);
crm_debug("Looking for a HA message");
msg = fsa_cluster_conn->llc_ops->readmsg(fsa_cluster_conn, 0);
if(msg != NULL) {
crm_debug("There was a HA message");
ha_msg_del(msg);
}
startTimer(wait_timer);
crmd_fsa_stall();
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)
{
crm_err("Action %s (%.16llx) not supported\n",
fsa_action2string(action), action);
return I_SHUTDOWN;
}
/* 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)
{
xmlNodePtr cib_copy = get_cib_copy();
xmlNodePtr config = get_object_root(XML_CIB_TAG_CRMCONFIG, cib_copy);
xml_child_iter(
config, iter, XML_CIB_TAG_NVPAIR,
const char *name = xmlGetProp(iter, XML_NVPAIR_ATTR_NAME);
const char *value = xmlGetProp(iter, XML_NVPAIR_ATTR_VALUE);
if(name == NULL || value == NULL) {
continue;
} else if(safe_str_eq(name, "dc_heartbeat")) {
dc_heartbeat->period_ms = atoi(value);
} else if(safe_str_eq(name, "dc_deadtime")) {
election_trigger->period_ms = atoi(value);
} else if(safe_str_eq(name, "shutdown_escalation")) {
shutdown_escalation_timer->period_ms = atoi(value);
} else if(safe_str_eq(name, "join_reannouce")) {
fsa_join_reannouce = atoi(value);
}
);
if(dc_heartbeat->period_ms < 1) {
/* sensible default */
dc_heartbeat->period_ms = 1000;
}
if(election_trigger->period_ms < 1) {
/* sensible default */
election_trigger->period_ms = dc_heartbeat->period_ms * 4;
}
if(shutdown_escalation_timer->period_ms < 1) {
/* sensible default */
shutdown_escalation_timer->period_ms
= election_trigger->period_ms * 3 *10;/* 10 for testing */
}
if(fsa_join_reannouce < 0) {
fsa_join_reannouce = 100; /* how many times should we let
* go by before reannoucning
* ourselves to the DC
*/
}
election_timeout->period_ms = dc_heartbeat->period_ms * 6;
integration_timer->period_ms = dc_heartbeat->period_ms * 6;
finalization_timer->period_ms = dc_heartbeat->period_ms * 6;
return I_NULL;
}
void
crm_shutdown(int nsig)
{
CL_SIGNAL(nsig, crm_shutdown);
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(C_SHUTDOWN, I_ERROR, NULL);
s_crmd_fsa(C_SHUTDOWN);
} else {
set_bit_inplace(fsa_input_register, R_SHUTDOWN);
if(is_set(fsa_input_register, R_SHUTDOWN)) {
/* cant rely on this... */
startTimer(shutdown_escalation_timer);
register_fsa_input(C_SHUTDOWN, I_SHUTDOWN, NULL);
s_crmd_fsa(C_SHUTDOWN);
} else {
crm_err("Could not set R_SHUTDOWN");
exit(LSB_EXIT_ENOTSUPPORTED);
}
}
} else {
crm_info("exit from shutdown");
exit(LSB_EXIT_OK);
}
return;
}
IPC_WaitConnection *
wait_channel_init(char daemonsocket[])
{
IPC_WaitConnection *wait_ch;
mode_t mask;
char path[] = IPC_PATH_ATTR;
GHashTable * attrs;
attrs = g_hash_table_new(g_str_hash,g_str_equal);
g_hash_table_insert(attrs, path, daemonsocket);
mask = umask(0);
wait_ch = ipc_wait_conn_constructor(IPC_ANYTYPE, attrs);
if (wait_ch == NULL) {
cl_perror("Can't create wait channel of type %s",
IPC_ANYTYPE);
exit(1);
}
mask = umask(mask);
g_hash_table_destroy(attrs);
return wait_ch;
}
int
init_server_ipc_comms(
const char *child,
gboolean (*channel_client_connect)(IPC_Channel *newclient,gpointer user_data),
void (*channel_connection_destroy)(gpointer user_data))
{
/* the clients wait channel is the other source of events.
* This source delivers the clients connection events.
* listen to this source at a relatively lower priority.
*/
char commpath[SOCKET_LEN];
IPC_WaitConnection *wait_ch;
sprintf(commpath, WORKING_DIR "/%s", child);
wait_ch = wait_channel_init(commpath);
if (wait_ch == NULL) {
return 1;
}
G_main_add_IPC_WaitConnection(
G_PRIORITY_LOW, wait_ch, NULL, FALSE,
channel_client_connect, wait_ch, channel_connection_destroy);
crm_debug("Listening on: %s", commpath);
return 0;
}
#define safe_val3(def, t,u,v) (t?t->u?t->u->v:def:def)
gboolean
register_with_ha(ll_cluster_t *hb_cluster, const char *client_name)
{
int facility;
if(safe_val3(NULL, hb_cluster, llc_ops, errmsg) == NULL) {
crm_crit("cluster errmsg function unavailable");
}
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;
}
/* change the logging facility to the one used by heartbeat daemon */
crm_info("Switching to Heartbeat logger");
if (( facility =
hb_cluster->llc_ops->get_logfacility(hb_cluster)) > 0) {
cl_log_set_facility(facility);
}
crm_verbose("Facility: %d", facility);
crm_debug("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("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("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\n",
hb_cluster->llc_ops->errmsg(hb_cluster));
return FALSE;
}
crm_debug("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("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("FSA Hostname: %s", fsa_our_uname);
+ /* Async get client status information in the cluster */
+ crm_debug("Requesting an initial dump of CRMD client_status");
+ fsa_cluster_conn->llc_ops->client_status(
+ fsa_cluster_conn, NULL, CRM_SYSTEM_CRMD, -1);
+
+
return TRUE;
}
diff --git a/crm/crmd/crmd_fsa.h b/crm/crmd/crmd_fsa.h
index 30171f1c9c..c522f4ad60 100644
--- a/crm/crmd/crmd_fsa.h
+++ b/crm/crmd/crmd_fsa.h
@@ -1,126 +1,127 @@
-/* $Id: crmd_fsa.h,v 1.31 2004/10/12 21:05:53 andrew Exp $ */
+/* $Id: crmd_fsa.h,v 1.32 2004/11/24 15:37:44 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 CRMD_FSA__H
#define CRMD_FSA__H
#include <fsa_defines.h>
#include <ocf/oc_event.h>
#include <clplumbing/ipc.h>
#include <hb_api.h>
#include <libxml/tree.h>
#include <lrm/lrm_api.h>
#include <crm/crm.h>
struct crmd_ccm_data_s
{
oc_ev_membership_t *oc;
oc_ed_t *event;
};
struct oc_node_list_s
{
int members_size;
GHashTable *members; /* contents: oc_node_t * */
int new_members_size;
GHashTable *new_members; /* contents: oc_node_t * */
int dead_members_size;
GHashTable *dead_members; /* contents: oc_node_t * */
};
typedef struct oc_node_list_s oc_node_list_t;
/* copy from struct client_child in heartbeat.h
*
* Plus a couple of other things
*/
struct crm_subsystem_s {
- pid_t pid; /* Process id of child process */
- const char* command; /* What command to run? */
- const char* path; /* Path (argv[0])? */
-/* extras */
- const char* name;
- IPC_Channel *ipc; /* How can we communicate with it */
- long long flag; /* */
+ pid_t pid; /* Process id of child process */
+ const char* name; /* executable name */
+ const char* path; /* Command location */
+ const char* command; /* Command with path */
+ const char* args; /* Command arguments */
+
+ IPC_Channel *ipc; /* How can we communicate with it */
+ long long flag; /* */
};
typedef struct fsa_timer_s fsa_timer_t;
struct fsa_timer_s
{
guint source_id; /* timer source id */
int period_ms; /* timer period */
enum crmd_fsa_input fsa_input;
gboolean (*callback)(gpointer data);
};
typedef struct fsa_data_s fsa_data_t;
struct fsa_data_s
{
int id;
enum crmd_fsa_input fsa_input;
enum crmd_fsa_cause fsa_cause;
long long actions;
const char *where;
void *data;
};
extern enum crmd_fsa_state s_crmd_fsa(enum crmd_fsa_cause cause);
/* Global FSA stuff */
extern volatile gboolean do_fsa_stall;
extern volatile enum crmd_fsa_state fsa_state;
extern oc_node_list_t *fsa_membership_copy;
extern ll_cluster_t *fsa_cluster_conn;
extern ll_lrm_t *fsa_lrm_conn;
extern volatile long long fsa_input_register;
extern volatile long long fsa_actions;
extern const char *fsa_our_uname;
extern char *fsa_pe_ref; /* the last invocation of the PE */
extern char *fsa_our_dc;
extern GListPtr fsa_message_queue;
extern fsa_timer_t *election_trigger; /* */
extern fsa_timer_t *election_timeout; /* */
extern fsa_timer_t *shutdown_escalation_timer; /* */
extern fsa_timer_t *dc_heartbeat;
extern fsa_timer_t *integration_timer;
extern fsa_timer_t *finalization_timer;
extern fsa_timer_t *wait_timer;
extern int fsa_join_reannouce;
extern struct crm_subsystem_s *cib_subsystem;
extern struct crm_subsystem_s *te_subsystem;
extern struct crm_subsystem_s *pe_subsystem;
/* these two should be moved elsewhere... */
extern xmlNodePtr do_update_cib_nodes(xmlNodePtr updates, gboolean overwrite);
extern gboolean do_dc_heartbeat(gpointer data);
#define AM_I_DC is_set(fsa_input_register, R_THE_DC)
#define AM_I_OPERATIONAL (is_set(fsa_input_register, R_STARTING)==FALSE)
#include <fsa_proto.h>
#include <crmd_utils.h>
#endif
diff --git a/crm/crmd/subsystems.c b/crm/crmd/subsystems.c
index a52ac6ba05..ce95cca46d 100644
--- a/crm/crmd/subsystems.c
+++ b/crm/crmd/subsystems.c
@@ -1,174 +1,182 @@
/*
* 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 <sys/param.h>
#include <crm/crm.h>
#include <crmd_fsa.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h> /* for access */
#include <clplumbing/cl_signal.h>
#include <clplumbing/realtime.h>
#include <sys/types.h> /* for calls to open */
#include <sys/stat.h> /* for calls to open */
#include <fcntl.h> /* for calls to open */
#include <pwd.h> /* for getpwuid */
#include <grp.h> /* for initgroups */
#include <sys/time.h> /* for getrlimit */
#include <sys/resource.h>/* for getrlimit */
#include <errno.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
#include <crmd_messages.h>
#include <crmd_callbacks.h>
#include <crm/cib.h>
#include <crmd.h>
#include <crm/dmalloc_wrapper.h>
gboolean
stop_subsystem(struct crm_subsystem_s* the_subsystem)
{
crm_info("Stopping sub-system \"%s\"", the_subsystem->name);
if (the_subsystem->pid <= 0) {
- crm_err("Client %s not running yet", the_subsystem->command);
+ crm_err("Client %s not running yet", the_subsystem->name);
} else if(! is_set(fsa_input_register, the_subsystem->flag) ) {
/* running but not yet connected */
crm_warn("Stopping %s before it had connected",
the_subsystem->name);
kill(the_subsystem->pid, -9);
the_subsystem->pid = -1;
} else {
crm_info("Sending quit message to %s.", the_subsystem->name);
send_request(NULL,NULL, CRM_OP_QUIT, NULL,
the_subsystem->name, NULL);
}
return TRUE;
}
gboolean
start_subsystem(struct crm_subsystem_s* the_subsystem)
{
pid_t pid;
struct stat buf;
int s_res;
unsigned int j;
struct rlimit oflimits;
const char *devnull = "/dev/null";
- crm_info("Starting sub-system \"%s\"", the_subsystem->command);
+ crm_info("Starting sub-system \"%s\"", the_subsystem->name);
if (the_subsystem->pid > 0) {
crm_warn("Client %s already running as pid %d",
- the_subsystem->command, (int) the_subsystem->pid);
+ the_subsystem->name, (int) the_subsystem->pid);
/* starting a started X is not an error */
return TRUE;
}
/*
* We want to ensure that the exec will succeed before
* we bother forking.
*/
if (access(the_subsystem->path, F_OK|X_OK) != 0) {
cl_perror("Cannot (access) exec %s", the_subsystem->path);
return FALSE;
}
s_res = stat(the_subsystem->command, &buf);
if(s_res != 0) {
cl_perror("Cannot (stat) exec %s", the_subsystem->command);
return FALSE;
}
/* We need to fork so we can make child procs not real time */
switch(pid=fork()) {
case -1:
crm_err("Cannot fork.");
return FALSE;
default: /* Parent */
the_subsystem->pid = pid;
return TRUE;
case 0: /* Child */
break;
}
- crm_info("Executing \"%s\" (pid %d)",
- the_subsystem->command, (int) getpid());
+ crm_info("Executing \"%s %s\" (pid %d)",
+ the_subsystem->command, the_subsystem->args, (int) getpid());
/* A precautionary measure */
getrlimit(RLIMIT_NOFILE, &oflimits);
for (j=0; j < oflimits.rlim_cur; ++j) {
close(j);
}
(void)open(devnull, O_RDONLY); /* Stdin: fd 0 */
(void)open(devnull, O_WRONLY); /* Stdout: fd 1 */
(void)open(devnull, O_WRONLY); /* Stderr: fd 2 */
- (void)execl("/bin/sh", "sh", "-c", the_subsystem->command,
- (const char *)NULL);
+ {
+ char* const start_args[] = {
+ crm_strdup(the_subsystem->args),
+ NULL
+ };
+
+ (void)execv(the_subsystem->command, start_args);
+ }
/* Should not happen */
- cl_perror("FATAL: Cannot exec %s", the_subsystem->command);
+ cl_perror("FATAL: Cannot exec %s %s",
+ the_subsystem->command, the_subsystem->args);
+
exit(100); /* Suppress respawning */
return TRUE; /* never reached */
}
void
cleanup_subsystem(struct crm_subsystem_s *the_subsystem)
{
int pid_status = -1;
the_subsystem->ipc = NULL;
clear_bit_inplace(fsa_input_register, the_subsystem->flag);
/* Forcing client to die */
kill(the_subsystem->pid, -9);
/* cleanup the ps entry */
waitpid(the_subsystem->pid, &pid_status, WNOHANG);
the_subsystem->pid = -1;
if(is_set(fsa_input_register, R_THE_DC)) {
/* this wasnt supposed to happen */
crm_err("The %s subsystem terminated unexpectedly",
the_subsystem->name);
register_fsa_input(C_IPC_MESSAGE, I_ERROR, NULL);
s_crmd_fsa(C_IPC_MESSAGE);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:13 PM (21 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2002529
Default Alt Text
(34 KB)

Event Timeline