diff --git a/crm/tengine/unpack.c b/crm/tengine/unpack.c index ac2c396cb4..a03ae76ee4 100644 --- a/crm/tengine/unpack.c +++ b/crm/tengine/unpack.c @@ -1,438 +1,438 @@ -/* $Id: unpack.c,v 1.1 2004/09/15 09:22:57 andrew Exp $ */ +/* $Id: unpack.c,v 1.2 2004/09/15 20:23:18 andrew Exp $ */ /* * Copyright (C) 2004 Andrew Beekhof * * 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 #include #include #include #include #include #include #include #include #include #include gboolean process_te_message(xmlNodePtr msg, IPC_Channel *sender); action_t* unpack_action(xmlNodePtr xml_action); xmlNodePtr create_shutdown_event(const char *node, int op_status); gboolean unpack_graph(xmlNodePtr xml_graph) { /* id = num_synapses++; new_synapse->complete = FALSE; new_synapse->actions = NULL; new_synapse->inputs = NULL; graph = g_list_append(graph, new_synapse); xml_child_iter( synapse, actions, "action_set", xml_child_iter( actions, action, NULL, action_t *new_action = unpack_action(action); num_actions++; if(new_action == NULL) { action = action->next; break; } new_synapse->actions = g_list_append( new_synapse->actions, new_action); ); ); xml_child_iter( synapse, inputs, "inputs", xml_child_iter( inputs, trigger, NULL, xml_child_iter( trigger, input, NULL, action_t *new_input = unpack_action(input); if(new_input == NULL) { input = input->next; break; } new_synapse->inputs = g_list_append( new_synapse->inputs, new_input); ); ); ); ); crm_info("Unpacked %d actions in %d synapses", num_actions, num_synapses); if(num_actions > 0) { return TRUE; } else { /* indicate to caller that there's nothing to do */ return FALSE; } } action_t* unpack_action(xmlNodePtr xml_action) { const char *tmp = xmlGetProp(xml_action, "id"); action_t *action = NULL; xmlNodePtr action_copy = NULL; if(tmp == NULL) { crm_err("Actions must have an id!"); crm_xml_devel(xml_action, "Action with missing id"); return NULL; } action_copy = copy_xml_node_recursive(xml_action); action = crm_malloc(sizeof(action_t)); action->id = atoi(tmp); action->timeout = 0; action->timer_id = -1; action->invoked = FALSE; action->complete = FALSE; action->can_fail = FALSE; action->type = action_type_rsc; action->xml = action_copy; if(safe_str_eq(action_copy->name, "rsc_op")) { action->type = action_type_rsc; } else if(safe_str_eq(action_copy->name, "pseudo_event")) { action->type = action_type_pseudo; } else if(safe_str_eq(action_copy->name, "crm_event")) { action->type = action_type_crm; } tmp = xmlGetProp(action_copy, "timeout"); if(tmp != NULL) { action->timeout = atoi(tmp); } tmp = xmlGetProp(action_copy, "can_fail"); if(safe_str_eq(tmp, "true")) { action->can_fail = TRUE; } return action; } gboolean extract_event(xmlNodePtr msg) { gboolean abort = FALSE; xmlNodePtr iter = NULL; xmlNodePtr cib = NULL; const char *section = NULL; const char *event_node = NULL; /* [cib fragment] ... */ crm_trace("Extracting event"); iter = find_xml_node(msg, XML_TAG_FRAGMENT); section = xmlGetProp(iter, XML_ATTR_SECTION); if(safe_str_eq(section, XML_CIB_TAG_CRMCONFIG)) { /* ignore - for the moment */ crm_debug("Ignoring changes to the %s section", XML_CIB_TAG_CRMCONFIG); return TRUE; } else if(safe_str_neq(section, XML_CIB_TAG_STATUS)) { /* these too are never expected */ crm_debug("Ignoring changes outside the %s section", XML_CIB_TAG_STATUS); return FALSE; } cib = find_xml_node(iter, XML_TAG_CIB); iter = get_object_root(XML_CIB_TAG_STATUS, cib); if(iter != NULL) { iter = iter->children; } else { crm_xml_warn(cib, XML_CIB_TAG_STATUS " section missing?"); } while(abort == FALSE && iter != NULL) { xmlNodePtr node_state = iter; xmlNodePtr child = iter->children; const char *state = xmlGetProp( node_state, XML_CIB_ATTR_CRMDSTATE); iter = iter->next; crm_xml_devel(node_state,"Processing"); if(xmlGetProp(node_state, XML_CIB_ATTR_SHUTDOWN) != NULL) { crm_trace("Aborting on %s attribute", XML_CIB_ATTR_SHUTDOWN); abort = TRUE; } else if(xmlGetProp(node_state, XML_CIB_ATTR_STONITH) != NULL) { /* node marked for STONITH * possibly by us when a shutdown timmed out */ crm_trace("Checking for STONITH"); event_node = xmlGetProp(node_state, XML_ATTR_UNAME); xmlNodePtr shutdown = create_shutdown_event( event_node, LRM_OP_TIMEOUT); process_graph_event(shutdown); free_xml(shutdown); } else if(state != NULL && child == NULL) { /* simple node state update... * possibly from a shutdown we requested */ crm_trace("Processing simple state update"); if(safe_str_neq(state, OFFLINESTATUS)) { /* always recompute */ abort = TRUE; continue; } event_node = xmlGetProp(node_state, XML_ATTR_UNAME); xmlNodePtr shutdown = create_shutdown_event( event_node, LRM_OP_DONE); process_graph_event(shutdown); free_xml(shutdown); } else if(state == NULL && child != NULL) { /* LRM resource update... */ crm_trace("Processing LRM resource update"); child = find_xml_node(node_state, XML_CIB_TAG_LRM); child = find_xml_node(child, XML_LRM_TAG_RESOURCES); if(child != NULL) { child = child->children; } else { abort = TRUE; } event_node = xmlGetProp(node_state, XML_ATTR_UNAME); while(abort == FALSE && child != NULL) { process_graph_event(child); child = child->next; } } else if(state != NULL && child != NULL) { /* this is a complex event and could not be completely * due to any request we made */ crm_trace("Aborting on complex update"); abort = TRUE; } else { /* ignore */ crm_err("Ignoring message"); } } return !abort; } gboolean process_te_message(xmlNodePtr msg, IPC_Channel *sender) { - const char *op = get_xml_attr (msg, XML_TAG_OPTIONS, - XML_ATTR_OP, FALSE); - + xmlNodePtr graph = NULL; const char *sys_to = xmlGetProp(msg, XML_ATTR_SYSTO); const char *ref = xmlGetProp(msg, XML_ATTR_REFERENCE); - xmlNodePtr graph = NULL; + const char *op = get_xml_attr( + msg, XML_TAG_OPTIONS, XML_ATTR_OP, FALSE); + crm_debug("Recieved %s (%s) message", op, ref); #ifdef MSG_LOG struct stat buf; if(stat(DEVEL_DIR, &buf) != 0) { cl_perror("Stat of %s failed... exiting", DEVEL_DIR); exit(100); } if(msg_te_strm == NULL) { msg_te_strm = fopen(DEVEL_DIR"/te.log", "w"); } char *xml = dump_xml_formatted(msg); fprintf(msg_te_strm, "[Input %s]\t%s\n", op, xml); fflush(msg_te_strm); crm_free(xml); #endif if(safe_str_eq(xmlGetProp(msg, XML_ATTR_MSGTYPE), XML_ATTR_RESPONSE) && safe_str_neq(op, CRM_OP_EVENTCC)) { #ifdef MSG_LOG fprintf(msg_te_strm, "[Result ]\tDiscarded\n"); fflush(msg_te_strm); #endif crm_info("Message was a response not a request. Discarding"); return TRUE; } crm_debug("Processing %s (%s) message", op, ref); if(op == NULL){ /* error */ } else if(strcmp(op, CRM_OP_HELLO) == 0) { /* ignore */ } else if(sys_to == NULL || strcmp(sys_to, CRM_SYSTEM_TENGINE) != 0) { crm_verbose("Bad sys-to %s", sys_to); return FALSE; } else if(strcmp(op, CRM_OP_TRANSITION) == 0) { crm_trace("Initializing graph..."); initialize_graph(); graph = find_xml_node(msg, "transition_graph"); crm_trace("Unpacking graph..."); unpack_graph(graph); crm_trace("Initiating transition..."); in_transition = TRUE; if(initiate_transition() == FALSE) { /* nothing to be done.. means we're done. */ crm_info("No actions to be taken..." " transition compelte."); } crm_trace("Processing complete..."); } else if(strcmp(op, CRM_OP_ABORT) == 0) { initialize_graph(); } else if(strcmp(op, CRM_OP_QUIT) == 0) { crm_err("Received quit message, terminating"); exit(0); } else if(in_transition == FALSE) { crm_info("Received event_cc while not in a transition..." " Poking the Policy Engine"); send_abort("Initiate a transition", NULL); } else if(strcmp(op, CRM_OP_EVENTCC) == 0) { const char *true_op = get_xml_attr (msg, XML_TAG_OPTIONS, XML_ATTR_TRUEOP, TRUE); crm_trace("Processing %s...", CRM_OP_EVENTCC); if(true_op == NULL) { crm_err( "Illegal update," " the original operation must be specified"); send_abort("Illegal update", msg); } else if(strcmp(true_op, CRM_OP_CREATE) == 0 || strcmp(true_op, CRM_OP_DELETE) == 0 || strcmp(true_op, CRM_OP_REPLACE) == 0 || strcmp(true_op, CRM_OP_WELCOME) == 0 || strcmp(true_op, CRM_OP_SHUTDOWN_REQ) == 0 || strcmp(true_op, CRM_OP_ERASE) == 0) { /* these are always unexpected, trigger the PE */ send_abort("Config update", msg); } else if(strcmp(true_op, CRM_OP_UPDATE) == 0) { /* this may not be un-expected */ // if( extract_event(msg); //== FALSE){ // send_abort(msg); // } } else { crm_err( "Did not expect copy of action %s", op); } } crm_debug("finished processing message"); print_state(FALSE); return TRUE; } xmlNodePtr create_shutdown_event(const char *node, int op_status) { xmlNodePtr event = create_xml_node(NULL, XML_CIB_TAG_STATE); char *code = crm_itoa(op_status); set_xml_property_copy(event, XML_LRM_ATTR_TARGET, node); // event_rsc = set_xml_property_copy(event, XML_ATTR_ID); set_xml_property_copy(event, XML_LRM_ATTR_RC, "0"); set_xml_property_copy( event, XML_LRM_ATTR_LASTOP, XML_CIB_ATTR_SHUTDOWN); set_xml_property_copy( event, XML_LRM_ATTR_RSCSTATE, CRMD_RSCSTATE_GENERIC_OK); set_xml_property_copy(event, XML_LRM_ATTR_OPSTATUS, code); crm_free(code); return event; }