📄 lrm.c
字号:
return TRUE;}crm_data_t*do_lrm_query(gboolean is_replace){ crm_data_t *xml_result= NULL; crm_data_t *xml_state = create_xml_node(NULL, XML_CIB_TAG_STATE); crm_data_t *xml_data = create_xml_node(xml_state, XML_CIB_TAG_LRM); crm_data_t *rsc_list = create_xml_node(xml_data,XML_LRM_TAG_RESOURCES);#if 0 /* Build a list of supported agents and metadata */ crm_data_t *xml_agent_list = create_xml_node(xml_data, XML_LRM_TAG_AGENTS); crm_data_t *xml_metadata_list = create_xml_node(xml_data, "metatdata"); build_suppported_RAs(xml_metadata_list, xml_agent_list);#endif /* Build a list of active (not always running) resources */ build_active_RAs(rsc_list); if(is_replace) { set_xml_property_copy( xml_state, XML_CIB_ATTR_REPLACE, XML_CIB_TAG_LRM); } set_uuid(fsa_cluster_conn, xml_state, XML_ATTR_UUID, fsa_our_uname); set_xml_property_copy(xml_state, XML_ATTR_UNAME, fsa_our_uname); xml_result = create_cib_fragment(xml_state, NULL); crm_xml_devel(xml_state, "Current state of the LRM"); return xml_result;}/* A_LRM_INVOKE */enum crmd_fsa_inputdo_lrm_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){ const char *crm_op = NULL; const char *operation = NULL; enum crmd_fsa_input next_input = I_NULL; ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg); crm_op = cl_get_string(input->msg, F_CRM_TASK); operation = get_xml_attr_nested( input->xml, rsc_path, DIMOF(rsc_path) -3, XML_LRM_ATTR_TASK, FALSE); if(crm_op != NULL && safe_str_eq(crm_op, "lrm_query")) { crm_data_t *data = do_lrm_query(FALSE); HA_Message *reply = create_reply(input->msg, data); if(relay_message(reply, TRUE) == FALSE) { crm_err("Unable to route reply"); crm_log_message(LOG_ERR, reply); crm_msg_del(reply); } free_xml(data); } else if(operation != NULL) { char rid[64]; const char *id_from_cib = NULL; lrm_rsc_t *rsc = NULL; id_from_cib = get_xml_attr_nested( input->xml, rsc_path, DIMOF(rsc_path) -2, XML_ATTR_ID, TRUE); if(id_from_cib == NULL) { crm_err("No value for %s in message at level %d.", XML_ATTR_ID, DIMOF(rsc_path) -2); return I_NULL; } /* only the first 16 chars are used by the LRM */ strncpy(rid, id_from_cib, 64); rid[63] = 0; rsc = fsa_lrm_conn->lrm_ops->get_rsc(fsa_lrm_conn, rid); next_input = do_lrm_rsc_op(rsc, rid, operation, input->xml); } else { crm_err("Operation was neither a lrm_query, nor a rsc op. %s", crm_str(crm_op)); next_input = I_ERROR; } return next_input;}enum crmd_fsa_inputdo_lrm_rsc_op( lrm_rsc_t *rsc, char *rid, const char *operation, crm_data_t *msg){ lrm_op_t* op = NULL; int call_id = 0; int action_timeout = 0; fsa_data_t *msg_data = NULL; const char *type = NULL; const char *class = NULL; const char *timeout = NULL; if(rsc != NULL) { class = rsc->class; type = rsc->type; } else if(msg != NULL) { class = get_xml_attr_nested( msg, rsc_path, DIMOF(rsc_path) -2, XML_AGENT_ATTR_CLASS, TRUE); type = get_xml_attr_nested( msg, rsc_path, DIMOF(rsc_path) -2, XML_ATTR_TYPE, TRUE); timeout = get_xml_attr_nested( msg, rsc_path, DIMOF(rsc_path) -2, XML_ATTR_TIMEOUT, FALSE); } if(rsc == NULL) { /* add it to the list */ crm_verbose("adding rsc %s before operation", rid); fsa_lrm_conn->lrm_ops->add_rsc( fsa_lrm_conn, rid, class, type, NULL, NULL); rsc = fsa_lrm_conn->lrm_ops->get_rsc(fsa_lrm_conn, rid); } if(rsc == NULL) { crm_err("Could not add resource to LRM"); register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); return I_NULL; } if(timeout) { action_timeout = atoi(timeout); if(action_timeout < 0) { action_timeout = 0; } } /* stop the monitor before stopping the resource */ if(safe_str_eq(operation, CRMD_RSCSTATE_STOP)) { gpointer foo = g_hash_table_lookup(monitors, rsc->id); call_id = GPOINTER_TO_INT(foo); if(call_id > 0) { crm_debug("Stopping status op for %s", rsc->id); rsc->ops->cancel_op(rsc, call_id); g_hash_table_remove(monitors, rsc->id); /* TODO: Clean up key */ } else { crm_warn("No monitor operation found for %s", rsc->id); /* TODO: we probably need to look up the LRM to find it */ } } /* now do the op */ crm_info("Performing op %s on %s", operation, rid); crm_malloc(op, sizeof(lrm_op_t)); op->op_type = crm_strdup(operation); op->timeout = action_timeout; op->interval = 0; op->user_data = NULL; op->target_rc = EVERYTIME; if(msg != NULL) { op->params = xml2list(msg, rsc_path, DIMOF(rsc_path)); } else { CRM_DEV_ASSERT(safe_str_eq(CRMD_RSCSTATE_STOP, operation)); } if(safe_str_eq(CRMD_RSCSTATE_START, operation)) { op->user_data = crm_strdup(CRMD_RSCSTATE_START_OK); } else if(safe_str_eq(CRMD_RSCSTATE_STOP, operation)) { op->user_data = crm_strdup(CRMD_RSCSTATE_STOP_OK); } else { crm_warn("Using status \"complete\" for op \"%s\"" "... this is still in the experimental stage.", operation); op->user_data = crm_strdup(CRMD_RSCSTATE_GENERIC_OK); } op->user_data_len = 1+strlen(op->user_data); call_id = rsc->ops->perform_op(rsc, op); free_lrm_op(op); if(call_id <= 0) { crm_err("Operation %s on %s failed", operation, rid); register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); return I_NULL; } if(safe_str_eq(operation, CRMD_RSCSTATE_START)) { /* initiate the monitor action */ crm_malloc(op, sizeof(lrm_op_t)); op->op_type = crm_strdup(CRMD_RSCSTATE_MON); op->params = NULL; op->user_data = crm_strdup(CRMD_RSCSTATE_MON_OK); op->timeout = 0; op->interval = 9000; op->target_rc = CHANGED; op->user_data_len = 1+strlen(op->user_data); call_id = rsc->ops->perform_op(rsc, op); free_lrm_op(op); if (call_id > 0) { crm_debug("Adding monitor op for %s", rsc->id); g_hash_table_insert( monitors, strdup(rsc->id), GINT_TO_POINTER(call_id)); } else { crm_err("Monitor op for %s did not have a call id", rsc->id); } } return I_NULL;}voidfree_lrm_op(lrm_op_t *op) { crm_free(op->user_data); crm_free(op->op_type); crm_free(op);}GHashTable *xml2list(crm_data_t *parent, const char**attr_path, int depth){ crm_data_t *nvpair_list = NULL; GHashTable *nvpair_hash = g_hash_table_new(g_str_hash, g_str_equal); CRM_DEV_ASSERT(parent != NULL); if(parent != NULL) { nvpair_list = find_xml_node_nested(parent, attr_path, depth); if(nvpair_list == NULL) { crm_xml_devel(parent, "No attributes for resource op"); } } xml_child_iter( nvpair_list, node_iter, XML_CIB_TAG_NVPAIR, const char *key = crm_element_value( node_iter, XML_NVPAIR_ATTR_NAME); const char *value = crm_element_value( node_iter, XML_NVPAIR_ATTR_VALUE); crm_verbose("Added %s=%s", key, value); g_hash_table_insert( nvpair_hash,crm_strdup(key), crm_strdup(value)); ); return nvpair_hash;}voiddo_update_resource(lrm_rsc_t *rsc, lrm_op_t* op){/* <status> <nodes_status id=uname> <lrm> <lrm_resources> <lrm_resource id=> </...>*/ crm_data_t *update, *iter; char *tmp = NULL; crm_data_t *fragment; int len = 0; char *fail_state = NULL; if(op == NULL || rsc == NULL) { crm_err("Either resouce or op was not specified"); return; } crm_info("Updating resouce %s after op %s", rsc->id, op->op_type); update = create_xml_node(NULL, XML_CIB_TAG_STATE); set_uuid(fsa_cluster_conn, update, XML_ATTR_UUID, fsa_our_uname); set_xml_property_copy(update, XML_ATTR_UNAME, fsa_our_uname); iter = create_xml_node(update, XML_CIB_TAG_LRM); iter = create_xml_node(iter, XML_LRM_TAG_RESOURCES); iter = create_xml_node(iter, XML_LRM_TAG_RESOURCE); set_xml_property_copy(iter, XML_ATTR_ID, rsc->id); set_xml_property_copy(iter, XML_LRM_ATTR_LASTOP, op->op_type); len = strlen(op->op_type); len += strlen("_failed_"); crm_malloc(fail_state, sizeof(char)*len); if(fail_state != NULL) { sprintf(fail_state, "%s_failed", op->op_type); } switch(op->op_status) { case LRM_OP_CANCELLED: break; case LRM_OP_ERROR: case LRM_OP_TIMEOUT: case LRM_OP_NOTSUPPORTED: crm_err("An LRM operation failed or was aborted"); set_xml_property_copy( iter, XML_LRM_ATTR_RSCSTATE, fail_state); break; case LRM_OP_DONE: set_xml_property_copy( iter, XML_LRM_ATTR_RSCSTATE, op->user_data); break; } crm_free(fail_state); tmp = crm_itoa(op->rc); set_xml_property_copy(iter, XML_LRM_ATTR_RC, tmp); crm_free(tmp); tmp = crm_itoa(op->op_status); set_xml_property_copy(iter, XML_LRM_ATTR_OPSTATUS, tmp); crm_free(tmp); set_xml_property_copy(iter, XML_LRM_ATTR_TARGET, fsa_our_uname); fragment = create_cib_fragment(update, NULL); { int rc = cib_ok; rc = fsa_cib_conn->cmds->modify( fsa_cib_conn, XML_CIB_TAG_STATUS, fragment, NULL, cib_sync_call); /* * There are a couple of options here... * * One is that maybe just the CRMd died. So this is a * callback from last time. * This can also be triggered by the HA shutdown bug. * * Another is that the update occurred while the next DC was * being elected. * * Either way, as long as one of the conditions below is met, * then the resource state will be discovered during * the next signup or election. */ if(rc == cib_ok) { crm_debug("Resource state update: %s", cib_error2string(rc)); } else if(AM_I_DC) { crm_err("Resource state update failed: %s", cib_error2string(rc)); CRM_DEV_ASSERT(rc == cib_ok && AM_I_DC); } else if(rc == cib_master_timeout && (fsa_state==S_PENDING || fsa_state==S_ELECTION)) { crm_warn("Resource state update failed: %s", cib_error2string(rc)); crm_warn("The resource state will be updated during the" " next transition"); } else { crm_err("Resource state update failed: %s", cib_error2string(rc)); CRM_DEV_ASSERT(rc == cib_ok); } } free_xml(fragment); free_xml(update);}enum crmd_fsa_inputdo_lrm_event(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t *msg_data){ lrm_op_t* op = NULL; lrm_rsc_t* rsc = NULL; if(msg_data->fsa_cause != C_LRM_OP_CALLBACK) { register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); return I_NULL; } op = fsa_typed_data(fsa_dt_lrm); CRM_DEV_ASSERT(op != NULL); CRM_DEV_ASSERT(op != NULL && op->rsc != NULL); if(op == NULL || op->rsc == NULL) { return I_NULL; } rsc = op->rsc; switch(op->op_status) { case LRM_OP_ERROR: crm_err("LRM operation %s/%s failed", crm_str(rsc->id), op->op_type); break; case LRM_OP_CANCELLED: crm_warn("LRM operation %s/%s was cancelled", crm_str(rsc->id), op->op_type); break; case LRM_OP_TIMEOUT: crm_err("LRM operation %s/%s timed out", crm_str(rsc->id), op->op_type); break; case LRM_OP_NOTSUPPORTED: crm_err("LRM operation %s/%s was not suported", crm_str(rsc->id), op->op_type); break; case LRM_OP_DONE: crm_debug("LRM operation %s/%s passed", crm_str(rsc->id), op->op_type); break; } do_update_resource(rsc, op); return I_NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -