Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4624308
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
34 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:13 PM (17 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2002529
Default Alt Text
(34 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment