📄 lrm.c
字号:
/* * 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 <errno.h>#include <crm/cib.h>#include <crm/msg_xml.h>#include <crm/common/xml.h>#include <crmd.h>#include <crmd_messages.h>#include <crmd_callbacks.h>#include <lrm/raexec.h>#include <crm/dmalloc_wrapper.h>gboolean stop_all_resources(void);gboolean build_suppported_RAs( crm_data_t *metadata_list, crm_data_t *xml_agent_list);gboolean build_active_RAs(crm_data_t *rsc_list);void do_update_resource(lrm_rsc_t *rsc, lrm_op_t *op);enum crmd_fsa_input do_lrm_rsc_op( lrm_rsc_t *rsc, char *rid, const char *operation, crm_data_t *msg);enum crmd_fsa_input do_fake_lrm_op(gpointer data);GHashTable *xml2list(crm_data_t *parent, const char **attr_path, int depth);GHashTable *monitors = NULL;int num_lrm_register_fails = 0;int max_lrm_register_fails = 30;const char *rsc_path[] = {/* XML_GRAPH_TAG_RSC_OP, */ XML_CIB_TAG_RESOURCE, "instance_attributes", "rsc_parameters"};enum crmd_rscstate { crmd_rscstate_NULL, crmd_rscstate_START, crmd_rscstate_START_PENDING, crmd_rscstate_START_OK, crmd_rscstate_START_FAIL, crmd_rscstate_STOP, crmd_rscstate_STOP_PENDING, crmd_rscstate_STOP_OK, crmd_rscstate_STOP_FAIL, crmd_rscstate_MON, crmd_rscstate_MON_PENDING, crmd_rscstate_MON_OK, crmd_rscstate_MON_FAIL, crmd_rscstate_GENERIC_PENDING, crmd_rscstate_GENERIC_OK, crmd_rscstate_GENERIC_FAIL };void free_lrm_op(lrm_op_t *op);const char *crmd_rscstate2string(enum crmd_rscstate state);const char *crmd_rscstate2string(enum crmd_rscstate state) { switch(state) { case crmd_rscstate_NULL: return NULL; case crmd_rscstate_START: return CRMD_RSCSTATE_START; case crmd_rscstate_START_PENDING: return CRMD_RSCSTATE_START_PENDING; case crmd_rscstate_START_OK: return CRMD_RSCSTATE_START_OK; case crmd_rscstate_START_FAIL: return CRMD_RSCSTATE_START_FAIL; case crmd_rscstate_STOP: return CRMD_RSCSTATE_STOP; case crmd_rscstate_STOP_PENDING: return CRMD_RSCSTATE_STOP_PENDING; case crmd_rscstate_STOP_OK: return CRMD_RSCSTATE_STOP_OK; case crmd_rscstate_STOP_FAIL: return CRMD_RSCSTATE_STOP_FAIL; case crmd_rscstate_MON: return CRMD_RSCSTATE_MON; case crmd_rscstate_MON_PENDING: return CRMD_RSCSTATE_MON_PENDING; case crmd_rscstate_MON_OK: return CRMD_RSCSTATE_MON_OK; case crmd_rscstate_MON_FAIL: return CRMD_RSCSTATE_MON_FAIL; case crmd_rscstate_GENERIC_PENDING: return CRMD_RSCSTATE_GENERIC_PENDING; case crmd_rscstate_GENERIC_OK: return CRMD_RSCSTATE_GENERIC_OK; case crmd_rscstate_GENERIC_FAIL: return CRMD_RSCSTATE_GENERIC_FAIL; } return "<unknown>";}/* A_LRM_CONNECT */enum crmd_fsa_inputdo_lrm_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){ int ret = HA_OK; if(action & A_LRM_DISCONNECT) { if(fsa_lrm_conn) { fsa_lrm_conn->lrm_ops->signoff(fsa_lrm_conn); } /* TODO: Clean up the hashtable */ } if(action & A_LRM_CONNECT) { crm_trace("LRM: connect..."); ret = HA_OK; monitors = g_hash_table_new(g_str_hash, g_str_equal); fsa_lrm_conn = ll_lrm_new(XML_CIB_TAG_LRM); if(NULL == fsa_lrm_conn) { register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); ret = HA_FAIL; } if(ret == HA_OK) { crm_trace("LRM: sigon..."); ret = fsa_lrm_conn->lrm_ops->signon( fsa_lrm_conn, CRM_SYSTEM_CRMD); } if(ret != HA_OK) { if(++num_lrm_register_fails < max_lrm_register_fails) { crm_warn("Failed to sign on to the LRM %d" " (%d max) times", num_lrm_register_fails, max_lrm_register_fails); startTimer(wait_timer); crmd_fsa_stall(); return I_NULL; } } if(ret == HA_OK) { crm_trace("LRM: set_lrm_callback..."); ret = fsa_lrm_conn->lrm_ops->set_lrm_callback( fsa_lrm_conn, lrm_op_callback); if(ret != HA_OK) { crm_err("Failed to set LRM callbacks"); } } if(ret != HA_OK) { crm_err("Failed to sign on to the LRM %d" " (max) times", num_lrm_register_fails); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); return I_NULL; } /* TODO: create a destroy handler that causes * some recovery to happen */ G_main_add_fd(G_PRIORITY_LOW, fsa_lrm_conn->lrm_ops->inputfd(fsa_lrm_conn), FALSE, lrm_dispatch, fsa_lrm_conn, default_ipc_connection_destroy); set_bit_inplace(fsa_input_register, R_LRM_CONNECTED); } if(action & ~(A_LRM_CONNECT|A_LRM_DISCONNECT)) { crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } return I_NULL;}gbooleanbuild_suppported_RAs(crm_data_t *metadata_list, crm_data_t *xml_agent_list){ GList *types = NULL; GList *classes = NULL; const char *version = NULL; crm_data_t *xml_agent = NULL; /* return TRUE; */ if(fsa_lrm_conn == NULL) { return FALSE; } classes = fsa_lrm_conn->lrm_ops->get_rsc_class_supported(fsa_lrm_conn); slist_iter( class, char, classes, lpc, types = fsa_lrm_conn->lrm_ops->get_rsc_type_supported( fsa_lrm_conn, class); slist_iter( type, char, types, llpc, version = "1"; xml_agent = create_xml_node( xml_agent_list, XML_LRM_TAG_AGENT); set_xml_property_copy( xml_agent, XML_AGENT_ATTR_CLASS, class); set_xml_property_copy(xml_agent, XML_ATTR_TYPE, type); set_xml_property_copy( xml_agent, XML_ATTR_VERSION, version); ) g_list_free(types); ); g_list_free(classes); return TRUE;}gbooleanstop_all_resources(void){ GList *op_list = NULL; GList *lrm_list = NULL; state_flag_t cur_state = 0; const char *this_op = NULL; if(fsa_lrm_conn == NULL) { return TRUE; } lrm_list = fsa_lrm_conn->lrm_ops->get_all_rscs(fsa_lrm_conn); slist_iter( rid, char, lrm_list, lpc,/* GHashTable* params; */ lrm_rsc_t *the_rsc = fsa_lrm_conn->lrm_ops->get_rsc(fsa_lrm_conn, rid); crm_info("Processing lrm_rsc_t entry %s", rid); if(the_rsc == NULL) { crm_err("NULL resource returned from the LRM"); continue; } op_list = the_rsc->ops->get_cur_state(the_rsc, &cur_state); crm_verbose("\tcurrent state:%s\n", cur_state==LRM_RSC_IDLE?"Idle":"Busy"); slist_iter( op, lrm_op_t, op_list, llpc, this_op = op->op_type; crm_debug("Processing op %s for %s (status=%d, rc=%d)", op->op_type, the_rsc->id, op->op_status, op->rc); if(safe_str_neq(this_op, CRMD_RSCSTATE_STOP)){ do_lrm_rsc_op(the_rsc, the_rsc->id, CRMD_RSCSTATE_STOP, NULL); } break; ); ); return TRUE;}gbooleanbuild_active_RAs(crm_data_t *rsc_list){ GList *op_list = NULL; GList *lrm_list = NULL; gboolean found_op = FALSE; state_flag_t cur_state = 0; const char *this_op = NULL; char *tmp = NULL; if(fsa_lrm_conn == NULL) { return FALSE; } lrm_list = fsa_lrm_conn->lrm_ops->get_all_rscs(fsa_lrm_conn); slist_iter( rid, char, lrm_list, lpc,/* GHashTable* params; */ lrm_rsc_t *the_rsc = fsa_lrm_conn->lrm_ops->get_rsc(fsa_lrm_conn, rid); crm_data_t *xml_rsc = create_xml_node( rsc_list, XML_LRM_TAG_RESOURCE); crm_info("Processing lrm_rsc_t entry %s", rid); if(the_rsc == NULL) { crm_err("NULL resource returned from the LRM"); continue; } set_xml_property_copy(xml_rsc, XML_ATTR_ID, the_rsc->id); set_xml_property_copy( xml_rsc, XML_LRM_ATTR_TARGET, fsa_our_uname); op_list = the_rsc->ops->get_cur_state(the_rsc, &cur_state); crm_verbose("\tcurrent state:%s\n", cur_state==LRM_RSC_IDLE?"Idle":"Busy"); slist_iter( op, lrm_op_t, op_list, llpc, this_op = op->op_type; crm_debug("Processing op %s for %s (status=%d, rc=%d)", op->op_type, the_rsc->id, op->op_status, op->rc); if(op->rc != 0 || safe_str_neq(this_op, CRMD_RSCSTATE_MON)){ set_xml_property_copy( xml_rsc, XML_LRM_ATTR_RSCSTATE, op->user_data); set_xml_property_copy( xml_rsc, XML_LRM_ATTR_LASTOP, this_op); tmp = crm_itoa(op->rc); set_xml_property_copy( xml_rsc, XML_LRM_ATTR_RC, tmp); crm_free(tmp); tmp = crm_itoa(op->op_status); set_xml_property_copy( xml_rsc, XML_LRM_ATTR_OPSTATUS, tmp); crm_free(tmp); /* we only want the last one */ found_op = TRUE; break; } else { set_xml_property_copy( xml_rsc, XML_LRM_ATTR_RSCSTATE, CRMD_RSCSTATE_START_OK); set_xml_property_copy( xml_rsc, XML_LRM_ATTR_LASTOP, CRMD_RSCSTATE_START); tmp = crm_itoa(op->rc); set_xml_property_copy( xml_rsc, XML_LRM_ATTR_RC, tmp); crm_free(tmp); set_xml_property_copy( xml_rsc, XML_LRM_ATTR_OPSTATUS, "0"); /* we only want the last one */ found_op = TRUE; break; } ); if(found_op == FALSE) { crm_err("Could not properly determin last op" " for %s from %d entries", the_rsc->id, g_list_length(op_list)); } g_list_free(op_list); ); g_list_free(lrm_list);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -