diff --git a/crm/admin/adminmain.c b/crm/admin/adminmain.c index 99c00c2efb..62ba3da011 100644 --- a/crm/admin/adminmain.c +++ b/crm/admin/adminmain.c @@ -1,624 +1,620 @@ -/* $Id: adminmain.c,v 1.27 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: adminmain.c,v 1.28 2004/06/02 15:25:10 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 */ #include <portability.h> #include <crm/crm.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <hb_api.h> #include <clplumbing/uids.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/ctrl.h> #include <crm/common/ipc.h> #include <crm/cib.h> #define OPTARGS "V?i:o:D:C:S:HA:U:M:I:EWRFt:m:a:d:w:c:r:p:s:" #include <getopt.h> #include <crm/dmalloc_wrapper.h> GMainLoop *mainloop = NULL; const char *crm_system_name = "crmadmin"; IPC_Channel *crmd_channel = NULL; char *admin_uuid = NULL; void usage(const char *cmd, int exit_status); ll_cluster_t *do_init(void); int do_work(ll_cluster_t * hb_cluster); gboolean admin_msg_callback(IPC_Channel * source_data, void *private_data); char *pluralSection(const char *a_section); xmlNodePtr handleCibMod(void); gboolean DO_DAEMON = FALSE; gboolean BE_VERBOSE = FALSE; int expected_responses = 1; gboolean DO_HEALTH = FALSE; gboolean DO_ELECT_DC = FALSE; gboolean DO_WHOIS_DC = FALSE; gboolean DO_RECALC_TREE = FALSE; gboolean DO_FLUSH_RECALC = FALSE; const char *cib_action = NULL; xmlNodePtr msg_options = NULL; typedef struct str_list_s { int num_items; char *value; struct str_list_s *next; } str_list_t; const char *verbose = XML_BOOLEAN_FALSE; char *id = NULL; char *this_msg_reference = NULL; char *obj_type = NULL; char *clear = NULL; char *status = NULL; char *disconnect = NULL; char *unload_ha = NULL; char *migrate_from = NULL; char *migrate_res = NULL; char *subtype = NULL; char *reset = NULL; int operation_status = 0; const char *sys_to = NULL;; int main(int argc, char **argv) { int option_index = 0; int argerr = 0; int flag; ll_cluster_t *hb_cluster = NULL; static struct option long_options[] = { // Top-level Options {"daemon", 0, 0, 0}, {CRM_OP_ERASE, 0, 0, 0}, {CRM_OP_QUERY, 0, 0, 0}, {CRM_OP_CREATE, 0, 0, 0}, {CRM_OP_REPLACE, 0, 0, 0}, {CRM_OP_STORE, 0, 0, 0}, {CRM_OP_UPDATE, 0, 0, 0}, {CRM_OP_DELETE, 0, 0, 0}, {"verbose", 0, 0, 'V'}, {"help", 0, 0, '?'}, {"reference", 1, 0, 0}, // common options {XML_ATTR_ID, 1, 0, 'i'}, {"obj_type", 1, 0, 'o'}, // daemon options {"reset", 1, 0, 'C'}, {"status", 1, 0, 'S'}, {"health", 0, 0, 'H'}, {"disconnect", 1, 0, 'A'}, {"unload_ha", 1, 0, 'U'}, {"migrate_from", 1, 0, 'M'}, {"migrate_res", 1, 0, 'I'}, {"elect_dc", 0, 0, 'E'}, {"whois_dc", 0, 0, 'W'}, {"recalc_tree", 0, 0, 'R'}, {"flush_recalc_tree", 0, 0, 'F'}, {0, 0, 0, 0} }; cl_log_set_entity(crm_system_name); cl_log_enable_stderr(TRUE); cl_log_set_facility(LOG_USER); while (1) { flag = getopt_long(argc, argv, OPTARGS, long_options, &option_index); if (flag == -1) break; switch(flag) { case 0: printf("option %s", long_options[option_index].name); if (optarg) printf(" with arg %s", optarg); printf("\n"); if (strcmp("daemon", long_options[option_index].name) == 0) DO_DAEMON = TRUE; else if (strcmp(CRM_OP_ERASE, long_options[option_index].name) == 0 || strcmp(CRM_OP_CREATE, long_options[option_index].name) == 0 || strcmp(CRM_OP_UPDATE, long_options[option_index].name) == 0 || strcmp(CRM_OP_DELETE, long_options[option_index].name) == 0 || strcmp(CRM_OP_REPLACE, long_options[option_index].name) == 0 || strcmp(CRM_OP_STORE, long_options[option_index].name) == 0 || strcmp(CRM_OP_QUERY, long_options[option_index].name) == 0){ cib_action = crm_strdup(long_options[option_index].name); } else if (strcmp("reference", long_options[option_index].name) == 0) { this_msg_reference = crm_strdup(optarg); } else { printf( "?? Long option (--%s) is not yet properly supported ??\n", long_options[option_index].name); ++argerr; } break; /* a sample test for multiple instance if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); */ case 'V': BE_VERBOSE = TRUE; verbose = XML_BOOLEAN_TRUE; break; case '?': usage(crm_system_name, LSB_EXIT_OK); break; case 'i': - CRM_DEBUG("Option %c => %s", flag, optarg); + crm_verbose("Option %c => %s", flag, optarg); id = crm_strdup(optarg); break; case 'o': - CRM_DEBUG("Option %c => %s", flag, optarg); + crm_verbose("Option %c => %s", flag, optarg); obj_type = crm_strdup(optarg); break; case 'C': printf("Option %c is not yet supported\n", flag); ++argerr; break; case 'S': DO_HEALTH = TRUE; status = crm_strdup(optarg); break; case 'H': DO_HEALTH = TRUE; break; case 'A': printf("Option %c is not yet supported\n", flag); ++argerr; break; case 'U': printf("Option %c is not yet supported\n", flag); ++argerr; break; case 'M': printf("Option %c is not yet supported\n", flag); ++argerr; break; case 'I': printf("Option %c is not yet supported\n", flag); ++argerr; break; case 'E': DO_ELECT_DC = TRUE; printf("Option %c is not yet supported\n", flag); ++argerr; break; case 'W': DO_WHOIS_DC = TRUE; printf("Option %c is not yet supported\n", flag); ++argerr; break; case 'R': DO_RECALC_TREE = TRUE; printf("Option %c is not yet supported\n", flag); ++argerr; break; case 'F': DO_FLUSH_RECALC = TRUE; printf("Option %c is not yet supported\n", flag); ++argerr; break; default: printf("?? getopt returned character code 0%o ??\n", flag); ++argerr; break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); } if (optind > argc) { ++argerr; } if (argerr) { usage(crm_system_name, LSB_EXIT_GENERIC); } hb_cluster = do_init(); if (hb_cluster != NULL) { if (do_work(hb_cluster) > 0) { /* wait for the reply by creating a mainloop and running it until * the callbacks are invoked... */ mainloop = g_main_new(FALSE); - cl_log(LOG_INFO, - "%s waiting for reply from the local CRM", - crm_system_name); + crm_info("%s waiting for reply from the local CRM", + crm_system_name); g_main_run(mainloop); return_to_orig_privs(); } else { - cl_log(LOG_ERR, "No message to send"); + crm_err("No message to send"); operation_status = -1; } } else { - cl_log(LOG_ERR, - "Init failed, could not perform requested operations"); + crm_err("Init failed, could not perform requested operations"); operation_status = -2; } - cl_log(LOG_DEBUG, "%s exiting normally", crm_system_name); + crm_debug("%s exiting normally", crm_system_name); return operation_status; } xmlNodePtr handleCibMod(void) { const char *attr_name = NULL; const char *attr_value = NULL; xmlNodePtr fragment = NULL; xmlNodePtr cib_object = file2xml(stdin); if(cib_object == NULL) { return NULL; } if(strcmp(cib_object->name, obj_type) != 0) { - cl_log(LOG_ERR, "Mismatching xml." + crm_err("Mismatching xml." " Expected root element <%s>, got <%s>", obj_type, cib_object->name); return NULL; } attr_name = XML_ATTR_ID; attr_value = xmlGetProp(cib_object, attr_name); if(attr_name == NULL || strlen(attr_name) == 0) { - cl_log(LOG_ERR, "No value for %s specified.", attr_name); + crm_err("No value for %s specified.", attr_name); return NULL; } - CRM_NOTE("Object creation complete"); + crm_trace("Object creation complete"); // create the cib request fragment = create_cib_fragment(cib_object, NULL); set_xml_property_copy(msg_options, XML_ATTR_OP, cib_action); return fragment; } int do_work(ll_cluster_t * hb_cluster) { /* construct the request */ xmlNodePtr msg_data = NULL; const char *dest_node = NULL; gboolean all_is_good = TRUE; char *obj_type_parent = NULL; const char *ping_type = NULL; msg_options = create_xml_node(NULL, XML_TAG_OPTIONS); set_xml_property_copy(msg_options, XML_ATTR_VERBOSE, verbose); set_xml_property_copy(msg_options, XML_ATTR_TIMEOUT, "0"); if (DO_DAEMON == TRUE && cib_action != NULL) { if(strcmp(CRM_OP_QUERY, cib_action) == 0) { - cl_log(LOG_DEBUG, "Querying the CIB"); + crm_debug("Querying the CIB"); obj_type_parent = pluralSection(obj_type); - CRM_DEBUG("Querying the CIB for section: %s", + crm_verbose("Querying the CIB for section: %s", obj_type_parent); set_xml_property_copy(msg_options, XML_ATTR_OP, CRM_OP_QUERY); set_xml_property_copy(msg_options, XML_ATTR_FILTER_ID, obj_type_parent); dest_node = status; - CRM_DEBUG("CIB query creation %s", + crm_verbose("CIB query creation %s", msg_data == NULL ? "failed." : "passed."); sys_to = CRM_SYSTEM_DCIB; } else if (strcmp(CRM_OP_ERASE, cib_action) == 0) { set_xml_property_copy(msg_options, XML_ATTR_OP, CRM_OP_ERASE); dest_node = status; - CRM_NOTE("CIB Erase op in progress"); + crm_trace("CIB Erase op in progress"); sys_to = CRM_SYSTEM_DCIB; } else { - cl_log(LOG_ERR, "Unknown daemon options"); + crm_err("Unknown daemon options"); all_is_good = FALSE; } } else if(cib_action != NULL) { msg_data = handleCibMod(); sys_to = CRM_SYSTEM_DCIB; if(msg_data == NULL) all_is_good = FALSE; } else if (DO_DAEMON == TRUE && DO_HEALTH == TRUE) { - CRM_NOTE("Querying the system"); + crm_trace("Querying the system"); sys_to = CRM_SYSTEM_DC; if (status != NULL) { sys_to = CRM_SYSTEM_CRMD; ping_type = CRM_OP_PING; if (BE_VERBOSE) { ping_type = "ping_deep"; if (status != NULL) expected_responses = 2; // 5; // CRM/DC, LRMD, CIB, PENGINE, TENGINE else expected_responses = -1;// wait until timeout instead } set_xml_property_copy(msg_options, XML_ATTR_OP, ping_type); set_xml_property_copy(msg_options, XML_ATTR_TIMEOUT, "0"); dest_node = status; } else { - cl_log(LOG_INFO, "Cluster-wide health not available yet"); + crm_info("Cluster-wide health not available yet"); all_is_good = FALSE; } } else { - cl_log(LOG_ERR, "Unknown options"); + crm_err("Unknown options"); all_is_good = FALSE; } if(all_is_good == FALSE) { - cl_log(LOG_ERR, "Creation of request failed. No message to send"); + crm_err("Creation of request failed. No message to send"); return -1; } /* send it */ if (crmd_channel == NULL) { - cl_log(LOG_ERR, - "The IPC connection is not valid, cannot send anything"); + crm_err("The IPC connection is not valid, cannot send anything"); return -1; } if(sys_to == NULL) { if (dest_node != NULL) sys_to = CRM_SYSTEM_CRMD; else sys_to = CRM_SYSTEM_DC; } send_ipc_request(crmd_channel, msg_options, msg_data, dest_node, sys_to, crm_system_name, admin_uuid, this_msg_reference); return 1; } ll_cluster_t * do_init(void) { int facility; ll_cluster_t *hb_cluster = NULL; /* docs say only do this once, but in their code they do it every time! */ xmlInitParser (); /* change the logging facility to the one used by heartbeat daemon */ hb_cluster = ll_cluster_new("heartbeat"); - cl_log(LOG_INFO, "Switching to Heartbeat logger"); + crm_info("Switching to Heartbeat logger"); if (( facility = hb_cluster->llc_ops->get_logfacility(hb_cluster)) > 0) { cl_log_set_facility(facility); } admin_uuid = crm_malloc(sizeof(char) * 11); snprintf(admin_uuid, 10, "%d", getpid()); admin_uuid[10] = '\0'; crmd_channel = init_client_ipc_comms(CRM_SYSTEM_CRMD,admin_msg_callback,NULL); if(crmd_channel != NULL) { send_hello_message(crmd_channel, admin_uuid, crm_system_name, "0", "1"); return hb_cluster; } return NULL; } void usage(const char *cmd, int exit_status) { FILE *stream; stream = exit_status ? stderr : stdout; fprintf(stream, "usage: %s [-srkh]" "[-c configure file]\n", cmd); /* fprintf(stream, "\t-d\tsets debug level\n"); */ /* fprintf(stream, "\t-s\tgets daemon status\n"); */ /* fprintf(stream, "\t-r\trestarts daemon\n"); */ /* fprintf(stream, "\t-k\tstops daemon\n"); */ /* fprintf(stream, "\t-h\thelp message\n"); */ fflush(stream); exit(exit_status); } const char *ournode; gboolean admin_msg_callback(IPC_Channel * server, void *private_data) { int lpc = 0; IPC_Message *msg = NULL; gboolean hack_return_good = TRUE; static int received_responses = 0; char *filename; int filename_len = 0; const char *result = NULL; xmlNodePtr options = NULL; xmlNodePtr xml_root_node = NULL; char *buffer = NULL; FNIN(); while (server->ch_status != IPC_DISCONNECT && server->ops->is_message_pending(server) == TRUE) { if (server->ops->recv(server, &msg) != IPC_OK) { perror("Receive failure:"); FNRET(!hack_return_good); } if (msg == NULL) { - CRM_NOTE("No message this time"); + crm_trace("No message this time"); continue; } lpc++; buffer =(char *) msg->msg_body; - CRM_DEBUG("Got xml [text=%s]", buffer); + crm_verbose("Got xml [text=%s]", buffer); xml_root_node = find_xml_in_ipcmessage(msg, TRUE); if (xml_root_node == NULL) { - cl_log(LOG_INFO, + crm_info( "XML in IPC message was not valid... " "discarding."); continue; } else if (validate_crm_message(xml_root_node, crm_system_name, admin_uuid, "response") == FALSE) { - cl_log(LOG_INFO, + crm_info( "Message was not a CRM response. Discarding."); continue; } options = find_xml_node(xml_root_node, XML_TAG_OPTIONS); result = xmlGetProp(options, XML_ATTR_RESULT); if(result == NULL || strcmp(result, "ok") == 0) { result = "pass"; } else { result = "fail"; } received_responses++; // do stuff if (this_msg_reference != NULL) { // in testing mode... /* 31 = "test-_.xml" + an_int_as_string + '\0' */ filename_len = 31 + strlen(this_msg_reference); filename = crm_malloc(sizeof(char) * filename_len); sprintf(filename, "%s-%s_%d.xml", result, this_msg_reference, received_responses); filename[filename_len - 1] = '\0'; if (xmlSaveFormatFile(filename, xml_root_node->doc, 1) < 0) { - cl_log(LOG_CRIT, - "Could not save response %s_%s_%d.xml", - this_msg_reference, - result, - received_responses); + crm_crit("Could not save response %s_%s_%d.xml", + this_msg_reference, + result, + received_responses); } } } if (server->ch_status == IPC_DISCONNECT) { - cl_log(LOG_INFO, "admin_msg_callback: received HUP"); + crm_info("admin_msg_callback: received HUP"); FNRET(!hack_return_good); } if (received_responses >= expected_responses) { - cl_log(LOG_INFO, + crm_info( "Recieved expected number (%d) of messages from Heartbeat." " Exiting normally.", expected_responses); g_main_quit(mainloop); return !hack_return_good; } FNRET(hack_return_good); } diff --git a/crm/cib/cib.c b/crm/cib/cib.c index 2aef6981b0..d134459c82 100644 --- a/crm/cib/cib.c +++ b/crm/cib/cib.c @@ -1,313 +1,310 @@ -/* $Id: cib.c,v 1.39 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: cib.c,v 1.40 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <clplumbing/cl_log.h> #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/msg.h> #include <cibio.h> #include <cibmessages.h> #include <crm/dmalloc_wrapper.h> gboolean startCib(const char *filename) { xmlNodePtr cib = readCibXmlFile(filename); if (initializeCib(cib)) { - cl_log(LOG_INFO, - "CIB Initialization completed successfully"); + crm_info("CIB Initialization completed successfully"); } else { // free_xml(cib); - cl_log(LOG_WARNING, - "CIB Initialization failed, " - "starting with an empty default."); + crm_warn("CIB Initialization failed, " + "starting with an empty default."); activateCibXml(createEmptyCib(), filename); } return TRUE; } xmlNodePtr get_cib_copy() { return copy_xml_node_recursive(get_the_CIB()); } /* * The caller should never free the return value */ xmlNodePtr get_object_root(const char *object_type, xmlNodePtr the_root) { const char *node_stack[2]; xmlNodePtr tmp_node = NULL; FNIN(); node_stack[0] = XML_CIB_TAG_CONFIGURATION; node_stack[1] = object_type; if(object_type == NULL || strlen(object_type) == 0) { FNRET(the_root); /* get the whole cib */ } else if(strcmp(object_type, XML_CIB_TAG_STATUS) == 0) { node_stack[0] = XML_CIB_TAG_STATUS; node_stack[1] = NULL; /* these live in a different place */ } tmp_node = find_xml_node_nested(the_root, node_stack, 2); if (tmp_node == NULL) { - cl_log(LOG_ERR, + crm_err( "[cib] Section cib[%s[%s]] not present", node_stack[0], node_stack[1]); } FNRET(tmp_node); } xmlNodePtr process_cib_message(xmlNodePtr message, gboolean auto_reply) { xmlNodePtr data; xmlNodePtr reply; enum cib_result result = CIBRES_OK; xmlNodePtr fragment = find_xml_node(message, XML_TAG_FRAGMENT); xmlNodePtr options = find_xml_node(message, XML_TAG_OPTIONS); const char *op = get_xml_attr (message, XML_TAG_OPTIONS, XML_ATTR_OP, TRUE); data = cib_process_request(op, options, fragment, &result); - CRM_DEBUG("[cib] operation returned result %d", result); + crm_verbose("[cib] operation returned result %d", result); if(auto_reply) { reply = create_reply(message, data); free_xml(data); // TODO: put real result in here set_xml_attr(reply, XML_TAG_OPTIONS, XML_ATTR_RESULT, "ok", TRUE); return reply; } return data; } xmlNodePtr process_cib_request(const char *op, const xmlNodePtr options, const xmlNodePtr fragment) { enum cib_result result = CIBRES_OK; return cib_process_request(op, options, fragment, &result); } xmlNodePtr create_cib_fragment(xmlNodePtr update, const char *section) { gboolean whole_cib = FALSE; xmlNodePtr fragment = create_xml_node(NULL, XML_TAG_FRAGMENT); xmlNodePtr cib = NULL; xmlNodePtr object_root = NULL; char *auto_section = pluralSection(update?update->name:NULL); if(update == NULL) { - cl_log(LOG_ERR, "No update to create a fragment for"); + crm_err("No update to create a fragment for"); crm_free(auto_section); return NULL; } else if(section == NULL) { section = auto_section; } else if(strcmp(auto_section, section) != 0) { - cl_log(LOG_ERR, - "Values for update (tag=%s) and section (%s)" - " were not consistent", update->name, section); + crm_err("Values for update (tag=%s) and section (%s)" + " were not consistent", update->name, section); crm_free(auto_section); return NULL; } if(strcmp(section, "all")==0 && strcmp(update->name, XML_TAG_CIB)==0) { whole_cib = TRUE; } set_xml_property_copy(fragment, XML_ATTR_SECTION, section); if(whole_cib == FALSE) { cib = createEmptyCib(); object_root = get_object_root(section, cib); xmlAddChildList(object_root, xmlCopyNodeList(update)); } else { cib = xmlCopyNodeList(update); } xmlAddChild(fragment, cib); crm_free(auto_section); return fragment; } char * pluralSection(const char *a_section) { char *a_section_parent = NULL; if (a_section == NULL) { a_section_parent = crm_strdup("all"); } else if(strcmp(a_section, XML_TAG_CIB) == 0) { a_section_parent = crm_strdup("all"); } else if(strcmp(a_section, XML_CIB_TAG_NODE) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_NODES); } else if(strcmp(a_section, XML_CIB_TAG_STATE) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_STATUS); } else if(strcmp(a_section, XML_CIB_TAG_CONSTRAINT) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_CONSTRAINTS); } else if(strcmp(a_section, XML_CIB_TAG_RESOURCE) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_RESOURCES); } else { - cl_log(LOG_ERR, "Unknown section %s", a_section); + crm_err("Unknown section %s", a_section); a_section_parent = crm_strdup("all"); } - CRM_DEBUG("Plural is %s", a_section_parent); + crm_verbose("Plural is %s", a_section_parent); return a_section_parent; } const char * cib_error2string(enum cib_result return_code) { const char *error_msg = NULL; switch(return_code) { case CIBRES_MISSING_ID: error_msg = "The id field is missing"; break; case CIBRES_MISSING_TYPE: error_msg = "The type field is missing"; break; case CIBRES_MISSING_FIELD: error_msg = "A required field is missing"; break; case CIBRES_OBJTYPE_MISMATCH: error_msg = "CIBRES_OBJTYPE_MISMATCH"; break; case CIBRES_FAILED_EXISTS: error_msg = "The object already exists"; break; case CIBRES_FAILED_NOTEXISTS: error_msg = "The object does not exist"; break; case CIBRES_CORRUPT: error_msg = "The CIB is corrupt"; break; case CIBRES_FAILED_NOOBJECT: error_msg = "The update was empty"; break; case CIBRES_FAILED_NOPARENT: error_msg = "The parent object does not exist"; break; case CIBRES_FAILED_NODECOPY: error_msg = "Failed while copying update"; break; case CIBRES_OTHER: error_msg = "CIBRES_OTHER"; break; case CIBRES_OK: error_msg = "ok"; break; case CIBRES_FAILED: error_msg = "Failed"; break; case CIBRES_FAILED_STALE: error_msg = "Discarded old update"; break; case CIBRES_FAILED_ACTIVATION: error_msg = "Activation Failed"; break; case CIBRES_FAILED_NOSECTION: error_msg = "Required section was missing"; break; case CIBRES_FAILED_NOTSUPPORTED: error_msg = "Supplied information is not supported"; break; } if(error_msg == NULL) { - cl_log(LOG_ERR, "Unknown CIB Error %d", return_code); + crm_err("Unknown CIB Error %d", return_code); error_msg = "<unknown error>"; } return error_msg; } const char * cib_op2string(enum cib_op operation) { const char *operation_msg = NULL; switch(operation) { case 0: operation_msg = "none"; break; case 1: operation_msg = "add"; break; case 2: operation_msg = "modify"; break; case 3: operation_msg = "delete"; break; case CIB_OP_MAX: operation_msg = "invalid operation"; break; } if(operation_msg == NULL) { - cl_log(LOG_ERR, "Unknown CIB operation %d", operation); + crm_err("Unknown CIB operation %d", operation); operation_msg = "<unknown operation>"; } return operation_msg; } diff --git a/crm/cib/cibio.c b/crm/cib/cibio.c index 7993954516..e1fdba9646 100644 --- a/crm/cib/cibio.c +++ b/crm/cib/cibio.c @@ -1,427 +1,419 @@ -/* $Id: cibio.c,v 1.25 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: cibio.c,v 1.26 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <crm/crm.h> #include <cibio.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/util.h> #include <crm/dmalloc_wrapper.h> const char * local_resource_path[] = { XML_CIB_TAG_STATUS, }; const char * resource_path[] = { XML_CIB_TAG_RESOURCES, }; const char * node_path[] = { XML_CIB_TAG_NODES, }; const char * constraint_path[] = { XML_CIB_TAG_CONSTRAINTS, }; gboolean initialized = FALSE; xmlNodePtr the_cib = NULL; xmlNodePtr node_search = NULL; xmlNodePtr resource_search = NULL; xmlNodePtr constraint_search = NULL; xmlNodePtr status_search = NULL; /* * It is the callers responsibility to free both the new CIB (output) * and the new CIB (input) */ xmlNodePtr createEmptyCib(void) { xmlNodePtr cib_root = NULL, config = NULL, status = NULL; cib_root = create_xml_node(NULL, XML_TAG_CIB); config = create_xml_node(cib_root, XML_CIB_TAG_CONFIGURATION); status = create_xml_node(cib_root, XML_CIB_TAG_STATUS); set_node_tstamp(cib_root); set_node_tstamp(config); set_node_tstamp(status); set_xml_property_copy(cib_root, "version", "1"); set_xml_property_copy(cib_root, "generated", XML_BOOLEAN_TRUE); create_xml_node(config, XML_CIB_TAG_NODES); create_xml_node(config, XML_CIB_TAG_RESOURCES); create_xml_node(config, XML_CIB_TAG_CONSTRAINTS); if (verifyCibXml(cib_root)) { FNRET(cib_root); } - cl_log(LOG_CRIT, + crm_crit( "The generated CIB did not pass integrity testing!!" " All hope is lost."); FNRET(NULL); } gboolean verifyCibXml(xmlNodePtr cib) { gboolean is_valid = TRUE; xmlNodePtr tmp_node = NULL; FNIN(); if (cib == NULL) { - cl_log(LOG_ERR, "XML Buffer was empty."); + crm_err("XML Buffer was empty."); FNRET(FALSE); } tmp_node = get_object_root(XML_CIB_TAG_NODES, cib); if (tmp_node == NULL) is_valid = FALSE; tmp_node = get_object_root(XML_CIB_TAG_RESOURCES, cib); if (tmp_node == NULL) is_valid = FALSE; tmp_node = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); if (tmp_node == NULL) is_valid = FALSE; tmp_node = get_object_root(XML_CIB_TAG_STATUS, cib); if (tmp_node == NULL) is_valid = FALSE; // more integrity tests FNRET(is_valid); } /* * It is the callers responsibility to free the output of this function */ xmlNodePtr readCibXml(char *buffer) { xmlNodePtr root = string2xml(buffer); if (verifyCibXml(root) == FALSE) { free_xml(root); FNRET(createEmptyCib()); } FNRET(root); } /* * It is the callers responsibility to free the output of this function */ xmlNodePtr readCibXmlFile(const char *filename) { int s_res = -1; struct stat buf; xmlNodePtr root = NULL; FNIN(); if(filename != NULL) { s_res = stat(filename, &buf); } if (s_res == 0) { FILE *cib_file = fopen(filename, "r"); root = file2xml(cib_file); set_xml_property_copy(root, "generated", XML_BOOLEAN_FALSE); fclose(cib_file); } else { - cl_log(LOG_WARNING, - "Stat of (%s) failed, file does not exist.", - CIB_FILENAME); + crm_warn("Stat of (%s) failed, file does not exist.", + CIB_FILENAME); } if (verifyCibXml(root) == FALSE) { free_xml(root); // FNRET(createEmptyCib()); root = NULL; } FNRET(root); } /* * The caller should never free the return value */ xmlNodePtr get_the_CIB(void) { FNIN(); FNRET(the_cib); } gboolean uninitializeCib(void) { xmlNodePtr tmp_cib = the_cib; FNIN(); if(tmp_cib == NULL) { - cl_log(LOG_ERR, "The CIB has already been deallocated."); + crm_err("The CIB has already been deallocated."); FNRET(FALSE); } initialized = FALSE; the_cib = NULL; node_search = NULL; resource_search = NULL; constraint_search = NULL; status_search = NULL; - cl_log(LOG_WARNING, "Deallocating the CIB."); + crm_err("Deallocating the CIB."); free_xml(tmp_cib); - cl_log(LOG_WARNING, "The CIB has been deallocated."); + crm_err("The CIB has been deallocated."); FNRET(TRUE); } /* * This method will not free the old CIB pointer or the new one. * We rely on the caller to have saved a pointer to the old CIB * and to free the old/bad one depending on what is appropriate. */ gboolean initializeCib(xmlNodePtr new_cib) { if (verifyCibXml(new_cib)) { initialized = FALSE; the_cib = new_cib; // update search paths /* not used yet... node_search = get_object_root(XML_CIB_TAG_NODES, new_cib); resource_search = get_object_root(XML_CIB_TAG_RESOURCES, new_cib); constraint_search = get_object_root(XML_CIB_TAG_CONSTRAINTS, new_cib); status_search = get_object_root(XML_CIB_TAG_STATUS, new_cib); */ initialized = TRUE; - CRM_NOTE("CIB initialized"); + crm_trace("CIB initialized"); FNRET(TRUE); } else { - cl_log(LOG_ERR, "CIB Verification failed"); + crm_err("CIB Verification failed"); } FNRET(FALSE); } int moveFile(const char *oldname, const char *newname, gboolean backup, char *ext) { /* move 'oldname' to 'newname' by creating a hard link to it * and then removing the original hard link */ int res = 0; struct stat tmp; int s_res = stat(newname, &tmp); FNIN(); if (s_res >= 0) { if (backup == TRUE) { char backname[1024]; static const char *back_ext = "bak"; if (ext != NULL) back_ext = (char*)ext; snprintf(backname, sizeof(backname)-1, "%s.%s", newname, back_ext); moveFile(newname, backname, FALSE, NULL); } else { res = unlink(newname); if (res < 0) { perror("Could not remove the current backup of Cib"); FNRET(-1); } } } s_res = stat(oldname, &tmp); if (s_res >= 0) { res = link(oldname, newname); if (res < 0) { perror("Could not create backup of current Cib"); FNRET(-2); } res = unlink(oldname); if (res < 0) { perror("Could not unlink the current Cib"); FNRET(-3); } } FNRET(0); } int activateCibBuffer(char *buffer, const char *filename) { int result = -1; xmlNodePtr local_cib = NULL; FNIN(); local_cib = readCibXml(buffer); result = activateCibXml(local_cib, filename); FNRET(result); } /* * This method will free the old CIB pointer on success and the new one * on failure. */ int activateCibXml(xmlNodePtr new_cib, const char *filename) { int error_code = 0; xmlNodePtr saved_cib = get_the_CIB(); const char *filename_bak = CIB_BACKUP; // calculate xmlDocPtr foo; FNIN(); if (initializeCib(new_cib) == TRUE) { int res = moveFile(filename, filename_bak, FALSE, NULL); if (res < 0) { - cl_log(LOG_INFO, - "Could not make backup of the current Cib " - "(code: %d)... aborting update.", res); + crm_info("Could not make backup of the current Cib " + "(code: %d)... aborting update.", res); error_code = -1; } else { - cl_log(LOG_INFO, - "Writing CIB out to %s", - CIB_FILENAME); + crm_info("Writing CIB out to %s", CIB_FILENAME); if (new_cib->doc == NULL) { foo = xmlNewDoc("1.0"); xmlDocSetRootElement(foo, new_cib); xmlSetTreeDoc(new_cib,foo); } time_t now = time(NULL); char *now_str = asctime(localtime(&now)); set_xml_property_copy(new_cib, "last_written",now_str); free(now_str); /* save it. * set arg 3 to 0 to disable line breaks,1 to enable * res == num bytes saved */ res = xmlSaveFormatFile(filename, new_cib->doc, 1); /* for some reason, reading back after saving with * line-breaks doesnt go real well */ - cl_log(LOG_INFO, - "Saved %d bytes to the Cib as XML", - res); + crm_info("Saved %d bytes to the Cib as XML", + res); if (res < 0) { // assume 0 is good if (moveFile(filename_bak, filename, FALSE, NULL) < -1) { - cl_log(LOG_CRIT, - "Could not restore the " - "backup of the current Cib " - "(code: %d)... panic!", - res); + crm_crit("Could not restore the " + "backup of the current Cib " + "(code: %d)... panic!", + res); error_code = -2; // should probably exit here } else if (initializeCib(saved_cib) == FALSE) { // oh we are so dead - cl_log(LOG_CRIT, - "Could not re-initialize " - "with the old CIB. " - "Everything is about to go " - "pear shaped"); + crm_crit("Could not re-initialize " + "with the old CIB. " + "Everything is about to go " + "pear shaped"); error_code = -3; } else { - cl_log(LOG_CRIT, - "Update of Cib failed " - "(code: %d)... reverted to " - "last known valid version", - res); + crm_crit("Update of Cib failed " + "(code: %d)... reverted to " + "last known valid version", + res); error_code = -4; } } } } else { - cl_log(LOG_INFO, "Ignoring invalid or NULL Cib"); + crm_info("Ignoring invalid or NULL Cib"); error_code = -5; } // Make sure memory is cleaned up appropriately if (error_code != 0) { -// CRM_DEBUG("Freeing new CIB %p", new_cib); + crm_trace("Freeing new CIB %p", new_cib); free_xml(new_cib); } else { -// CRM_DEBUG("Freeing saved CIB %p", saved_cib); + crm_trace("Freeing saved CIB %p", saved_cib); free_xml(saved_cib); } FNRET(error_code); } diff --git a/crm/cib/cibmain.c b/crm/cib/cibmain.c index 5896ff8c0a..3eec1dcf7d 100644 --- a/crm/cib/cibmain.c +++ b/crm/cib/cibmain.c @@ -1,264 +1,261 @@ -/* $Id: cibmain.c,v 1.21 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: cibmain.c,v 1.22 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <hb_api.h> #include <clplumbing/uids.h> //#include <ocf/oc_event.h> #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/ipc.h> #include <crm/common/ctrl.h> #include <crm/common/xml.h> #include <crm/common/msg.h> #include <cibio.h> #include <crm/dmalloc_wrapper.h> /* #define REALTIME_SUPPORT 0 */ #define PID_FILE WORKING_DIR"/cib.pid" #define DAEMON_LOG LOG_DIR"/cib.log" #define DAEMON_DEBUG LOG_DIR"/cib.debug" GMainLoop* mainloop = NULL; const char* crm_system_name = CRM_SYSTEM_CIB; void usage(const char* cmd, int exit_status); int init_start(void); void cib_shutdown(int nsig); gboolean cib_msg_callback(IPC_Channel *client, gpointer user_data); gboolean process_maincib_message(xmlNodePtr msg, IPC_Channel *sender); #define OPTARGS "skrh" int main(int argc, char ** argv) { int req_comms_restart = FALSE; int req_restart = FALSE; int req_status = FALSE; int req_stop = FALSE; int argerr = 0; int flag; cl_log_set_entity(crm_system_name); cl_log_enable_stderr(TRUE); cl_log_set_facility(LOG_USER); while ((flag = getopt(argc, argv, OPTARGS)) != EOF) { switch(flag) { case 's': /* Status */ req_status = TRUE; break; case 'k': /* Stop (kill) */ req_stop = TRUE; break; case 'r': /* Restart */ req_restart = TRUE; break; case 'c': /* Restart */ req_comms_restart = TRUE; break; case 'h': /* Help message */ usage(crm_system_name, LSB_EXIT_OK); break; default: ++argerr; break; } } if (optind > argc) { ++argerr; } if (argerr) { usage(crm_system_name,LSB_EXIT_GENERIC); } // read local config file if (req_status){ FNRET(init_status(PID_FILE, crm_system_name)); } if (req_stop){ FNRET(init_stop(PID_FILE)); } if (req_restart) { init_stop(PID_FILE); } FNRET(init_start()); } int init_start(void) { long pid; ll_cluster_t *hb_fd; int facility; IPC_Channel *crm_ch = NULL; #ifdef REALTIME_SUPPORT static int crm_realtime = 1; #endif if ((pid = get_running_pid(PID_FILE, NULL)) > 0) { - cl_log(LOG_CRIT, "already running: [pid %ld].", pid); + crm_crit("already running: [pid %ld].", pid); exit(LSB_EXIT_OK); } - cl_log(LOG_INFO, "Register PID"); + crm_info("Register PID"); register_pid(PID_FILE, FALSE, cib_shutdown); cl_log_set_logfile(DAEMON_LOG); -// if (crm_debug()) { +// if (crm_verbose()) { cl_log_set_debugfile(DAEMON_DEBUG); // } hb_fd = ll_cluster_new("heartbeat"); - cl_log(LOG_INFO, "Switching to Heartbeat logger"); + crm_info("Switching to Heartbeat logger"); if ((facility = hb_fd->llc_ops->get_logfacility(hb_fd))>0) { cl_log_set_facility(facility); } if(startCib(CIB_FILENAME) == FALSE){ - cl_log(LOG_CRIT, "Cannot start CIB... terminating"); + crm_crit("Cannot start CIB... terminating"); exit(1); } crm_ch = init_client_ipc_comms(CRM_SYSTEM_CRMD, subsystem_input_dispatch, (void*)process_maincib_message); if(crm_ch != NULL) { send_hello_message(crm_ch, "-", CRM_SYSTEM_CIB, "0", "1"); /* Create the mainloop and run it... */ mainloop = g_main_new(FALSE); - cl_log(LOG_INFO, "Starting %s", crm_system_name); + crm_info("Starting %s", crm_system_name); #ifdef REALTIME_SUPPORT if (crm_realtime == 1) { cl_enable_realtime(); } else if (crm_realtime == 0) { cl_disable_realtime(); } cl_make_realtime(SCHED_RR, 5, 64, 64); #endif g_main_run(mainloop); return_to_orig_privs(); } else { - cl_log(LOG_ERR, "Connection to CRM not valid, exiting."); + crm_err("Connection to CRM not valid, exiting."); } if (unlink(PID_FILE) == 0) { - cl_log(LOG_INFO, "[%s] stopped", crm_system_name); + crm_info("[%s] stopped", crm_system_name); } FNRET(0); } gboolean process_maincib_message(xmlNodePtr msg, IPC_Channel *sender) { const char *op = get_xml_attr (msg, XML_TAG_OPTIONS, XML_ATTR_OP, FALSE); const char *sys_to = xmlGetProp(msg, XML_ATTR_SYSTO); - cl_log(LOG_DEBUG, "Processing %s message", op); + crm_debug("Processing %s message", op); if(safe_str_eq(xmlGetProp(msg, XML_ATTR_MSGTYPE), XML_ATTR_REQUEST)) { - cl_log(LOG_INFO, - "Message was a response not a request." - " Discarding"); + crm_info("Message was a response not a request." + " Discarding"); } else if (strcmp(sys_to, CRM_SYSTEM_CIB) == 0 || strcmp(sys_to, CRM_SYSTEM_DCIB) == 0) { xmlNodePtr answer = process_cib_message(msg, TRUE); if (send_xmlipc_message(sender, answer)==FALSE) - cl_log(LOG_WARNING, - "Cib answer could not be sent"); + crm_warn("Cib answer could not be sent"); free_xml(answer); } else { - cl_log(LOG_WARNING, - "Received a message destined for %s by mistake", - sys_to); + crm_warn("Received a message destined for %s by mistake", + sys_to); FNRET(FALSE); } FNRET(TRUE); } void usage(const char* cmd, int exit_status) { FILE* stream; stream = exit_status ? stderr : stdout; fprintf(stream, "usage: %s [-srkh]" "[-c configure file]\n", cmd); /* fprintf(stream, "\t-d\tsets debug level\n"); */ /* fprintf(stream, "\t-s\tgets daemon status\n"); */ /* fprintf(stream, "\t-r\trestarts daemon\n"); */ /* fprintf(stream, "\t-k\tstops daemon\n"); */ /* fprintf(stream, "\t-h\thelp message\n"); */ fflush(stream); exit(exit_status); } void cib_shutdown(int nsig) { static int shuttingdown = 0; CL_SIGNAL(nsig, cib_shutdown); if (!shuttingdown) { shuttingdown = 1; } if (mainloop != NULL && g_main_is_running(mainloop)) { g_main_quit(mainloop); } else { exit(LSB_EXIT_OK); } } diff --git a/crm/cib/cibmessages.c b/crm/cib/cibmessages.c index 0c86a0c96d..4ce013ea9e 100644 --- a/crm/cib/cibmessages.c +++ b/crm/cib/cibmessages.c @@ -1,474 +1,472 @@ -/* $Id: cibmessages.c,v 1.38 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: cibmessages.c,v 1.39 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <clplumbing/cl_log.h> #include <time.h> #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/msg.h> #include <crm/common/xml.h> #include <cibio.h> #include <cibmessages.h> #include <cibprimatives.h> #include <crm/dmalloc_wrapper.h> FILE *msg_cib_strm = NULL; enum cib_result updateList(xmlNodePtr local_cib, xmlNodePtr update_command, xmlNodePtr failed, int operation, const char *section); xmlNodePtr createCibFragmentAnswer(const char *section, xmlNodePtr failed); gboolean replace_section(const char *section, xmlNodePtr tmpCib, xmlNodePtr command); gboolean check_generation(xmlNodePtr newCib, xmlNodePtr oldCib); gboolean update_results(xmlNodePtr failed, xmlNodePtr target, int operation, int return_code); xmlNodePtr cib_process_request(const char *op, const xmlNodePtr options, const xmlNodePtr fragment, enum cib_result *result) { const char *verbose = NULL; const char *section = NULL; const char *output_section = NULL; xmlNodePtr failed = NULL; xmlNodePtr cib_answer = NULL; gboolean update_the_cib = FALSE; int cib_update_op = CIB_OP_NONE; xmlNodePtr tmpCib; char *new_value = NULL; char *old_value = NULL; int int_value = -1; FNIN(); *result = CIBRES_OK; verbose = xmlGetProp(options, XML_ATTR_VERBOSE); section = xmlGetProp(options, XML_ATTR_FILTER_TYPE); failed = create_xml_node(NULL, XML_TAG_FAILED); #ifdef MSG_LOG if(msg_cib_strm == NULL) { msg_cib_strm = fopen("/tmp/cib.log", "w"); } fprintf(msg_cib_strm, "[Input %s]\t%s\n", op, dump_xml_node(fragment, FALSE)); fflush(msg_cib_strm); #endif - cl_log(LOG_DEBUG, "[cib] Processing \"%s\" event", op); + crm_debug("[cib] Processing \"%s\" event", op); if(op == NULL) { *result = CIBRES_FAILED; - cl_log(LOG_ERR, "No operation specified\n"); + crm_err("No operation specified\n"); } else if(strcmp("noop", op) == 0) { ; } else if(strcmp(CRM_OP_QUIT, op) == 0) { - cl_log(LOG_WARNING, + crm_warn( "The CRMd has asked us to exit... complying"); exit(0); } else if (strcmp(CRM_OP_PING, op) == 0) { cib_answer = createPingAnswerFragment(CRM_SYSTEM_CIB, "ok"); } else if (strcmp(CRM_OP_BUMP, op) == 0) { tmpCib = get_cib_copy(); - CRM_DEBUG("Handling a %s for section=%s of the cib", + crm_verbose("Handling a %s for section=%s of the cib", CRM_OP_BUMP, section); // modify the timestamp set_node_tstamp(tmpCib); old_value = xmlGetProp(get_the_CIB(), XML_ATTR_GENERATION); if(old_value != NULL) { new_value = (char*)crm_malloc(128*(sizeof(char))); int_value = atoi(old_value); sprintf(new_value, "%d", ++int_value); } else { new_value = crm_strdup("0"); } - cl_log(LOG_DEBUG, "Generation %d(%s)->%s", + crm_debug("Generation %d(%s)->%s", int_value, old_value, new_value); set_xml_property_copy(tmpCib, XML_ATTR_GENERATION, new_value); crm_free(new_value); if(activateCibXml(tmpCib, CIB_FILENAME) >= 0) { verbose = XML_BOOLEAN_TRUE; } else { *result = CIBRES_FAILED; } } else if (strcmp("query", op) == 0) { - CRM_DEBUG("Handling a query for section=%s of the cib", + crm_verbose("Handling a query for section=%s of the cib", section); /* force a pick-up of the relevant section before * returning */ verbose = XML_BOOLEAN_TRUE; } else if (strcmp(CRM_OP_ERASE, op) == 0) { xmlNodePtr new_cib = createEmptyCib(); // Preserve generation counters etc copy_in_properties(new_cib, get_the_CIB()); if (activateCibXml(new_cib, CIB_FILENAME) < 0) { *result = CIBRES_FAILED; } } else if (strcmp(CRM_OP_CREATE, op) == 0) { update_the_cib = TRUE; cib_update_op = CIB_OP_ADD; } else if (strcmp(CRM_OP_UPDATE, op) == 0 || strcmp(CRM_OP_WELCOME, op) == 0 || strcmp(CRM_OP_SHUTDOWN_REQ, op) == 0) { update_the_cib = TRUE; cib_update_op = CIB_OP_MODIFY; } else if (strcmp(CRM_OP_DELETE, op) == 0) { update_the_cib = TRUE; cib_update_op = CIB_OP_DELETE; } else if (strcmp(CRM_OP_REPLACE, op) == 0) { - CRM_DEBUG("Replacing section=%s of the cib", section); + crm_verbose("Replacing section=%s of the cib", section); section = xmlGetProp(fragment, XML_ATTR_SECTION); if (section == NULL || strlen(section) == 0 || strcmp("all", section) == 0) { tmpCib = copy_xml_node_recursive( find_xml_node(fragment, XML_TAG_CIB)); } else { tmpCib = copy_xml_node_recursive(get_the_CIB()); replace_section(section, tmpCib, fragment); } /*if(check_generation(cib_updates, tmpCib) == FALSE) *result = "discarded old update"; else */ if (activateCibXml(tmpCib, CIB_FILENAME) < 0) *result = CIBRES_FAILED; } else { *result = CIBRES_FAILED_NOTSUPPORTED; - cl_log(LOG_ERR, "Action [%s] is not supported by the CIB", op); + crm_err("Action [%s] is not supported by the CIB", op); } if (update_the_cib) { tmpCib = copy_xml_node_recursive(get_the_CIB()); section = xmlGetProp(fragment, XML_ATTR_SECTION); - CRM_DEBUG("Updating section=%s of the cib (op=%s)", + crm_verbose("Updating section=%s of the cib (op=%s)", section, op); // should we be doing this? // do logging // make changes to a temp copy then activate if(section == NULL) { - cl_log(LOG_ERR, "No section specified in %s", + crm_err("No section specified in %s", XML_ATTR_FILTER_TYPE); *result = CIBRES_FAILED_NOSECTION; } else if(strcmp("all", section) == 0 && cib_update_op == CIB_OP_DELETE) { // delete /* order is no longer important here */ updateList(tmpCib, fragment, failed, cib_update_op, XML_CIB_TAG_STATUS); updateList(tmpCib, fragment, failed, cib_update_op, XML_CIB_TAG_CONSTRAINTS); updateList(tmpCib, fragment, failed, cib_update_op, XML_CIB_TAG_RESOURCES); updateList(tmpCib, fragment, failed, cib_update_op, XML_CIB_TAG_NODES); } else if(strcmp("all", section) == 0) { /* order is no longer important here */ updateList(tmpCib, fragment, failed, cib_update_op, XML_CIB_TAG_NODES); updateList(tmpCib, fragment, failed, cib_update_op, XML_CIB_TAG_RESOURCES); updateList(tmpCib, fragment, failed, cib_update_op, XML_CIB_TAG_CONSTRAINTS); updateList(tmpCib, fragment, failed, cib_update_op, XML_CIB_TAG_STATUS); } else { *result = updateList(tmpCib, fragment, failed, cib_update_op, section); } - CRM_NOTE("Activating temporary CIB"); + crm_trace("Activating temporary CIB"); /* if(check_generation(cib_updates, tmpCib) == FALSE) */ /* status = "discarded old update"; */ /* else */ if (activateCibXml(tmpCib, CIB_FILENAME) < 0) { *result = CIBRES_FAILED_ACTIVATION; } else if (failed->children != NULL) { *result = CIBRES_FAILED; } - CRM_DEBUG("CIB update status: %d", *result); + crm_verbose("CIB update status: %d", *result); } output_section = section; if (failed->children != NULL || *result != CIBRES_OK) { cib_answer = createCibFragmentAnswer(NULL /*"all"*/, failed); } else if (verbose != NULL && strcmp(XML_BOOLEAN_TRUE, verbose) == 0) { cib_answer = createCibFragmentAnswer(output_section, failed); } free_xml(failed); #ifdef MSG_LOG fprintf(msg_cib_strm, "[Reply (%s)]\t%s\n", op, dump_xml_node(cib_answer, FALSE)); fflush(msg_cib_strm); #endif FNRET(cib_answer); } gboolean replace_section(const char *section, xmlNodePtr tmpCib, xmlNodePtr fragment) { xmlNodePtr parent = NULL, cib_updates = NULL, new_section = NULL, old_section = NULL; FNIN(); cib_updates = find_xml_node(fragment, XML_TAG_CIB); /* find the old and new versions of the section */ new_section = get_object_root(section, cib_updates); old_section = get_object_root(section, tmpCib); if(old_section == NULL) { - cl_log(LOG_ERR, - "The CIB is corrupt, cannot replace missing section %s", + crm_err("The CIB is corrupt, cannot replace missing section %s", section); FNRET(FALSE); } else if(new_section == NULL) { - cl_log(LOG_ERR, - "The CIB is corrupt, cannot set section %s to nothing", + crm_err("The CIB is corrupt, cannot set section %s to nothing", section); FNRET(FALSE); } parent = old_section->parent; /* unlink and free the old one */ unlink_xml_node(old_section); free_xml(old_section); /* add the new copy */ add_node_copy(parent, new_section); FNRET(TRUE); } enum cib_result updateList(xmlNodePtr local_cib, xmlNodePtr update_fragment, xmlNodePtr failed, int operation, const char *section) { xmlNodePtr child = NULL; xmlNodePtr this_section = get_object_root(section, local_cib); xmlNodePtr cib_updates = find_xml_node(update_fragment, XML_TAG_CIB); xmlNodePtr xml_section = get_object_root(section, cib_updates); if (section == NULL || xml_section == NULL) { - cl_log(LOG_ERR, "Section %s not found in message." + crm_err("Section %s not found in message." " CIB update is corrupt, ignoring.", section); return CIBRES_FAILED_NOSECTION; } if(CIB_OP_NONE > operation > CIB_OP_MAX) { - cl_log(LOG_ERR, "Invalid operation on section %s", section); + crm_err("Invalid operation on section %s", section); return CIBRES_FAILED; } set_node_tstamp(this_section); child = xml_section->children; while(child != NULL) { if(operation == CIB_OP_DELETE) { update_results(failed, child, operation, delete_cib_object(this_section, child)); } else if(operation == CIB_OP_MODIFY) { update_results(failed, child, operation, update_cib_object(this_section, child, FALSE)); } else { update_results(failed, child, operation, add_cib_object(this_section, child)); } child = child->next; } if (failed->children != NULL) return CIBRES_FAILED; else return CIBRES_OK; } xmlNodePtr createCibFragmentAnswer(const char *section, xmlNodePtr failed) { xmlNodePtr fragment = create_xml_node(NULL, XML_TAG_FRAGMENT); FNIN(); set_xml_property_copy(fragment, XML_ATTR_SECTION, section); if (section == NULL || strlen(section) == 0 || strcmp("all", section) == 0) { add_node_copy(fragment, get_the_CIB()); } else { xmlNodePtr cib = create_xml_node(fragment, XML_TAG_CIB); add_node_copy(cib, get_object_root(section, get_the_CIB())); copy_in_properties(cib, get_the_CIB()); } if (failed != NULL && failed->children != NULL) { add_node_copy(fragment, failed); } FNRET(fragment); } gboolean check_generation(xmlNodePtr newCib, xmlNodePtr oldCib) { char *new_value = xmlGetProp(newCib, XML_ATTR_GENERATION); char *old_value = xmlGetProp(oldCib, XML_ATTR_GENERATION); int int_new_value = -1; int int_old_value = -1; if(old_value != NULL) int_old_value = atoi(old_value); if(new_value != NULL) int_new_value = atoi(new_value); if(int_new_value >= int_old_value) { return TRUE; } else { - cl_log(LOG_ERR, "Generation from update (%d) is older than %d", + crm_err("Generation from update (%d) is older than %d", int_new_value, int_old_value); } return FALSE; } gboolean update_results(xmlNodePtr failed, xmlNodePtr target, int operation, int return_code) { gboolean was_error = FALSE; const char *error_msg = NULL; const char *operation_msg = NULL; xmlNodePtr xml_node; FNIN(); if (return_code != CIBRES_OK) { error_msg = cib_error2string(return_code); operation_msg = cib_op2string(operation); xml_node = create_xml_node(failed, XML_FAIL_TAG_CIB); was_error = TRUE; set_xml_property_copy(xml_node, XML_FAILCIB_ATTR_ID, ID(target)); set_xml_property_copy(xml_node, XML_FAILCIB_ATTR_OBJTYPE, TYPE(target)); set_xml_property_copy(xml_node, XML_FAILCIB_ATTR_OP, operation_msg); set_xml_property_copy(xml_node, XML_FAILCIB_ATTR_REASON, error_msg); - cl_log(LOG_DEBUG, + crm_debug( "Action %s failed: %s (cde=%d)", operation_msg, error_msg, return_code); } FNRET(was_error); } diff --git a/crm/cib/cibprimatives.c b/crm/cib/cibprimatives.c index b9b0811b99..8579c0cffb 100644 --- a/crm/cib/cibprimatives.c +++ b/crm/cib/cibprimatives.c @@ -1,574 +1,574 @@ -/* $Id: cibprimatives.c,v 1.33 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: cibprimatives.c,v 1.34 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <clplumbing/cl_log.h> #include <crm/crm.h> #include <crm/cib.h> #include <cibprimatives.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/dmalloc_wrapper.h> /* * In case of confusion, this is the memory management policy for * all functions in this file. * * All add/modify functions use copies of supplied data. * It is therefore appropriate that the callers free the supplied data * at some point after the function has finished. * * All delete functions will handle the freeing of deleted data * but not the function arguments. */ void update_node_state(xmlNodePtr existing_node, xmlNodePtr update); //--- Resource int addResource(xmlNodePtr cib, xmlNodePtr anXmlNode) { const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Adding " XML_CIB_TAG_RESOURCE " (%s)...", id); + crm_verbose("Adding " XML_CIB_TAG_RESOURCE " (%s)...", id); root = get_object_root(XML_CIB_TAG_RESOURCES, cib); return add_cib_object(root, anXmlNode); } xmlNodePtr findResource(xmlNodePtr cib, const char *id) { xmlNodePtr root = NULL, ret = NULL; FNIN(); root = get_object_root(XML_CIB_TAG_RESOURCES, cib); ret = find_entity(root, XML_CIB_TAG_RESOURCE, id, FALSE); FNRET(ret); } int updateResource(xmlNodePtr cib, xmlNodePtr anXmlNode) { const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Updating " XML_CIB_TAG_RESOURCE " (%s)...", id); + crm_verbose("Updating " XML_CIB_TAG_RESOURCE " (%s)...", id); root = get_object_root(XML_CIB_TAG_RESOURCES, cib); return update_cib_object(root, anXmlNode, FALSE); } int delResource(xmlNodePtr cib, xmlNodePtr delete_spec) { const char *id = ID(delete_spec); xmlNodePtr root; if(id == NULL || strlen(id) == 0) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Deleting " XML_CIB_TAG_RESOURCE " (%s)...", id); + crm_verbose("Deleting " XML_CIB_TAG_RESOURCE " (%s)...", id); root = get_object_root(XML_CIB_TAG_RESOURCES, cib); return delete_cib_object(root, delete_spec); } //--- Constraint int addConstraint(xmlNodePtr cib, xmlNodePtr anXmlNode) { const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Adding " XML_CIB_TAG_CONSTRAINT " (%s)...", id); + crm_verbose("Adding " XML_CIB_TAG_CONSTRAINT " (%s)...", id); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); return add_cib_object(root, anXmlNode); } xmlNodePtr findConstraint(xmlNodePtr cib, const char *id) { xmlNodePtr root = NULL, ret = NULL; FNIN(); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); ret = find_entity(root, XML_CIB_TAG_CONSTRAINT, id, FALSE); FNRET(ret); } int updateConstraint(xmlNodePtr cib, xmlNodePtr anXmlNode) { const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Updating " XML_CIB_TAG_CONSTRAINT " (%s)...", id); + crm_verbose("Updating " XML_CIB_TAG_CONSTRAINT " (%s)...", id); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); return update_cib_object(root, anXmlNode, FALSE); } int delConstraint(xmlNodePtr cib, xmlNodePtr delete_spec) { const char *id = ID(delete_spec); xmlNodePtr root; if(id == NULL || strlen(id) == 0) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Deleting " XML_CIB_TAG_CONSTRAINT " (%s)...", id); + crm_verbose("Deleting " XML_CIB_TAG_CONSTRAINT " (%s)...", id); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); return delete_cib_object(root, delete_spec); } //--- HaNode int addHaNode(xmlNodePtr cib, xmlNodePtr anXmlNode) { const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Adding " XML_CIB_TAG_NODE " (%s)...", id); + crm_verbose("Adding " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_NODES, cib); return add_cib_object(root, anXmlNode); } xmlNodePtr findHaNode(xmlNodePtr cib, const char *id) { xmlNodePtr root = NULL, ret = NULL; FNIN(); root = get_object_root(XML_CIB_TAG_NODES, cib); ret = find_entity(root, XML_CIB_TAG_NODE, id, FALSE); FNRET(ret); } int updateHaNode(xmlNodePtr cib, cibHaNode *anXmlNode) { const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Updating " XML_CIB_TAG_NODE " (%s)...", id); + crm_verbose("Updating " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_NODES, cib); return update_cib_object(root, anXmlNode, FALSE); } int delHaNode(xmlNodePtr cib, xmlNodePtr delete_spec) { const char *id = ID(delete_spec); xmlNodePtr root; if(id == NULL || strlen(id) == 0) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Deleting " XML_CIB_TAG_NODE " (%s)...", id); + crm_verbose("Deleting " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); return delete_cib_object(root, delete_spec); } //--- Status int addStatus(xmlNodePtr cib, xmlNodePtr anXmlNode) { const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Adding " XML_CIB_TAG_NODE " (%s)...", id); + crm_verbose("Adding " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_STATUS, cib); return add_cib_object(root, anXmlNode); } xmlNodePtr findStatus(xmlNodePtr cib, const char *id) { xmlNodePtr root = NULL, ret = NULL; root = get_object_root(XML_CIB_TAG_STATUS, cib); ret = find_entity(root, XML_CIB_TAG_STATE, id, FALSE); FNRET(ret); } int updateStatus(xmlNodePtr cib, xmlNodePtr anXmlNode) { const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Updating " XML_CIB_TAG_NODE " (%s)...", id); + crm_verbose("Updating " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_STATUS, cib); return update_cib_object(root, anXmlNode, FALSE); } int delStatus(xmlNodePtr cib, xmlNodePtr delete_spec) { const char *id = ID(delete_spec); xmlNodePtr root; if(id == NULL || strlen(id) == 0) { return CIBRES_MISSING_ID; } - CRM_DEBUG("Deleting " XML_CIB_TAG_STATE " (%s)...", id); + crm_verbose("Deleting " XML_CIB_TAG_STATE " (%s)...", id); root = get_object_root(XML_CIB_TAG_STATUS, cib); return delete_cib_object(root, delete_spec); } int delete_cib_object(xmlNodePtr parent, xmlNodePtr delete_spec) { const char *object_name = NULL; const char *object_id = NULL; xmlNodePtr equiv_node = NULL; xmlNodePtr children = NULL; int result = CIBRES_OK; if(delete_spec == NULL) { return CIBRES_FAILED_NOOBJECT; } else if(parent == NULL) { return CIBRES_FAILED_NOPARENT; } object_name = delete_spec->name; object_id = xmlGetProp(delete_spec, XML_ATTR_ID); children = delete_spec->children; if(object_id == NULL) { // placeholder object equiv_node = find_xml_node(parent, object_name); } else { equiv_node = find_entity(parent, object_name, object_id, FALSE); } if(equiv_node == NULL) { return CIBRES_FAILED_NOTEXISTS; } else if(children == NULL) { // only leaves are deleted unlink_xml_node(equiv_node); free_xml(equiv_node); } else { while(children != NULL) { int tmp_result = delete_cib_object(equiv_node, children); // only the first error is likely to be interesting if(tmp_result != CIBRES_OK && result == CIBRES_OK) { result = tmp_result; } children = children->next; } } return result; } int add_cib_object(xmlNodePtr parent, xmlNodePtr new_obj) { const char *object_name = NULL; const char *object_id = NULL; xmlNodePtr equiv_node = NULL; xmlNodePtr children = NULL; if(new_obj == NULL) { return CIBRES_FAILED_NOOBJECT; } else if(parent == NULL) { return CIBRES_FAILED_NOPARENT; } object_name = new_obj->name; object_id = xmlGetProp(new_obj, XML_ATTR_ID); children = new_obj->children; if(object_id == NULL) { // placeholder object equiv_node = find_xml_node(parent, object_name); } else { equiv_node = find_entity(parent, object_name, object_id, FALSE); } if(equiv_node != NULL) { return CIBRES_FAILED_EXISTS; } else if(add_node_copy(parent, new_obj) == NULL) { return CIBRES_FAILED_NODECOPY; } return CIBRES_OK; } int update_cib_object(xmlNodePtr parent, xmlNodePtr new_obj, gboolean force) { const char *object_name = NULL; const char *object_id = NULL; xmlNodePtr equiv_node = NULL; xmlNodePtr children = NULL; int result = CIBRES_OK; if(new_obj == NULL) { return CIBRES_FAILED_NOOBJECT; } else if(parent == NULL) { return CIBRES_FAILED_NOPARENT; } object_name = new_obj->name; object_id = xmlGetProp(new_obj, XML_ATTR_ID); children = new_obj->children; if(object_id == NULL) { // placeholder object equiv_node = find_xml_node(parent, object_name); } else { equiv_node = find_entity(parent, object_name, object_id, FALSE); } if(equiv_node != NULL) { if(force == FALSE) { const char *ts_existing = NULL; const char *ts_new = NULL; /* default to false? * * that would mean every node would have to * carry a timestamp */ gboolean is_update = TRUE; ts_existing = TSTAMP(equiv_node); ts_new = TSTAMP(new_obj); if(ts_new != NULL && ts_existing != NULL) { is_update = (strcmp(ts_new, ts_existing) > 0); } if(is_update == FALSE) { - cl_log(LOG_ERR, + crm_err( "Ignoring old update to <%s id=\"%s\">" "(%s vs. %s)", object_name, object_id, ts_new, ts_existing); return CIBRES_FAILED_STALE; } } if(safe_str_eq(XML_CIB_TAG_STATE, object_name)){ update_node_state(equiv_node, new_obj); } else { copy_in_properties(equiv_node, new_obj); } while(children != NULL) { int tmp_result = update_cib_object(equiv_node, children,force); // only the first error is likely to be interesting if(tmp_result != CIBRES_OK && result == CIBRES_OK) { result = tmp_result; } children = children->next; } } else if(add_node_copy(parent, new_obj) == NULL) { return CIBRES_FAILED_NODECOPY; } return result; } void update_node_state(xmlNodePtr target, xmlNodePtr update) { const char *source = NULL; const char *replace = NULL; xmlAttrPtr prop_iter = NULL; gboolean any_updates = FALSE; gboolean clear_stonith = FALSE; gboolean clear_shutdown = FALSE; FNIN(); prop_iter = update->properties; while(prop_iter != NULL) { const char *local_prop_name = prop_iter->name; const char *local_prop_value = xmlGetProp(update, local_prop_name); if(local_prop_name == NULL) { // error } else if(strcmp(local_prop_name, XML_ATTR_ID) == 0) { } else if(strcmp(local_prop_name, XML_ATTR_TSTAMP) == 0) { } else if(strcmp(local_prop_name, XML_CIB_ATTR_CLEAR_SHUTDOWN) == 0) { clear_shutdown = TRUE; } else if(strcmp(local_prop_name, XML_CIB_ATTR_CLEAR_STONITH) == 0) { clear_stonith = TRUE; clear_shutdown = TRUE; } else if(strcmp(local_prop_name, "replace") == 0) { replace = local_prop_value; any_updates = TRUE; } else if(strcmp(local_prop_name, "source") == 0) { source = local_prop_value; } else { any_updates = TRUE; set_xml_property_copy(target, local_prop_name, local_prop_value); } prop_iter = prop_iter->next; } if(clear_shutdown) { // unset XML_CIB_ATTR_SHUTDOWN - CRM_DEBUG("Clearing %s", XML_CIB_ATTR_SHUTDOWN); + crm_verbose("Clearing %s", XML_CIB_ATTR_SHUTDOWN); xmlUnsetProp(target, XML_CIB_ATTR_SHUTDOWN); any_updates = TRUE; } if(clear_stonith) { // unset XML_CIB_ATTR_STONITH - CRM_DEBUG("Clearing %s", XML_CIB_ATTR_STONITH); + crm_verbose("Clearing %s", XML_CIB_ATTR_STONITH); xmlUnsetProp(target, XML_CIB_ATTR_STONITH); any_updates = TRUE; } if(replace != NULL) { xmlNodePtr lrm = find_xml_node(target, replace); xmlUnlinkNode(lrm); lrm->doc = NULL; free_xml(lrm); } if(any_updates) { set_node_tstamp(target); set_xml_property_copy(target, "source", source); } } diff --git a/crm/common/Makefile.am b/crm/common/Makefile.am index edad54aadc..aac649a84e 100644 --- a/crm/common/Makefile.am +++ b/crm/common/Makefile.am @@ -1,65 +1,64 @@ # # 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 # of the License, or (at your option) any later version. # # This program 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 program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl \ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ -I$(top_builddir) -I$(top_srcdir) hadir = $(sysconfdir)/ha.d halibdir = $(libdir)/@HB_PKG@ commmoddir = $(halibdir)/modules/comm havarlibdir = $(localstatedir)/lib/@HB_PKG@ PIDFILE = $(localstatedir)/run/crmd.pid XML_FLAGS = `xml2-config --cflags` XML_LIBS = `xml2-config --libs` # sockets with path crmdir = $(havarlibdir)/crm apigid = @HA_APIGID@ crmuid = @HA_CCMUID@ crmreqsocket = $(havarlibdir)/api/crm.req crmressocket = $(havarlibdir)/api/crm.rsp LIBRT = @LIBRT@ AM_CFLAGS = @CFLAGS@ \ - -DPIDFILE='"$(PIDFILE)"' \ $(CRM_DEBUG_FLAGS) ## libraries lib_LTLIBRARIES = libcrmcommon.la ## binary progs halib_PROGRAMS = ## SOURCES noinst_HEADERS = libcrmcommon_la_SOURCES = ipc.c msg.c utils.c xml.c ctrl.c libcrmcommon_la_LDFLAGS = -version-info 0:0:0 clean-generic: rm -f *.log *.debug *.xml *~ install-exec-local: uninstall-local: diff --git a/crm/common/crmutils.c b/crm/common/crmutils.c index 72ae5200f0..d6c137d059 100644 --- a/crm/common/crmutils.c +++ b/crm/common/crmutils.c @@ -1,371 +1,370 @@ -/* $Id: crmutils.c,v 1.17 2004/06/01 15:59:41 andrew Exp $ */ +/* $Id: crmutils.c,v 1.18 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <crm/crm.h> #include <crm/msg_xml.h> #include <apphb.h> #include <clplumbing/cl_log.h> #include <clplumbing/Gmain_timeout.h> #include <crmutils.h> #include <xmlutils.h> #include <crm/dmalloc_wrapper.h> static int wdt_interval_ms = 10000; gboolean tickle_apphb_template(gpointer data) { char app_instance[APPNAME_LEN]; int rc = 0; sprintf(app_instance, "%s_%ld", "our_system_name", (long)getpid()); rc = apphb_hb(); if (rc < 0) { cl_perror("%s apphb_hb failure", app_instance); exit(3); } return TRUE; } void register_pid(const char *pid_file, gboolean do_fork, void (*shutdown)(int nsig)) { int j; long pid; FILE * lockfd; if (do_fork) { pid = fork(); if (pid < 0) { - cl_log(LOG_CRIT, "cannot start daemon"); + crm_crit("cannot start daemon"); exit(LSB_EXIT_GENERIC); }else if (pid > 0) { exit(LSB_EXIT_OK); } } lockfd = fopen(pid_file, "w"); if (lockfd == NULL) { - cl_log(LOG_CRIT, "cannot create pid file: %s", pid_file); + crm_crit("cannot create pid file: %s", pid_file); exit(LSB_EXIT_GENERIC); }else{ pid = getpid(); fprintf(lockfd, "%ld\n", pid); fclose(lockfd); } umask(022); for (j=0; j < 3; ++j) { close(j); (void)open("/dev/null", j == 0 ? O_RDONLY : O_RDONLY); } // CL_IGNORE_SIG(SIGINT); // CL_IGNORE_SIG(SIGHUP); CL_SIGNAL(SIGTERM, shutdown); } long get_running_pid(const char *pid_file, gboolean* anypidfile) { long pid; FILE * lockfd; lockfd = fopen(pid_file, "r"); if (anypidfile) { *anypidfile = (lockfd != NULL); } if (lockfd != NULL && fscanf(lockfd, "%ld", &pid) == 1 && pid > 0) { if (CL_PID_EXISTS((pid_t)pid)) { fclose(lockfd); return(pid); } } if (lockfd != NULL) { fclose(lockfd); } return(-1L); } int init_stop(const char *pid_file) { long pid; int rc = LSB_EXIT_OK; FNIN(); if (pid_file == NULL) { - cl_log(LOG_ERR, "No pid file specified to kill process"); + crm_err("No pid file specified to kill process"); return LSB_EXIT_GENERIC; } pid = get_running_pid(pid_file, NULL); if (pid > 0) { if (CL_KILL((pid_t)pid, SIGTERM) < 0) { rc = (errno == EPERM ? LSB_EXIT_EPERM : LSB_EXIT_GENERIC); fprintf(stderr, "Cannot kill pid %ld\n", pid); }else{ - cl_log(LOG_INFO, + crm_info( "Signal sent to pid=%ld," " waiting for process to exit", pid); while (CL_PID_EXISTS(pid)) { sleep(1); } } } FNRET(rc); } int init_status(const char *pid_file, const char *client_name) { gboolean anypidfile; long pid = get_running_pid(pid_file, &anypidfile); if (pid > 0) { fprintf(stderr, "%s is running [pid: %ld]\n" , client_name, pid); return LSB_STATUS_OK; } if (anypidfile) { fprintf(stderr, "%s is stopped [pidfile exists]\n" , client_name); return LSB_STATUS_VAR_PID; } fprintf(stderr, "%s is stopped.\n", client_name); return LSB_STATUS_STOPPED; } gboolean register_with_ha(ll_cluster_t *hb_cluster, const char *client_name, gboolean (*dispatch_method)(int fd, gpointer user_data), void (*message_callback)(const struct ha_msg* msg, void* private_data), GDestroyNotify cleanup_method) { const char* ournode = NULL; - cl_log(LOG_INFO, "Signing in with Heartbeat"); + crm_info("Signing in with Heartbeat"); if (hb_cluster->llc_ops->signon(hb_cluster, client_name)!= HA_OK) { - cl_log(LOG_ERR, "Cannot sign on with heartbeat"); - cl_log(LOG_ERR, - "REASON: %s", - hb_cluster->llc_ops->errmsg(hb_cluster)); + crm_err("Cannot sign on with heartbeat"); + crm_err("REASON: %s", + hb_cluster->llc_ops->errmsg(hb_cluster)); return FALSE; } - cl_log(LOG_DEBUG, "Finding our node name"); + crm_debug("Finding our node name"); if ((ournode = hb_cluster->llc_ops->get_mynodeid(hb_cluster)) == NULL) { - cl_log(LOG_ERR, "get_mynodeid() failed"); + crm_err("get_mynodeid() failed"); return FALSE; } - cl_log(LOG_INFO, "hostname: %s", ournode); + crm_info("hostname: %s", ournode); - cl_log(LOG_DEBUG, "Be informed of CRM messages"); + crm_debug("Be informed of CRM messages"); if (hb_cluster->llc_ops->set_msg_callback(hb_cluster, "CRM", message_callback, hb_cluster) !=HA_OK){ - cl_log(LOG_ERR, "Cannot set CRM message callback"); - cl_log(LOG_ERR, + crm_err("Cannot set CRM message callback"); + crm_err( "REASON: %s", hb_cluster->llc_ops->errmsg(hb_cluster)); return FALSE; } G_main_add_fd(G_PRIORITY_HIGH, hb_cluster->llc_ops->inputfd(hb_cluster), FALSE, dispatch_method, hb_cluster, // usrdata cleanup_method); /* it seems we need to poke the message receiving stuff in order for it to * start seeing messages. Its like it gets blocked or something. */ dispatch_method(0, hb_cluster); return TRUE; } void register_with_apphb(const char *client_name, gboolean(*tickle_fn)(gpointer data)) { char app_instance[APPNAME_LEN]; int hb_intvl_ms = wdt_interval_ms * 2; int rc = 0; // Register with apphb - cl_log(LOG_INFO, "Signing in with AppHb"); + crm_info("Signing in with AppHb"); sprintf(app_instance, "%s_%ld", client_name, (long)getpid()); - cl_log(LOG_INFO, "Client %s registering with apphb", app_instance); + crm_info("Client %s registering with apphb", app_instance); rc = apphb_register(client_name, app_instance); if (rc < 0) { cl_perror("%s registration failure", app_instance); exit(1); } - cl_log(LOG_DEBUG, "Client %s registered with apphb", app_instance); + crm_debug("Client %s registered with apphb", app_instance); - cl_log(LOG_INFO, + crm_info( "Client %s setting %d ms apphb heartbeat interval" , app_instance, hb_intvl_ms); rc = apphb_setinterval(hb_intvl_ms); if (rc < 0) { cl_perror("%s setinterval failure", app_instance); exit(2); } // regularly tell apphb that we are alive - cl_log(LOG_INFO, "Setting up AppHb Heartbeat"); + crm_info("Setting up AppHb Heartbeat"); Gmain_timeout_add(wdt_interval_ms, tickle_fn, NULL); } char * crm_itoa(int an_int) { int len = 32; char *buffer = crm_malloc(sizeof(char)*(len+1)); snprintf(buffer, len, "%d", an_int); return buffer; } gboolean subsystem_input_dispatch(IPC_Channel *sender, void *user_data) { int lpc = 0; char *buffer = NULL; IPC_Message *msg = NULL; gboolean all_is_well = TRUE; xmlNodePtr root_xml_node = NULL; const char *sys_to; const char *type; FNIN(); while(sender->ops->is_message_pending(sender)) { if (sender->ch_status == IPC_DISCONNECT) { /* The message which was pending for us is that * the IPC status is now IPC_DISCONNECT */ break; } if (sender->ops->recv(sender, &msg) != IPC_OK) { perror("Receive failure:"); FNRET(!all_is_well); } if (msg == NULL) { - cl_log(LOG_ERR, "No message this time"); + crm_err("No message this time"); continue; } lpc++; buffer = (char*)msg->msg_body; root_xml_node = string2xml(buffer); sys_to= xmlGetProp(root_xml_node, XML_ATTR_SYSTO); type = xmlGetProp(root_xml_node, XML_ATTR_MSGTYPE); if (root_xml_node == NULL) { - cl_log(LOG_ERR, "Root node was NULL!!"); + crm_err("Root node was NULL!!"); } else if(sys_to == NULL) { - cl_log(LOG_ERR, "Value of %s was NULL!!", + crm_err("Value of %s was NULL!!", XML_ATTR_SYSTO); } else if(type == NULL) { - cl_log(LOG_ERR, "Value of %s was NULL!!", + crm_err("Value of %s was NULL!!", XML_ATTR_MSGTYPE); } else { gboolean (*process_function) (xmlNodePtr msg, IPC_Channel *sender) = NULL; process_function = user_data; if(process_function(root_xml_node, sender) == FALSE) { - cl_log(LOG_WARNING, + crm_warn( "Received a message destined for %s" " by mistake", sys_to); } } free_xml(root_xml_node); root_xml_node = NULL; msg->msg_done(msg); msg = NULL; } // clean up after a break if(msg != NULL) msg->msg_done(msg); if(root_xml_node != NULL) free_xml(root_xml_node); - CRM_DEBUG("Processed %d messages", lpc); + crm_verbose("Processed %d messages", lpc); if (sender->ch_status == IPC_DISCONNECT) { - cl_log(LOG_ERR, "The server has left us: Shutting down...NOW"); + crm_err("The server has left us: Shutting down...NOW"); exit(1); // shutdown properly later FNRET(!all_is_well); } FNRET(all_is_well); } diff --git a/crm/common/ctrl.c b/crm/common/ctrl.c index cb21bbf81e..7d2db77981 100644 --- a/crm/common/ctrl.c +++ b/crm/common/ctrl.c @@ -1,216 +1,215 @@ -/* $Id: ctrl.c,v 1.1 2004/06/02 11:45:28 andrew Exp $ */ +/* $Id: ctrl.c,v 1.2 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <crm/crm.h> #include <crm/msg_xml.h> #include <crm/common/ctrl.h> #include <apphb.h> #include <clplumbing/cl_log.h> #include <clplumbing/Gmain_timeout.h> #include <crm/dmalloc_wrapper.h> static int wdt_interval_ms = 10000; void register_pid(const char *pid_file, gboolean do_fork, void (*shutdown)(int nsig)) { int j; long pid; FILE * lockfd; if (do_fork) { pid = fork(); if (pid < 0) { - cl_log(LOG_CRIT, "cannot start daemon"); + crm_crit("cannot start daemon"); exit(LSB_EXIT_GENERIC); }else if (pid > 0) { exit(LSB_EXIT_OK); } } lockfd = fopen(pid_file, "w"); if (lockfd == NULL) { - cl_log(LOG_CRIT, "cannot create pid file: %s", pid_file); + crm_crit("cannot create pid file: %s", pid_file); exit(LSB_EXIT_GENERIC); }else{ pid = getpid(); fprintf(lockfd, "%ld\n", pid); fclose(lockfd); } umask(022); for (j=0; j < 3; ++j) { close(j); (void)open("/dev/null", j == 0 ? O_RDONLY : O_RDONLY); } // CL_IGNORE_SIG(SIGINT); // CL_IGNORE_SIG(SIGHUP); CL_SIGNAL(SIGTERM, shutdown); } long get_running_pid(const char *pid_file, gboolean* anypidfile) { long pid; FILE * lockfd; lockfd = fopen(pid_file, "r"); if (anypidfile) { *anypidfile = (lockfd != NULL); } if (lockfd != NULL && fscanf(lockfd, "%ld", &pid) == 1 && pid > 0) { if (CL_PID_EXISTS((pid_t)pid)) { fclose(lockfd); return(pid); } } if (lockfd != NULL) { fclose(lockfd); } return(-1L); } int init_stop(const char *pid_file) { long pid; int rc = LSB_EXIT_OK; FNIN(); if (pid_file == NULL) { - cl_log(LOG_ERR, "No pid file specified to kill process"); + crm_err("No pid file specified to kill process"); return LSB_EXIT_GENERIC; } pid = get_running_pid(pid_file, NULL); if (pid > 0) { if (CL_KILL((pid_t)pid, SIGTERM) < 0) { rc = (errno == EPERM ? LSB_EXIT_EPERM : LSB_EXIT_GENERIC); fprintf(stderr, "Cannot kill pid %ld\n", pid); }else{ - cl_log(LOG_INFO, + crm_info( "Signal sent to pid=%ld," " waiting for process to exit", pid); while (CL_PID_EXISTS(pid)) { sleep(1); } } } FNRET(rc); } int init_status(const char *pid_file, const char *client_name) { gboolean anypidfile; long pid = get_running_pid(pid_file, &anypidfile); if (pid > 0) { fprintf(stderr, "%s is running [pid: %ld]\n" , client_name, pid); return LSB_STATUS_OK; } if (anypidfile) { fprintf(stderr, "%s is stopped [pidfile exists]\n" , client_name); return LSB_STATUS_VAR_PID; } fprintf(stderr, "%s is stopped.\n", client_name); return LSB_STATUS_STOPPED; } void register_with_apphb(const char *client_name, gboolean(*tickle_fn)(gpointer data)) { char app_instance[APPNAME_LEN]; int hb_intvl_ms = wdt_interval_ms * 2; int rc = 0; // Register with apphb - cl_log(LOG_INFO, "Signing in with AppHb"); + crm_info("Signing in with AppHb"); sprintf(app_instance, "%s_%ld", client_name, (long)getpid()); - cl_log(LOG_INFO, "Client %s registering with apphb", app_instance); + crm_info("Client %s registering with apphb", app_instance); rc = apphb_register(client_name, app_instance); if (rc < 0) { cl_perror("%s registration failure", app_instance); exit(1); } - cl_log(LOG_DEBUG, "Client %s registered with apphb", app_instance); + crm_debug("Client %s registered with apphb", app_instance); - cl_log(LOG_INFO, - "Client %s setting %d ms apphb heartbeat interval" - , app_instance, hb_intvl_ms); + crm_info("Client %s setting %d ms apphb heartbeat interval", + app_instance, hb_intvl_ms); rc = apphb_setinterval(hb_intvl_ms); if (rc < 0) { cl_perror("%s setinterval failure", app_instance); exit(2); } // regularly tell apphb that we are alive - cl_log(LOG_INFO, "Setting up AppHb Heartbeat"); + crm_info("Setting up AppHb Heartbeat"); Gmain_timeout_add(wdt_interval_ms, tickle_fn, NULL); } gboolean tickle_apphb_template(gpointer data) { char app_instance[APPNAME_LEN]; int rc = 0; sprintf(app_instance, "%s_%ld", "our_system_name", (long)getpid()); rc = apphb_hb(); if (rc < 0) { cl_perror("%s apphb_hb failure", app_instance); exit(3); } return TRUE; } diff --git a/crm/common/ipc.c b/crm/common/ipc.c index 95c0f61022..064d7d0213 100644 --- a/crm/common/ipc.c +++ b/crm/common/ipc.c @@ -1,392 +1,383 @@ -/* $Id: ipc.c,v 1.1 2004/06/02 11:45:28 andrew Exp $ */ +/* $Id: ipc.c,v 1.2 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <crm/crm.h> #include <clplumbing/ipc.h> #include <clplumbing/Gmain_timeout.h> #include <clplumbing/cl_log.h> #include <clplumbing/cl_signal.h> #include <clplumbing/lsb_exitcodes.h> #include <clplumbing/uids.h> #include <clplumbing/realtime.h> #include <clplumbing/GSource.h> #include <clplumbing/cl_poll.h> #include <libxml/xmlmemory.h> #include <libxml/parser.h> #include <libxml/xpath.h> #include <crm/common/ipc.h> #include <crm/msg_xml.h> #include <crm/dmalloc_wrapper.h> IPC_Message *create_simple_message(char *text, IPC_Channel *ch); gboolean send_ipc_message(IPC_Channel *ipc_client, IPC_Message *msg); gboolean send_xmlipc_message(IPC_Channel *ipc_client, xmlNodePtr msg) { int log_level = LOG_DEBUG; char *xml_message = NULL; IPC_Message *cib_dump = NULL; gboolean res; FNIN(); xml_message = dump_xml(msg); cib_dump = create_simple_message(xml_message, ipc_client); res = send_ipc_message(ipc_client, cib_dump); crm_free(xml_message); if(res == FALSE) { log_level = LOG_ERR; } - cl_log(log_level, + do_crm_log(log_level, __FUNCTION__, "Sending IPC message (ref=%s) to %s@%s %s.", xmlGetProp(msg, XML_ATTR_REFERENCE), xmlGetProp(msg, XML_ATTR_SYSTO), xmlGetProp(msg, XML_ATTR_HOSTTO), res?"succeeded":"failed"); FNRET(res); } gboolean send_ipc_message(IPC_Channel *ipc_client, IPC_Message *msg) { int lpc = 0; gboolean all_is_good = TRUE; FNIN(); if (msg == NULL) { - cl_log(LOG_WARNING, "cant send NULL message"); + crm_err("cant send NULL message"); all_is_good = FALSE; } else if (msg->msg_len <= 0) { - cl_log(LOG_WARNING, "cant send 0 sized message"); + crm_err("cant send 0 sized message"); all_is_good = FALSE; } else if (msg->msg_len > MAXDATASIZE) { - cl_log(LOG_WARNING, "cant send msg... too big"); + crm_err("cant send msg... too big"); all_is_good = FALSE; } -/* CRM_DEBUG("Sending message: %s", (char*)msg->msg_body); */ - CRM_DEBUG("Message is%s valid to send", all_is_good?"":" not"); + crm_trace("Sending message: %s", (char*)msg->msg_body); + crm_verbose("Message is%s valid to send", all_is_good?"":" not"); if (ipc_client == NULL) { all_is_good = FALSE; } - CRM_DEBUG("IPC Client is%s set.", all_is_good?"":" not"); + crm_verbose("IPC Client is%s set.", all_is_good?"":" not"); if (all_is_good) { while(lpc++ < MAX_IPC_FAIL && ipc_client->ops->send(ipc_client, msg) == IPC_FAIL) { - cl_log(LOG_WARNING, "ipc channel blocked"); + crm_err("ipc channel blocked"); cl_shortsleep(); } } if (lpc == MAX_IPC_FAIL) { - cl_log(LOG_ERR, - "Could not send IPC, message. Channel is dead."); + crm_err("Could not send IPC, message. Channel is dead."); all_is_good = FALSE; } FNRET(all_is_good); } IPC_Message * create_simple_message(char *text, IPC_Channel *ch) { // char str[256]; IPC_Message *ack_msg = NULL; FNIN(); if (text == NULL) FNRET(NULL); ack_msg = (IPC_Message *)crm_malloc(sizeof(IPC_Message)); ack_msg->msg_private = NULL; ack_msg->msg_done = NULL; ack_msg->msg_body = text; ack_msg->msg_ch = ch; ack_msg->msg_len = strlen(text)+1; FNRET(ack_msg); } xmlNodePtr find_xml_in_ipcmessage(IPC_Message *msg, gboolean do_free) { char *buffer = NULL; xmlDocPtr doc; xmlNodePtr root; FNIN(); if (msg == NULL) { - CRM_NOTE("IPC Message was empty..."); + crm_trace("IPC Message was empty..."); FNRET(NULL); } buffer = (char*)msg->msg_body; doc = xmlParseMemory(buffer, strlen(buffer)); if (do_free) msg->msg_done(msg); if (doc == NULL) { - cl_log(LOG_INFO, - "IPC Message did not contain an XML buffer..."); + crm_info("IPC Message did not contain an XML buffer..."); FNRET(NULL); } root = xmlDocGetRootElement(doc); if (root == NULL) { - cl_log(LOG_INFO, "Root node was NULL."); + crm_info("Root node was NULL."); FNRET(NULL); } FNRET(root); } void default_ipc_input_destroy(gpointer user_data) { FNIN(); FNOUT(); } IPC_Channel * init_client_ipc_comms(const char *child, gboolean (*dispatch)(IPC_Channel* source_data ,gpointer user_data), crmd_client_t *client_data) { IPC_Channel *ch; GHashTable * attrs; GCHSource *the_source = NULL; void *callback_data = client_data; static char path[] = IPC_PATH_ATTR; char *commpath = NULL; int local_socket_len = 2; // 2 = '/' + '\0' FNIN(); local_socket_len += strlen(child); local_socket_len += strlen(WORKING_DIR); commpath = (char*)crm_malloc(sizeof(char)*local_socket_len); sprintf(commpath, WORKING_DIR "/%s", child); commpath[local_socket_len - 1] = '\0'; - cl_log(LOG_DEBUG, "Attempting to talk on: %s", commpath); + crm_debug("Attempting to talk on: %s", commpath); attrs = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(attrs, path, commpath); ch = ipc_channel_constructor(IPC_ANYTYPE, attrs); g_hash_table_destroy(attrs); if (ch == NULL) { - cl_log(LOG_CRIT, - "Could not access channel on: %s", - commpath); + crm_crit("Could not access channel on: %s", commpath); } else if (ch->ops->initiate_connection(ch) != IPC_OK) { - cl_log(LOG_CRIT, "Could not init comms on: %s", commpath); + crm_crit("Could not init comms on: %s", commpath); FNRET(NULL); } if(callback_data == NULL) callback_data = ch; ch->ops->set_recv_qlen(ch, 100); ch->ops->set_send_qlen(ch, 100); the_source = G_main_add_IPC_Channel(G_PRIORITY_LOW, ch, FALSE, dispatch, callback_data, default_ipc_input_destroy); - cl_log(LOG_DEBUG, "Processing of %s complete", commpath); + crm_debug("Processing of %s complete", commpath); FNRET(ch); } /* * This method adds a copy of xml_response_data */ gboolean send_ipc_request(IPC_Channel *ipc_channel, xmlNodePtr msg_options, xmlNodePtr msg_data, const char *host_to, const char *sys_to, const char *sys_from, const char *uuid_from, const char *crm_msg_reference) { gboolean was_sent = FALSE; xmlNodePtr request = NULL; FNIN(); request = create_request(msg_options, msg_data, host_to, sys_to, sys_from, uuid_from, crm_msg_reference); -// xml_message_debug(request, "Final request..."); - was_sent = send_xmlipc_message(ipc_channel, request); free_xml(request); FNRET(was_sent); } /* * This method adds a copy of xml_response_data */ gboolean send_ipc_reply(IPC_Channel *ipc_channel, xmlNodePtr xml_request, xmlNodePtr xml_response_data) { gboolean was_sent = FALSE; xmlNodePtr reply; FNIN(); reply = create_reply(xml_request, xml_response_data); -// xml_message_debug(reply, "Final reply..."); - if (reply != NULL) { was_sent = send_xmlipc_message(ipc_channel, reply); free_xml(reply); } FNRET(was_sent); } gboolean subsystem_input_dispatch(IPC_Channel *sender, void *user_data) { int lpc = 0; char *buffer = NULL; IPC_Message *msg = NULL; gboolean all_is_well = TRUE; xmlNodePtr root_xml_node = NULL; const char *sys_to; const char *type; FNIN(); while(sender->ops->is_message_pending(sender)) { if (sender->ch_status == IPC_DISCONNECT) { /* The message which was pending for us is that * the IPC status is now IPC_DISCONNECT */ break; } if (sender->ops->recv(sender, &msg) != IPC_OK) { perror("Receive failure:"); FNRET(!all_is_well); } if (msg == NULL) { - cl_log(LOG_ERR, "No message this time"); + crm_err("No message this time"); continue; } lpc++; buffer = (char*)msg->msg_body; root_xml_node = string2xml(buffer); sys_to= xmlGetProp(root_xml_node, XML_ATTR_SYSTO); type = xmlGetProp(root_xml_node, XML_ATTR_MSGTYPE); if (root_xml_node == NULL) { - cl_log(LOG_ERR, "Root node was NULL!!"); + crm_err("Root node was NULL!!"); } else if(sys_to == NULL) { - cl_log(LOG_ERR, "Value of %s was NULL!!", + crm_err("Value of %s was NULL!!", XML_ATTR_SYSTO); } else if(type == NULL) { - cl_log(LOG_ERR, "Value of %s was NULL!!", + crm_err("Value of %s was NULL!!", XML_ATTR_MSGTYPE); } else { gboolean (*process_function) (xmlNodePtr msg, IPC_Channel *sender) = NULL; process_function = user_data; if(process_function(root_xml_node, sender) == FALSE) { - cl_log(LOG_WARNING, - "Received a message destined for %s" - " by mistake", sys_to); + crm_warn("Received a message destined for %s" + " by mistake", sys_to); } } free_xml(root_xml_node); root_xml_node = NULL; msg->msg_done(msg); msg = NULL; } // clean up after a break if(msg != NULL) msg->msg_done(msg); if(root_xml_node != NULL) free_xml(root_xml_node); - CRM_DEBUG("Processed %d messages", lpc); + crm_verbose("Processed %d messages", lpc); if (sender->ch_status == IPC_DISCONNECT) { - cl_log(LOG_ERR, "The server has left us: Shutting down...NOW"); + crm_err("The server has left us: Shutting down...NOW"); exit(1); // shutdown properly later FNRET(!all_is_well); } FNRET(all_is_well); } diff --git a/crm/common/msg.c b/crm/common/msg.c index e57a6c9c0d..b151ae95c0 100644 --- a/crm/common/msg.c +++ b/crm/common/msg.c @@ -1,407 +1,397 @@ -/* $Id: msg.c,v 1.1 2004/06/02 11:45:28 andrew Exp $ */ +/* $Id: msg.c,v 1.2 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <clplumbing/cl_log.h> #include <time.h> #include <crm/crm.h> #include <crm/msg_xml.h> #include <crm/common/msg.h> #include <crm/dmalloc_wrapper.h> xmlNodePtr create_common_message(xmlNodePtr original_request, xmlNodePtr xml_response_data); xmlNodePtr createPingAnswerFragment(const char *from, const char *status) { xmlNodePtr ping = NULL; FNIN(); ping = create_xml_node(NULL, XML_CRM_TAG_PING); set_xml_property_copy(ping, XML_PING_ATTR_STATUS, status); set_xml_property_copy(ping, XML_PING_ATTR_SYSFROM, from); FNRET(ping); } xmlNodePtr createPingRequest(const char *crm_msg_reference, const char *to) { xmlNodePtr root_xml_node = NULL; int sub_type_len; int msg_type_len; char *sub_type_target; char *msg_type_target; FNIN(); // 2 = "_" + '\0' sub_type_len = strlen(to) + strlen(XML_ATTR_REQUEST) + 2; sub_type_target = (char*)crm_malloc(sizeof(char)*(sub_type_len)); sprintf(sub_type_target, "%s_%s", to, XML_ATTR_REQUEST); root_xml_node = create_xml_node(NULL, sub_type_target); set_xml_property_copy(root_xml_node, XML_ATTR_REFERENCE, crm_msg_reference); msg_type_len = strlen(to) + 10 + 1; // + "_operation" + '\0' msg_type_target = (char*)crm_malloc(sizeof(char)*(msg_type_len)); sprintf(msg_type_target, "%s_operation", to); set_xml_property_copy(root_xml_node, msg_type_target, CRM_OP_PING); crm_free(msg_type_target); FNRET(root_xml_node); } xmlNodePtr validate_crm_message(xmlNodePtr root_xml_node, const char *sys, const char *uuid, const char *msg_type) { const char *from = NULL; const char *to = NULL; const char *type = NULL; const char *crm_msg_reference = NULL; xmlNodePtr action = NULL; const char *true_sys; FNIN(); if (root_xml_node == NULL) { FNRET(NULL); } from = xmlGetProp(root_xml_node, XML_ATTR_SYSFROM); to = xmlGetProp(root_xml_node, XML_ATTR_SYSTO); type = xmlGetProp(root_xml_node, XML_ATTR_MSGTYPE); crm_msg_reference = xmlGetProp(root_xml_node, XML_ATTR_REFERENCE); /* - cl_log(LOG_DEBUG, "Recieved XML message with (version=%s)", + crm_debug("Recieved XML message with (version=%s)", xmlGetProp(root_xml_node, XML_ATTR_VERSION)); - cl_log(LOG_DEBUG, "Recieved XML message with (from=%s)", from); - cl_log(LOG_DEBUG, "Recieved XML message with (to=%s)" , to); - cl_log(LOG_DEBUG, "Recieved XML message with (type=%s)", type); - cl_log(LOG_DEBUG, "Recieved XML message with (ref=%s)" , + crm_debug("Recieved XML message with (from=%s)", from); + crm_debug("Recieved XML message with (to=%s)" , to); + crm_debug("Recieved XML message with (type=%s)", type); + crm_debug("Recieved XML message with (ref=%s)" , crm_msg_reference); */ action = root_xml_node; true_sys = sys; if (uuid != NULL) true_sys = generate_hash_key(sys, uuid); if (to == NULL) { - cl_log(LOG_INFO, "No sub-system defined."); + crm_info("No sub-system defined."); action = NULL; } else if (true_sys != NULL && strcmp(to, true_sys) != 0) { - cl_log(LOG_DEBUG, - "The message is not for this sub-system (%s != %s).", - to, - true_sys); + crm_debug("The message is not for this sub-system (%s != %s).", + to, true_sys); action = NULL; } if (type == NULL) { - cl_log(LOG_INFO, "No message type defined."); + crm_info("No message type defined."); FNRET(NULL); } else if (msg_type != NULL && strcmp(msg_type, type) != 0) { - cl_log(LOG_INFO, - "Expecting a (%s) message but receieved a (%s).", + crm_info("Expecting a (%s) message but receieved a (%s).", msg_type, type); action = NULL; } if (crm_msg_reference == NULL) { - cl_log(LOG_INFO, "No message crm_msg_reference defined."); + crm_info("No message crm_msg_reference defined."); action = NULL; } /* if(action != NULL) - cl_log(LOG_DEBUG, + crm_debug( "XML is valid and node with message type (%s) found.", type); - cl_log(LOG_DEBUG, "Returning node (%s)", xmlGetNodePath(action)); + crm_debug("Returning node (%s)", xmlGetNodePath(action)); */ FNRET(action); } void send_hello_message(IPC_Channel *ipc_client, const char *uuid, const char *client_name, const char *major_version, const char *minor_version) { xmlNodePtr hello_node = NULL; FNIN(); if (uuid == NULL || strlen(uuid) == 0 || client_name == NULL || strlen(client_name) == 0 || major_version == NULL || strlen(major_version) == 0 || minor_version == NULL || strlen(minor_version) == 0) { - cl_log(LOG_ERR, - "Missing fields, Hello message will not be valid."); + crm_err("Missing fields, Hello message will not be valid."); return; } hello_node = create_xml_node(NULL, XML_TAG_OPTIONS); set_xml_property_copy(hello_node, "major_version", major_version); set_xml_property_copy(hello_node, "minor_version", minor_version); set_xml_property_copy(hello_node, "client_name", client_name); set_xml_property_copy(hello_node, "client_uuid", uuid); set_xml_property_copy(hello_node, XML_ATTR_OP, CRM_OP_HELLO); send_ipc_request(ipc_client, hello_node, NULL, NULL, NULL, client_name, uuid, NULL); free_xml(hello_node); } gboolean process_hello_message(xmlNodePtr hello, char **uuid, char **client_name, char **major_version, char **minor_version) { xmlNodePtr opts = NULL; const char *op = NULL; const char *local_uuid; const char *local_client_name; const char *local_major_version; const char *local_minor_version; FNIN(); *uuid = NULL; *client_name = NULL; *major_version = NULL; *minor_version = NULL; opts = find_xml_node(hello, XML_TAG_OPTIONS); op = xmlGetProp(opts, XML_ATTR_OP); local_uuid = xmlGetProp(opts, "client_uuid"); local_client_name = xmlGetProp(opts, "client_name"); local_major_version = xmlGetProp(opts, "major_version"); local_minor_version = xmlGetProp(opts, "minor_version"); if (op == NULL || strcmp(CRM_OP_HELLO, op) != 0) { FNRET(FALSE); } else if (local_uuid == NULL || strlen(local_uuid) == 0) { - cl_log(LOG_ERR, - "Hello message was not valid (field %s not found)", + crm_err("Hello message was not valid (field %s not found)", "uuid"); FNRET(FALSE); } else if (local_client_name==NULL || strlen(local_client_name)==0){ - cl_log(LOG_ERR, - "Hello message was not valid (field %s not found)", - "client name"); + crm_err("Hello message was not valid (field %s not found)", + "client name"); FNRET(FALSE); } else if(local_major_version == NULL || strlen(local_major_version) == 0){ - cl_log(LOG_ERR, - "Hello message was not valid (field %s not found)", - "major version"); + crm_err("Hello message was not valid (field %s not found)", + "major version"); FNRET(FALSE); } else if (local_minor_version == NULL || strlen(local_minor_version) == 0){ - cl_log(LOG_ERR, - "Hello message was not valid (field %s not found)", - "minor version"); + crm_err("Hello message was not valid (field %s not found)", + "minor version"); FNRET(FALSE); } *uuid = crm_strdup(local_uuid); *client_name = crm_strdup(local_client_name); *major_version = crm_strdup(local_major_version); *minor_version = crm_strdup(local_minor_version); FNRET(TRUE); } xmlNodePtr create_request(xmlNodePtr msg_options, xmlNodePtr msg_data, const char *host_to, const char *sys_to, const char *sys_from, const char *uuid_from, const char *crm_msg_reference) { const char *true_from = sys_from; xmlNodePtr request; FNIN(); if (uuid_from != NULL) true_from = generate_hash_key(sys_from, uuid_from); // else make sure we are internal else { if (strcmp(CRM_SYSTEM_LRMD, sys_from) != 0 && strcmp(CRM_SYSTEM_PENGINE, sys_from) != 0 && strcmp(CRM_SYSTEM_TENGINE, sys_from) != 0 && strcmp(CRM_SYSTEM_DC, sys_from) != 0 && strcmp(CRM_SYSTEM_CRMD, sys_from) != 0) { - cl_log(LOG_ERR, - "only internal systems can leave uuid_from blank"); + crm_err("only internal systems can leave" + " uuid_from blank"); FNRET(FALSE); } } if (crm_msg_reference == NULL) { crm_msg_reference = generateReference( xmlGetProp(msg_options,XML_ATTR_OP),sys_from); } // host_from will get set for us if necessary by CRMd when routed request = create_xml_node(NULL, XML_MSG_TAG); set_node_tstamp(request); set_xml_property_copy(request, XML_ATTR_VERSION, CRM_VERSION); set_xml_property_copy(request, XML_ATTR_MSGTYPE, XML_ATTR_REQUEST); set_xml_property_copy(request, XML_ATTR_SYSTO, sys_to); set_xml_property_copy(request, XML_ATTR_SYSFROM, true_from); set_xml_property_copy(request, XML_ATTR_REFERENCE, crm_msg_reference); if(host_to != NULL && strlen(host_to) > 0) set_xml_property_copy(request, XML_ATTR_HOSTTO, host_to); if (msg_options != NULL) { add_node_copy(request, msg_options); } if (msg_data != NULL) { add_node_copy(request, msg_data); } FNRET(request); } /* * This method adds a copy of xml_response_data */ xmlNodePtr create_reply(xmlNodePtr original_request, xmlNodePtr xml_response_data) { const char *host_from = NULL; const char *sys_from = NULL; const char *sys_to = NULL; xmlNodePtr reply; FNIN(); host_from = xmlGetProp(original_request, XML_ATTR_HOSTFROM); sys_from = xmlGetProp(original_request, XML_ATTR_SYSFROM); sys_to = xmlGetProp(original_request, XML_ATTR_SYSTO); reply = create_common_message(original_request, xml_response_data); set_xml_property_copy(reply, XML_ATTR_MSGTYPE, XML_ATTR_RESPONSE); /* since this is a reply, we reverse the from and to */ // HOSTTO will be ignored if it is to the DC anyway. if(host_from != NULL && strlen(host_from) > 0) set_xml_property_copy(reply, XML_ATTR_HOSTTO, host_from); set_xml_property_copy(reply, XML_ATTR_SYSTO, sys_from); set_xml_property_copy(reply, XML_ATTR_SYSFROM, sys_to); FNRET(reply); } xmlNodePtr create_common_message(xmlNodePtr original_request, xmlNodePtr xml_response_data) { const char *crm_msg_reference = NULL; const char *type = NULL; const char *operation = NULL; xmlNodePtr options = NULL; xmlNodePtr new_message; FNIN(); crm_msg_reference = xmlGetProp(original_request, XML_ATTR_REFERENCE); type = xmlGetProp(original_request, XML_ATTR_MSGTYPE); operation = xmlGetProp(original_request, XML_ATTR_OP); if (type == NULL) { - cl_log(LOG_ERR, - "Cannot create new_message," - " no message type in original message"); + crm_err("Cannot create new_message," + " no message type in original message"); FNRET(NULL); #if 0 } else if (strcmp(XML_ATTR_REQUEST, type) != 0) { - cl_log(LOG_ERR, - "Cannot create new_message," - " original message was not a request"); + crm_err("Cannot create new_message," + " original message was not a request"); FNRET(NULL); #endif } new_message = create_xml_node(NULL, XML_MSG_TAG); set_node_tstamp(new_message); set_xml_property_copy(new_message, XML_ATTR_VERSION, CRM_VERSION); set_xml_property_copy(new_message, XML_ATTR_OP, operation); set_xml_property_copy(new_message, XML_ATTR_REFERENCE, crm_msg_reference); if (xml_response_data != NULL) { add_node_copy(new_message, xml_response_data); } options = find_xml_node(original_request, XML_TAG_OPTIONS); if (options != NULL) { add_node_copy(new_message, options); } FNRET(new_message); } diff --git a/crm/common/utils.c b/crm/common/utils.c index f6d0ec56cb..c3da66d8aa 100644 --- a/crm/common/utils.c +++ b/crm/common/utils.c @@ -1,203 +1,260 @@ -/* $Id: utils.c,v 1.1 2004/06/02 11:45:28 andrew Exp $ */ +/* $Id: utils.c,v 1.2 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #include <stdlib.h> + #include <clplumbing/cl_log.h> #include <time.h> #include <clplumbing/Gmain_timeout.h> #include <crm/crm.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/util.h> #include <crm/dmalloc_wrapper.h> +#define MAXLINE 512 static uint ref_counter = 0; const char * generateReference(const char *custom1, const char *custom2) { const char *local_cust1 = custom1; const char *local_cust2 = custom2; int reference_len = 4; char *since_epoch = NULL; FNIN(); reference_len += 20; // too big reference_len += 40; // too big if(local_cust1 == NULL) local_cust1 = "_empty_"; reference_len += strlen(local_cust1); if(local_cust2 == NULL) local_cust2 = "_empty_"; reference_len += strlen(local_cust2); since_epoch = (char*)crm_malloc(reference_len*(sizeof(char))); FNIN(); sprintf(since_epoch, "%s-%s-%ld-%u", local_cust1, local_cust2, (unsigned long)time(NULL), ref_counter++); FNRET(since_epoch); } gboolean decodeNVpair(const char *srcstring, char separator, char **name, char **value) { int lpc = 0; int len = 0; const char *temp = NULL; FNIN(); - CRM_DEBUG("Attempting to decode: [%s]", srcstring); + crm_verbose("Attempting to decode: [%s]", srcstring); if (srcstring != NULL) { len = strlen(srcstring); while(lpc < len) { if (srcstring[lpc++] == separator) { *name = (char*)crm_malloc(sizeof(char)*lpc); strncpy(*name, srcstring, lpc-1); (*name)[lpc-1] = '\0'; // this sucks but as the strtok *is* a bug len = len-lpc+1; *value = (char*)crm_malloc(sizeof(char)*len); temp = srcstring+lpc; strncpy(*value, temp, len-1); (*value)[len-1] = '\0'; FNRET(TRUE); } } } *name = NULL; *value = NULL; FNRET(FALSE); } char * generate_hash_key(const char *crm_msg_reference, const char *sys) { int ref_len = strlen(sys?sys:"none") + strlen(crm_msg_reference) + 2; char *hash_key = (char*)crm_malloc(sizeof(char)*(ref_len)); FNIN(); sprintf(hash_key, "%s_%s", sys?sys:"none", crm_msg_reference); hash_key[ref_len-1] = '\0'; - cl_log(LOG_INFO, "created hash key: (%s)", hash_key); + crm_info("created hash key: (%s)", hash_key); FNRET(hash_key); } char * generate_hash_value(const char *src_node, const char *src_subsys) { int ref_len; char *hash_value; FNIN(); if (src_node == NULL || src_subsys == NULL) { FNRET(NULL); } if (strcmp(CRM_SYSTEM_DC, src_subsys) == 0) { hash_value = crm_strdup(src_subsys); if (!hash_value) { - cl_log(LOG_ERR, - "memory allocation failed in " + crm_err("memory allocation failed in " "generate_hash_value()\n"); FNRET(NULL); } FNRET(hash_value); } ref_len = strlen(src_subsys) + strlen(src_node) + 2; hash_value = (char*)crm_malloc(sizeof(char)*(ref_len)); if (!hash_value) { - cl_log(LOG_ERR, - "memory allocation failed in " + crm_err("memory allocation failed in " "generate_hash_value()\n"); FNRET(NULL); } snprintf(hash_value, ref_len-1, "%s_%s", src_node, src_subsys); hash_value[ref_len-1] = '\0';// make sure it is null terminated - cl_log(LOG_INFO, "created hash value: (%s)", hash_value); + crm_info("created hash value: (%s)", hash_value); FNRET(hash_value); } gboolean decode_hash_value(gpointer value, char **node, char **subsys) { char *char_value = (char*)value; int value_len = strlen(char_value); FNIN(); - cl_log(LOG_INFO, "Decoding hash value: (%s:%d)", + crm_info("Decoding hash value: (%s:%d)", char_value, value_len); if (strcmp(CRM_SYSTEM_DC, (char*)value) == 0) { *node = NULL; *subsys = (char*)crm_strdup(char_value); if (!*subsys) { - cl_log(LOG_ERR, "memory allocation failed in " + crm_err("memory allocation failed in " "decode_hash_value()\n"); FNRET(FALSE); } - cl_log(LOG_INFO, "Decoded value: (%s:%d)", *subsys, + crm_info("Decoded value: (%s:%d)", *subsys, (int)strlen(*subsys)); FNRET(TRUE); } else if (char_value != NULL) { if (decodeNVpair(char_value, '_', node, subsys)) { FNRET(TRUE); } else { *node = NULL; *subsys = NULL; FNRET(FALSE); } } FNRET(FALSE); } char * crm_itoa(int an_int) { int len = 32; char *buffer = crm_malloc(sizeof(char)*(len+1)); snprintf(buffer, len, "%d", an_int); return buffer; } + +unsigned int crm_log_level = LOG_VERBOSE; + +/* returns the old value */ +unsigned int +set_crm_log_level(unsigned int level) +{ + unsigned int old = crm_log_level; + crm_log_level = level; + return old; +} + +unsigned int +get_crm_log_level(unsigned int level) +{ + int old = crm_log_level; + crm_log_level = level; + return old; +} + +void +do_crm_log(int log_level, const char *function, const char *fmt, ...) +{ + gboolean do_log = FALSE; + switch(log_level) { + case LOG_NOTICE: + case LOG_WARNING: + case LOG_ERR: + do_log = TRUE; + break; + default: + if(log_level >= crm_log_level) { + do_log = TRUE; + if(log_level != LOG_INFO) { + log_level = LOG_DEBUG; + } + } + break; + } + + if(do_log) { + va_list ap; + char buf[MAXLINE]; + int nbytes; + + buf[MAXLINE-1] = EOS; + va_start(ap, fmt); + nbytes=vsnprintf(buf, sizeof(buf)-1, fmt, ap); + va_end(ap); + + if(function == NULL) { + cl_log(log_level, "%s", buf); + } else { + cl_log(log_level, "(%s) %s", function, buf); + } + } +} diff --git a/crm/common/xml.c b/crm/common/xml.c index 4738acca7e..315575de2e 100644 --- a/crm/common/xml.c +++ b/crm/common/xml.c @@ -1,835 +1,789 @@ -/* $Id: xml.c,v 1.1 2004/06/02 11:45:28 andrew Exp $ */ +/* $Id: xml.c,v 1.2 2004/06/02 15:25:10 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <time.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <libxml/tree.h> #include <clplumbing/ipc.h> #include <clplumbing/cl_log.h> #include <crm/crm.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/dmalloc_wrapper.h> void dump_array(int log_level, const char *message, const char **array, int depth); xmlNodePtr find_xml_node_nested(xmlNodePtr root, const char **search_path, int len) { int j; xmlNodePtr child; xmlNodePtr lastMatch; FNIN(); if (root == NULL) { FNRET(NULL); } if(search_path == NULL) { - CRM_NOTE("Will never find NULL"); + crm_trace("Will never find NULL"); FNRET(NULL); } -#ifdef XML_TRACE - dump_array(LOG_DEBUG, + dump_array(LOG_TRACE, "Looking for.", search_path, len); -#endif child = root->children, lastMatch = NULL; for (j=0; j < len; ++j) { gboolean is_found = FALSE; if (search_path[j] == NULL) { len = j; /* a NULL also means stop searching */ break; } while(child != NULL) { const char * child_name = (const char*)child->name; -#ifdef XML_TRACE - CRM_DEBUG("comparing (%s) with (%s).", + crm_trace("comparing (%s) with (%s).", search_path[j], child->name); -#endif if (strcmp(child_name, search_path[j]) == 0) { lastMatch = child; child = lastMatch->children; -#ifdef XML_TRACE - CRM_DEBUG("found node (%s) @line (%ld).", + crm_trace("found node (%s) @line (%ld).", search_path[j], xmlGetLineNo(child)); -#endif is_found = TRUE; break; } child = child->next; } if (is_found == FALSE) { -#ifdef XML_TRACE - CRM_DEBUG( - "No more siblings left... %s cannot be found.", + crm_trace("No more siblings left... %s cannot be found.", search_path[j]); -#endif break; } } if (j == len && lastMatch != NULL && strcmp(lastMatch->name, search_path[j-1]) == 0) { -#ifdef XML_TRACE - CRM_DEBUG("returning node (%s).", + crm_trace("returning node (%s).", xmlGetNodePath(lastMatch)); -#endif FNRET(lastMatch); } dump_array(LOG_WARNING, "Could not find the full path to the node you specified.", search_path, len); - cl_log(LOG_WARNING,"Closest point was node (%s) starting from %s.", + crm_warn("Closest point was node (%s) starting from %s.", xmlGetNodePath(lastMatch), root?root->name:NULL); FNRET(NULL); } const char * get_xml_attr(xmlNodePtr parent, const char *node_name, const char *attr_name, gboolean error) { if(node_name == NULL) { // get it from the current node return get_xml_attr_nested(parent, NULL, 0, attr_name, error); } return get_xml_attr_nested(parent, &node_name, 1, attr_name, error); } const char * get_xml_attr_nested(xmlNodePtr parent, const char **node_path, int length, const char *attr_name, gboolean error) { const char *attr_value = NULL; xmlNodePtr attr_parent = NULL; if(parent == NULL) { - cl_log(LOG_ERR, "Can not find attribute %s in NULL parent", + crm_err("Can not find attribute %s in NULL parent", attr_name); return NULL; } if(attr_name == NULL || strlen(attr_name) == 0) { - cl_log(LOG_ERR, "Can not find attribute with no name in %s", + crm_err("Can not find attribute with no name in %s", xmlGetNodePath(parent)); return NULL; } if(length == 0) { attr_parent = parent; } else { attr_parent = find_xml_node_nested(parent, node_path, length); if(attr_parent == NULL && error) { - cl_log(LOG_ERR, "No node at the path you specified."); + crm_err("No node at the path you specified."); return NULL; } } attr_value = xmlGetProp(attr_parent, attr_name); if((attr_value == NULL || strlen(attr_value) == 0) && error) { - cl_log(LOG_ERR, + crm_err( "No value present for %s at %s", attr_name, xmlGetNodePath(attr_parent)); return NULL; } return attr_value; } xmlNodePtr set_xml_attr(xmlNodePtr parent, const char *node_name, const char *attr_name, const char *attr_value, gboolean create) { if(node_name == NULL) { // set it on the current node return set_xml_attr_nested(parent, NULL, 0, attr_name, attr_value, create); } return set_xml_attr_nested(parent, &node_name, 1, attr_name, attr_value, create); } xmlNodePtr set_xml_attr_nested(xmlNodePtr parent, const char **node_path, int length, const char *attr_name, const char *attr_value, gboolean create) { xmlAttrPtr result = NULL; xmlNodePtr attr_parent = NULL; xmlNodePtr create_parent = NULL; xmlNodePtr tmp; if(parent == NULL && create == FALSE) { - cl_log(LOG_ERR, "Can not set attribute in NULL parent"); + crm_err("Can not set attribute in NULL parent"); return NULL; } if(attr_name == NULL || strlen(attr_name) == 0) { - cl_log(LOG_ERR, "Can not set attribute to %s with no name", + crm_err("Can not set attribute to %s with no name", attr_value); return NULL; } if(length == 0 && parent != NULL) { attr_parent = parent; } else if(length == 0 || node_path == NULL || *node_path == NULL || strlen(*node_path) == 0) { - cl_log(LOG_ERR, + crm_err( "Can not create parent to set attribute %s=%s on", attr_name, attr_value); return NULL; } else { attr_parent = find_xml_node_nested(parent, node_path, length); } if(create && attr_parent == NULL) { int j = 0; attr_parent = parent; for (j=0; j < length; ++j) { if (node_path[j] == NULL) { break; } tmp = find_xml_node(attr_parent, node_path[j]); if(tmp == NULL) { attr_parent = create_xml_node(attr_parent, node_path[j]); if(j==0) { create_parent = attr_parent; } } else { attr_parent = tmp; } } } else if(attr_parent == NULL) { - cl_log(LOG_ERR, "Can not find parent to set attribute on"); + crm_err("Can not find parent to set attribute on"); return NULL; } result = set_xml_property_copy(attr_parent, attr_name, attr_value); if(result == NULL) { - cl_log(LOG_WARNING, + crm_warn( "Could not set %s=%s at %s", attr_name, attr_value, xmlGetNodePath(attr_parent)); } if(create_parent != NULL) { return create_parent; } return parent; } xmlNodePtr find_xml_node(xmlNodePtr root, const char * search_path) { if(root == NULL) return NULL; return find_xml_node_nested(root, &search_path, 1); } xmlNodePtr find_entity(xmlNodePtr parent, const char *node_name, const char *id, gboolean siblings) { return find_entity_nested(parent, node_name, NULL, NULL, id, siblings); } xmlNodePtr find_entity_nested(xmlNodePtr parent, const char *node_name, const char *elem_filter_name, const char *elem_filter_value, const char *id, gboolean siblings) { xmlNodePtr child; FNIN(); -#ifdef XML_TRACE - cl_log(LOG_DEBUG, "Looking for %s elem with id=%s.", node_name, id); -#endif + crm_trace("Looking for %s elem with id=%s.", node_name, id); while(parent != NULL) { -#ifdef XML_TRACE - CRM_DEBUG("examining (%s).", xmlGetNodePath(parent)); -#endif + crm_trace("examining (%s).", xmlGetNodePath(parent)); child = parent->children; while(child != NULL) { -#ifdef XML_TRACE - CRM_DEBUG("looking for (%s) [name].", node_name); -#endif + crm_trace("looking for (%s) [name].", node_name); if (node_name != NULL && strcmp(child->name, node_name) != 0) { -#ifdef XML_TRACE - CRM_DEBUG( + crm_trace( "skipping entity (%s=%s) [node_name].", xmlGetNodePath(child), child->name); -#endif break; } else if (elem_filter_name != NULL && elem_filter_value != NULL) { const char* child_value = (const char*) xmlGetProp(child, elem_filter_name); -#ifdef XML_TRACE - cl_log(LOG_DEBUG, + crm_trace( "comparing (%s) with (%s) [attr_value].", child_value, elem_filter_value); -#endif if (strcmp(child_value, elem_filter_value)) { -#ifdef XML_TRACE - CRM_DEBUG("skipping entity (%s) [attr_value].", + crm_trace("skipping entity (%s) [attr_value].", xmlGetNodePath(child)); -#endif break; } } -#ifdef XML_TRACE - cl_log(LOG_DEBUG, + crm_trace( "looking for entity (%s) in %s.", id, xmlGetNodePath(child)); -#endif while(child != NULL) { -#ifdef XML_TRACE - cl_log(LOG_DEBUG, + crm_trace( "looking for entity (%s) in %s.", id, xmlGetNodePath(child)); -#endif xmlChar *child_id = xmlGetProp(child, XML_ATTR_ID); if (child_id == NULL) { - cl_log(LOG_CRIT, + crm_crit( "Entity (%s) has id=NULL..." "Cib not valid!", xmlGetNodePath(child)); } else if (strcmp(id, child_id) == 0) { -#ifdef XML_TRACE - CRM_DEBUG("found entity (%s).", id); -#endif + crm_trace("found entity (%s).", id); FNRET(child); } child = child->next; } } if (siblings == TRUE) { -#ifdef XML_TRACE - CRM_NOTE("Nothing yet... checking siblings"); -#endif + crm_trace("Nothing yet... checking siblings"); parent = parent->next; } else parent = NULL; } - cl_log(LOG_INFO, + crm_info( "Couldnt find anything appropriate for %s elem with id=%s.", node_name, id); FNRET(NULL); } void copy_in_properties(xmlNodePtr target, xmlNodePtr src) { if(src == NULL) { - cl_log(LOG_WARNING, "No node to copy properties from"); + crm_err("No node to copy properties from"); } else if (src->properties == NULL) { - cl_log(LOG_INFO, "No properties to copy"); + crm_info("No properties to copy"); } else if (target == NULL) { - cl_log(LOG_WARNING, "No node to copy properties into"); + crm_err("No node to copy properties into"); } else { #ifndef USE_BUGGY_LIBXML xmlAttrPtr prop_iter = NULL; FNIN(); prop_iter = src->properties; while(prop_iter != NULL) { const char *local_prop_name = prop_iter->name; const char *local_prop_value = xmlGetProp(src, local_prop_name); set_xml_property_copy(target, local_prop_name, local_prop_value); prop_iter = prop_iter->next; } #else xmlCopyPropList(target, src->properties); #endif } FNOUT(); } char * dump_xml(xmlNodePtr msg) { FNIN(); FNRET(dump_xml_node(msg, FALSE)); } void xml_message_debug(xmlNodePtr msg, const char *text) { char *msg_buffer; FNIN(); if(msg == NULL) { - CRM_DEBUG("%s: %s", + crm_verbose("%s: %s", text==NULL?"<null>":text,"<null>"); FNOUT(); } msg_buffer = dump_xml_node(msg, FALSE); - CRM_DEBUG("%s: %s", + crm_verbose("%s: %s", text==NULL?"<null>":text, msg_buffer==NULL?"<null>":msg_buffer); crm_free(msg_buffer); FNOUT(); } char * dump_xml_node(xmlNodePtr msg, gboolean whole_doc) { int lpc = 0; int msg_size = -1; xmlChar *xml_message = NULL; xmlBufferPtr xml_buffer; FNIN(); if (msg == NULL) FNRET(NULL); xmlInitParser(); if (whole_doc) { if (msg->doc == NULL) { xmlDocPtr foo = xmlNewDoc("1.0"); xmlDocSetRootElement(foo, msg); xmlSetTreeDoc(msg,foo); } xmlDocDumpMemory(msg->doc, &xml_message, &msg_size); } else { -#ifdef XML_TRACE - CRM_DEBUG("mem used by xml: %d", xmlMemUsed()); + crm_trace("mem used by xml: %d", xmlMemUsed()); xmlMemoryDump (); -#endif xml_buffer = xmlBufferCreate(); msg_size = xmlNodeDump(xml_buffer, msg->doc, msg, 0, 0); xml_message = (xmlChar*)crm_strdup(xmlBufferContent(xml_buffer)); xmlBufferFree(xml_buffer); if (!xml_message) { - cl_log(LOG_ERR, + crm_err( "memory allocation failed in dump_xml_node()"); } } xmlCleanupParser(); // HA wont send messages with newlines in them. for(; xml_message != NULL && lpc < msg_size; lpc++) if (xml_message[lpc] == '\n') xml_message[lpc] = ' '; FNRET((char*)xml_message); } xmlNodePtr add_node_copy(xmlNodePtr new_parent, xmlNodePtr xml_node) { xmlNodePtr node_copy = NULL; FNIN(); if(xml_node != NULL && new_parent != NULL) { node_copy = copy_xml_node_recursive(xml_node); xmlAddChild(new_parent, node_copy); } else if(xml_node == NULL) { - cl_log(LOG_ERR, "Could not add copy of NULL node"); + crm_err("Could not add copy of NULL node"); } else { - cl_log(LOG_ERR, "Could not add copy of node to NULL parent"); + crm_err("Could not add copy of node to NULL parent"); } FNRET(node_copy); } xmlAttrPtr set_xml_property_copy(xmlNodePtr node, const xmlChar *name, const xmlChar *value) { const char *parent_name = NULL; const char *local_name = NULL; const char *local_value = NULL; xmlAttrPtr ret_value = NULL; FNIN(); if(node != NULL) { parent_name = node->name; } -#ifdef XML_TRACE - CRM_DEBUG("[%s] Setting %s to %s", parent_name, name, value); -#endif + crm_trace("[%s] Setting %s to %s", parent_name, name, value); if (name == NULL || strlen(name) <= 0) { ret_value = NULL; } else if(node == NULL) { ret_value = NULL; } else if (value == NULL || strlen(value) <= 0) { ret_value = NULL; xmlUnsetProp(node, local_name); } else { local_value = crm_strdup(value); local_name = crm_strdup(name); ret_value = xmlSetProp(node, local_name, local_value); } FNRET(ret_value); } xmlNodePtr create_xml_node(xmlNodePtr parent, const char *name) { const char *local_name = NULL; const char *parent_name = NULL; xmlNodePtr ret_value = NULL; FNIN(); if (name == NULL || strlen(name) < 1) { ret_value = NULL; } else { local_name = crm_strdup(name); if(parent == NULL) ret_value = xmlNewNode(NULL, local_name); else { parent_name = parent->name; ret_value = xmlNewChild(parent, NULL, local_name, NULL); } } -#ifdef XML_TRACE - CRM_DEBUG("Created node [%s [%s]]", parent_name, local_name); -#endif + crm_trace("Created node [%s [%s]]", parent_name, local_name); FNRET(ret_value); } void unlink_xml_node(xmlNodePtr node) { xmlUnlinkNode(node); /* this helps us with frees and really should be being done by * the library call */ node->doc = NULL; } void free_xml(xmlNodePtr a_node) { FNIN(); if (a_node == NULL) ; // nothing to do else if (a_node->doc != NULL) xmlFreeDoc(a_node->doc); else { /* make sure the node is unlinked first */ xmlUnlinkNode(a_node); - -#if 0 - /* set a new doc, wont delete without one? */ - xmlDocPtr foo = xmlNewDoc("1.0"); - xmlDocSetRootElement(foo, a_node); - xmlSetTreeDoc(a_node,foo); - xmlFreeDoc(foo); -#else xmlFreeNode(a_node); -#endif } FNOUT(); } void set_node_tstamp(xmlNodePtr a_node) { char *since_epoch = (char*)crm_malloc(128*(sizeof(char))); FNIN(); sprintf(since_epoch, "%ld", (unsigned long)time(NULL)); set_xml_property_copy(a_node, XML_ATTR_TSTAMP, since_epoch); crm_free(since_epoch); } xmlNodePtr copy_xml_node_recursive(xmlNodePtr src_node) { #if XML_TRACE const char *local_name = NULL; xmlNodePtr local_node = NULL, node_iter = NULL, local_child = NULL; xmlAttrPtr prop_iter = NULL; FNIN(); if(src_node != NULL && src_node->name != NULL) { local_node = create_xml_node(NULL, src_node->name); prop_iter = src_node->properties; while(prop_iter != NULL) { const char *local_prop_name = prop_iter->name; const char *local_prop_value = xmlGetProp(src_node, local_prop_name); set_xml_property_copy(local_node, local_prop_name, local_prop_value); prop_iter = prop_iter->next; } node_iter = src_node->children; while(node_iter != NULL) { local_child = copy_xml_node_recursive(node_iter); if(local_child != NULL) { xmlAddChild(local_node, local_child); - CRM_DEBUG("Copied node [%s [%s]", local_name, local_child->name); + crm_trace("Copied node [%s [%s]", local_name, local_child->name); } node_iter = node_iter->next; } - CRM_DEBUG("Returning [%s]", local_node->name); + crm_trace("Returning [%s]", local_node->name); FNRET(local_node); } - CRM_NOTE("Returning null"); + crm_trace("Returning null"); FNRET(NULL); #else return xmlCopyNode(src_node, 1); #endif } xmlNodePtr string2xml(const char *input) { char ch = 0; int lpc = 0, input_len = strlen(input); gboolean more = TRUE; gboolean inTag = FALSE; xmlNodePtr xml_object = NULL; const char *the_xml; xmlDocPtr doc; xmlBufferPtr xml_buffer = xmlBufferCreate(); for(lpc = 0; (lpc < input_len) && more; lpc++) { ch = input[lpc]; switch(ch) { case EOF: case 0: ch = 0; more = FALSE; xmlBufferAdd(xml_buffer, &ch, 1); break; case '>': case '<': inTag = TRUE; if(ch == '>') inTag = FALSE; xmlBufferAdd(xml_buffer, &ch, 1); break; case '\n': case '\t': case ' ': ch = ' '; if(inTag) { xmlBufferAdd(xml_buffer, &ch, 1); } break; default: xmlBufferAdd(xml_buffer, &ch, 1); break; } } xmlInitParser(); the_xml = xmlBufferContent(xml_buffer); doc = xmlParseMemory(the_xml, strlen(the_xml)); xmlCleanupParser(); if (doc == NULL) { - cl_log(LOG_ERR, "Malformed XML [xml=%s]", the_xml); + crm_err("Malformed XML [xml=%s]", the_xml); xmlBufferFree(xml_buffer); return NULL; } xmlBufferFree(xml_buffer); xml_object = xmlDocGetRootElement(doc); return xml_object; } xmlNodePtr file2xml(FILE *input) { char ch = 0; gboolean more = TRUE; gboolean inTag = FALSE; xmlNodePtr xml_object = NULL; xmlBufferPtr xml_buffer = xmlBufferCreate(); const char *the_xml; xmlDocPtr doc; if(input == NULL) { - cl_log(LOG_ERR, "File pointer was NULL"); + crm_err("File pointer was NULL"); return NULL; } while (more) { ch = fgetc(input); -// cl_log(LOG_DEBUG, "Got [%c]", ch); +// crm_debug("Got [%c]", ch); switch(ch) { case EOF: case 0: ch = 0; more = FALSE; xmlBufferAdd(xml_buffer, &ch, 1); break; case '>': case '<': inTag = TRUE; if(ch == '>') inTag = FALSE; xmlBufferAdd(xml_buffer, &ch, 1); break; case '\n': case '\t': case ' ': ch = ' '; if(inTag) { xmlBufferAdd(xml_buffer, &ch, 1); } break; default: xmlBufferAdd(xml_buffer, &ch, 1); break; } } xmlInitParser(); the_xml = xmlBufferContent(xml_buffer); doc = xmlParseMemory(the_xml, strlen(the_xml)); xmlCleanupParser(); if (doc == NULL) { - cl_log(LOG_ERR, "Malformed XML [xml=%s]", the_xml); + crm_err("Malformed XML [xml=%s]", the_xml); xmlBufferFree(xml_buffer); return NULL; } xmlBufferFree(xml_buffer); xml_object = xmlDocGetRootElement(doc); xml_message_debug(xml_object, "Created fragment"); return xml_object; } void dump_array(int log_level, const char *message, const char **array, int depth) { int j; if(message != NULL) { - cl_log(log_level, "%s", message); + do_crm_log(log_level, __FUNCTION__, "%s", message); } - cl_log(log_level, "Contents of the array:"); + do_crm_log(log_level, __FUNCTION__, "Contents of the array:"); if(array == NULL || array[0] == NULL || depth == 0) { - cl_log(log_level, "\t<empty>"); + do_crm_log(log_level, __FUNCTION__, "\t<empty>"); } for (j=0; j < depth && array[j] != NULL; j++) { if (array[j] == NULL) break; - cl_log(log_level, "\t--> (%s).", array[j]); + do_crm_log(log_level, __FUNCTION__, "\t--> (%s).", array[j]); } } diff --git a/crm/crmd/callbacks.c b/crm/crmd/callbacks.c index 5b653e4514..3468ae8a6b 100644 --- a/crm/crmd/callbacks.c +++ b/crm/crmd/callbacks.c @@ -1,322 +1,317 @@ /* * 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 <portability.h> #include <crm/crm.h> #include <string.h> #include <crmd_fsa.h> #include <libxml/tree.h> #include <heartbeat.h> #include <hb_api.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/msg.h> #include <crm/cib.h> #include <crmd.h> #include <crmd_messages.h> #include <crm/dmalloc_wrapper.h> FILE *msg_in_strm = NULL; xmlNodePtr find_xml_in_hamessage(const struct ha_msg* msg); void crmd_ha_input_callback(const struct ha_msg* msg, void* private_data) { const char *from = ha_msg_value(msg, F_ORIG); const char *to = NULL; xmlNodePtr root_xml_node; FNIN(); #ifdef MSG_LOG if(msg_in_strm == NULL) { msg_in_strm = fopen("/tmp/inbound.log", "w"); } #endif if(from == NULL || strcmp(from, fsa_our_uname) == 0) { #ifdef MSG_LOG fprintf(msg_in_strm, "Discarded message [F_SEQ=%s] from ourselves.\n", ha_msg_value(msg, F_SEQ)); #endif FNOUT(); } #ifdef MSG_LOG fprintf(msg_in_strm, "[%s (%s:%s)]\t%s\n", from, ha_msg_value(msg, F_SEQ), ha_msg_value(msg, F_TYPE), ha_msg_value(msg, "xml") ); fflush(msg_in_strm); #endif root_xml_node = find_xml_in_hamessage(msg); to = xmlGetProp(root_xml_node, XML_ATTR_HOSTTO); if(to != NULL && strlen(to) > 0 && strcmp(to, fsa_our_uname) != 0) { #ifdef MSG_LOG fprintf(msg_in_strm, "Discarding message [F_SEQ=%s] for someone else.", ha_msg_value(msg, F_SEQ)); #endif FNOUT(); } set_xml_property_copy(root_xml_node, XML_ATTR_HOSTFROM, from); s_crmd_fsa(C_HA_MESSAGE, I_ROUTER, root_xml_node); free_xml(root_xml_node); FNOUT(); } /* * Apparently returning TRUE means "stay connected, keep doing stuff". * Returning FALSE means "we're all done, close the connection" */ gboolean crmd_ipc_input_callback(IPC_Channel *client, gpointer user_data) { int lpc = 0; char *buffer = NULL; IPC_Message *msg = NULL; gboolean hack_return_good = TRUE; xmlNodePtr root_xml_node; crmd_client_t *curr_client = (crmd_client_t*)user_data; FNIN(); - CRM_DEBUG("Processing IPC message from %s", + crm_verbose("Processing IPC message from %s", curr_client->table_key); while(client->ops->is_message_pending(client)) { if (client->ch_status == IPC_DISCONNECT) { /* The message which was pending for us is that * the IPC status is now IPC_DISCONNECT */ break; } if (client->ops->recv(client, &msg) != IPC_OK) { perror("Receive failure:"); FNRET(!hack_return_good); } if (msg == NULL) { - cl_log(LOG_WARNING, "No message this time"); + crm_err("No message this time"); continue; } lpc++; buffer = (char*)msg->msg_body; - CRM_DEBUG("Processing xml from %s [text=%s]", + crm_verbose("Processing xml from %s [text=%s]", curr_client->table_key, buffer); root_xml_node = find_xml_in_ipcmessage(msg, FALSE); if (root_xml_node != NULL) { if (crmd_authorize_message(root_xml_node, msg, curr_client)) { s_crmd_fsa(C_IPC_MESSAGE, I_ROUTER, root_xml_node); } } else { - cl_log(LOG_INFO, - "IPC Message was not valid... discarding."); + crm_info("IPC Message was not valid... discarding."); } free_xml(root_xml_node); msg->msg_done(msg); msg = NULL; buffer = NULL; root_xml_node = NULL; } - CRM_DEBUG("Processed %d messages", lpc); + crm_verbose("Processed %d messages", lpc); if (client->ch_status == IPC_DISCONNECT) { - cl_log(LOG_INFO, - "received HUP from %s", - curr_client->table_key); + crm_info("received HUP from %s", + curr_client->table_key); if (curr_client != NULL) { struct crm_subsystem_s *the_subsystem = NULL; if (curr_client->sub_sys == NULL) { - cl_log(LOG_WARNING, - "Client hadn't registered with us yet"); + crm_warn("Client hadn't registered with us yet"); } else if (strcmp(CRM_SYSTEM_PENGINE, curr_client->sub_sys) == 0) { the_subsystem = pe_subsystem; } else if (strcmp(CRM_SYSTEM_TENGINE, curr_client->sub_sys) == 0) { the_subsystem = te_subsystem; } else if (strcmp(CRM_SYSTEM_CIB, curr_client->sub_sys) == 0){ the_subsystem = cib_subsystem; } if(the_subsystem != NULL) { cleanup_subsystem(the_subsystem); } // else that was a transient client if (curr_client->table_key != NULL) { /* * Key is destroyed below: * curr_client->table_key * Value is cleaned up by: * G_main_del_IPC_Channel */ g_hash_table_remove( ipc_clients, curr_client->table_key); } if(curr_client->client_source != NULL) { gboolean det = G_main_del_IPC_Channel( curr_client->client_source); - CRM_DEBUG("crm_client was %s detached", + crm_verbose("crm_client was %s detached", det?"successfully":"not"); } crm_free(curr_client->table_key); crm_free(curr_client->sub_sys); crm_free(curr_client->uuid); crm_free(curr_client); } FNRET(!hack_return_good); } FNRET(hack_return_good); } void lrm_op_callback (lrm_op_t* op) { s_crmd_fsa(C_LRM_OP_CALLBACK, I_LRM_EVENT, op); } void lrm_monitor_callback (lrm_mon_t* monitor) { s_crmd_fsa(C_LRM_MONITOR_CALLBACK, I_LRM_EVENT, monitor); } void CrmdClientStatus(const char * node, const char * client, const char * status, void * private) { const char *join = NULL; const char *extra = NULL; xmlNodePtr update = NULL; xmlNodePtr fragment = NULL; if(safe_str_eq(status, JOINSTATUS)){ status = ONLINESTATUS; extra = XML_CIB_ATTR_CLEAR_SHUTDOWN; } else if(safe_str_eq(status, LEAVESTATUS)){ status = OFFLINESTATUS; join = CRMD_JOINSTATE_DOWN; extra = XML_CIB_ATTR_CLEAR_SHUTDOWN; } - cl_log(LOG_NOTICE, - "Status update: Client %s/%s now has status [%s]\n", - node, client, status); + crm_notice("Status update: Client %s/%s now has status [%s]\n", + node, client, status); if(AM_I_DC) { update = create_node_state(node, NULL, status, join); if(extra != NULL) { set_xml_property_copy(update, extra, XML_BOOLEAN_TRUE); } fragment = create_cib_fragment(update, NULL); store_request(NULL, fragment, CRM_OP_UPDATE, CRM_SYSTEM_DCIB); free_xml(fragment); free_xml(update); s_crmd_fsa(C_CRMD_STATUS_CALLBACK, I_NULL, NULL); } else { - cl_log(LOG_ERR, "Got client status callback in non-DC mode"); + crm_err("Got client status callback in non-DC mode"); } } xmlNodePtr find_xml_in_hamessage(const struct ha_msg* msg) { const char *xml; xmlDocPtr doc; xmlNodePtr root; FNIN(); if (msg == NULL) { - cl_log(LOG_INFO, - "**** ha_crm_msg_callback called on a NULL message"); + crm_info("**** ha_crm_msg_callback called on a NULL message"); FNRET(NULL); } #if 0 - cl_log(LOG_DEBUG, "[F_TYPE=%s]", ha_msg_value(msg, F_TYPE)); - cl_log(LOG_DEBUG, "[F_ORIG=%s]", ha_msg_value(msg, F_ORIG)); - cl_log(LOG_DEBUG, "[F_TO=%s]", ha_msg_value(msg, F_TO)); - cl_log(LOG_DEBUG, "[F_COMMENT=%s]", ha_msg_value(msg, F_COMMENT)); - cl_log(LOG_DEBUG, "[F_XML=%s]", ha_msg_value(msg, "xml")); -// cl_log(LOG_DEBUG, "[F_=%s]", ha_msg_value(ha_msg, F_)); + crm_debug("[F_TYPE=%s]", ha_msg_value(msg, F_TYPE)); + crm_debug("[F_ORIG=%s]", ha_msg_value(msg, F_ORIG)); + crm_debug("[F_TO=%s]", ha_msg_value(msg, F_TO)); + crm_debug("[F_COMMENT=%s]", ha_msg_value(msg, F_COMMENT)); + crm_debug("[F_XML=%s]", ha_msg_value(msg, "xml")); +// crm_debug("[F_=%s]", ha_msg_value(ha_msg, F_)); #endif if (strcmp("CRM", ha_msg_value(msg, F_TYPE)) != 0) { - cl_log(LOG_INFO, "Received a (%s) message by mistake.", + crm_info("Received a (%s) message by mistake.", ha_msg_value(msg, F_TYPE)); FNRET(NULL); } xml = ha_msg_value(msg, "xml"); if (xml == NULL) { - cl_log(LOG_INFO, "No XML attached to this message."); + crm_info("No XML attached to this message."); FNRET(NULL); } doc = xmlParseMemory(xml, strlen(xml)); if (doc == NULL) { - cl_log(LOG_INFO, "XML Buffer was not valid."); + crm_info("XML Buffer was not valid."); FNRET(NULL); } root = xmlDocGetRootElement(doc); if (root == NULL) { - cl_log(LOG_INFO, "Root node was NULL."); + crm_info("Root node was NULL."); FNRET(NULL); } FNRET(root); } diff --git a/crm/crmd/ccm.c b/crm/crmd/ccm.c index 279a4c0d21..17e10d8a8f 100644 --- a/crm/crmd/ccm.c +++ b/crm/crmd/ccm.c @@ -1,577 +1,564 @@ /* * 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 */ /* put these first so that uuid_t is defined without conflicts */ #include <portability.h> #include <ocf/oc_event.h> #include <ocf/oc_membership.h> #include <clplumbing/GSource.h> #include <string.h> #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crmd_messages.h> #include <crmd_fsa.h> #include <fsa_proto.h> #include <crm/dmalloc_wrapper.h> void oc_ev_special(const oc_ev_t *, oc_ev_class_t , int ); int register_with_ccm(ll_cluster_t *hb_cluster); void msg_ccm_join(const struct ha_msg *msg, void *foo); void crmd_ccm_input_callback(oc_ed_t event, void *cookie, size_t size, const void *data); void ccm_event_detail(const oc_ev_membership_t *oc, oc_ed_t event); gboolean ccm_dispatch(int fd, gpointer user_data); gboolean ghash_node_clfree(gpointer key, gpointer value, gpointer user_data); void ghash_update_cib_node(gpointer key, gpointer value, gpointer user_data); #define CCM_EVENT_DETAIL 1 oc_ev_t *fsa_ev_token; /* A_CCM_CONNECT */ enum crmd_fsa_input do_ccm_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { int ret; int fsa_ev_fd; FNIN(); if(action & A_CCM_DISCONNECT){ oc_ev_unregister(fsa_ev_token); } if(action & A_CCM_CONNECT) { - cl_log(LOG_INFO, "Registering with CCM"); + crm_info("Registering with CCM"); oc_ev_register(&fsa_ev_token); - cl_log(LOG_INFO, "Setting up CCM callbacks"); + crm_info("Setting up CCM callbacks"); oc_ev_set_callback(fsa_ev_token, OC_EV_MEMB_CLASS, crmd_ccm_input_callback, NULL); oc_ev_special(fsa_ev_token, OC_EV_MEMB_CLASS, 0/*don't care*/); - cl_log(LOG_INFO, "Activating CCM token"); + crm_info("Activating CCM token"); ret = oc_ev_activate(fsa_ev_token, &fsa_ev_fd); if (ret){ - cl_log(LOG_INFO, "CCM Activation failed... unregistering"); + crm_info("CCM Activation failed... unregistering"); oc_ev_unregister(fsa_ev_token); return(I_FAIL); } - cl_log(LOG_INFO, "CCM Activation passed... all set to go!"); + crm_info("CCM Activation passed... all set to go!"); //GFDSource* G_main_add_fd(G_PRIORITY_LOW, fsa_ev_fd, FALSE, ccm_dispatch, fsa_ev_token, default_ipc_input_destroy); } if(action & ~(A_CCM_CONNECT|A_CCM_DISCONNECT)) { - cl_log(LOG_ERR, "Unexpected action %s in %s", + crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } FNRET(I_NULL); } /* A_CCM_EVENT */ enum crmd_fsa_input do_ccm_event(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input return_input = I_NULL; const oc_ev_membership_t *oc = ((struct ccm_data *)data)->oc; oc_ed_t event = *((struct ccm_data *)data)->event; FNIN(); - cl_log(LOG_INFO,"event=%s", + crm_info("event=%s", event==OC_EV_MS_NEW_MEMBERSHIP?"NEW MEMBERSHIP": event==OC_EV_MS_NOT_PRIMARY?"NOT PRIMARY": event==OC_EV_MS_PRIMARY_RESTORED?"PRIMARY RESTORED": event==OC_EV_MS_EVICTED?"EVICTED": "NO QUORUM MEMBERSHIP"); if(CCM_EVENT_DETAIL) { ccm_event_detail(oc, event); } if (OC_EV_MS_EVICTED == event) { /* get out... NOW! */ return_input = I_SHUTDOWN; } if(return_input == I_SHUTDOWN) { ; /* ignore everything, the new DC will handle it */ } else { /* My understanding is that we will never get both * node leaving *and* node joining callbacks at the * same time. * * This logic would need to change if this is not * the case */ if(oc->m_n_out !=0) { return_input = I_NODE_LEFT; } else if(oc->m_n_in !=0) { /* delay the I_NODE_JOIN until they acknowledge our * DC status and send us their CIB */ return_input = I_NULL; } else { - cl_log(LOG_INFO, - "So why are we here? What CCM event happened?"); + crm_warn("So why are we here? What CCM event happened?"); } } FNRET(return_input); } /* A_CCM_UPDATE_CACHE */ /* * Take the opportunity to update the node status in the CIB as well * (but only if we are the DC) */ enum crmd_fsa_input do_ccm_update_cache(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input next_input = I_NULL; int lpc, offset; GHashTable *members = NULL; oc_ed_t event = *((struct ccm_data *)data)->event; const oc_ev_membership_t *oc = ((struct ccm_data *)data)->oc; oc_node_list_t *tmp = NULL, *membership_copy = (oc_node_list_t *) crm_malloc(sizeof(oc_node_list_t)); FNIN(); - cl_log(LOG_INFO,"Updating CCM cache after a \"%s\" event.", + crm_info("Updating CCM cache after a \"%s\" event.", event==OC_EV_MS_NEW_MEMBERSHIP?"NEW MEMBERSHIP": event==OC_EV_MS_NOT_PRIMARY?"NOT PRIMARY": event==OC_EV_MS_PRIMARY_RESTORED?"PRIMARY RESTORED": event==OC_EV_MS_EVICTED?"EVICTED": "NO QUORUM MEMBERSHIP"); /*--*-- All Member Nodes --*--*/ offset = oc->m_memb_idx; membership_copy->members_size = oc->m_n_member; if(membership_copy->members_size > 0) { membership_copy->members = g_hash_table_new(g_str_hash, g_str_equal); members = membership_copy->members; for(lpc=0; lpc < membership_copy->members_size; lpc++) { oc_node_t *member = (oc_node_t *) crm_malloc(sizeof(oc_node_t)); member->node_id = oc->m_array[offset+lpc].node_id; member->node_born_on = oc->m_array[offset+lpc].node_born_on; member->node_uname = crm_strdup(oc->m_array[offset+lpc].node_uname); g_hash_table_insert(members, member->node_uname, member); } } else { membership_copy->members = NULL; } /*--*-- New Member Nodes --*--*/ offset = oc->m_in_idx; membership_copy->new_members_size = oc->m_n_in; if(membership_copy->new_members_size > 0) { membership_copy->new_members = g_hash_table_new(g_str_hash, g_str_equal); members = membership_copy->new_members; for(lpc=0; lpc < membership_copy->new_members_size; lpc++) { oc_node_t *member = (oc_node_t *) crm_malloc(sizeof(oc_node_t)); member->node_id = oc->m_array[offset+lpc].node_id; member->node_born_on = oc->m_array[offset+lpc].node_born_on; member->node_uname = crm_strdup(oc->m_array[offset+lpc].node_uname); g_hash_table_insert(members, member->node_uname, member); } } else { membership_copy->new_members = NULL; } /*--*-- Recently Dead Member Nodes --*--*/ offset = oc->m_out_idx; membership_copy->dead_members_size = oc->m_n_out; if(membership_copy->dead_members_size > 0) { membership_copy->dead_members = g_hash_table_new(g_str_hash, g_str_equal); members = membership_copy->dead_members; for(lpc=0; lpc < membership_copy->dead_members_size; lpc++) { oc_node_t *member = (oc_node_t *) crm_malloc(sizeof(oc_node_t)); member->node_id = oc->m_array[offset+lpc].node_id; member->node_born_on = oc->m_array[offset+lpc].node_born_on; member->node_uname = crm_strdup(oc->m_array[offset+lpc].node_uname); g_hash_table_insert(members, member->node_uname, member); } } else { membership_copy->dead_members = NULL; } tmp = fsa_membership_copy; fsa_membership_copy = membership_copy; if(AM_I_DC) { // should be sufficient for only the DC to do this free_xml(do_update_cib_nodes(NULL, FALSE)); } /* Free the old copy */ if(tmp != NULL) { if(tmp->members != NULL) g_hash_table_foreach_remove( tmp->members, ghash_node_clfree, NULL); if(tmp->new_members != NULL) g_hash_table_foreach_remove( tmp->new_members, ghash_node_clfree, NULL); if(tmp->dead_members != NULL) g_hash_table_foreach_remove( tmp->dead_members, ghash_node_clfree, NULL); crm_free(tmp); } FNRET(next_input); } void ccm_event_detail(const oc_ev_membership_t *oc, oc_ed_t event) { int member_id = -1; gboolean member = FALSE; int lpc; int node_list_size; - cl_log(LOG_INFO,"trans=%d, nodes=%d, new=%d, lost=%d n_idx=%d, " + crm_info("trans=%d, nodes=%d, new=%d, lost=%d n_idx=%d, " "new_idx=%d, old_idx=%d", oc->m_instance, oc->m_n_member, oc->m_n_in, oc->m_n_out, oc->m_memb_idx, oc->m_in_idx, oc->m_out_idx); - cl_log(LOG_INFO, "NODES IN THE PRIMARY MEMBERSHIP"); + crm_info("NODES IN THE PRIMARY MEMBERSHIP"); node_list_size = oc->m_n_member; for(lpc=0; lpc<node_list_size; lpc++) { - cl_log(LOG_INFO,"\t%s [nodeid=%d, born=%d]", + crm_info("\t%s [nodeid=%d, born=%d]", oc->m_array[oc->m_memb_idx+lpc].node_uname, oc->m_array[oc->m_memb_idx+lpc].node_id, oc->m_array[oc->m_memb_idx+lpc].node_born_on); - CRM_DEBUG("%s ? %s", fsa_our_uname, + crm_verbose("%s ? %s", fsa_our_uname, oc->m_array[oc->m_memb_idx+lpc].node_uname); if(safe_str_eq(fsa_our_uname, oc->m_array[oc->m_memb_idx+lpc].node_uname)) { member = TRUE; member_id = oc->m_array[oc->m_memb_idx+lpc].node_id; } } if (member == FALSE) { - cl_log(LOG_WARNING, - "MY NODE IS NOT IN CCM THE MEMBERSHIP LIST"); + crm_warn("MY NODE IS NOT IN CCM THE MEMBERSHIP LIST"); } else { - cl_log(LOG_INFO, "MY NODE ID IS %d", member_id); + crm_info("MY NODE ID IS %d", member_id); } - cl_log(LOG_INFO, "NEW MEMBERS"); + crm_info("NEW MEMBERS"); if (oc->m_n_in==0) - cl_log(LOG_INFO, "\tNONE"); + crm_info("\tNONE"); for(lpc=0; lpc<oc->m_n_in; lpc++) { - cl_log(LOG_INFO,"\t%s [nodeid=%d, born=%d]", + crm_info("\t%s [nodeid=%d, born=%d]", oc->m_array[oc->m_in_idx+lpc].node_uname, oc->m_array[oc->m_in_idx+lpc].node_id, oc->m_array[oc->m_in_idx+lpc].node_born_on); } - cl_log(LOG_INFO, "MEMBERS LOST"); + crm_info("MEMBERS LOST"); if (oc->m_n_out==0) - cl_log(LOG_INFO, "\tNONE"); + crm_info("\tNONE"); for(lpc=0; lpc<oc->m_n_out; lpc++) { - cl_log(LOG_INFO,"\t%s [nodeid=%d, born=%d]", + crm_info("\t%s [nodeid=%d, born=%d]", oc->m_array[oc->m_out_idx+lpc].node_uname, oc->m_array[oc->m_out_idx+lpc].node_id, oc->m_array[oc->m_out_idx+lpc].node_born_on); if(fsa_our_uname != NULL - && strcmp(fsa_our_uname, oc->m_array[oc->m_memb_idx+lpc].node_uname)) { - cl_log(LOG_ERR, - "We're not part of the cluster anymore"); + && strcmp(fsa_our_uname, + oc->m_array[oc->m_memb_idx+lpc].node_uname)) { + crm_err("We're not part of the cluster anymore"); } } - cl_log(LOG_INFO, "-----------------------"); + crm_info("-----------------------"); } int register_with_ccm(ll_cluster_t *hb_cluster) { FNRET(0); } gboolean ccm_dispatch(int fd, gpointer user_data) { oc_ev_t *ccm_token = (oc_ev_t*)user_data; oc_ev_handle_event(ccm_token); return TRUE; } void crmd_ccm_input_callback(oc_ed_t event, void *cookie, size_t size, const void *data) { struct ccm_data *event_data = NULL; FNIN(); if(data != NULL) { event_data = (struct ccm_data *) crm_malloc(sizeof(struct ccm_data)); event_data->event = &event; event_data->oc = (const oc_ev_membership_t *)data; s_crmd_fsa(C_CCM_CALLBACK, I_CCM_EVENT, (void*)event_data); event_data->event = NULL; event_data->oc = NULL; crm_free(event_data); } else { - cl_log(LOG_INFO, "CCM Callback with NULL data... " + crm_info("CCM Callback with NULL data... " "I dont /think/ this is bad"); } oc_ev_callback_done(cookie); FNOUT(); } void msg_ccm_join(const struct ha_msg *msg, void *foo) { FNIN(); - cl_log(LOG_INFO, "\n###### Recieved ccm_join message..."); + crm_verbose("\n###### Recieved ccm_join message..."); if (msg != NULL) { - cl_log(LOG_INFO, - "[type=%s]", - ha_msg_value(msg, F_TYPE)); - cl_log(LOG_INFO, - "[orig=%s]", - ha_msg_value(msg, F_ORIG)); - cl_log(LOG_INFO, - "[to=%s]", - ha_msg_value(msg, F_TO)); - cl_log(LOG_INFO, - "[status=%s]", - ha_msg_value(msg, F_STATUS)); - cl_log(LOG_INFO, - "[info=%s]", - ha_msg_value(msg, F_COMMENT)); - cl_log(LOG_INFO, - "[rsc_hold=%s]", - ha_msg_value(msg, F_RESOURCES)); - cl_log(LOG_INFO, - "[stable=%s]", - ha_msg_value(msg, F_ISSTABLE)); - cl_log(LOG_INFO, - "[rtype=%s]", - ha_msg_value(msg, F_RTYPE)); - cl_log(LOG_INFO, - "[ts=%s]", - ha_msg_value(msg, F_TIME)); - cl_log(LOG_INFO, - "[seq=%s]", - ha_msg_value(msg, F_SEQ)); - cl_log(LOG_INFO, - "[generation=%s]", - ha_msg_value(msg, F_HBGENERATION)); - // cl_log(LOG_INFO, "[=%s]", ha_msg_value(msg, F_)); + crm_verbose("[type=%s]", + ha_msg_value(msg, F_TYPE)); + crm_verbose("[orig=%s]", + ha_msg_value(msg, F_ORIG)); + crm_verbose("[to=%s]", + ha_msg_value(msg, F_TO)); + crm_verbose("[status=%s]", + ha_msg_value(msg, F_STATUS)); + crm_verbose("[info=%s]", + ha_msg_value(msg, F_COMMENT)); + crm_verbose("[rsc_hold=%s]", + ha_msg_value(msg, F_RESOURCES)); + crm_verbose("[stable=%s]", + ha_msg_value(msg, F_ISSTABLE)); + crm_verbose("[rtype=%s]", + ha_msg_value(msg, F_RTYPE)); + crm_verbose("[ts=%s]", + ha_msg_value(msg, F_TIME)); + crm_verbose("[seq=%s]", + ha_msg_value(msg, F_SEQ)); + crm_verbose("[generation=%s]", + ha_msg_value(msg, F_HBGENERATION)); + // crm_verbose("[=%s]", ha_msg_value(msg, F_)); } FNOUT(); } struct update_data_s { xmlNodePtr updates; const char *state; const char *join; }; xmlNodePtr do_update_cib_nodes(xmlNodePtr updates, gboolean overwrite) { struct update_data_s update_data; update_data.updates = updates; update_data.state = XML_BOOLEAN_NO; update_data.join = CRMD_JOINSTATE_DOWN; if(fsa_membership_copy->dead_members != NULL) { g_hash_table_foreach(fsa_membership_copy->dead_members, ghash_update_cib_node, &update_data); } update_data.state = XML_BOOLEAN_YES; update_data.join = NULL; if(overwrite) { update_data.join = CRMD_JOINSTATE_PENDING; } if(fsa_membership_copy->members != NULL) { g_hash_table_foreach(fsa_membership_copy->members, ghash_update_cib_node, &update_data); } /* this is most likely overkill... * * make *sure* that the join status of nodes entering the ccm list * is reset * update_data.join = CRMD_JOINSTATE_PENDING; if(fsa_membership_copy->new_members != NULL) { g_hash_table_foreach(fsa_membership_copy->new_members, ghash_update_cib_node, &update_data); } */ if(update_data.updates != NULL) { xmlNodePtr fragment = create_cib_fragment(update_data.updates, NULL); store_request(NULL, fragment, CRM_OP_UPDATE, CRM_SYSTEM_DCIB); free_xml(fragment); } return update_data.updates; } void ghash_update_cib_node(gpointer key, gpointer value, gpointer user_data) { xmlNodePtr tmp1 = NULL; const char *node_uname = (const char*)key; struct update_data_s* data = (struct update_data_s*)user_data; const char *state = data->join; - crm_debug("%s processing %s (%s)", + crm_verbose("%s processing %s (%s)", __FUNCTION__, node_uname, data->state); if(state != NULL && safe_str_eq(fsa_our_uname, node_uname)) { /* the DC is always a member */ state = CRMD_JOINSTATE_MEMBER; } tmp1 = create_node_state(node_uname, data->state, NULL, state); if(data->updates == NULL) { - crm_debug("Creating first update"); + crm_verbose("Creating first update"); data->updates = tmp1; } else { xmlAddNextSibling(data->updates, tmp1); } } gboolean ghash_node_clfree(gpointer key, gpointer value, gpointer user_data) { // value->node_uname is free'd as "key" if(key != NULL) { crm_free(key); } if(value != NULL) { crm_free(value); } return TRUE; } diff --git a/crm/crmd/control.c b/crm/crmd/control.c index 03c1adfe11..b995d85668 100644 --- a/crm/crmd/control.c +++ b/crm/crmd/control.c @@ -1,553 +1,550 @@ /* * 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 <portability.h> #include <crm/crm.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> #define PID_FILE WORKING_DIR"/crm.pid" #define DAEMON_LOG LOG_DIR"/crm.log" #define DAEMON_DEBUG LOG_DIR"/crm.debug" gboolean crmd_ha_input_dispatch(int fd, gpointer user_data); void crmd_ha_input_destroy(gpointer user_data); void crm_shutdown(int nsig); IPC_WaitConnection *wait_channel_init(char daemonsocket[]); int init_server_ipc_comms( const char *child, gboolean (*channel_client_connect)(IPC_Channel *newclient, gpointer user_data), void (*channel_input_destroy)(gpointer user_data)); gboolean register_with_ha(ll_cluster_t *hb_cluster, const char *client_name, gboolean (*dispatch_method)(int fd, gpointer user_data), void (*message_callback)(const struct ha_msg* msg, void* private_data), GDestroyNotify cleanup_method); 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, void *data) { gboolean registered = FALSE; FNIN(); 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, crmd_ha_input_dispatch, crmd_ha_input_callback, crmd_ha_input_destroy); if(registered == FALSE) { FNRET(I_FAIL); } } if(action & ~(A_HA_CONNECT|A_HA_DISCONNECT)) { - cl_log(LOG_ERR, "Unexpected action %s in %s", + crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } FNRET(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, void *data) { enum crmd_fsa_input next_input = I_NULL; enum crmd_fsa_input tmp = I_NULL; FNIN(); /* last attempt to shut these down */ if(is_set(fsa_input_register, R_PE_CONNECTED)) { - cl_log(LOG_WARNING, - "Last attempt to shutdown the PolicyEngine"); + crm_warn("Last attempt to shutdown the PolicyEngine"); tmp = do_pe_control(A_PE_STOP, cause, cur_state, current_input, data); if(tmp != I_NULL) { next_input = I_ERROR; - cl_log(LOG_ERR, "Failed to shutdown the PolicyEngine"); + crm_err("Failed to shutdown the PolicyEngine"); } } if(is_set(fsa_input_register, R_TE_CONNECTED)) { - cl_log(LOG_WARNING, - "Last attempt to shutdown the Transitioner"); + crm_warn("Last attempt to shutdown the Transitioner"); tmp = do_pe_control(A_TE_STOP, cause, cur_state, current_input, data); if(tmp != I_NULL) { next_input = I_ERROR; - cl_log(LOG_ERR, "Failed to shutdown the Transitioner"); + crm_err("Failed to shutdown the Transitioner"); } } /* TODO: shutdown all remaining resources? */ FNRET(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, void *data) { enum crmd_fsa_input next_input = I_NULL; FNIN(); if(send_request(NULL, NULL, CRM_OP_SHUTDOWN_REQ, NULL, CRM_SYSTEM_DC, NULL) == FALSE){ next_input = I_ERROR; } FNRET(next_input); } gboolean crmd_ha_input_dispatch(int fd, gpointer user_data) { int lpc = 0; ll_cluster_t* hb_cluster = (ll_cluster_t*)user_data; FNIN(); while(hb_cluster->llc_ops->msgready(hb_cluster)) { lpc++; // invoke the callbacks but dont block hb_cluster->llc_ops->rcvmsg(hb_cluster, 0); } if(lpc == 0){ // hey what happened?? - cl_log(LOG_ERR, "We were called but no message was ready.\n" + crm_err("We were called but no message was ready.\n" "\tLikely the connection to Heartbeat failed, check the logs"); // TODO: feed this back into the FSA FNRET(FALSE); } FNRET(TRUE); } void crmd_ha_input_destroy(gpointer user_data) { - cl_log(LOG_INFO, "in my hb_input_destroy"); + crm_info("in my hb_input_destroy"); } /* 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, void *data) { FNIN(); - cl_log(LOG_ERR, "Action %s (%.16llx) not supported\n", fsa_action2string(action), action); + crm_err("Action %s (%.16llx) not supported\n", + fsa_action2string(action), action); if(action & A_EXIT_0) { g_main_quit(crmd_mainloop); } else { exit(1); } FNRET(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, void *data) { int facility; int was_error = 0; int interval = 1; // seconds between DC heartbeats FNIN(); fsa_input_register = 0; // zero out the regester - cl_log(LOG_INFO, "Register PID"); + crm_info("Register PID"); register_pid(PID_FILE, FALSE, crm_shutdown); cl_log_set_logfile(DAEMON_LOG); -/* if (crm_debug()) { */ +/* if (crm_verbose()) { */ cl_log_set_debugfile(DAEMON_DEBUG); /* cl_log_enable_stderr(FALSE); } */ ipc_clients = g_hash_table_new(&g_str_hash, &g_str_equal); /* change the logging facility to the one used by heartbeat daemon */ fsa_cluster_conn = ll_cluster_new("heartbeat"); - cl_log(LOG_INFO, "Switching to Heartbeat logger"); + crm_info("Switching to Heartbeat logger"); if ((facility = fsa_cluster_conn->llc_ops->get_logfacility( fsa_cluster_conn)) > 0) { cl_log_set_facility(facility); } - CRM_DEBUG("Facility: %d", facility); + crm_verbose("Facility: %d", facility); if(was_error == 0) { - cl_log(LOG_INFO, "Init server comms"); + crm_info("Init server comms"); was_error = init_server_ipc_comms(CRM_SYSTEM_CRMD, crmd_client_connect, default_ipc_input_destroy); } if (was_error == 0) { fsa_our_uname = fsa_cluster_conn->llc_ops->get_mynodeid( fsa_cluster_conn); if (fsa_our_uname == NULL) { - cl_log(LOG_ERR, "get_mynodeid() failed"); + crm_err("get_mynodeid() failed"); was_error = 1; } - cl_log(LOG_INFO, "FSA Hostname: %s", fsa_our_uname); + crm_info("FSA Hostname: %s", fsa_our_uname); } /* set up the timers */ dc_heartbeat = (fsa_timer_t *)crm_malloc(sizeof(fsa_timer_t)); integration_timer= (fsa_timer_t *)crm_malloc(sizeof(fsa_timer_t)); election_trigger = (fsa_timer_t *)crm_malloc(sizeof(fsa_timer_t)); election_timeout = (fsa_timer_t *)crm_malloc(sizeof(fsa_timer_t)); shutdown_escalation_timmer = (fsa_timer_t *) crm_malloc(sizeof(fsa_timer_t)); interval = interval * 1000; election_trigger->source_id = -1; election_trigger->period_ms = interval*4; election_trigger->fsa_input = I_DC_TIMEOUT; election_trigger->callback = timer_popped; dc_heartbeat->source_id = -1; dc_heartbeat->period_ms = interval; dc_heartbeat->fsa_input = I_NULL; dc_heartbeat->callback = do_dc_heartbeat; election_timeout->source_id = -1; election_timeout->period_ms = interval*6; election_timeout->fsa_input = I_ELECTION_DC; election_timeout->callback = timer_popped; integration_timer->source_id = -1; integration_timer->period_ms = interval*6; integration_timer->fsa_input = I_INTEGRATION_TIMEOUT; integration_timer->callback = timer_popped; shutdown_escalation_timmer->source_id = -1; shutdown_escalation_timmer->period_ms = interval*130; shutdown_escalation_timmer->fsa_input = I_TERMINATE; shutdown_escalation_timmer->callback = timer_popped; /* set up the sub systems */ cib_subsystem = (struct crm_subsystem_s*) crm_malloc(sizeof(struct crm_subsystem_s)); cib_subsystem->pid = 0; cib_subsystem->respawn = 1; 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; te_subsystem = (struct crm_subsystem_s*) crm_malloc(sizeof(struct crm_subsystem_s)); te_subsystem->pid = 0; te_subsystem->respawn = 1; 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; pe_subsystem = (struct crm_subsystem_s*) crm_malloc(sizeof(struct crm_subsystem_s)); pe_subsystem->pid = 0; pe_subsystem->respawn = 1; 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; if(was_error) FNRET(I_FAIL); FNRET(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, void *data) { FNIN(); - cl_log(LOG_ERR, "Action %s (%.16llx) not supported\n", + crm_err("Action %s (%.16llx) not supported\n", fsa_action2string(action), action); FNRET(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, void *data) { FNIN(); clear_bit_inplace(&fsa_input_register, R_STARTING); FNRET(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, void *data) { FNIN(); - cl_log(LOG_ERR, "Action %s (%.16llx) not supported\n", + crm_err("Action %s (%.16llx) not supported\n", fsa_action2string(action), action); FNRET(I_SHUTDOWN); } void crm_shutdown(int nsig) { FNIN(); CL_SIGNAL(nsig, crm_shutdown); if (crmd_mainloop != NULL && g_main_is_running(crmd_mainloop)) { if(is_set(fsa_input_register, R_SHUTDOWN)) { - cl_log(LOG_WARNING, "Escalating the shutdown"); + crm_err("Escalating the shutdown"); s_crmd_fsa(C_SHUTDOWN, I_ERROR, NULL); } else { set_bit_inplace(&fsa_input_register, R_SHUTDOWN); // cant rely on this... startTimer(shutdown_escalation_timmer); s_crmd_fsa(C_SHUTDOWN, I_SHUTDOWN, NULL); } } else { - cl_log(LOG_INFO, "exit from shutdown"); + crm_info("exit from shutdown"); exit(LSB_EXIT_OK); } FNOUT(); } IPC_WaitConnection * wait_channel_init(char daemonsocket[]) { IPC_WaitConnection *wait_ch; mode_t mask; char path[] = IPC_PATH_ATTR; GHashTable * attrs; FNIN(); 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); FNRET(wait_ch); } int init_server_ipc_comms( const char *child, gboolean (*channel_client_connect)(IPC_Channel *newclient, gpointer user_data), void (*channel_input_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; FNIN(); sprintf(commpath, WORKING_DIR "/%s", child); wait_ch = wait_channel_init(commpath); if (wait_ch == NULL) FNRET(1); G_main_add_IPC_WaitConnection(G_PRIORITY_LOW, wait_ch, NULL, FALSE, channel_client_connect, wait_ch, // user data passed to ?? channel_input_destroy); - cl_log(LOG_DEBUG, "Listening on: %s", commpath); + crm_debug("Listening on: %s", commpath); FNRET(0); } gboolean register_with_ha(ll_cluster_t *hb_cluster, const char *client_name, gboolean (*dispatch_method)(int fd, gpointer user_data), void (*message_callback)(const struct ha_msg* msg, void* private_data), GDestroyNotify cleanup_method) { const char* ournode = NULL; - cl_log(LOG_INFO, "Signing in with Heartbeat"); + crm_info("Signing in with Heartbeat"); if (hb_cluster->llc_ops->signon(hb_cluster, client_name)!= HA_OK) { - cl_log(LOG_ERR, "Cannot sign on with heartbeat"); - cl_log(LOG_ERR, - "REASON: %s", - hb_cluster->llc_ops->errmsg(hb_cluster)); + crm_err("Cannot sign on with heartbeat"); + crm_err("REASON: %s", + hb_cluster->llc_ops->errmsg(hb_cluster)); return FALSE; } - cl_log(LOG_DEBUG, "Finding our node name"); + crm_debug("Finding our node name"); if ((ournode = hb_cluster->llc_ops->get_mynodeid(hb_cluster)) == NULL) { - cl_log(LOG_ERR, "get_mynodeid() failed"); + crm_err("get_mynodeid() failed"); return FALSE; } - cl_log(LOG_INFO, "hostname: %s", ournode); + crm_info("hostname: %s", ournode); - cl_log(LOG_DEBUG, "Be informed of CRM messages"); + crm_debug("Be informed of CRM messages"); if (hb_cluster->llc_ops->set_msg_callback(hb_cluster, "CRM", message_callback, hb_cluster) !=HA_OK){ - cl_log(LOG_ERR, "Cannot set CRM message callback"); - cl_log(LOG_ERR, - "REASON: %s", - hb_cluster->llc_ops->errmsg(hb_cluster)); + crm_err("Cannot set CRM message callback"); + crm_err("REASON: %s", + hb_cluster->llc_ops->errmsg(hb_cluster)); return FALSE; } G_main_add_fd(G_PRIORITY_HIGH, hb_cluster->llc_ops->inputfd(hb_cluster), FALSE, dispatch_method, hb_cluster, // usrdata cleanup_method); /* it seems we need to poke the message receiving stuff in order for it to * start seeing messages. Its like it gets blocked or something. */ dispatch_method(0, hb_cluster); return TRUE; } diff --git a/crm/crmd/crmdmain.c b/crm/crmd/crmdmain.c index 9cdf802048..10d82cd0d5 100644 --- a/crm/crmd/crmdmain.c +++ b/crm/crmd/crmdmain.c @@ -1,204 +1,204 @@ -/* $Id: crmdmain.c,v 1.18 2004/06/02 12:31:34 andrew Exp $ */ +/* $Id: crmdmain.c,v 1.19 2004/06/02 15:25:11 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 */ #include <portability.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <apphb.h> #include <clplumbing/ipc.h> #include <clplumbing/Gmain_timeout.h> #include <clplumbing/cl_log.h> #include <clplumbing/cl_signal.h> #include <clplumbing/lsb_exitcodes.h> #include <clplumbing/uids.h> #include <clplumbing/realtime.h> #include <clplumbing/GSource.h> #include <clplumbing/cl_poll.h> #include <crm/crm.h> #include <crm/common/ctrl.h> #include <crm/common/ipc.h> #include <crm/common/xml.h> #include <crmd.h> #include <crmd_fsa.h> #include <crm/dmalloc_wrapper.h> const char* crm_system_name = CRM_SYSTEM_CRMD; #define PID_FILE WORKING_DIR"/crm.pid" #define OPTARGS "skrh" void usage(const char* cmd, int exit_status); int init_start(void); void crmd_hamsg_callback(const struct ha_msg* msg, void* private_data); gboolean crmd_tickle_apphb(gpointer data); GMainLoop* crmd_mainloop = NULL; -gboolean crm_debug_state = TRUE; +gboolean crm_verbose_state = TRUE; int main(int argc, char ** argv) { int req_restart = FALSE; int req_status = FALSE; int req_stop = FALSE; int argerr = 0; int flag; cl_log_set_entity(crm_system_name); cl_log_enable_stderr(TRUE); cl_log_set_facility(LOG_USER); while ((flag = getopt(argc, argv, OPTARGS)) != EOF) { switch(flag) { case 's': /* Status */ req_status = TRUE; break; case 'k': /* Stop (kill) */ req_stop = TRUE; break; case 'r': /* Restart */ req_restart = TRUE; break; case 'h': /* Help message */ usage(crm_system_name, LSB_EXIT_OK); break; default: ++argerr; break; } } if (optind > argc) { ++argerr; } if (argerr) { usage(crm_system_name,LSB_EXIT_GENERIC); } // read local config file if (req_status){ FNRET(init_status(PID_FILE, crm_system_name)); } if (req_stop){ FNRET(init_stop(PID_FILE)); } if (req_restart) { init_stop(PID_FILE); } FNRET(init_start()); } int init_start(void) { long pid; enum crmd_fsa_state state; if ((pid = get_running_pid(PID_FILE, NULL)) > 0) { - cl_log(LOG_CRIT, "already running: [pid %ld].", pid); + crm_crit("already running: [pid %ld].", pid); exit(LSB_EXIT_OK); } fsa_state = S_PENDING; state = s_crmd_fsa(C_STARTUP, I_STARTUP, NULL); if (state == S_PENDING) { /* Create the mainloop and run it... */ crmd_mainloop = g_main_new(FALSE); - cl_log(LOG_INFO, "Starting %s", crm_system_name); + crm_info("Starting %s", crm_system_name); #ifdef REALTIME_SUPPORT static int crm_realtime = 1; if (crm_realtime == 1){ cl_enable_realtime(); }else if (crm_realtime == 0){ cl_disable_realtime(); } cl_make_realtime(SCHED_RR, 5, 64, 64); #endif g_main_run(crmd_mainloop); return_to_orig_privs(); } else { - cl_log(LOG_ERR, "Startup of CRMd failed. Current state: %s", + crm_err("Startup of CRMd failed. Current state: %s", fsa_state2string(state)); } if (unlink(PID_FILE) == 0) { - cl_log(LOG_INFO, "[%s] stopped", crm_system_name); + crm_info("[%s] stopped", crm_system_name); } FNRET(state != S_PENDING); } void usage(const char* cmd, int exit_status) { FILE* stream; stream = exit_status ? stderr : stdout; fprintf(stream, "usage: %s [-srkh]" "[-c configure file]\n", cmd); /* fprintf(stream, "\t-d\tsets debug level\n"); */ /* fprintf(stream, "\t-s\tgets daemon status\n"); */ /* fprintf(stream, "\t-r\trestarts daemon\n"); */ /* fprintf(stream, "\t-k\tstops daemon\n"); */ /* fprintf(stream, "\t-h\thelp message\n"); */ fflush(stream); exit(exit_status); } gboolean crmd_tickle_apphb(gpointer data) { char app_instance[APPNAME_LEN]; int rc = 0; sprintf(app_instance, "%s_%ld", crm_system_name, (long)getpid()); rc = apphb_hb(); if (rc < 0) { cl_perror("%s apphb_hb failure", app_instance); exit(3); } return TRUE; } diff --git a/crm/crmd/election.c b/crm/crmd/election.c index 72231f2772..c8f0aebd84 100644 --- a/crm/crmd/election.c +++ b/crm/crmd/election.c @@ -1,385 +1,383 @@ /* * 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 <portability.h> #include <heartbeat.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/crm.h> #include <crmd_fsa.h> #include <crmd_messages.h> #include <crm/dmalloc_wrapper.h> void ghash_count_vote(gpointer key, gpointer value, gpointer user_data); /* A_ELECTION_VOTE */ enum crmd_fsa_input do_election_vote(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input election_result = I_NULL; FNIN(); /* dont vote if we're in one of these states or wanting to shut down */ switch(cur_state) { case S_RECOVERY: case S_RECOVERY_DC: case S_STOPPING: case S_RELEASE_DC: case S_TERMINATE: FNRET(I_NULL); // log warning break; default: if(is_set(fsa_input_register, R_SHUTDOWN)) { FNRET(I_NULL); // log warning } break; } send_request(NULL, NULL, CRM_OP_VOTE, NULL, CRM_SYSTEM_CRMD, NULL); FNRET(election_result); } gboolean do_dc_heartbeat(gpointer data) { fsa_timer_t *timer = (fsa_timer_t *)data; -// cl_log(LOG_DEBUG, "#!!#!!# Heartbeat timer just popped!"); +// crm_debug("#!!#!!# Heartbeat timer just popped!"); gboolean was_sent = send_request(NULL, NULL, CRM_OP_HBEAT, NULL, CRM_SYSTEM_CRMD, NULL); if(was_sent == FALSE) { // this is bad stopTimer(timer); // dont make it go off again s_crmd_fsa(C_HEARTBEAT_FAILED, I_SHUTDOWN, NULL); } return TRUE; } struct election_data_s { const char *winning_uname; unsigned int winning_bornon; }; /* A_ELECTION_COUNT */ enum crmd_fsa_input do_election_count_vote(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { gboolean we_loose = FALSE; xmlNodePtr vote = (xmlNodePtr)data; enum crmd_fsa_input election_result = I_NULL; const char *vote_from = xmlGetProp(vote, XML_ATTR_HOSTFROM); FNIN(); if(vote_from == NULL || strcmp(vote_from, fsa_our_uname) == 0) { // dont count our own vote FNRET(election_result); } if(fsa_membership_copy->members_size < 1) { // if even we are not in the cluster then we should not vote FNRET(I_FAIL); } oc_node_t *our_node = (oc_node_t*) g_hash_table_lookup(fsa_membership_copy->members, fsa_our_uname); oc_node_t *your_node = (oc_node_t*) g_hash_table_lookup(fsa_membership_copy->members, vote_from); #if 0 - cl_log(LOG_DEBUG, "%s (bornon=%d), our bornon (%d)", + crm_debug("%s (bornon=%d), our bornon (%d)", vote_from, our_node->born, my_born); - cl_log(LOG_DEBUG, "%s %s %s", + crm_debug("%s %s %s", fsa_our_uname, strcmp(fsa_our_uname, vote_from) < 0?"<":">=", vote_from); #endif if(is_set(fsa_input_register, R_SHUTDOWN)) { - cl_log(LOG_DEBUG, - "Election fail: we are shutting down"); + crm_debug("Election fail: we are shutting down"); we_loose = TRUE; } else if(our_node == NULL) { - cl_log(LOG_DEBUG, - "Election fail: we dont exist in the CCM list"); + crm_debug("Election fail: we dont exist in the CCM list"); we_loose = TRUE; } else if(your_node == NULL) { - cl_log(LOG_ERR, "The other side doesnt exist in the CCM list"); + crm_err("The other side doesnt exist in the CCM list"); } else if(your_node->node_born_on < our_node->node_born_on) { - cl_log(LOG_DEBUG, "Election fail: born_on"); + crm_debug("Election fail: born_on"); we_loose = TRUE; } else if(your_node->node_born_on == our_node->node_born_on && strcmp(fsa_our_uname, vote_from) > 0) { - cl_log(LOG_DEBUG, "Election fail: uname"); + crm_debug("Election fail: uname"); we_loose = TRUE; } else { struct election_data_s election_data; election_data.winning_uname = NULL; election_data.winning_bornon = -1; // maximum integer - CRM_NOTE("We might win... we should vote (possibly again)"); + crm_trace("We might win... we should vote (possibly again)"); election_result = I_DC_TIMEOUT; // new "default" g_hash_table_foreach(fsa_membership_copy->members, ghash_count_vote, &election_data); - cl_log(LOG_DEBUG, "Election winner should be %s (born_on=%d)", + crm_debug("Election winner should be %s (born_on=%d)", election_data.winning_uname, election_data.winning_bornon); if(safe_str_eq(election_data.winning_uname, fsa_our_uname)){ - cl_log(LOG_DEBUG, "Election win: lowest born_on and uname"); + crm_debug("Election win: lowest born_on and uname"); election_result = I_ELECTION_DC; } } if(we_loose) { if(fsa_input_register & R_THE_DC) { - cl_log(LOG_DEBUG, "Give up the DC"); + crm_debug("Give up the DC"); election_result = I_RELEASE_DC; } else { - cl_log(LOG_DEBUG, "We werent the DC anyway"); + crm_debug("We werent the DC anyway"); election_result = I_NOT_DC; } } if(we_loose || election_result == I_ELECTION_DC) { // cancel timer, its been decided stopTimer(election_timeout); } FNRET(election_result); } /* A_ELECT_TIMER_START, A_ELECTION_TIMEOUT */ // we won enum crmd_fsa_input do_election_timer_ctrl(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { FNIN(); if(action & A_ELECT_TIMER_START) { startTimer(election_timeout); } else if(action & A_ELECT_TIMER_STOP || action & A_ELECTION_TIMEOUT) { stopTimer(election_timeout); } else { - cl_log(LOG_ERR, "unexpected action %s", + crm_err("unexpected action %s", fsa_action2string(action)); } if(action & A_ELECTION_TIMEOUT) { - CRM_NOTE("The election timer went off, we win!"); + crm_trace("The election timer went off, we win!"); FNRET(I_ELECTION_DC); } FNRET(I_NULL); } /* A_DC_TIMER_STOP, A_DC_TIMER_START */ enum crmd_fsa_input do_dc_timer_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { gboolean timer_op_ok = TRUE; FNIN(); if(action & A_DC_TIMER_STOP) { timer_op_ok = stopTimer(election_trigger); } /* dont start a timer that wasnt already running */ if(action & A_DC_TIMER_START && timer_op_ok) { startTimer(election_trigger); } FNRET(I_NULL); } /* A_DC_TAKEOVER */ enum crmd_fsa_input do_dc_takeover(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { xmlNodePtr update = NULL, fragment = NULL; FNIN(); - CRM_NOTE("################## Taking over the DC ##################"); + crm_trace("################## Taking over the DC ##################"); set_bit_inplace(&fsa_input_register, R_THE_DC); - CRM_DEBUG("Am I the DC? %s", AM_I_DC?XML_BOOLEAN_YES:XML_BOOLEAN_NO); + crm_verbose("Am I the DC? %s", AM_I_DC?XML_BOOLEAN_YES:XML_BOOLEAN_NO); fsa_our_dc = NULL; set_bit_inplace(&fsa_input_register, R_JOIN_OK); set_bit_inplace(&fsa_input_register, R_INVOKE_PE); clear_bit_inplace(&fsa_input_register, R_CIB_DONE); clear_bit_inplace(&fsa_input_register, R_HAVE_CIB); startTimer(dc_heartbeat); if (fsa_cluster_conn->llc_ops->set_cstatus_callback( fsa_cluster_conn, CrmdClientStatus, NULL)!=HA_OK){ - cl_log(LOG_ERR, "Cannot set client status callback\n"); - cl_log(LOG_ERR, "REASON: %s\n", + crm_err("Cannot set client status callback\n"); + crm_err("REASON: %s\n", fsa_cluster_conn->llc_ops->errmsg(fsa_cluster_conn)); } /* store our state in the CIB (since some fields will not be * filled in because the DC doesnt go through the join process * with itself * * bypass the TE for now, it will be informed in good time */ update = create_node_state( fsa_our_uname, NULL, ONLINESTATUS, CRMD_JOINSTATE_MEMBER); set_xml_property_copy( update,XML_CIB_ATTR_EXPSTATE, CRMD_STATE_ACTIVE); fragment = create_cib_fragment(update, NULL); store_request(NULL, fragment, CRM_OP_UPDATE, CRM_SYSTEM_DCIB); free_xml(update); free_xml(fragment); /* Async get client status information in the cluster */ fsa_cluster_conn->llc_ops->client_status( fsa_cluster_conn, NULL, CRM_SYSTEM_CRMD, -1); FNRET(I_NULL); } /* A_DC_RELEASE */ enum crmd_fsa_input do_dc_release(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input result = I_NULL; FNIN(); - CRM_NOTE("################## Releasing the DC ##################"); + crm_trace("################## Releasing the DC ##################"); stopTimer(dc_heartbeat); if (fsa_cluster_conn->llc_ops->set_cstatus_callback( fsa_cluster_conn, NULL, NULL)!=HA_OK){ - cl_log(LOG_ERR, "Cannot unset client status callback\n"); - cl_log(LOG_ERR, "REASON: %s\n", + crm_err("Cannot unset client status callback\n"); + crm_err("REASON: %s\n", fsa_cluster_conn->llc_ops->errmsg(fsa_cluster_conn)); result = I_ERROR; } if(action & A_DC_RELEASE) { clear_bit_inplace(&fsa_input_register, R_THE_DC); /* get a new CIB from the new DC */ clear_bit_inplace(&fsa_input_register, R_HAVE_CIB); } else if (action & A_DC_RELEASED) { if(cur_state == S_STOPPING) { result = I_SHUTDOWN; // necessary? result = I_RELEASE_SUCCESS; } #if 0 else if( are there errors ) { // we cant stay up if not healthy // or perhaps I_ERROR and go to S_RECOVER? result = I_SHUTDOWN; } #endif else result = I_RELEASE_SUCCESS; } else { - cl_log(LOG_ERR, "Warning, do_dc_release invoked for action %s", + crm_err("Warning, do_dc_release invoked for action %s", fsa_action2string(action)); } - CRM_DEBUG("Am I still the DC? %s", AM_I_DC?XML_BOOLEAN_YES:XML_BOOLEAN_NO); + crm_verbose("Am I still the DC? %s", AM_I_DC?XML_BOOLEAN_YES:XML_BOOLEAN_NO); FNRET(result); } void ghash_count_vote(gpointer key, gpointer value, gpointer user_data) { struct election_data_s *election_data = (struct election_data_s *)user_data; oc_node_t *cur_node = (oc_node_t*)value; const char *node_uname = (const char*)key; if(election_data->winning_bornon > cur_node->node_born_on) { election_data->winning_uname = node_uname; election_data->winning_bornon = cur_node->node_born_on; } else if(election_data->winning_bornon == cur_node->node_born_on && (election_data->winning_uname == NULL || strcmp(election_data->winning_uname, node_uname) > 0)) { election_data->winning_uname = node_uname; election_data->winning_bornon = cur_node->node_born_on; } } diff --git a/crm/crmd/fsa.c b/crm/crmd/fsa.c index 478e9e26f8..822c6c7fa5 100644 --- a/crm/crmd/fsa.c +++ b/crm/crmd/fsa.c @@ -1,602 +1,599 @@ /* * 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 <portability.h> #include <stdio.h> #include <string.h> #include <time.h> #include <crm/crm.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/msg.h> #include <clplumbing/Gmain_timeout.h> #include <crmd_messages.h> #include <crmd_fsa.h> #include <fsa_proto.h> #include <fsa_matrix.h> #include <crm/dmalloc_wrapper.h> long long do_state_transition(long long actions, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_state next_state, enum crmd_fsa_input current_input, void *data); // delete this extern fsa_message_queue_t fsa_message_queue; #ifdef DOT_FSA_ACTIONS # ifdef FSA_TRACE # define IF_FSA_ACTION(x,y) \ if(is_set(actions,x)) { \ - CRM_DEBUG("Invoking action %s (%.16llx)", \ + crm_verbose("Invoking action %s (%.16llx)", \ fsa_action2string(x), x); \ last_action = x; \ actions = clear_bit(actions, x); \ next_input = y(x, cause, cur_state, last_input, data); \ if( (x & O_DC_TICKLE) == 0 && next_input != I_DC_HEARTBEAT ) \ fprintf(dot_strm, \ "\t// %s:\t%s\t(data? %s)\t(result=%s)\n", \ fsa_input2string(cur_input), \ fsa_action2string(x), \ - data==NULL?XML_BOOLEAN_NO:XML_BOOLEAN_YES, \ + data==NULL?XML_BOOLEAN_NO:XML_BOOLEAN_YES, \ fsa_input2string(next_input)); \ fflush(dot_strm); \ - CRM_DEBUG("Result of action %s was %s", \ + crm_verbose("Result of action %s was %s", \ fsa_action2string(x), fsa_input2string(next_input)); \ } # else # define IF_FSA_ACTION(x,y) \ if(is_set(actions,x)) { \ last_action = x; \ actions = clear_bit(actions, x); \ next_input = y(x, cause, cur_state, last_input, data); \ if( (x & O_DC_TICKLE) == 0 && next_input != I_DC_HEARTBEAT ) \ fprintf(dot_strm, \ "\t// %s:\t%s\t(data? %s)\t(result=%s)\n", \ fsa_input2string(cur_input), \ fsa_action2string(x), \ - data==NULL?XML_BOOLEAN_NO:XML_BOOLEAN_YES, \ + data==NULL?XML_BOOLEAN_NO:XML_BOOLEAN_YES, \ fsa_input2string(next_input)); \ fflush(dot_strm); \ } # endif #else # ifdef FSA_TRACE # define IF_FSA_ACTION(x,y) \ if(is_set(actions,x)) { \ - CRM_DEBUG("Invoking action %s (%.16llx)", \ + crm_verbose("Invoking action %s (%.16llx)", \ fsa_action2string(x), x); \ last_action = x; \ actions = clear_bit(actions, x); \ next_input = y(x, cause, cur_state, last_input, data); \ - CRM_DEBUG("Result of action %s was %s", \ + crm_verbose("Result of action %s was %s", \ fsa_action2string(x), fsa_input2string(next_input)); \ } # else # define IF_FSA_ACTION(x,y) \ if(is_set(actions,x)) { \ last_action = x; \ actions = clear_bit(actions, x); \ next_input = y(x, cause, cur_state, last_input, data); \ } # endif #endif #define ELSEIF_FSA_ACTION(x,y) else IF_FSA_ACTION(x,y) const char *dot_intro = "digraph \"g\" {\n" " size = \"30,30\"\n" " graph [\n" " fontsize = \"12\"\n" " fontname = \"Times-Roman\"\n" " fontcolor = \"black\"\n" " bb = \"0,0,398.922306,478.927856\"\n" " color = \"black\"\n" " ]\n" " node [\n" " fontsize = \"12\"\n" " fontname = \"Times-Roman\"\n" " fontcolor = \"black\"\n" " shape = \"ellipse\"\n" " color = \"black\"\n" " ]\n" " edge [\n" " fontsize = \"12\"\n" " fontname = \"Times-Roman\"\n" " fontcolor = \"black\"\n" " color = \"black\"\n" " ]\n" "// special nodes\n" " \"S_PENDING\" \n" " [\n" " color = \"blue\"\n" " fontcolor = \"blue\"\n" " ]\n" " \"S_TERMINATE\" \n" " [\n" " color = \"red\"\n" " fontcolor = \"red\"\n" " ]\n" "\n" "// DC only nodes\n" " \"S_RECOVERY_DC\" [ fontcolor = \"green\" ]\n" " \"S_INTEGRATION\" [ fontcolor = \"green\" ]\n" " \"S_POLICY_ENGINE\" [ fontcolor = \"green\" ]\n" " \"S_TRANSITION_ENGINE\" [ fontcolor = \"green\" ]\n" " \"S_RELEASE_DC\" [ fontcolor = \"green\" ]\n" " \"S_IDLE\" [ fontcolor = \"green\" ]\n"; static FILE *dot_strm = NULL; enum crmd_fsa_state fsa_state; oc_node_list_t *fsa_membership_copy; ll_cluster_t *fsa_cluster_conn; ll_lrm_t *fsa_lrm_conn; long long fsa_input_register; long long fsa_actions = A_NOTHING; const char *fsa_our_uname; const char *fsa_our_dc; fsa_timer_t *election_trigger = NULL; /* */ fsa_timer_t *election_timeout = NULL; /* */ fsa_timer_t *shutdown_escalation_timmer = NULL; /* */ fsa_timer_t *integration_timer = NULL; fsa_timer_t *dc_heartbeat = NULL; enum crmd_fsa_state s_crmd_fsa(enum crmd_fsa_cause cause, enum crmd_fsa_input initial_input, void *data) { long long actions = fsa_actions; long long new_actions = A_NOTHING; long long last_action = A_NOTHING; enum crmd_fsa_input last_input = initial_input; enum crmd_fsa_input cur_input; enum crmd_fsa_input next_input; enum crmd_fsa_state last_state, cur_state, next_state, starting_state; FNIN(); starting_state = fsa_state; cur_input = initial_input; next_input = initial_input; last_state = starting_state; cur_state = starting_state; next_state = starting_state; #ifdef FSA_TRACE - CRM_DEBUG("FSA invoked with Cause: %s\n\tState: %s, Input: %s", + crm_verbose("FSA invoked with Cause: %s\n\tState: %s, Input: %s", fsa_cause2string(cause), fsa_state2string(cur_state), fsa_input2string(cur_input)); #endif #ifdef DOT_FSA_ACTIONS if(dot_strm == NULL) { dot_strm = fopen("/tmp/live.dot", "w"); fprintf(dot_strm, "%s", dot_intro); } #endif /* * Process actions in order of priority but do only one * action at a time to avoid complicating the ordering. * * Actions may result in a new I_ event, these are added to * (not replace) existing actions before the next iteration. * */ while(next_input != I_NULL || actions != A_NOTHING || is_message()) { if(next_input == I_WAIT_FOR_EVENT) { /* we may be waiting for an a-sync task to "happen" * and until it does, we cant do anything else * * Re-add the last action */ actions |= last_action; - cl_log(LOG_INFO, "Wait until something else happens"); + crm_info("Wait until something else happens"); break; } #ifdef FSA_TRACE - CRM_DEBUG("FSA while loop:\tState: %s, Input: %s", + crm_verbose("FSA while loop:\tState: %s, Input: %s", fsa_state2string(cur_state), fsa_input2string(cur_input)); #endif /* update input variables */ cur_input = next_input; if(cur_input != I_NULL) { last_input = cur_input; } /* get the next batch of actions */ new_actions = crmd_fsa_actions[cur_input][cur_state]; if(new_actions != A_NOTHING) { #ifdef FSA_TRACE - CRM_DEBUG("Adding actions %.16llx", new_actions); + crm_verbose("Adding actions %.16llx", new_actions); #endif actions |= new_actions; } /* logging : *before* the state is changed */ IF_FSA_ACTION(A_ERROR, do_log) ELSEIF_FSA_ACTION(A_WARN, do_log) ELSEIF_FSA_ACTION(A_LOG, do_log) /* update state variables */ next_state = crmd_fsa_state[cur_input][cur_state]; last_state = cur_state; cur_state = next_state; fsa_state = next_state; /* start doing things... */ /* * Hook for change of state. * Allows actions to be added or removed when entering a state */ if(last_state != cur_state){ actions = do_state_transition(actions, cause, last_state, cur_state, last_input, data); } /* this is always run, some inputs/states may make various * actions irrelevant/invalid */ actions = clear_flags(actions, cause, cur_state, cur_input); /* regular action processing in order of action priority * * Make sure all actions that connect to required systems * are performed first */ if(actions == A_NOTHING) { - cl_log(LOG_INFO, "Nothing to do"); + crm_info("Nothing to do"); next_input = I_NULL; /* // check registers, see if anything is pending if(is_set(fsa_input_register, R_SHUTDOWN)) { - CRM_DEBUG("(Re-)invoking shutdown"); + crm_verbose("(Re-)invoking shutdown"); next_input = I_SHUTDOWN; } else if(is_set(fsa_input_register, R_INVOKE_PE)) { - CRM_DEBUG("Invoke the PE somehow"); + crm_verbose("Invoke the PE somehow"); } */ } /* get out of here NOW! before anything worse happens */ ELSEIF_FSA_ACTION(A_EXIT_1, do_exit) ELSEIF_FSA_ACTION(A_STARTUP, do_startup) ELSEIF_FSA_ACTION(A_CIB_START, do_cib_control) ELSEIF_FSA_ACTION(A_HA_CONNECT, do_ha_control) ELSEIF_FSA_ACTION(A_LRM_CONNECT,do_lrm_control) ELSEIF_FSA_ACTION(A_CCM_CONNECT,do_ccm_control) /* sub-system start */ ELSEIF_FSA_ACTION(A_TE_START, do_te_control) ELSEIF_FSA_ACTION(A_PE_START, do_pe_control) /* sub-system restart */ ELSEIF_FSA_ACTION(O_CIB_RESTART,do_cib_control) ELSEIF_FSA_ACTION(O_PE_RESTART, do_pe_control) ELSEIF_FSA_ACTION(O_TE_RESTART, do_te_control) ELSEIF_FSA_ACTION(A_STARTED, do_started) /* DC Timer */ ELSEIF_FSA_ACTION(O_DC_TIMER_RESTART, do_dc_timer_control) ELSEIF_FSA_ACTION(A_DC_TIMER_STOP, do_dc_timer_control) ELSEIF_FSA_ACTION(A_DC_TIMER_START, do_dc_timer_control) /* * Highest priority actions */ ELSEIF_FSA_ACTION(A_CIB_BUMPGEN, do_cib_invoke) ELSEIF_FSA_ACTION(A_TE_COPYTO, do_te_copyto) ELSEIF_FSA_ACTION(A_MSG_ROUTE, do_msg_route) ELSEIF_FSA_ACTION(A_RECOVER, do_recover) ELSEIF_FSA_ACTION(A_UPDATE_NODESTATUS, do_lrm_invoke) ELSEIF_FSA_ACTION(A_JOIN_ACK, do_ack_welcome) ELSEIF_FSA_ACTION(A_SHUTDOWN_REQ, do_shutdown_req) ELSEIF_FSA_ACTION(A_ELECTION_VOTE, do_election_vote) ELSEIF_FSA_ACTION(A_ELECT_TIMER_STOP, do_election_timer_ctrl) ELSEIF_FSA_ACTION(A_ELECT_TIMER_START, do_election_timer_ctrl) ELSEIF_FSA_ACTION(A_ELECTION_COUNT, do_election_count_vote) ELSEIF_FSA_ACTION(A_ELECTION_TIMEOUT, do_election_timer_ctrl) /* * "Get this over with" actions */ ELSEIF_FSA_ACTION(A_MSG_STORE, do_msg_store) /* * High priority actions * Update the cache first */ ELSEIF_FSA_ACTION(A_CCM_UPDATE_CACHE, do_ccm_update_cache) ELSEIF_FSA_ACTION(A_CCM_EVENT, do_ccm_event) /* * Medium priority actions */ ELSEIF_FSA_ACTION(A_DC_TAKEOVER, do_dc_takeover) ELSEIF_FSA_ACTION(A_DC_RELEASE, do_dc_release) ELSEIF_FSA_ACTION(A_JOIN_WELCOME_ALL, do_send_welcome_all) ELSEIF_FSA_ACTION(A_JOIN_WELCOME, do_send_welcome) ELSEIF_FSA_ACTION(A_JOIN_PROCESS_ACK, do_process_welcome_ack) /* * Low(er) priority actions * Make sure the CIB is always updated before invoking the * PE, and the PE before the TE */ ELSEIF_FSA_ACTION(A_CIB_INVOKE_LOCAL, do_cib_invoke) ELSEIF_FSA_ACTION(A_CIB_INVOKE, do_cib_invoke) ELSEIF_FSA_ACTION(A_LRM_INVOKE, do_lrm_invoke) ELSEIF_FSA_ACTION(A_LRM_EVENT, do_lrm_event) ELSEIF_FSA_ACTION(A_TE_CANCEL, do_te_invoke) ELSEIF_FSA_ACTION(A_PE_INVOKE, do_pe_invoke) ELSEIF_FSA_ACTION(A_TE_INVOKE, do_te_invoke) ELSEIF_FSA_ACTION(A_ANNOUNCE, do_announce) /* sub-system stop */ ELSEIF_FSA_ACTION(A_PE_STOP, do_pe_control) ELSEIF_FSA_ACTION(A_TE_STOP, do_te_control) ELSEIF_FSA_ACTION(A_DC_RELEASED, do_dc_release) ELSEIF_FSA_ACTION(A_HA_DISCONNECT, do_ha_control) ELSEIF_FSA_ACTION(A_CCM_DISCONNECT, do_ccm_control) ELSEIF_FSA_ACTION(A_LRM_DISCONNECT, do_lrm_control) ELSEIF_FSA_ACTION(A_CIB_STOP, do_cib_control) /* time to go now... */ /* Some of these can probably be consolidated */ ELSEIF_FSA_ACTION(A_SHUTDOWN, do_shutdown) ELSEIF_FSA_ACTION(A_STOP, do_stop) /* exit gracefully */ ELSEIF_FSA_ACTION(A_EXIT_0, do_exit) // ELSEIF_FSA_ACTION(A_, do_) else if((actions & A_MSG_PROCESS) != 0 || is_message()) { xmlNodePtr stored_msg = NULL; - crm_debug("Checking messages... %d", + crm_verbose("Checking messages... %d", g_slist_length(fsa_message_queue)); stored_msg = get_message(); if(is_message() == FALSE) { actions = clear_bit(actions, A_MSG_PROCESS); } if(stored_msg == NULL) { - cl_log(LOG_ERR, "Invalid stored message"); + crm_err("Invalid stored message"); continue; } /* * This is where we should clean up old messages * The problem is that we dont always know the * type of the data (and therefore the correct way * to free it). A wrapper is probably required. */ data = stored_msg; #ifdef DOT_FSA_ACTIONS fprintf(dot_strm, "\t// %s:\t%s\t(data? %s)", fsa_input2string(cur_input), fsa_action2string(A_MSG_PROCESS), stored_msg==NULL?XML_BOOLEAN_NO:XML_BOOLEAN_YES); fflush(dot_strm); #endif #ifdef FSA_TRACE - CRM_DEBUG("Invoking action %s (%.16llx)", + crm_verbose("Invoking action %s (%.16llx)", fsa_action2string(A_MSG_PROCESS), A_MSG_PROCESS); #endif //#ifdef FSA_TRACE xml_message_debug(stored_msg,"FSA processing message"); //#endif next_input = handle_message(stored_msg); #ifdef DOT_FSA_ACTIONS fprintf(dot_strm, "\t(result=%s)\n", fsa_input2string(next_input)); #endif - CRM_DEBUG("Result of action %s was %s", + crm_verbose("Result of action %s was %s", fsa_action2string(A_MSG_PROCESS), fsa_input2string(next_input)); /* Error checking and reporting */ } else if(cur_input != I_NULL && is_set(actions, A_NOTHING)) { - cl_log(LOG_WARNING, + crm_warn( "No action specified for input,state (%s,%s)", fsa_input2string(cur_input), fsa_state2string(cur_state)); next_input = I_NULL; } else if(cur_input == I_NULL && is_set(actions, A_NOTHING)) { #ifdef FSA_TRACE - cl_log(LOG_INFO, "Nothing left to do"); + crm_info("Nothing left to do"); #endif } else { - cl_log(LOG_ERR, "Action %s (0x%llx) not supported ", + crm_err("Action %s (0x%llx) not supported ", fsa_action2string(actions), actions); next_input = I_ERROR; } if(is_message()) { actions |= A_MSG_PROCESS; } } #ifdef FSA_TRACE - CRM_DEBUG("################# Exiting the FSA (%s) ##################", + crm_verbose("################# Exiting the FSA (%s) ##################", fsa_state2string(fsa_state)); #endif #ifdef DOT_FSA_ACTIONS fprintf(dot_strm, "\t// ### Exiting the FSA (%s)\n", fsa_state2string(fsa_state)); fflush(dot_strm); #endif // cleanup inputs? fsa_actions = actions; FNRET(fsa_state); } long long do_state_transition(long long actions, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_state next_state, enum crmd_fsa_input current_input, void *data) { long long tmp = actions; const char *state_from = fsa_state2string(cur_state); const char *state_to = fsa_state2string(next_state); const char *input = fsa_input2string(current_input); time_t now = time(NULL); if(cur_state == next_state) { - cl_log(LOG_ERR, - "%s called in state %s with no transtion", + crm_err("%s called in state %s with no transtion", __FUNCTION__, state_from); return A_NOTHING; } // if(current_input != I_NULL // && (current_input != I_DC_HEARTBEAT || cur_state != S_NOT_DC)){ fprintf(dot_strm, "\t\"%s\" -> \"%s\" [ label =\"%s\" ] // %s", state_from, state_to, input, asctime(localtime(&now))); fflush(dot_strm); //} - cl_log(LOG_INFO, - "State transition \"%s\" -> \"%s\" [ cause =\"%s\" %s ]", - state_from, state_to, input, asctime(localtime(&now))); + crm_info("State transition \"%s\" -> \"%s\" [ cause =\"%s\" %s ]", + state_from, state_to, input, asctime(localtime(&now))); switch(next_state) { case S_PENDING: break; case S_NOT_DC: if(is_set(fsa_input_register, R_SHUTDOWN)){ - cl_log(LOG_INFO, - "(Re)Issuing shutdown request now" - " that we have a new DC"); + crm_info("(Re)Issuing shutdown request now" + " that we have a new DC"); tmp = set_bit(tmp, A_SHUTDOWN_REQ); } tmp = clear_bit(tmp, A_RECOVER); break; case S_RECOVERY_DC: case S_RECOVERY: tmp = set_bit(tmp, A_RECOVER); break; default: tmp = clear_bit(tmp, A_RECOVER); break; } if(tmp != actions) { - cl_log(LOG_INFO, "Action b4 %.16llx ", actions); - cl_log(LOG_INFO, "Action after %.16llx ", tmp); + crm_info("Action b4 %.16llx ", actions); + crm_info("Action after %.16llx ", tmp); actions = tmp; } return actions; } long long clear_flags(long long actions, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input) { if(is_set(fsa_input_register, R_SHUTDOWN)){ clear_bit_inplace(&actions, A_DC_TIMER_START); } switch(cur_state) { case S_IDLE: break; case S_ELECTION: break; case S_INTEGRATION: break; case S_NOT_DC: break; case S_POLICY_ENGINE: break; case S_RECOVERY: break; case S_RECOVERY_DC: break; case S_RELEASE_DC: break; case S_PENDING: break; case S_STOPPING: break; case S_TERMINATE: break; case S_TRANSITION_ENGINE: break; case S_ILLEGAL: break; } return actions; } diff --git a/crm/crmd/join.c b/crm/crmd/join.c index 6f3250531e..cc3d4ad72f 100644 --- a/crm/crmd/join.c +++ b/crm/crmd/join.c @@ -1,365 +1,360 @@ /* * 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 <portability.h> #include <heartbeat.h> #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crmd_fsa.h> #include <crmd_messages.h> #include <crm/dmalloc_wrapper.h> GHashTable *joined_nodes = NULL; /* A_JOIN_WELCOME, A_JOIN_WELCOME_ALL */ enum crmd_fsa_input do_send_welcome(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { FNIN(); if(action & A_JOIN_WELCOME && data == NULL) { - cl_log(LOG_ERR, - "Attempt to send welcome message " - "without a message to reply to!"); + crm_err("Attempt to send welcome message " + "without a message to reply to!"); FNRET(I_NULL); } else if(action & A_JOIN_WELCOME) { xmlNodePtr welcome = (xmlNodePtr)data; const char *join_to = xmlGetProp(welcome, XML_ATTR_HOSTFROM); if(join_to != NULL) { xmlNodePtr update = create_node_state( join_to, NULL, NULL, CRMD_JOINSTATE_PENDING); xmlNodePtr tmp1 = create_cib_fragment(update, NULL); store_request(NULL, tmp1, CRM_OP_UPDATE, CRM_SYSTEM_DCIB); send_request(NULL, NULL, CRM_OP_WELCOME, join_to, CRM_SYSTEM_CRMD, NULL); free_xml(update); free_xml(tmp1); } else { - cl_log(LOG_ERR, "No recipient for welcome message"); + crm_err("No recipient for welcome message"); } FNRET(I_NULL); } FNRET(I_ERROR); } // welcome everyone... enum crmd_fsa_input do_send_welcome_all(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { FNIN(); // reset everyones status back to down or in_ccm in the CIB xmlNodePtr update = NULL; xmlNodePtr cib_copy = get_cib_copy(); xmlNodePtr tmp1 = get_object_root(XML_CIB_TAG_STATUS, cib_copy); xmlNodePtr node_entry = tmp1->children; /* Give everyone a chance to join before invoking the PolicyEngine */ stopTimer(integration_timer); startTimer(integration_timer); if(joined_nodes != NULL) { g_hash_table_destroy(joined_nodes); joined_nodes = g_hash_table_new(&g_str_hash, &g_str_equal); } // catch any nodes that are active in the CIB but not in the CCM list while(node_entry != NULL){ const char *node_id = xmlGetProp(node_entry, XML_ATTR_ID); gpointer a_node = g_hash_table_lookup(fsa_membership_copy->members, node_id); node_entry = node_entry->next; if(a_node != NULL || (safe_str_eq(fsa_our_uname, node_id))) { /* handled by do_update_cib_node() */ continue; } tmp1 = create_node_state(node_id, XML_BOOLEAN_NO, NULL, CRMD_JOINSTATE_DOWN); if(update == NULL) { update = tmp1; } else { update = xmlAddSibling(update, tmp1); } } // now process the CCM data free_xml(do_update_cib_nodes(update, TRUE)); free_xml(cib_copy); /* Avoid ordered message delays caused when the CRMd proc * isnt running yet (ie. send as a broadcast msg which are never * sent ordered. */ send_request(NULL, NULL, CRM_OP_WELCOME, NULL, CRM_SYSTEM_CRMD, NULL); /* No point hanging around in S_INTEGRATION if we're the only ones here! */ if(g_hash_table_size(joined_nodes) == fsa_membership_copy->members_size) { // that was the last outstanding join ack) - cl_log(LOG_INFO,"That was the last outstanding join ack"); + crm_info("That was the last outstanding join ack"); FNRET(I_SUCCESS); } else { - cl_log(LOG_DEBUG, - "Still waiting on %d outstanding join acks", - fsa_membership_copy->members_size - g_hash_table_size(joined_nodes)); + crm_debug("Still waiting on %d outstanding join acks", + fsa_membership_copy->members_size + - g_hash_table_size(joined_nodes)); // dont waste time by invoking the pe yet; } FNRET(I_NULL); } /* A_JOIN_ACK */ enum crmd_fsa_input do_ack_welcome(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { xmlNodePtr welcome = (xmlNodePtr)data; xmlNodePtr cib_copy; xmlNodePtr tmp1; xmlNodePtr tmp2; FNIN(); #if 0 if(we are sick) { log error ; FNRET(I_NULL); } #endif fsa_our_dc = xmlGetProp(welcome, XML_ATTR_HOSTFROM); if(fsa_our_dc == NULL) { - cl_log(LOG_ERR, "Failed to determin our DC"); + crm_err("Failed to determin our DC"); FNRET(I_FAIL); } /* send our status section to the DC */ cib_copy = get_cib_copy(); tmp1 = get_object_root(XML_CIB_TAG_STATUS, cib_copy); tmp2 = create_cib_fragment(tmp1, NULL); send_ha_reply(fsa_cluster_conn, welcome, tmp2); free_xml(tmp2); free_xml(cib_copy); FNRET(I_NULL); } /* A_ANNOUNCE */ enum crmd_fsa_input do_announce(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { xmlNodePtr msg = (xmlNodePtr)data; FNIN(); /* Once we hear from the DC, we can stop the timer * * This timer was started either on startup or when a node * left the CCM list */ /* dont announce if we're in one of these states */ switch(cur_state) { case S_RECOVERY: case S_RECOVERY_DC: case S_RELEASE_DC: case S_TERMINATE: - cl_log(LOG_WARNING, - "Do not announce ourselves in state %s", - fsa_state2string(cur_state)); + crm_warn("Do not announce ourselves in state %s", + fsa_state2string(cur_state)); FNRET(I_NULL); break; default: break; } if(AM_I_OPERATIONAL) { const char *from = xmlGetProp(msg, XML_ATTR_HOSTFROM); if(from == NULL) { - cl_log(LOG_ERR, "Failed to origin of ping message"); + crm_err("Failed to origin of ping message"); FNRET(I_FAIL); } send_request(NULL, NULL, CRM_OP_ANNOUNCE, from, CRM_SYSTEM_DC, NULL); } else { /* Delay announce until we have finished local startup */ - cl_log(LOG_WARNING, - "Delaying announce until local startup is complete"); + crm_warn("Delaying announce until local startup is complete"); FNRET(I_NULL); } FNRET(I_NULL); } /* A_JOIN_PROCESS_ACK */ enum crmd_fsa_input do_process_welcome_ack(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { xmlNodePtr tmp1; xmlNodePtr tmp2; xmlNodePtr cib_fragment; xmlNodePtr msg_cib; xmlNodePtr join_ack = (xmlNodePtr)data; int size = 0; gboolean is_a_member = FALSE; const char *join_from = xmlGetProp(join_ack, XML_ATTR_HOSTFROM); const char *ref = xmlGetProp(join_ack, XML_ATTR_REFERENCE); FNIN(); gpointer join_node = g_hash_table_lookup(fsa_membership_copy->members, join_from); if(join_node != NULL) { is_a_member = TRUE; } cib_fragment = find_xml_node(join_ack, XML_TAG_FRAGMENT); if(is_a_member == FALSE) { - cl_log(LOG_ERR, "Node %s is not known to us (ref %s)", + crm_err("Node %s is not known to us (ref %s)", join_from, ref); /* make sure any information from this node is discarded, * it is invalid */ free_xml(cib_fragment); FNRET(I_FAIL); } - cl_log(LOG_DEBUG, "Welcoming node %s after ACK (ref %s)", + crm_debug("Welcoming node %s after ACK (ref %s)", join_from, ref); /* add them to our list of CRMD_STATE_ACTIVE nodes TODO: still used? */ g_hash_table_insert(joined_nodes, strdup(join_from),strdup(join_from)); if(cib_fragment == NULL) { - cl_log(LOG_ERR, - "No status information was part of the" - " Welcome ACK from %s", - join_from); + crm_err("No status information was part of the" + " Welcome ACK from %s", + join_from); FNRET(I_NULL); } /* make sure a node entry exists for the new node * * this will add anyone except the first ever node in the cluster * since it will also be the DC which doesnt go through the * join process (with itself). We can include a special case * later if desired. */ tmp1 = create_xml_node(NULL, XML_CIB_TAG_NODE); set_xml_property_copy(tmp1, XML_ATTR_ID, join_from); set_xml_property_copy(tmp1, "uname", join_from); set_xml_property_copy(tmp1, XML_ATTR_TYPE, "node"); tmp2 = create_cib_fragment(tmp1, NULL); /* do not forward this to the TE */ invoke_local_cib(NULL, tmp2, CRM_OP_UPDATE); free_xml(tmp2); free_xml(tmp1); /* Make changes so that exp_state=active for this node when the update * is processed by A_CIB_INVOKE */ msg_cib = find_xml_node(cib_fragment, XML_TAG_CIB); tmp1 = get_object_root(XML_CIB_TAG_STATUS, msg_cib); tmp2 = find_entity(tmp1, XML_CIB_TAG_STATE, join_from, FALSE); if(tmp2 == NULL) { - cl_log(LOG_ERR, - "Status entry for %s not found in update, adding", - join_from); + crm_err("Status entry for %s not found in update, adding", + join_from); tmp2 = create_xml_node(tmp1, XML_CIB_TAG_STATE); set_xml_property_copy(tmp2, XML_ATTR_ID, join_from); } - set_xml_property_copy(tmp2, XML_CIB_ATTR_EXPSTATE, CRMD_STATE_ACTIVE); - set_xml_property_copy(tmp2, XML_CIB_ATTR_JOINSTATE, CRMD_JOINSTATE_MEMBER); + set_xml_property_copy( + tmp2, XML_CIB_ATTR_EXPSTATE, CRMD_STATE_ACTIVE); + set_xml_property_copy( + tmp2, XML_CIB_ATTR_JOINSTATE,CRMD_JOINSTATE_MEMBER); if(g_hash_table_size(joined_nodes) == fsa_membership_copy->members_size) { - cl_log(LOG_INFO,"That was the last outstanding join ack"); + crm_info("That was the last outstanding join ack"); FNRET(I_SUCCESS); /* The update isnt lost, the A_CIB_OP action is part of the * matrix for S_INTEGRATION + I_SUCCESS. */ } else { - cl_log(LOG_DEBUG, - "Still waiting on %d outstanding join acks", - size); + crm_debug("Still waiting on %d outstanding join acks", size); /* dont waste time by invoking the pe yet */ } FNRET(I_CIB_OP); } diff --git a/crm/crmd/lrm.c b/crm/crmd/lrm.c index 11ffeefac3..3812755a91 100644 --- a/crm/crmd/lrm.c +++ b/crm/crmd/lrm.c @@ -1,609 +1,607 @@ /* * 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 <portability.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 <crm/dmalloc_wrapper.h> xmlNodePtr do_lrm_query(void); GHashTable *xml2list(xmlNodePtr parent, const char **attr_path, int depth); gboolean lrm_dispatch(int fd, gpointer user_data); void do_update_resource(lrm_rsc_t *rsc, int status, int rc, const char *op_type); /* A_LRM_CONNECT */ enum crmd_fsa_input do_lrm_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input failed = I_NULL;//I_FAIL; int ret = HA_OK; FNIN(); if(action & A_LRM_DISCONNECT) { fsa_lrm_conn->lrm_ops->signoff(fsa_lrm_conn); } if(action & A_LRM_CONNECT) { - CRM_NOTE("LRM: connect..."); + crm_trace("LRM: connect..."); fsa_lrm_conn = ll_lrm_new(XML_CIB_TAG_LRM); if(NULL == fsa_lrm_conn) { return failed; } - CRM_NOTE("LRM: sigon..."); + crm_trace("LRM: sigon..."); ret = fsa_lrm_conn->lrm_ops->signon(fsa_lrm_conn, CRM_SYSTEM_CRMD); if(ret != HA_OK) { - cl_log(LOG_ERR, "Failed to sign on to the LRM"); + crm_err("Failed to sign on to the LRM"); return failed; } - CRM_NOTE("LRM: set_lrm_callback..."); + crm_trace("LRM: set_lrm_callback..."); ret = fsa_lrm_conn->lrm_ops->set_lrm_callback( fsa_lrm_conn, lrm_op_callback, lrm_monitor_callback); if(ret != HA_OK) { - cl_log(LOG_ERR, "Failed to set LRM callbacks"); + crm_err("Failed to set LRM callbacks"); return failed; } /* 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_input_destroy); } if(action & ~(A_LRM_CONNECT|A_LRM_DISCONNECT)) { - cl_log(LOG_ERR, "Unexpected action %s in %s", + crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } FNRET(I_NULL); } gboolean lrm_dispatch(int fd, gpointer user_data) { ll_lrm_t *lrm = (ll_lrm_t*)user_data; lrm->lrm_ops->rcvmsg(lrm, FALSE); return TRUE; } xmlNodePtr do_lrm_query(void) { GList* lrm_list = NULL; GList* element = NULL; GList* op_list = NULL; xmlNodePtr agent = NULL; xmlNodePtr data = create_xml_node(NULL, XML_CIB_TAG_LRM); xmlNodePtr agent_list = create_xml_node(data, "lrm_agents"); xmlNodePtr rsc_list; char *rsc_type = NULL; state_flag_t cur_state = 0; const char *this_op = NULL; GList* node = NULL; lrm_list = fsa_lrm_conn->lrm_ops->get_ra_supported(fsa_lrm_conn); if (NULL != lrm_list) { GList* element = g_list_first(lrm_list); while (NULL != element) { rsc_type = (char*)element->data; agent = create_xml_node(agent_list, "lrm_agent"); set_xml_property_copy(agent, "class", rsc_type); /* we dont have these yet */ set_xml_property_copy(agent, XML_ATTR_TYPE, NULL); set_xml_property_copy(agent, "version", NULL); element = g_list_next(element); } } g_list_free(lrm_list); lrm_list = fsa_lrm_conn->lrm_ops->get_all_rscs(fsa_lrm_conn); rsc_list = create_xml_node(data, XML_LRM_TAG_RESOURCES); if (NULL != lrm_list) { element = g_list_first(lrm_list); } while (NULL != element) { lrm_rsc_t *the_rsc = (lrm_rsc_t*)element->data; /* const char* ra_type; */ /* GHashTable* params; */ xmlNodePtr xml_rsc = create_xml_node(rsc_list, "rsc_state"); set_xml_property_copy(xml_rsc, XML_ATTR_ID, the_rsc->id); set_xml_property_copy(xml_rsc, "rsc_id", the_rsc->name); set_xml_property_copy(xml_rsc, "node_id",fsa_our_uname); op_list = the_rsc->ops->get_cur_state(the_rsc, &cur_state); - CRM_DEBUG("\tcurrent state:%s\n", + crm_verbose("\tcurrent state:%s\n", cur_state==LRM_RSC_IDLE?"Idle":"Busy"); node = g_list_first(op_list); while(NULL != node){ lrm_op_t* op = (lrm_op_t*)node->data; this_op = op->op_type; if(this_op == NULL || strcmp(this_op, "status") != 0){ const char *status_text = "<unknown>"; switch(op->status) { case LRM_OP_DONE: status_text = "done"; break; case LRM_OP_CANCELLED: status_text = "cancelled"; break; case LRM_OP_TIMEOUT: status_text = "timeout"; break; case LRM_OP_NOTSUPPORTED: status_text = "not suported"; break; case LRM_OP_ERROR: status_text = "error"; break; } set_xml_property_copy(xml_rsc, "op_result", status_text); set_xml_property_copy(xml_rsc, "rsc_op", this_op); // we only want the last one break; } node = g_list_next(node); } element = g_list_next(element); } if (NULL != lrm_list) { g_list_free(lrm_list); } return data; } /* A_LRM_INVOKE */ enum crmd_fsa_input do_lrm_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input next_input = I_NULL; xmlNodePtr fragment, tmp1; xmlNodePtr msg; const char *rsc_path[] = { "msg_data", "rsc_op", "resource", "instance_attributes", "parameters" }; const char *operation = NULL; rsc_id_t rid; const char *id_from_cib = NULL; const char *crm_op = NULL; lrm_rsc_t *rsc = NULL; lrm_mon_t* mon = NULL; lrm_op_t* op = NULL; FNIN(); if(action & A_UPDATE_NODESTATUS) { xmlNodePtr data = NULL; #ifndef USE_FAKE_LRM data = do_lrm_query(); #endif set_xml_property_copy(data, "replace", XML_CIB_TAG_LRM); tmp1 = create_xml_node(NULL, XML_CIB_TAG_STATE); set_xml_property_copy(tmp1, XML_ATTR_ID, fsa_our_uname); fragment = create_cib_fragment(tmp1, NULL); add_node_copy(tmp1, data); /* this only happens locally. the updates are pushed out * as part of the join process */ store_request(NULL, fragment, CRM_OP_UPDATE, CRM_SYSTEM_DC); free_xml(fragment); free_xml(tmp1); free_xml(data); FNRET(next_input); } #ifdef USE_FAKE_LRM if(data == NULL) { FNRET(I_ERROR); } msg = (xmlNodePtr)data; operation = get_xml_attr_nested(msg, rsc_path, DIMOF(rsc_path) -3, XML_LRM_ATTR_TASK, TRUE); id_from_cib = get_xml_attr_nested(msg, rsc_path, DIMOF(rsc_path) -2, XML_ATTR_ID, TRUE); crm_op = get_xml_attr(msg, XML_TAG_OPTIONS, XML_ATTR_OP, TRUE); if(safe_str_eq(crm_op, "rsc_op")) { const char *op_status = NULL; xmlNodePtr update = NULL; xmlNodePtr state = create_xml_node(NULL, XML_CIB_TAG_STATE); xmlNodePtr iter = create_xml_node(state, XML_CIB_TAG_LRM); - CRM_DEBUG("performing op %s...", operation); + crm_verbose("performing op %s...", operation); // so we can identify where to do the update set_xml_property_copy(state, XML_ATTR_ID, fsa_our_uname); iter = create_xml_node(iter, XML_LRM_TAG_RESOURCES); iter = create_xml_node(iter, "lrm_resource"); set_xml_property_copy(iter, XML_ATTR_ID, id_from_cib); set_xml_property_copy(iter, XML_LRM_ATTR_LASTOP, operation); long int op_code = 0; #if 0 /* introduce a 10% chance of an action failing */ op_code = random(); #endif if((op_code % 10) == 1) { op_code = 1; } else { op_code = 0; } char *op_code_s = crm_itoa(op_code); if(op_code) { // fail if(safe_str_eq(operation, "start")){ op_status = "stopped"; } else { op_status = "started"; } } else { // pass if(safe_str_eq(operation, "start")){ op_status = "started"; } else { op_status = "stopped"; } } set_xml_property_copy(iter, XML_LRM_ATTR_OPSTATE,op_status); set_xml_property_copy(iter, XML_LRM_ATTR_OPCODE, op_code_s); set_xml_property_copy(iter, XML_LRM_ATTR_TARGET, fsa_our_uname); crm_free(op_code_s); update = create_cib_fragment(state, NULL); send_request(NULL, update, CRM_OP_UPDATE, fsa_our_dc, CRM_SYSTEM_DCIB, NULL); } FNRET(I_NULL); #endif - cl_log(LOG_WARNING, "Action %s (%.16llx) only kind of supported\n", + crm_err("Action %s (%.16llx) only kind of supported\n", fsa_action2string(action), action); msg = (xmlNodePtr)data; operation = get_xml_attr_nested(msg, rsc_path, DIMOF(rsc_path) -3, XML_ATTR_OP, TRUE); id_from_cib = get_xml_attr_nested(msg, rsc_path, DIMOF(rsc_path) -2, XML_ATTR_ID, TRUE); // only the first 16 chars are used by the LRM strncpy(rid, id_from_cib, 16); crm_op = get_xml_attr(msg, XML_TAG_OPTIONS, XML_ATTR_OP, TRUE); rsc = fsa_lrm_conn->lrm_ops->get_rsc(fsa_lrm_conn, rid); if(crm_op != NULL && strcmp(crm_op, "lrm_query") == 0) { xmlNodePtr data, tmp1, tmp2, reply; tmp1 = create_xml_node(NULL, XML_CIB_TAG_STATE); set_xml_property_copy(tmp1, XML_ATTR_ID, fsa_our_uname); data = create_cib_fragment(tmp1, NULL); tmp2 = do_lrm_query(); add_node_copy(tmp1, tmp2); reply = create_reply(msg, data); relay_message(reply, TRUE); free_xml(data); free_xml(reply); free_xml(tmp2); free_xml(tmp1); } else if(operation != NULL && strcmp(operation, "monitor") == 0) { if(rsc == NULL) { - cl_log(LOG_ERR, "Could not find resource to monitor"); + crm_err("Could not find resource to monitor"); FNRET(I_FAIL); } mon = g_new(lrm_mon_t, 1); mon->op_type = "status"; mon->params = NULL; mon->timeout = 0; mon->user_data = rsc; mon->mode = LRM_MONITOR_SET; mon->interval = 2; mon->target = 1; rsc->ops->set_monitor(rsc,mon); mon = g_new(lrm_mon_t, 1); } else if(operation != NULL) { if(rsc == NULL) { // add it to the list - CRM_DEBUG("adding rsc %s before operation", rid); + crm_verbose("adding rsc %s before operation", rid); fsa_lrm_conn->lrm_ops->add_rsc( fsa_lrm_conn, rid, get_xml_attr_nested(msg, rsc_path, DIMOF(rsc_path) -2, "class", TRUE), get_xml_attr_nested(msg, rsc_path, DIMOF(rsc_path) -2, XML_ATTR_TYPE, TRUE), NULL); rsc = fsa_lrm_conn->lrm_ops->get_rsc( fsa_lrm_conn, rid); } if(rsc == NULL) { - cl_log(LOG_ERR, "Could not add resource to LRM"); + crm_err("Could not add resource to LRM"); FNRET(I_FAIL); } // now do the op - CRM_DEBUG("performing op %s...", operation); + crm_verbose("performing op %s...", operation); op = g_new(lrm_op_t, 1); op->op_type = operation; op->params = xml2list(msg, rsc_path, DIMOF(rsc_path)); op->timeout = 0; op->user_data = rsc; rsc->ops->perform_op(rsc, op); } FNRET(next_input); } GHashTable * xml2list(xmlNodePtr parent, const char**attr_path, int depth) { xmlNodePtr node_iter = NULL; GHashTable *nvpair_hash = g_hash_table_new(&g_str_hash, &g_str_equal); xmlNodePtr nvpair_list = find_xml_node_nested(parent, attr_path, depth); if(nvpair_list != NULL){ node_iter = nvpair_list->children; while(node_iter != NULL) { const char *key = xmlGetProp( node_iter, XML_NVPAIR_ATTR_NAME); const char *value = xmlGetProp( node_iter, XML_NVPAIR_ATTR_VALUE); - CRM_DEBUG("Added %s=%s", key, value); + crm_verbose("Added %s=%s", key, value); g_hash_table_insert (nvpair_hash, crm_strdup(key), crm_strdup(value)); node_iter = node_iter->next; } } return nvpair_hash; } void do_update_resource(lrm_rsc_t *rsc, int status, int rc, const char *op_type) { /* <status> <nodes_status id=uname> <lrm> <lrm_resources> <lrm_resource id=> </...> */ xmlNodePtr update, iter; char *tmp = NULL; xmlNodePtr fragment, tmp1; update = create_xml_node(NULL, "node_state"); set_xml_property_copy(update, XML_ATTR_ID, 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, "lrm_resource"); set_xml_property_copy(iter, XML_ATTR_ID, rsc->id); set_xml_property_copy(iter, XML_LRM_ATTR_LASTOP, op_type); tmp = crm_itoa(status); set_xml_property_copy(iter, XML_LRM_ATTR_OPSTATE, tmp); crm_free(tmp); tmp = crm_itoa(rc); set_xml_property_copy(iter, XML_LRM_ATTR_OPCODE, tmp); crm_free(tmp); set_xml_property_copy(iter, XML_LRM_ATTR_TARGET, fsa_our_uname); tmp1 = create_xml_node(NULL, XML_CIB_TAG_STATE); set_xml_property_copy(tmp1, XML_ATTR_ID, fsa_our_uname); add_node_copy(tmp1, update); fragment = create_cib_fragment(tmp1, NULL); send_request(NULL, fragment, CRM_OP_UPDATE, fsa_our_dc, CRM_SYSTEM_DCIB, NULL); free_xml(fragment); free_xml(update); free_xml(tmp1); } enum crmd_fsa_input do_lrm_event(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, void *data) { FNIN(); if(cause == C_LRM_MONITOR_CALLBACK) { lrm_mon_t* monitor = (lrm_mon_t*)data; lrm_rsc_t* rsc = monitor->rsc; switch(monitor->status) { case LRM_OP_DONE: - CRM_NOTE("An LRM monitor operation passed"); + crm_trace("An LRM monitor operation passed"); FNRET(I_NULL); break; case LRM_OP_CANCELLED: case LRM_OP_TIMEOUT: case LRM_OP_NOTSUPPORTED: case LRM_OP_ERROR: - cl_log(LOG_ERR, - "An LRM monitor operation failed" - " or was aborted"); + crm_err("An LRM monitor operation failed" + " or was aborted"); do_update_resource(rsc, monitor->status, monitor->rc, monitor->op_type); break; } } else if(cause == C_LRM_OP_CALLBACK) { lrm_op_t* op = (lrm_op_t*)data; lrm_rsc_t* rsc = op->rsc; switch(op->status) { case LRM_OP_CANCELLED: case LRM_OP_TIMEOUT: case LRM_OP_NOTSUPPORTED: case LRM_OP_ERROR: - cl_log(LOG_ERR, - "An LRM operation failed" - " or was aborted"); + crm_err("An LRM operation failed" + " or was aborted"); // keep going case LRM_OP_DONE: do_update_resource(rsc, op->status, op->rc, op->op_type); break; } } else { FNRET(I_FAIL); } FNRET(I_NULL); } diff --git a/crm/crmd/messages.c b/crm/crmd/messages.c index ad452b0916..d5cb4ab123 100644 --- a/crm/crmd/messages.c +++ b/crm/crmd/messages.c @@ -1,903 +1,889 @@ /* * 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 <portability.h> #include <crm/crm.h> #include <string.h> #include <crmd_fsa.h> #include <libxml/tree.h> #include <hb_api.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/msg.h> #include <crm/cib.h> #include <crmd.h> #include <crmd_messages.h> #include <crm/dmalloc_wrapper.h> FILE *msg_out_strm = NULL; FILE *router_strm = NULL; fsa_message_queue_t fsa_message_queue = NULL; gboolean relay_message(xmlNodePtr xml_relay_message, gboolean originated_locally); gboolean send_ha_reply(ll_cluster_t *hb_cluster, xmlNodePtr xml_request, xmlNodePtr xml_response_data); gboolean send_xmlha_message(ll_cluster_t *hb_fd, xmlNodePtr root); #ifdef MSG_LOG # define ROUTER_RESULT(x) char *msg_text = dump_xml(xml_relay_message);\ if(router_strm == NULL) { \ router_strm = fopen("/tmp/router.log", "w"); \ } \ fprintf(router_strm, "[%d RESULT (%s)]\t%s\t%s\n", \ AM_I_DC, \ xmlGetProp(xml_relay_message, XML_ATTR_REFERENCE),\ x, msg_text); \ fflush(router_strm); \ crm_free(msg_text); #else -# define ROUTER_RESULT(x) CRM_DEBUG(x, NULL); +# define ROUTER_RESULT(x) crm_verbose(x, NULL); #endif /* returns the current head of the FIFO queue */ fsa_message_queue_t put_message(xmlNodePtr new_message) { int old_len = g_slist_length(fsa_message_queue); // make sure to free it properly later fsa_message_queue = g_slist_append(fsa_message_queue, copy_xml_node_recursive(new_message)); - CRM_DEBUG("Queue len: %d -> %d", old_len, + crm_verbose("Queue len: %d -> %d", old_len, g_slist_length(fsa_message_queue)); if(old_len == g_slist_length(fsa_message_queue)){ - cl_log(LOG_ERR, "Couldnt add message to the queue"); + crm_err("Couldnt add message to the queue"); } return fsa_message_queue; } /* returns the next message */ xmlNodePtr get_message(void) { xmlNodePtr message = g_slist_nth_data(fsa_message_queue, 0); fsa_message_queue = g_slist_remove(fsa_message_queue, message); return message; } /* returns the current head of the FIFO queue */ gboolean is_message(void) { return (g_slist_length(fsa_message_queue) > 0); } /* A_MSG_STORE */ enum crmd_fsa_input do_msg_store(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { // xmlNodePtr new_message = (xmlNodePtr)data; FNIN(); // put_message(new_message); FNRET(I_NULL); } /* A_MSG_ROUTE */ enum crmd_fsa_input do_msg_route(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input result = I_NULL; xmlNodePtr xml_message = (xmlNodePtr)data; gboolean routed = FALSE, defer = TRUE, do_process = TRUE; FNIN(); #if 0 // if(cause == C_IPC_MESSAGE) { if (crmd_authorize_message(root_xml_node, msg, curr_client) == FALSE) { - CRM_DEBUG("Message not authorized"); + crm_verbose("Message not authorized"); do_process = FALSE; } // } #endif if(do_process) { /* try passing the buck first */ routed = relay_message(xml_message, cause==C_IPC_MESSAGE); if(routed == FALSE) { defer = TRUE; /* calculate defer */ result = handle_message(xml_message); switch(result) { case I_NULL: defer = FALSE; break; case I_DC_HEARTBEAT: defer = FALSE; break; /* what else should go here? */ default: - CRM_NOTE("Defering local processing of message"); + crm_trace("Defering local processing of message"); put_message(xml_message); result = I_REQUEST; break; } } } FNRET(result); } /* * This method adds a copy of xml_response_data */ gboolean send_request(xmlNodePtr msg_options, xmlNodePtr msg_data, const char *operation, const char *host_to, const char *sys_to, char **msg_reference) { gboolean was_sent = FALSE; xmlNodePtr request = NULL; FNIN(); msg_options = set_xml_attr(msg_options, XML_TAG_OPTIONS, XML_ATTR_OP, operation, TRUE); request = create_request(msg_options, msg_data, host_to, sys_to, AM_I_DC?CRM_SYSTEM_DC:CRM_SYSTEM_CRMD, NULL, NULL); // xml_message_debug(request, "Final request..."); if(msg_reference != NULL) { *msg_reference = crm_strdup(xmlGetProp(request, XML_ATTR_REFERENCE)); } was_sent = relay_message(request, TRUE); if(was_sent == FALSE) { put_message(request); } free_xml(request); FNRET(was_sent); } /* * This method adds a copy of xml_response_data */ gboolean store_request(xmlNodePtr msg_options, xmlNodePtr msg_data, const char *operation, const char *sys_to) { xmlNodePtr request = NULL; FNIN(); msg_options = set_xml_attr(msg_options, XML_TAG_OPTIONS, XML_ATTR_OP, operation, TRUE); - crm_debug("Storing op=%s message for later processing", operation); + crm_verbose("Storing op=%s message for later processing", operation); request = create_request(msg_options, msg_data, NULL, sys_to, AM_I_DC?CRM_SYSTEM_DC:CRM_SYSTEM_CRMD, NULL, NULL); put_message(request); free_xml(request); FNRET(TRUE); } gboolean relay_message(xmlNodePtr xml_relay_message, gboolean originated_locally) { int is_for_dc = 0; int is_for_dcib = 0; int is_for_crm = 0; int is_for_cib = 0; int is_local = 0; gboolean dont_cc= TRUE; gboolean processing_complete = FALSE; const char *host_to = xmlGetProp(xml_relay_message,XML_ATTR_HOSTTO); const char *sys_to = xmlGetProp(xml_relay_message,XML_ATTR_SYSTO); FNIN(); if(xml_relay_message == NULL) { - cl_log(LOG_ERR, "Cannot route empty message"); + crm_err("Cannot route empty message"); FNRET(TRUE); } if(strcmp(CRM_OP_HELLO, xml_relay_message->name) == 0) { /* quietly ignore */ FNRET(TRUE); } if(strcmp(XML_MSG_TAG, xml_relay_message->name) != 0) { xml_message_debug(xml_relay_message, "Bad message type, should be crm_message"); - cl_log(LOG_ERR, "Ignoring message of type %s", + crm_err("Ignoring message of type %s", xml_relay_message->name); FNRET(TRUE); } if(sys_to == NULL) { xml_message_debug(xml_relay_message, "Message did not have any value for sys_to"); - cl_log(LOG_ERR, "Message did not have any value for %s", + crm_err("Message did not have any value for %s", XML_ATTR_SYSTO); FNRET(TRUE); } is_for_dc = (strcmp(CRM_SYSTEM_DC, sys_to) == 0); is_for_dcib = (strcmp(CRM_SYSTEM_DCIB, sys_to) == 0); is_for_cib = (strcmp(CRM_SYSTEM_CIB, sys_to) == 0); is_for_crm = (strcmp(CRM_SYSTEM_CRMD, sys_to) == 0); is_local = 0; if(host_to == NULL || strlen(host_to) == 0) { if(is_for_dc) is_local = 0; else if(is_for_crm && originated_locally) is_local = 0; else is_local = 1; } else if(strcmp(fsa_our_uname, host_to) == 0) { is_local=1; } #if 0 - CRM_DEBUG("is_local %d", is_local); - CRM_DEBUG("is_for_dcib %d", is_for_dcib); - CRM_DEBUG("is_for_dc %d", is_for_dc); - CRM_DEBUG("is_for_crm %d", is_for_crm); - CRM_DEBUG("AM_I_DC %d", AM_I_DC); - CRM_DEBUG("sys_to %s", sys_to); - CRM_DEBUG("host_to %s", host_to); + crm_verbose("is_local %d", is_local); + crm_verbose("is_for_dcib %d", is_for_dcib); + crm_verbose("is_for_dc %d", is_for_dc); + crm_verbose("is_for_crm %d", is_for_crm); + crm_verbose("AM_I_DC %d", AM_I_DC); + crm_verbose("sys_to %s", sys_to); + crm_verbose("host_to %s", host_to); #endif if(is_for_dc || is_for_dcib) { if(AM_I_DC) { ROUTER_RESULT("Message result: DC/CRMd process"); processing_complete = FALSE; // more to be done by caller } else if(originated_locally) { ROUTER_RESULT("Message result: External relay to DC"); send_msg_via_ha(xml_relay_message, NULL); processing_complete = TRUE; } else { ROUTER_RESULT("Message result: Discard, not DC"); processing_complete = TRUE; // discard } } else if(is_local && (is_for_crm || is_for_cib)) { ROUTER_RESULT("Message result: CRMd process"); } else if(is_local) { if(dont_cc) { ROUTER_RESULT("Message result: Local relay"); } else { /* The DC should also get this message */ ROUTER_RESULT("Message result: Local relay with CC"); } send_msg_via_ipc(xml_relay_message, sys_to); processing_complete = TRUE & dont_cc; } else { if(dont_cc) { ROUTER_RESULT("Message result: External relay"); } else { /* The DC should also get this message */ ROUTER_RESULT("Message result: External relay with CC"); } send_msg_via_ha(xml_relay_message, host_to); processing_complete = TRUE & dont_cc; } FNRET(processing_complete); } gboolean crmd_authorize_message(xmlNodePtr root_xml_node, IPC_Message *client_msg, crmd_client_t *curr_client) { // check the best case first const char *sys_from = xmlGetProp(root_xml_node, XML_ATTR_SYSFROM); char *uuid = NULL; char *client_name = NULL; char *major_version = NULL; char *minor_version = NULL; const char *filtered_from; gpointer table_key = NULL; gboolean result; const char *op = get_xml_attr(root_xml_node, XML_TAG_OPTIONS, XML_ATTR_OP, TRUE); FNIN(); if (safe_str_neq(CRM_OP_HELLO, op)) { if(sys_from == NULL) { return FALSE; } gboolean can_reply = FALSE; // no-one has registered with this id filtered_from = sys_from; /* The CIB can have two names on the DC */ if(strcmp(sys_from, CRM_SYSTEM_DCIB) == 0) filtered_from = CRM_SYSTEM_CIB; if (g_hash_table_lookup (ipc_clients, filtered_from) != NULL) can_reply = TRUE; // reply can be routed - CRM_DEBUG("Message reply can%s be routed from %s.", + crm_verbose("Message reply can%s be routed from %s.", can_reply?"":" not", sys_from); if(can_reply == FALSE) { - cl_log(LOG_ERR, "Message not authorized"); + crm_err("Message not authorized"); } return can_reply; } - cl_log(LOG_INFO, - "received client join msg: %s", - (char*)client_msg->msg_body); + crm_info("received client join msg: %s", + (char*)client_msg->msg_body); result = process_hello_message(root_xml_node, &uuid, &client_name, &major_version, &minor_version); if (result == TRUE) { // check version int mav = atoi(major_version); int miv = atoi(minor_version); if (mav < 0 || miv < 0) { - cl_log(LOG_ERR, - "Client version (%d:%d) is not acceptable", - mav, - miv); + crm_err("Client version (%d:%d) is not acceptable", + mav, miv); result = FALSE; } crm_free(major_version); crm_free(minor_version); } struct crm_subsystem_s *the_subsystem = NULL; if (result == TRUE) { /* if we already have one of those clients * only applies to te, pe etc. not admin clients */ if (client_name == NULL) - cl_log(LOG_WARNING, - "Client had not registered with us yet"); + crm_warn("Client had not registered with us yet"); else if (strcmp(CRM_SYSTEM_PENGINE, client_name) == 0) the_subsystem = pe_subsystem; else if (strcmp(CRM_SYSTEM_TENGINE, client_name) == 0) the_subsystem = te_subsystem; else if (strcmp(CRM_SYSTEM_CIB, client_name) == 0) the_subsystem = cib_subsystem; if (the_subsystem != NULL) { // do we already have one? result =(fsa_input_register & the_subsystem->flag)==0; if(result) { the_subsystem->ipc = curr_client->client_channel; } // else we didnt ask for the client to start } else if(client_name != NULL && uuid != NULL) { table_key = (gpointer) generate_hash_key(client_name, uuid); } else { result = FALSE; - cl_log(LOG_ERR, - "Bad client details (client_name=%s, uuid=%s)", + crm_err("Bad client details (client_name=%s, uuid=%s)", client_name, uuid); } } if(result == TRUE && table_key == NULL) { table_key = (gpointer)crm_strdup(client_name); } if (result == TRUE) { - cl_log(LOG_INFO, "Accepted client %s", (char*)table_key); + crm_info("Accepted client %s", (char*)table_key); curr_client->table_key = table_key; curr_client->sub_sys = crm_strdup(client_name); curr_client->uuid = crm_strdup(uuid); g_hash_table_insert (ipc_clients, table_key, curr_client->client_channel); send_hello_message(curr_client->client_channel, "n/a", CRM_SYSTEM_CRMD, "0", "1"); - cl_log(LOG_INFO, "Updated client list with %s", + crm_info("Updated client list with %s", (char*)table_key); if(the_subsystem != NULL) { set_bit_inplace(&fsa_input_register, the_subsystem->flag); } s_crmd_fsa(C_SUBSYSTEM_CONNECT, I_NULL, NULL); } else { - cl_log(LOG_ERR, "Rejected client logon request"); + crm_err("Rejected client logon request"); curr_client->client_channel->ch_status = IPC_DISC_PENDING; } if(uuid != NULL) crm_free(uuid); if(client_name != NULL) crm_free(client_name); /* hello messages should never be processed further */ return FALSE; } enum crmd_fsa_input handle_message(xmlNodePtr stored_msg) { enum crmd_fsa_input next_input = I_NULL; const char *sys_to = get_xml_attr( stored_msg, NULL, XML_ATTR_SYSTO, TRUE); const char *sys_from = get_xml_attr( stored_msg, NULL, XML_ATTR_SYSFROM, TRUE); const char *host_from= get_xml_attr( stored_msg, NULL, XML_ATTR_HOSTFROM, TRUE); const char *msg_ref = get_xml_attr( stored_msg, NULL, XML_ATTR_REFERENCE, TRUE); const char *type = get_xml_attr( stored_msg, NULL, XML_ATTR_MSGTYPE, TRUE); const char *op = get_xml_attr( stored_msg, XML_TAG_OPTIONS, XML_ATTR_OP, TRUE); // xml_message_debug(stored_msg, "Processing message"); - cl_log(LOG_DEBUG, - "Received %s %s in state %s", - op, type, fsa_state2string(fsa_state)); + crm_debug("Received %s %s in state %s", + op, type, fsa_state2string(fsa_state)); if(type == NULL || op == NULL) { - cl_log(LOG_ERR, "Ignoring message (type=%s), (op=%s)", + crm_err("Ignoring message (type=%s), (op=%s)", type, op); xml_message_debug(stored_msg, "Bad message"); } else if(strcmp(type, XML_ATTR_REQUEST) == 0){ if(strcmp(op, CRM_OP_VOTE) == 0) { next_input = I_ELECTION; } else if(AM_I_DC && strcmp(op, CRM_OP_TEABORT) == 0) { next_input = I_PE_CALC; } else if(AM_I_DC && strcmp(op, CRM_OP_TECOMPLETE) == 0) { if(fsa_state == S_TRANSITION_ENGINE) { next_input = I_SUCCESS; /* silently ignore? probably means the TE is signaling OK too early } else { - cl_log(LOG_WARNING, + crm_warn( "Op %s is only valid in state %s (%s)", op, fsa_state2string(S_TRANSITION_ENGINE), fsa_state2string(fsa_state)); */ } } else if(strcmp(op, CRM_OP_HBEAT) == 0) { next_input = I_DC_HEARTBEAT; } else if(strcmp(op, CRM_OP_WELCOME) == 0) { next_input = I_WELCOME; } else if(strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) { /* create cib fragment and add to message */ /* handle here to avoid potential version issues * where the shutdown message/proceedure may have * been changed in later versions. * * This way the DC is always in control of the shutdown */ xmlNodePtr frag = NULL; time_t now = time(NULL); char *now_s = crm_itoa((int)now); xmlNodePtr node_state = create_xml_node(NULL, XML_CIB_TAG_STATE); - cl_log(LOG_INFO, "Creating shutdown request for %s", + crm_info("Creating shutdown request for %s", host_from); set_xml_property_copy( node_state, XML_ATTR_ID, host_from); set_xml_property_copy( node_state, XML_CIB_ATTR_SHUTDOWN, now_s); set_xml_property_copy( node_state, XML_CIB_ATTR_EXPSTATE, CRMD_STATE_INACTIVE); frag = create_cib_fragment(node_state, NULL); xmlAddChild(stored_msg, frag); free_xml(node_state); crm_free(now_s); next_input = I_CIB_OP; } else if(strcmp(op, CRM_OP_SHUTDOWN) == 0) { next_input = I_TERMINATE; } else if(strcmp(op, CRM_OP_ANNOUNCE) == 0) { next_input = I_NODE_JOIN; } else if(strcmp(op, CRM_OP_REPLACE) == 0 || strcmp(op, CRM_OP_ERASE) == 0) { next_input = I_CIB_OP; fprintf(router_strm, "Message result: CIB Op\n"); } else if(AM_I_DC && (strcmp(op, CRM_OP_CREATE) == 0 || strcmp(op, CRM_OP_UPDATE) == 0 || strcmp(op, CRM_OP_DELETE) == 0)) { /* updates should only be performed on the DC */ next_input = I_CIB_OP; } else if(strcmp(op, CRM_OP_PING) == 0) { /* eventually do some stuff to figure out * if we /are/ ok */ xmlNodePtr ping = createPingAnswerFragment(sys_to, "ok"); xmlNodePtr wrapper = create_reply(stored_msg, ping); relay_message(wrapper, TRUE); free_xml(wrapper); } else { - cl_log(LOG_ERR, - "Unexpected request (op=%s) sent to the %s", - op, AM_I_DC?"DC":"CRMd"); + crm_err("Unexpected request (op=%s) sent to the %s", + op, AM_I_DC?"DC":"CRMd"); } } else if(strcmp(type, XML_ATTR_RESPONSE) == 0) { if(strcmp(op, CRM_OP_WELCOME) == 0) { next_input = I_WELCOME_ACK; } else if(AM_I_DC && strcmp(op, CRM_OP_PECALC) == 0) { if(fsa_state == S_POLICY_ENGINE && safe_str_eq(msg_ref, fsa_pe_ref)) { next_input = I_SUCCESS; } else if(fsa_state != S_POLICY_ENGINE) { - cl_log(LOG_ERR, - "Reply to %s is only valid in state %s", - op, fsa_state2string(S_POLICY_ENGINE)); + crm_err("Reply to %s is only valid in state %s", + op, fsa_state2string(S_POLICY_ENGINE)); } else { - CRM_DEBUG("Skipping superceeded reply from %s", + crm_verbose("Skipping superceeded reply from %s", sys_from); } } else if(strcmp(op, CRM_OP_VOTE) == 0 || strcmp(op, CRM_OP_HBEAT) == 0 || strcmp(op, CRM_OP_WELCOME) == 0 || strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0 || strcmp(op, CRM_OP_SHUTDOWN) == 0 || strcmp(op, CRM_OP_ANNOUNCE) == 0) { next_input = I_NULL; } 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_ERASE) == 0) { /* perhaps we should do somethign with these replies, * especially check that the actions passed */ /* fprintf(router_strm, "Message result: CIB Reply\n"); */ } else { - cl_log(LOG_ERR, - "Unexpected response (op=%s) sent to the %s", - op, AM_I_DC?"DC":"CRMd"); + crm_err("Unexpected response (op=%s) sent to the %s", + op, AM_I_DC?"DC":"CRMd"); next_input = I_NULL; } } else { - cl_log(LOG_ERR, "Unexpected message type %s", type); + crm_err("Unexpected message type %s", type); } -/* CRM_DEBUG("%s: Next input is %s", __FUNCTION__, */ +/* crm_verbose("%s: Next input is %s", __FUNCTION__, */ /* fsa_input2string(next_input)); */ return next_input; } gboolean send_xmlha_message(ll_cluster_t *hb_fd, xmlNodePtr root) { int xml_len = -1; int send_result = -1; char *xml_text = NULL; const char *host_to = NULL; const char *sys_to = NULL; struct ha_msg *msg = NULL; gboolean all_is_good = TRUE; gboolean broadcast = FALSE; int log_level = LOG_DEBUG; xmlNodePtr opts = find_xml_node(root, XML_TAG_OPTIONS); const char *op = xmlGetProp(opts, XML_ATTR_OP); #ifdef MSG_LOG char *msg_text = NULL; #endif FNIN(); if (root == NULL) { - cl_log(LOG_ERR, "Attempt to send NULL Message via HA failed."); + crm_err("Attempt to send NULL Message via HA failed."); all_is_good = FALSE; } host_to = xmlGetProp(root, XML_ATTR_HOSTTO); sys_to = xmlGetProp(root, XML_ATTR_SYSTO); if (all_is_good) { msg = ha_msg_new(4); ha_msg_add(msg, F_TYPE, "CRM"); ha_msg_add(msg, F_COMMENT, "A CRM xml message"); xml_text = dump_xml(root); xml_len = strlen(xml_text); if (xml_text == NULL || xml_len <= 0) { - cl_log(LOG_ERR, + crm_err( "Failed sending an invalid XML Message via HA"); all_is_good = FALSE; xml_message_debug(root, "Bad message was"); } else { if(ha_msg_add(msg, "xml", xml_text) == HA_FAIL) { - cl_log(LOG_ERR, - "Could not add xml to HA message"); + crm_err("Could not add xml to HA message"); all_is_good = FALSE; } } } if (all_is_good) { if (sys_to == NULL || strlen(sys_to) == 0) { - cl_log(LOG_ERR, - "You did not specify a destination sub-system" - " for this message."); + crm_err("You did not specify a destination sub-system" + " for this message."); all_is_good = FALSE; } } /* There are a number of messages may not need to be ordered. * At a later point perhaps we should detect them and send them * as unordered messages. */ if (all_is_good) { if (host_to == NULL || strlen(host_to) == 0) { broadcast = TRUE; send_result = hb_fd->llc_ops->sendclustermsg(hb_fd, msg); } else { send_result = hb_fd->llc_ops->send_ordered_nodemsg( hb_fd, msg, host_to); } if(send_result != HA_OK) all_is_good = FALSE; } if(all_is_good == FALSE) { log_level = LOG_ERR; } if(log_level == LOG_ERR || (safe_str_neq(op, CRM_OP_HBEAT))) { - cl_log(log_level, + do_crm_log(log_level, __FUNCTION__, "Sending %s HA message (ref=%s, len=%d) to %s@%s %s.", broadcast?"broadcast":"directed", xmlGetProp(root, XML_ATTR_REFERENCE), xml_len, sys_to, host_to==NULL?"<all>":host_to, all_is_good?"succeeded":"failed"); } #ifdef MSG_LOG msg_text = dump_xml(root); if(msg_out_strm == NULL) { msg_out_strm = fopen("/tmp/outbound.log", "w"); } fprintf(msg_out_strm, "[%d HA (%s:%d)]\t%s\n", all_is_good, xmlGetProp(root, XML_ATTR_REFERENCE), send_result, msg_text); fflush(msg_out_strm); crm_free(msg_text); if(msg != NULL) { ha_msg_del(msg); } #endif FNRET(all_is_good); } // required? or just send to self an let relay_message do its thing? /* * This method adds a copy of xml_response_data */ gboolean send_ha_reply(ll_cluster_t *hb_cluster, xmlNodePtr xml_request, xmlNodePtr xml_response_data) { gboolean was_sent = FALSE; xmlNodePtr reply; FNIN(); was_sent = FALSE; reply = create_reply(xml_request, xml_response_data); if (reply != NULL) { was_sent = send_xmlha_message(hb_cluster, reply); free_xml(reply); } FNRET(was_sent); } void send_msg_via_ha(xmlNodePtr action, const char *dest_node) { FNIN(); if (action == NULL) FNOUT(); if (validate_crm_message(action, NULL, NULL, NULL) == NULL) { - cl_log(LOG_ERR, - "Relay message to (%s) via HA was invalid, ignoring", - dest_node); + crm_err("Relay message to (%s) via HA was invalid, ignoring", + dest_node); FNOUT(); } -// CRM_DEBUG("Relaying message to (%s) via HA", dest_node); +// crm_verbose("Relaying message to (%s) via HA", dest_node); set_xml_property_copy(action, XML_ATTR_HOSTTO, dest_node); send_xmlha_message(fsa_cluster_conn, action); FNOUT(); } void send_msg_via_ipc(xmlNodePtr action, const char *sys) { IPC_Channel *client_channel; FNIN(); -// cl_log(LOG_DEBUG, "relaying msg to sub_sys=%s via IPC", sys); +// crm_debug("relaying msg to sub_sys=%s via IPC", sys); client_channel = (IPC_Channel*)g_hash_table_lookup (ipc_clients, sys); if (client_channel != NULL) { - cl_log(LOG_DEBUG, "Sending message via channel %s.", sys); + crm_debug("Sending message via channel %s.", sys); send_xmlipc_message(client_channel, action); } else if(sys != NULL && strcmp(sys, CRM_SYSTEM_CIB) == 0) { - cl_log(LOG_ERR, - "Sub-system (%s) has been incorporated into the CRMd.", - sys); + crm_err("Sub-system (%s) has been incorporated into the CRMd.", + sys); xml_message_debug(action, "Change the way we handle"); relay_message(process_cib_message(action, TRUE), TRUE); } else if(sys != NULL && strcmp(sys, CRM_SYSTEM_LRMD) == 0) { do_lrm_invoke(A_LRM_INVOKE, C_IPC_MESSAGE, fsa_state, I_MESSAGE, action); } else { - cl_log(LOG_ERR, - "Unknown Sub-system (%s)... discarding message.", - sys); + crm_err("Unknown Sub-system (%s)... discarding message.", + sys); } FNOUT(); } diff --git a/crm/crmd/misc.c b/crm/crmd/misc.c index ff372015c3..18a6d10ca6 100644 --- a/crm/crmd/misc.c +++ b/crm/crmd/misc.c @@ -1,54 +1,54 @@ /* * 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 <portability.h> #include <heartbeat.h> #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crmd_fsa.h> #include <crmd_messages.h> #include <crm/dmalloc_wrapper.h> /* A_LOG, A_WARN, A_ERROR */ enum crmd_fsa_input do_log(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { int log_type = LOG_DEBUG; FNIN(); if(action & A_LOG) log_type = LOG_INFO; if(action & A_WARN) log_type = LOG_WARNING; if(action & A_ERROR) log_type = LOG_ERR; - cl_log(log_type, + do_crm_log(log_type, __FUNCTION__, "[[FSA]] Input (%s) was received while in state (%s)", fsa_input2string(current_input), fsa_state2string(cur_state)); FNRET(I_NULL); } diff --git a/crm/crmd/subsystems.c b/crm/crmd/subsystems.c index 5d462690f2..ef4af90878 100644 --- a/crm/crmd/subsystems.c +++ b/crm/crmd/subsystems.c @@ -1,635 +1,628 @@ /* * 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 <portability.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 <crm/cib.h> #include <crmd.h> #include <crm/dmalloc_wrapper.h> #define CLIENT_EXIT_WAIT 10 static gboolean stop_subsystem (struct crm_subsystem_s *centry); static gboolean start_subsystem(struct crm_subsystem_s *centry); struct crm_subsystem_s *cib_subsystem = NULL; struct crm_subsystem_s *te_subsystem = NULL; struct crm_subsystem_s *pe_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, void *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; FNIN(); 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 { - cl_log(LOG_INFO, - "Ignoring request to start %s after shutdown", - this_subsys->command); + crm_info("Ignoring request to start %s after shutdown", + this_subsys->command); } } FNRET(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, void *data) { xmlNodePtr cib_msg = NULL; xmlNodePtr answer = NULL; xmlNodePtr new_options = NULL; const char *section = NULL; FNIN(); if(data != NULL) { cib_msg = (xmlNodePtr)data; } if(action & A_CIB_INVOKE) { const char *op = get_xml_attr(cib_msg, XML_TAG_OPTIONS, XML_ATTR_OP, TRUE); xml_message_debug(cib_msg, "[CIB] Invoking with"); if(cib_msg == NULL) { - cl_log(LOG_ERR, "No message for CIB command"); + crm_err("No message for CIB command"); FNRET(I_NULL); // I_ERROR } set_xml_property_copy(cib_msg, XML_ATTR_SYSTO, "cib"); answer = process_cib_message(cib_msg, TRUE); if(relay_message(answer, TRUE) == FALSE) { - cl_log(LOG_ERR, "Confused what to do with cib result"); + crm_err("Confused what to do with cib result"); xml_message_debug(answer, "Couldnt route: "); } if(op != NULL && AM_I_DC && (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_WELCOME) == 0 || strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0 || strcmp(op, CRM_OP_ERASE) == 0)) { FNRET(I_CIB_UPDATE); } if(op == NULL) { xml_message_debug(cib_msg, "Invalid CIB Message"); } // check the answer, see if we are interested in it also #if 0 if(interested in reply) { put_message(answer); FNRET(I_REQUEST); } #endif free_xml(answer); /* experimental */ } else if(action & A_CIB_INVOKE_LOCAL) { xml_message_debug(cib_msg, "[CIB] Invoking with"); if(cib_msg == NULL) { - cl_log(LOG_ERR, "No message for CIB command"); + crm_err("No message for CIB command"); FNRET(I_NULL); // I_ERROR } answer = process_cib_message(cib_msg, TRUE); put_message(answer); FNRET(I_REQUEST); } else if(action & A_CIB_BUMPGEN) { // check if the response was ok before next bit section = get_xml_attr(cib_msg, XML_TAG_OPTIONS, XML_ATTR_FILTER_TYPE, FALSE); /* set the section so that we dont always send the * whole thing */ 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) { - cl_log(LOG_ERR, "Result of BUMP in %s was NULL", + crm_err("Result of BUMP in %s was NULL", __FUNCTION__); FNRET(I_FAIL); } send_request(NULL, answer, CRM_OP_REPLACE, NULL, CRM_SYSTEM_CRMD, NULL); free_xml(answer); } else { - cl_log(LOG_ERR, "Unexpected action %s in %s", + crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } FNRET(I_NULL); } /* A_PE_START, A_PE_STOP, A_TE_RESTART */ enum crmd_fsa_input do_pe_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input result = I_NULL; struct crm_subsystem_s *this_subsys = pe_subsystem; long long stop_actions = A_PE_STOP; long long start_actions = A_PE_START; FNIN(); if(action & stop_actions) { if(stop_subsystem(this_subsys) == FALSE) result = I_FAIL; else if(this_subsys->pid > 0){ int lpc = CLIENT_EXIT_WAIT; int pid_status = -1; while(lpc-- > 0 && this_subsys->pid > 0 && CL_PID_EXISTS(this_subsys->pid)) { sleep(1); waitpid(this_subsys->pid, &pid_status, WNOHANG); } if(CL_PID_EXISTS(this_subsys->pid)) { - cl_log(LOG_ERR, - "Process %s is still active with pid=%d", + crm_err("Process %s is still active with pid=%d", this_subsys->command, this_subsys->pid); result = I_FAIL; } } cleanup_subsystem(this_subsys); } if(action & start_actions) { if(cur_state != S_STOPPING) { if(start_subsystem(this_subsys) == FALSE) { result = I_FAIL; cleanup_subsystem(this_subsys); } } else { - cl_log(LOG_INFO, - "Ignoring request to start %s while shutting down", + crm_info("Ignoring request to start %s while shutting down", this_subsys->command); } } FNRET(result); } char *fsa_pe_ref = NULL; /* A_PE_INVOKE */ enum crmd_fsa_input do_pe_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { FNIN(); stopTimer(integration_timer); if(is_set(fsa_input_register, R_PE_CONNECTED) == FALSE){ - cl_log(LOG_INFO, "Waiting for the PE to connect"); + crm_info("Waiting for the PE to connect"); FNRET(I_WAIT_FOR_EVENT); } xmlNodePtr local_cib = get_cib_copy(); - CRM_DEBUG("Invoking %s with %p", CRM_SYSTEM_PENGINE, local_cib); + crm_verbose("Invoking %s with %p", CRM_SYSTEM_PENGINE, local_cib); if(fsa_pe_ref) { crm_free(fsa_pe_ref); fsa_pe_ref = NULL; } send_request(NULL, local_cib, CRM_OP_PECALC, NULL, CRM_SYSTEM_PENGINE, &fsa_pe_ref); FNRET(I_NULL); } /* A_TE_START, A_TE_STOP, A_TE_RESTART */ enum crmd_fsa_input do_te_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { enum crmd_fsa_input result = I_NULL; struct crm_subsystem_s *this_subsys = te_subsystem; long long stop_actions = A_TE_STOP; long long start_actions = A_TE_START; FNIN(); /* if(action & stop_actions && cur_state != S_STOPPING */ /* && is_set(fsa_input_register, R_TE_PEND)) { */ /* result = I_WAIT_FOR_EVENT; */ /* FNRET(result); */ /* } */ if(action & stop_actions) { if(stop_subsystem(this_subsys) == FALSE) result = I_FAIL; else if(this_subsys->pid > 0){ int lpc = CLIENT_EXIT_WAIT; int pid_status = -1; while(lpc-- > 0 && this_subsys->pid > 0 && CL_PID_EXISTS(this_subsys->pid)) { sleep(1); waitpid(this_subsys->pid, &pid_status, WNOHANG); } if(CL_PID_EXISTS(this_subsys->pid)) { - cl_log(LOG_ERR, - "Process %s is still active with pid=%d", + crm_err("Process %s is still active with pid=%d", this_subsys->command, this_subsys->pid); result = I_FAIL; } } cleanup_subsystem(this_subsys); } if(action & start_actions) { if(cur_state != S_STOPPING) { if(start_subsystem(this_subsys) == FALSE) { result = I_FAIL; cleanup_subsystem(this_subsys); } } else { - cl_log(LOG_INFO, - "Ignoring request to start %s while shutting down", - this_subsys->command); + crm_info("Ignoring request to start %s while shutting down", + this_subsys->command); } } FNRET(result); } static xmlNodePtr te_last_input = NULL; static xmlNodePtr te_lastcc = NULL; /* A_TE_COPYTO */ enum crmd_fsa_input do_te_copyto(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { xmlNodePtr message = NULL; xmlNodePtr opts = NULL; const char *true_op = NULL; FNIN(); if(data != NULL) { message = copy_xml_node_recursive((xmlNodePtr)data); opts = find_xml_node(message, XML_TAG_OPTIONS); true_op = xmlGetProp(opts, XML_ATTR_OP); set_xml_property_copy(opts, XML_ATTR_OP, CRM_OP_EVENTCC); set_xml_property_copy(opts, XML_ATTR_TRUEOP, true_op); set_xml_property_copy(message, XML_ATTR_SYSTO, CRM_SYSTEM_TENGINE); } if(is_set(fsa_input_register, R_TE_CONNECTED) == FALSE){ - cl_log(LOG_INFO, "Waiting for the TE to connect"); + crm_info("Waiting for the TE to connect"); if(data != NULL) { free_xml(te_lastcc); te_lastcc = message; } FNRET(I_WAIT_FOR_EVENT); } if(message == NULL) { message = te_lastcc; te_lastcc = NULL; } else { free_xml(te_lastcc); } relay_message(message, FALSE); // only free it if it was a local copy if(data == NULL) { free_xml(message); } FNRET(I_NULL); } /* A_TE_INVOKE, A_TE_CANCEL */ enum crmd_fsa_input do_te_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, void *data) { xmlNodePtr graph = NULL; xmlNodePtr msg = (xmlNodePtr)data; FNIN(); if(is_set(fsa_input_register, R_TE_CONNECTED) == FALSE){ - cl_log(LOG_INFO, "Waiting for the TE to connect"); + crm_info("Waiting for the TE to connect"); if(data != NULL) { free_xml(te_last_input); te_last_input = copy_xml_node_recursive(msg); } FNRET(I_WAIT_FOR_EVENT); } if(msg == NULL) { msg = te_last_input; te_last_input = NULL; } else { free_xml(te_last_input); } if(action & A_TE_INVOKE) { graph = find_xml_node(msg, "transition_graph"); if(graph == NULL) { FNRET(I_FAIL); } send_request(NULL, graph, CRM_OP_TRANSITION, NULL, CRM_SYSTEM_TENGINE, NULL); } else { send_request(NULL, graph, CRM_OP_ABORT, NULL, CRM_SYSTEM_TENGINE, NULL); } // only free it if it was a local copy if(data == NULL) { free_xml(msg); } FNRET(I_NULL); } gboolean crmd_client_connect(IPC_Channel *client_channel, gpointer user_data) { FNIN(); if (client_channel == NULL) { - cl_log(LOG_ERR, "Channel was NULL"); + crm_err("Channel was NULL"); } else if (client_channel->ch_status == IPC_DISCONNECT) { - cl_log(LOG_ERR, "Channel was disconnected"); + crm_err("Channel was disconnected"); } else { crmd_client_t *blank_client = (crmd_client_t *)crm_malloc(sizeof(crmd_client_t)); if (blank_client == NULL) { - cl_log(LOG_ERR, - "Could not allocate memory for a blank crmd_client_t"); + crm_err("Could not allocate memory for a blank crmd_client_t"); FNRET(FALSE); } client_channel->ops->set_recv_qlen(client_channel, 100); client_channel->ops->set_send_qlen(client_channel, 100); blank_client->client_channel = client_channel; blank_client->sub_sys = NULL; blank_client->uuid = NULL; blank_client->table_key = NULL; blank_client->client_source = G_main_add_IPC_Channel(G_PRIORITY_LOW, client_channel, FALSE, crmd_ipc_input_callback, blank_client, default_ipc_input_destroy); } FNRET(TRUE); } static gboolean stop_subsystem(struct crm_subsystem_s* centry) { - cl_log(LOG_INFO, "Stopping sub-system \"%s\"", centry->name); + crm_info("Stopping sub-system \"%s\"", centry->name); if (centry->pid <= 0) { - cl_log(LOG_ERR, - "OOPS! client %s not running yet", - centry->command); + crm_err("OOPS! client %s not running yet", + centry->command); } else { - cl_log(LOG_INFO, "Sending quit message to %s.", centry->name); + crm_info("Sending quit message to %s.", centry->name); send_request(NULL, NULL, CRM_OP_QUIT, NULL, centry->name, NULL); } return TRUE; } static gboolean start_subsystem(struct crm_subsystem_s* centry) { pid_t pid; struct stat buf; int s_res; - cl_log(LOG_INFO, "Starting sub-system \"%s\"", centry->command); + crm_info("Starting sub-system \"%s\"", centry->command); if (centry->pid != 0) { - cl_log(LOG_ERR, "OOPS! client %s already running as pid %d" + crm_err("OOPS! client %s already running as pid %d" , centry->command, (int) centry->pid); } /* * We need to ensure that the exec will succeed before * we bother forking. We don't want to respawn something that * won't exec in the first place. */ if (access(centry->path, F_OK|X_OK) != 0) { cl_perror("Cannot (access) exec %s", centry->path); return FALSE; } s_res = stat(centry->command, &buf); if(s_res != 0) { cl_perror("Cannot (stat) exec %s", centry->command); return FALSE; } /* We need to fork so we can make child procs not real time */ switch(pid=fork()) { case -1: - cl_log(LOG_ERR, "start_a_child_client: Cannot fork."); + crm_err("start_a_child_client: Cannot fork."); return FALSE; default: /* Parent */ centry->pid = pid; return TRUE; case 0: /* Child */ break; } /* Child process: start the managed child */ cl_make_normaltime(); setpgid(0,0); /* Limit peak resource usage, maximize success chances */ if (centry->shortrcount > 0) { alarm(0); sleep(1); } - cl_log(LOG_INFO, "Executing \"%s\" (pid %d)", + crm_info("Executing \"%s\" (pid %d)", centry->command, (int) getpid()); if(CL_SIGINTERRUPT(SIGALRM, 0) < 0) { cl_perror("Cannot set interrupt for child process %s", centry->command); }else{ const char * devnull = "/dev/null"; unsigned int j; struct rlimit oflimits; CL_SIGNAL(SIGCHLD, SIG_DFL); alarm(0); CL_IGNORE_SIG(SIGALRM); /* A precautionary measure */ getrlimit(RLIMIT_NOFILE, &oflimits); for (j=0; j < oflimits.rlim_cur; ++j) { close(j); } (void)devnull; (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", centry->command, (const char *)NULL); /* Should not happen */ cl_perror("Cannot exec %s", centry->command); } /* Suppress respawning */ exit(100); // never reached return TRUE; } diff --git a/crm/crmd/utils.c b/crm/crmd/utils.c index 1b956a4e9d..a0d143e7f9 100644 --- a/crm/crmd/utils.c +++ b/crm/crmd/utils.c @@ -1,643 +1,634 @@ /* * 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 <portability.h> #include <crm/crm.h> #include <crmd_fsa.h> #include <clplumbing/Gmain_timeout.h> #include <sys/types.h> #include <sys/wait.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/msg.h> #include <crm/dmalloc_wrapper.h> gboolean timer_popped(gpointer data) { fsa_timer_t *timer = (fsa_timer_t *)data; - cl_log(LOG_INFO, "#!!#!!# Timer %s just popped!", + crm_info("#!!#!!# Timer %s just popped!", fsa_input2string(timer->fsa_input)); stopTimer(timer); // dont make it go off again s_crmd_fsa(C_TIMER_POPPED, timer->fsa_input, NULL); return TRUE; } gboolean startTimer(fsa_timer_t *timer) { if(((int)timer->source_id) < 0) { timer->source_id = Gmain_timeout_add(timer->period_ms, timer->callback, (void*)timer); /* - CRM_DEBUG("#!!#!!# Started %s timer (%d)", + crm_verbose("#!!#!!# Started %s timer (%d)", fsa_input2string(timer->fsa_input), timer->source_id); */ } else { - cl_log(LOG_INFO, "#!!#!!# Timer %s already running (%d)", + crm_info("#!!#!!# Timer %s already running (%d)", fsa_input2string(timer->fsa_input), timer->source_id); return FALSE; } return TRUE; } gboolean stopTimer(fsa_timer_t *timer) { if(((int)timer->source_id) > 0) { /* - CRM_DEBUG("#!!#!!# Stopping %s timer (%d)", + crm_verbose("#!!#!!# Stopping %s timer (%d)", fsa_input2string(timer->fsa_input), timer->source_id); */ g_source_remove(timer->source_id); timer->source_id = -2; } else { - cl_log(LOG_INFO, "#!!#!!# Timer %s already stopped (%d)", + crm_info("#!!#!!# Timer %s already stopped (%d)", fsa_input2string(timer->fsa_input), timer->source_id); return FALSE; } return TRUE; } long long toggle_bit(long long action_list, long long action) { -// CRM_DEBUG("Toggling bit %.16llx", action); + crm_trace("Toggling bit %.16llx", action); action_list ^= action; -// CRM_DEBUG("Result %.16llx", action_list & action); + crm_trace("Result %.16llx", action_list & action); return action_list; } long long clear_bit(long long action_list, long long action) { -// CRM_DEBUG("Clearing bit\t%.16llx", action); + crm_trace("Clearing bit\t%.16llx", action); // ensure its set action_list |= action; // then toggle action_list = action_list ^ action; return action_list; } long long set_bit(long long action_list, long long action) { -// CRM_DEBUG("Adding bit\t%.16llx", action); + crm_trace("Adding bit\t%.16llx", action); action_list |= action; return action_list; } void toggle_bit_inplace(long long *action_list, long long action) { *action_list = toggle_bit(*action_list, action); } void clear_bit_inplace(long long *action_list, long long action) { *action_list = clear_bit(*action_list, action); } void set_bit_inplace(long long *action_list, long long action) { *action_list = set_bit(*action_list, action); } gboolean is_set(long long action_list, long long action) { -// CRM_DEBUG("Checking bit\t%.16llx", action); +// crm_verbose("Checking bit\t%.16llx", action); return ((action_list & action) == action); } xmlNodePtr create_node_state(const char *node, const char *ccm_state, const char *crmd_state, const char *join_state) { xmlNodePtr node_state = create_xml_node(NULL, XML_CIB_TAG_STATE); set_xml_property_copy(node_state, XML_ATTR_ID, node); if(ccm_state != NULL) { set_xml_property_copy(node_state, XML_CIB_ATTR_INCCM, ccm_state); } if(crmd_state != NULL) { set_xml_property_copy(node_state, XML_CIB_ATTR_CRMDSTATE, crmd_state); } if(join_state != NULL) { set_xml_property_copy(node_state, XML_CIB_ATTR_JOINSTATE, join_state); } -/* if(exp_state != NULL) { */ -/* set_xml_property_copy(node_state, XML_CIB_ATTR_EXPSTATE, exp_state); */ -/* } */ - -/* if(lrm_data != NULL) { */ -/* // set_xml_property_copy(data, "replace", XML_CIB_TAG_LRM); */ -/* add_node_copy(node_state, lrm_data); */ -/* } */ - xml_message_debug(node_state, "created"); return node_state; } const char * fsa_input2string(enum crmd_fsa_input input) { const char *inputAsText = NULL; switch(input){ case I_NULL: inputAsText = "I_NULL"; break; case I_CCM_EVENT: inputAsText = "I_CCM_EVENT"; break; case I_CIB_OP: inputAsText = "I_CIB_OP"; break; case I_CIB_UPDATE: inputAsText = "I_CIB_UPDATE"; break; case I_DC_TIMEOUT: inputAsText = "I_DC_TIMEOUT"; break; case I_ELECTION: inputAsText = "I_ELECTION"; break; case I_PE_CALC: inputAsText = "I_PE_CALC"; break; case I_RELEASE_DC: inputAsText = "I_RELEASE_DC"; break; case I_ELECTION_DC: inputAsText = "I_ELECTION_DC"; break; case I_ERROR: inputAsText = "I_ERROR"; break; case I_FAIL: inputAsText = "I_FAIL"; break; case I_INTEGRATION_TIMEOUT: inputAsText = "I_INTEGRATION_TIMEOUT"; break; case I_NODE_JOIN: inputAsText = "I_NODE_JOIN"; break; case I_NODE_LEFT: inputAsText = "I_NODE_LEFT"; break; case I_NOT_DC: inputAsText = "I_NOT_DC"; break; case I_RECOVERED: inputAsText = "I_RECOVERED"; break; case I_RELEASE_FAIL: inputAsText = "I_RELEASE_FAIL"; break; case I_RELEASE_SUCCESS: inputAsText = "I_RELEASE_SUCCESS"; break; case I_RESTART: inputAsText = "I_RESTART"; break; case I_REQUEST: inputAsText = "I_REQUEST"; break; case I_ROUTER: inputAsText = "I_ROUTER"; break; case I_SHUTDOWN: inputAsText = "I_SHUTDOWN"; break; case I_STARTUP: inputAsText = "I_STARTUP"; break; case I_SUCCESS: inputAsText = "I_SUCCESS"; break; case I_TERMINATE: inputAsText = "I_TERMINATE"; break; case I_WELCOME: inputAsText = "I_WELCOME"; break; case I_WELCOME_ACK: inputAsText = "I_WELCOME_ACK"; break; case I_DC_HEARTBEAT: inputAsText = "I_DC_HEARTBEAT"; break; case I_WAIT_FOR_EVENT: inputAsText = "I_WAIT_FOR_EVENT"; break; case I_LRM_EVENT: inputAsText = "I_LRM_EVENT"; break; case I_ILLEGAL: inputAsText = "I_ILLEGAL"; break; } if(inputAsText == NULL) { - cl_log(LOG_ERR, "Input %d is unknown", input); + crm_err("Input %d is unknown", input); inputAsText = "<UNKNOWN_INPUT>"; } return inputAsText; } const char * fsa_state2string(enum crmd_fsa_state state) { const char *stateAsText = NULL; switch(state){ case S_IDLE: stateAsText = "S_IDLE"; break; case S_ELECTION: stateAsText = "S_ELECTION"; break; case S_INTEGRATION: stateAsText = "S_INTEGRATION"; break; case S_NOT_DC: stateAsText = "S_NOT_DC"; break; case S_POLICY_ENGINE: stateAsText = "S_POLICY_ENGINE"; break; case S_RECOVERY: stateAsText = "S_RECOVERY"; break; case S_RECOVERY_DC: stateAsText = "S_RECOVERY_DC"; break; case S_RELEASE_DC: stateAsText = "S_RELEASE_DC"; break; case S_PENDING: stateAsText = "S_PENDING"; break; case S_STOPPING: stateAsText = "S_STOPPING"; break; case S_TERMINATE: stateAsText = "S_TERMINATE"; break; case S_TRANSITION_ENGINE: stateAsText = "S_TRANSITION_ENGINE"; break; case S_ILLEGAL: stateAsText = "S_ILLEGAL"; break; } if(stateAsText == NULL) { - cl_log(LOG_ERR, "State %d is unknown", state); + crm_err("State %d is unknown", state); stateAsText = "<UNKNOWN_STATE>"; } return stateAsText; } const char * fsa_cause2string(enum crmd_fsa_cause cause) { const char *causeAsText = NULL; switch(cause){ case C_UNKNOWN: causeAsText = "C_UNKNOWN"; break; case C_STARTUP: causeAsText = "C_STARTUP"; break; case C_IPC_MESSAGE: causeAsText = "C_IPC_MESSAGE"; break; case C_HA_MESSAGE: causeAsText = "C_HA_MESSAGE"; break; case C_CCM_CALLBACK: causeAsText = "C_CCM_CALLBACK"; break; case C_TIMER_POPPED: causeAsText = "C_TIMER_POPPED"; break; case C_SHUTDOWN: causeAsText = "C_SHUTDOWN"; break; case C_HEARTBEAT_FAILED: causeAsText = "C_HEARTBEAT_FAILED"; break; case C_SUBSYSTEM_CONNECT: causeAsText = "C_SUBSYSTEM_CONNECT"; break; case C_LRM_OP_CALLBACK: causeAsText = "C_LRM_OP_CALLBACK"; break; case C_LRM_MONITOR_CALLBACK: causeAsText = "C_LRM_MONITOR_CALLBACK"; break; case C_CRMD_STATUS_CALLBACK: causeAsText = "C_CRMD_STATUS_CALLBACK"; break; case C_ILLEGAL: causeAsText = "C_ILLEGAL"; break; } if(causeAsText == NULL) { - cl_log(LOG_ERR, "Cause %d is unknown", cause); + crm_err("Cause %d is unknown", cause); causeAsText = "<UNKNOWN_CAUSE>"; } return causeAsText; } const char * fsa_action2string(long long action) { const char *actionAsText = NULL; switch(action){ case A_NOTHING: actionAsText = "A_NOTHING"; break; case O_SHUTDOWN: actionAsText = "O_SHUTDOWN"; break; case O_RELEASE: actionAsText = "O_RELEASE"; break; case A_STARTUP: actionAsText = "A_STARTUP"; break; case A_STARTED: actionAsText = "A_STARTED"; break; case A_HA_CONNECT: actionAsText = "A_HA_CONNECT"; break; case A_HA_DISCONNECT: actionAsText = "A_HA_DISCONNECT"; break; case A_LRM_CONNECT: actionAsText = "A_LRM_CONNECT"; break; case A_LRM_DISCONNECT: actionAsText = "A_LRM_DISCONNECT"; break; case O_DC_TIMER_RESTART: actionAsText = "O_DC_TIMER_RESTART"; break; case A_DC_TIMER_STOP: actionAsText = "A_DC_TIMER_STOP"; break; case A_DC_TIMER_START: actionAsText = "A_DC_TIMER_START"; break; case A_ELECTION_COUNT: actionAsText = "A_ELECTION_COUNT"; break; case A_ELECTION_TIMEOUT: actionAsText = "A_ELECTION_TIMEOUT"; break; case A_ELECT_TIMER_START: actionAsText = "A_ELECT_TIMER_START"; break; case A_ELECT_TIMER_STOP: actionAsText = "A_ELECT_TIMER_STOP"; break; case A_ELECTION_VOTE: actionAsText = "A_ELECTION_VOTE"; break; case A_ANNOUNCE: actionAsText = "A_ANNOUNCE"; break; case A_JOIN_ACK: actionAsText = "A_JOIN_ACK"; break; case A_JOIN_WELCOME: actionAsText = "A_JOIN_WELCOME"; break; case A_JOIN_WELCOME_ALL: actionAsText = "A_JOIN_WELCOME_ALL"; break; case A_JOIN_PROCESS_ACK: actionAsText = "A_JOIN_PROCESS_ACK"; break; case A_MSG_PROCESS: actionAsText = "A_MSG_PROCESS"; break; case A_MSG_ROUTE: actionAsText = "A_MSG_ROUTE"; break; case A_MSG_STORE: actionAsText = "A_MSG_STORE"; break; case A_RECOVER: actionAsText = "A_RECOVER"; break; case A_DC_RELEASE: actionAsText = "A_DC_RELEASE"; break; case A_DC_RELEASED: actionAsText = "A_DC_RELEASED"; break; case A_DC_TAKEOVER: actionAsText = "A_DC_TAKEOVER"; break; case A_SHUTDOWN: actionAsText = "A_SHUTDOWN"; break; case A_SHUTDOWN_REQ: actionAsText = "A_SHUTDOWN_REQ"; break; case A_STOP: actionAsText = "A_STOP "; break; case A_EXIT_0: actionAsText = "A_EXIT_0"; break; case A_EXIT_1: actionAsText = "A_EXIT_1"; break; case A_CCM_CONNECT: actionAsText = "A_CCM_CONNECT"; break; case A_CCM_DISCONNECT: actionAsText = "A_CCM_DISCONNECT"; break; case A_CCM_EVENT: actionAsText = "A_CCM_EVENT"; break; case A_CCM_UPDATE_CACHE: actionAsText = "A_CCM_UPDATE_CACHE"; break; case A_CIB_BUMPGEN: actionAsText = "A_CIB_BUMPGEN"; break; case A_CIB_INVOKE: actionAsText = "A_CIB_INVOKE"; break; case O_CIB_RESTART: actionAsText = "O_CIB_RESTART"; break; case A_CIB_START: actionAsText = "A_CIB_START"; break; case A_CIB_STOP: actionAsText = "A_CIB_STOP"; break; case A_TE_INVOKE: actionAsText = "A_TE_INVOKE"; break; case O_TE_RESTART: actionAsText = "O_TE_RESTART"; break; case A_TE_START: actionAsText = "A_TE_START"; break; case A_TE_STOP: actionAsText = "A_TE_STOP"; break; case A_TE_CANCEL: actionAsText = "A_TE_CANCEL"; break; case A_TE_COPYTO: actionAsText = "A_TE_COPYTO"; break; case A_PE_INVOKE: actionAsText = "A_PE_INVOKE"; break; case O_PE_RESTART: actionAsText = "O_PE_RESTART"; break; case A_PE_START: actionAsText = "A_PE_START"; break; case A_PE_STOP: actionAsText = "A_PE_STOP"; break; case A_NODE_BLOCK: actionAsText = "A_NODE_BLOCK"; break; case A_UPDATE_NODESTATUS: actionAsText = "A_UPDATE_NODESTATUS"; break; case A_LOG: actionAsText = "A_LOG "; break; case A_ERROR: actionAsText = "A_ERROR "; break; case A_WARN: actionAsText = "A_WARN "; break; } if(actionAsText == NULL) { - cl_log(LOG_ERR, "Action %.16llx is unknown", action); + crm_err("Action %.16llx is unknown", action); actionAsText = "<UNKNOWN_ACTION>"; } return actionAsText; } 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; } 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; FNIN(); 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); result = do_cib_invoke(A_CIB_INVOKE_LOCAL, C_UNKNOWN, fsa_state, I_CIB_OP, request); free_xml(request); FNRET(result); } diff --git a/crm/pengine/pengine.c b/crm/pengine/pengine.c index 45ea8a406b..136a47aa39 100755 --- a/crm/pengine/pengine.c +++ b/crm/pengine/pengine.c @@ -1,2140 +1,2114 @@ -/* $Id: pengine.c,v 1.30 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: pengine.c,v 1.31 2004/06/02 15:25:11 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 */ #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/msg.h> #include <glib.h> #include <libxml/tree.h> #include <pengine.h> #include <pe_utils.h> xmlNodePtr do_calculations(xmlNodePtr cib_object); gboolean process_pe_message(xmlNodePtr msg, IPC_Channel *sender); void color_resource(resource_t *lh_resource, GSListPtr *colors, GSListPtr resources); gboolean create_rsc_to_rsc(const char *id, enum con_strength strength, resource_t *rsc_lh, resource_t *rsc_rh); gboolean create_ordering(const char *id, enum con_strength strength, resource_t *rsc_lh, resource_t *rsc_rh, GSListPtr *action_constraints); gboolean unpack_constraints(xmlNodePtr xml_constraints, GSListPtr nodes, GSListPtr resources, GSListPtr *node_constraints, GSListPtr *action_constraints); gboolean unpack_resources(xmlNodePtr xml_resources, GSListPtr *resources, GSListPtr *actions, GSListPtr *action_cons, GSListPtr all_nodes); gboolean unpack_nodes(xmlNodePtr xml_nodes, GSListPtr *nodes); gboolean unpack_status(xmlNodePtr status, GSListPtr nodes, GSListPtr rsc_list, GSListPtr *node_constraints); gboolean apply_node_constraints(GSListPtr constraints, GSListPtr resources, GSListPtr nodes); gboolean is_active(rsc_to_node_t *cons); gboolean choose_node_from_list(GSListPtr colors, color_t *color, GSListPtr nodes); gboolean unpack_rsc_to_attr(xmlNodePtr xml_obj, GSListPtr rsc_list, GSListPtr node_list, GSListPtr *node_constraints); gboolean unpack_rsc_to_node(xmlNodePtr xml_obj, GSListPtr rsc_list, GSListPtr node_list, GSListPtr *node_constraints); gboolean unpack_rsc_to_rsc(xmlNodePtr xml_obj, GSListPtr rsc_list, GSListPtr *action_constraints); gboolean choose_color(resource_t *lh_resource); gboolean strict_postproc(rsc_to_rsc_t *constraint, color_t *local_color, color_t *other_color, GSListPtr *colors, GSListPtr resources); gboolean strict_preproc(rsc_to_rsc_t *constraint, color_t *local_color, color_t *other_color, GSListPtr *colors, GSListPtr resources); gboolean update_node_weight(rsc_to_node_t *cons, char *id, GSListPtr nodes); gboolean process_node_lrm_state(node_t *node, xmlNodePtr lrm_state, GSListPtr rsc_list, GSListPtr nodes, GSListPtr *node_constraints); GSListPtr match_attrs(xmlNodePtr attr_exp, GSListPtr node_list); gboolean update_runnable(GSListPtr actions); GSListPtr create_action_set(action_t *action); color_t *no_color = NULL; int max_valid_nodes = 0; int order_id = 1; int action_id = 1; gboolean pe_debug = FALSE; gboolean pe_debug_saved = FALSE; /* * Unpack everything * At the end you'll have: * - A list of nodes * - A list of resources (each with any dependancies on other resources) * - A list of constraints between resources and nodes * - A list of constraints between start/stop actions * - A list of nodes that need to be stonith'd * - A list of nodes that need to be shutdown * - A list of the possible stop/start actions (without dependancies) */ gboolean stage0(xmlNodePtr cib, GSListPtr *resources, GSListPtr *nodes, GSListPtr *node_constraints, GSListPtr *actions, GSListPtr *action_constraints, GSListPtr *stonith_list, GSListPtr *shutdown_list) { int lpc; xmlNodePtr cib_nodes = get_object_root( XML_CIB_TAG_NODES, cib); xmlNodePtr cib_status = get_object_root( XML_CIB_TAG_STATUS, cib); xmlNodePtr cib_resources = get_object_root( XML_CIB_TAG_RESOURCES, cib); xmlNodePtr cib_constraints = get_object_root( XML_CIB_TAG_CONSTRAINTS, cib); /* reset remaining global variables */ max_valid_nodes = 0; order_id = 1; action_id = 1; unpack_nodes(safe_val(NULL, cib_nodes, children), nodes); unpack_resources(safe_val(NULL, cib_resources, children), resources, actions, action_constraints, *nodes); unpack_status(safe_val(NULL, cib_status, children), *nodes, *resources, node_constraints); unpack_constraints(safe_val(NULL, cib_constraints, children), *nodes, *resources, node_constraints, action_constraints); slist_iter( node, node_t, *nodes, lpc, if(node->details->shutdown) { *shutdown_list = g_slist_append(*shutdown_list, node); - pdebug("Scheduling Node %s for shutdown", + crm_verbose("Scheduling Node %s for shutdown", node->details->id); } else if(node->details->unclean) { *stonith_list = g_slist_append(*stonith_list, node); - pdebug("Scheduling Node %s for STONITH", + crm_verbose("Scheduling Node %s for STONITH", node->details->id); } ); return TRUE; } /* * Count how many valid nodes we have (so we know the maximum number of * colors we can resolve). * * Apply node constraints (ie. filter the "allowed_nodes" part of resources */ gboolean stage1(GSListPtr node_constraints, GSListPtr nodes, GSListPtr resources) { int lpc = 0; slist_iter( node, node_t, nodes, lpc, if(node == NULL) { // error } else if(node->weight >= 0.0 && node->details->online && node->details->type == node_member) { max_valid_nodes++; } ); apply_node_constraints(node_constraints, nodes, resources); return TRUE; } /* * Choose a color for all resources from highest priority and XML_STRENGTH_VAL_MUST * dependancies to lowest, creating new colors as necessary (returned * as "colors"). * * Some nodes may be colored as a "no_color" meaning that it was unresolvable * given the current node stati and constraints. */ gboolean stage2(GSListPtr sorted_rscs, GSListPtr sorted_nodes, GSListPtr *colors) { int lpc; color_t *current_color = NULL; // Set initial color // Set color.candidate_nodes = all active nodes if(no_color != NULL) { crm_free(no_color->details); crm_free(no_color); } no_color = create_color(NULL, NULL, sorted_rscs); current_color = create_color(colors, sorted_nodes, sorted_rscs); // Set resource.color = color (all resources) // Set resource.provisional = TRUE (all resources) slist_iter( this_resource, resource_t, sorted_rscs, lpc, this_resource->color = current_color; this_resource->provisional = TRUE; ); - pdebug("initialized resources to default color"); + crm_verbose("initialized resources to default color"); // Take (next) highest resource slist_iter( lh_resource, resource_t, sorted_rscs, lpc, // if resource.provisional == FALSE, repeat if(lh_resource->provisional == FALSE) { // already processed this resource continue; } color_resource(lh_resource, colors, sorted_rscs); // next resource ); return TRUE; } /* * not sure if this is a good idea or not, but eventually we might like * to utilize as many nodes as possible... and this might be a convienient * hook */ gboolean stage3(GSListPtr colors) { // not sure if this is a good idea or not if(g_slist_length(colors) > max_valid_nodes) { // we need to consolidate some } else if(g_slist_length(colors) < max_valid_nodes) { // we can create a few more } return TRUE; } #define color_n_nodes color_n->details->candidate_nodes #define color_n_plus_1_nodes color_n_plus_1->details->candidate_nodes /* * Choose a node for each (if possible) color */ gboolean stage4(GSListPtr colors) { int lpc = 0; color_t *color_n = NULL; color_t *color_n_plus_1 = NULL; for(lpc = 0; lpc < g_slist_length(colors); lpc++) { color_n = color_n_plus_1; color_n_plus_1 = (color_t*)g_slist_nth_data(colors, lpc); - pdebug_action( + crm_debug_action( print_color("Choose node for...", color_n, FALSE)); if(color_n == NULL) { continue; } GSListPtr xor = node_list_xor(color_n_nodes, color_n_plus_1_nodes); GSListPtr minus = node_list_minus(color_n_nodes, color_n_plus_1_nodes); if(g_slist_length(xor) == 0 || g_slist_length(minus) == 0) { - pdebug("Choose any node from our list"); + crm_verbose("Choose any node from our list"); choose_node_from_list(colors, color_n, color_n_nodes); } else { - pdebug("Choose a node not in n+1"); + crm_verbose("Choose a node not in n+1"); choose_node_from_list(colors, color_n, minus); } pe_free_shallow(xor); pe_free_shallow(minus); } // choose last color if(color_n_plus_1 != NULL) { - pdebug_action(print_color("Choose node for last color...", + crm_debug_action(print_color("Choose node for last color...", color_n_plus_1, FALSE)); choose_node_from_list(colors, color_n_plus_1, color_n_plus_1_nodes); } - pdebug("done %s", __FUNCTION__); + crm_verbose("done"); return TRUE; } /* * Attach nodes to the actions that need to be taken * * Mark actions XML_LRM_ATTR_OPTIONAL if possible (Ie. if the start and stop are * for the same node) * * Mark unrunnable actions */ gboolean stage5(GSListPtr resources) { - pdebug("filling in the nodes to perform the actions on"); + crm_verbose("filling in the nodes to perform the actions on"); int lpc = 0; slist_iter( rsc, resource_t, resources, lpc, print_resource("Processing", rsc, FALSE); if(safe_val(NULL, rsc, stop) == NULL || safe_val(NULL, rsc, start) == NULL) { // error - cl_log(LOG_ERR, - "Either start action (%p) or" - " stop action (%p) were not defined", - safe_val(NULL, rsc, stop), - safe_val(NULL, rsc, start)); + crm_err("Either start action (%p) or" + " stop action (%p) were not defined", + safe_val(NULL, rsc, stop), + safe_val(NULL, rsc, start)); continue; } if(safe_val4(NULL, rsc, color, details, chosen_node) == NULL){ rsc->stop->node = safe_val(NULL, rsc, cur_node); rsc->start->node = NULL; - cl_log(LOG_DEBUG, - "Stop resource %s (%s)", - safe_val(NULL, rsc, id), - safe_val5(NULL, rsc, stop, node, details, id)); + crm_debug("Stop resource %s (%s)", + safe_val(NULL, rsc, id), + safe_val5(NULL, rsc, stop, node,details,id)); - pdebug_action( + crm_debug_action( print_action( CRMD_STATE_ACTIVE, rsc->stop, FALSE)); - } else if(safe_str_eq(safe_val4(NULL, rsc, cur_node, details, id), + } else if(safe_str_eq(safe_val4(NULL, rsc,cur_node,details,id), safe_val6(NULL, rsc, color ,details, chosen_node, details, id))){ - cl_log(LOG_DEBUG, - "No change for Resource %s (%s)", - safe_val(NULL, rsc, id), - safe_val4(NULL, rsc, cur_node, details, id)); + crm_debug("No change for Resource %s (%s)", + safe_val(NULL, rsc, id), + safe_val4(NULL, rsc, cur_node, details, id)); rsc->stop->optional = TRUE; rsc->start->optional = TRUE; rsc->stop->node = safe_val(NULL, rsc, cur_node); rsc->start->node = safe_val4(NULL, rsc, color, details, chosen_node); - } else if(safe_val4(NULL, rsc, cur_node, details, id) == NULL) { + } else if(safe_val4(NULL, rsc,cur_node,details,id) == NULL) { rsc->stop->optional = TRUE; rsc->start->node = safe_val4(NULL, rsc, color, details, chosen_node); - cl_log(LOG_DEBUG, - "Start resource %s (%s)", - safe_val(NULL, rsc, id), - safe_val5(NULL, rsc, start, node, details, id)); + crm_debug("Start resource %s (%s)", + safe_val(NULL, rsc, id), + safe_val5(NULL, rsc, start,node,details,id)); } else { rsc->stop->node = safe_val(NULL, rsc, cur_node); rsc->start->node = safe_val4(NULL, rsc, color, details, chosen_node); - cl_log(LOG_DEBUG, - "Move resource %s (%s -> %s)", - safe_val(NULL, rsc, id), - safe_val5(NULL, rsc, stop, node, details, id), - safe_val5(NULL, rsc, start, node, details, id)); + crm_debug("Move resource %s (%s -> %s)", + safe_val(NULL, rsc, id), + safe_val5(NULL, rsc, stop, node,details,id), + safe_val5(NULL, rsc, start,node,details,id)); } if(rsc->stop->node != NULL) { rsc->stop->runnable = TRUE; } if(rsc->start->node != NULL) { rsc->start->runnable = TRUE; } ); return TRUE; } /* * Create dependacies for stonith and shutdown operations */ gboolean stage6(GSListPtr *actions, GSListPtr *action_constraints, GSListPtr stonith_nodes, GSListPtr shutdown_nodes) { int lpc = 0; int llpc = 0; slist_iter( node, node_t, shutdown_nodes, lpc, action_t *down_node = action_new(action_id++, NULL, shutdown_crm); down_node->node = node; down_node->runnable = TRUE; *actions = g_slist_append(*actions, down_node); slist_iter( rsc, resource_t, node->details->running_rsc, llpc, order_constraint_t *order = (order_constraint_t*) crm_malloc(sizeof(order_constraint_t)); /* stop resources before shutdown */ order->id = order_id++; order->lh_action = rsc->stop; order->rh_action = down_node; order->strength = must; - pdebug_action( + crm_debug_action( print_action("LH (Shutdown)", order->lh_action, FALSE)); - pdebug_action( + crm_debug_action( print_action("RH (Shutdown)", order->rh_action, FALSE)); *action_constraints = g_slist_append(*action_constraints, order); ); ); slist_iter( node, node_t, stonith_nodes, lpc, action_t *stonith_node = action_new(action_id++, NULL, stonith_op); stonith_node->node = node; stonith_node->runnable = TRUE; *actions = g_slist_append(*actions, stonith_node); slist_iter( rsc, resource_t, node->details->running_rsc, llpc, order_constraint_t *order = NULL; #if 1 /* * Mark the stop as irrelevant * * Possibly one day failed actions wont terminate * the transition, but not yet */ rsc->stop->discard = TRUE; #else rsc->stop->optional = TRUE; #endif /* try stopping the resource before stonithing the node * * if the stop succeeds, the transitioner can then * decided if stonith is needed */ order = (order_constraint_t*) crm_malloc(sizeof(order_constraint_t)); order->lh_action = rsc->stop; order->rh_action = stonith_node; order->id = order_id++; order->strength = must; *action_constraints = g_slist_append(*action_constraints, order); /* stonith before start */ order = (order_constraint_t*) crm_malloc(sizeof(order_constraint_t)); order->id = order_id++; order->lh_action = stonith_node; order->rh_action = rsc->start; order->strength = must; *action_constraints = g_slist_append(*action_constraints, order); ); ); return TRUE; } /* * Determin the sets of independant actions and the correct order for the * actions in each set. * * Mark dependancies of un-runnable actions un-runnable * */ gboolean stage7(GSListPtr resources, GSListPtr actions, GSListPtr action_constraints, GSListPtr *action_sets) { int lpc; /* for(lpc = 0; lpc < g_slist_length(action_constraints); lpc++) { order_constraint_t *order = (order_constraint_t*) g_slist_nth_data(action_constraints, lpc); */ slist_iter( order, order_constraint_t, action_constraints, lpc, - pdebug("Processing %d -> %d", + crm_verbose("Processing %d -> %d", order->lh_action->id, order->rh_action->id); - pdebug_action( + crm_debug_action( print_action("LH (stage7)", order->lh_action, FALSE)); - pdebug_action( + crm_debug_action( print_action("RH (stage7)", order->rh_action, FALSE)); action_wrapper_t *wrapper = (action_wrapper_t*) crm_malloc(sizeof(action_wrapper_t)); wrapper->action = order->rh_action; wrapper->strength = order->strength; GSListPtr list = order->lh_action->actions_after; list = g_slist_append(list, wrapper); order->lh_action->actions_after = list; wrapper = (action_wrapper_t*) crm_malloc(sizeof(action_wrapper_t)); wrapper->action = order->lh_action; wrapper->strength = order->strength; list = order->rh_action->actions_before; list = g_slist_append(list, wrapper); order->rh_action->actions_before = list; ); // } update_runnable(actions); slist_iter( rsc, resource_t, resources, lpc, GSListPtr action_set = NULL; /* any non-essential stop actions will be marked redundant by * during stage6 */ action_set = create_action_set(rsc->start); if(action_set != NULL) { - pdebug("Created action set for %s->start", + crm_verbose("Created action set for %s->start", rsc->id); *action_sets = g_slist_append(*action_sets, action_set); } else { - pdebug("No actions resulting from %s->start", + crm_verbose("No actions resulting from %s->start", rsc->id); } ); return TRUE; } /* * Create a dependancy graph to send to the transitioner (via the CRMd) */ gboolean stage8(GSListPtr action_sets, xmlNodePtr *graph) { int lpc = 0; xmlNodePtr xml_action_set = NULL; *graph = create_xml_node(NULL, "transition_graph"); /* errors... slist_iter(action, action_t, action_list, lpc, if(action->optional == FALSE && action->runnable == FALSE) { print_action("Ignoring", action, TRUE); } ); */ int lpc2; slist_iter(action_set, GSList, action_sets, lpc, - pdebug("Processing Action Set %d", lpc); + crm_verbose("Processing Action Set %d", lpc); xml_action_set = create_xml_node(NULL, "actions"); set_xml_property_copy( xml_action_set, XML_ATTR_ID, crm_itoa(lpc)); slist_iter(action, action_t, action_set, lpc2, xmlNodePtr xml_action = action2xml(action); xmlAddChild(xml_action_set, xml_action); ) xmlAddChild(*graph, xml_action_set); ); xml_message_debug(*graph, "created action list"); return TRUE; } /* * Print a nice human readable high-level summary of what we're going to do */ gboolean summary(GSListPtr resources) { int lpc = 0; slist_iter( rsc, resource_t, resources, lpc, char *rsc_id = safe_val(NULL, rsc, id); char *node_id = safe_val4(NULL, rsc, cur_node, details, id); char *new_node_id = safe_val6(NULL, rsc, color, details, chosen_node, details, id); if(rsc->runnable == FALSE) { - cl_log(LOG_ERR, - "Resource %s was not runnable", - rsc_id); + crm_err("Resource %s was not runnable", rsc_id); if(node_id != NULL) { - cl_log(LOG_WARNING, - "Stopping Resource (%s) on node %s", - rsc_id, - node_id); + crm_warn("Stopping Resource (%s) on node %s", + rsc_id, node_id); } } else if(safe_val4(NULL, rsc, color, details, chosen_node) == NULL) { - cl_log(LOG_ERR, - "Could not allocate Resource %s", - rsc_id); - pdebug_action(print_resource("Could not allocate", rsc, TRUE)); + crm_err("Could not allocate Resource %s", rsc_id); + crm_debug_action( + print_resource("Could not allocate",rsc,TRUE)); if(node_id != NULL) { - cl_log(LOG_WARNING, - "Stopping Resource (%s) on node %s", - rsc_id, - node_id); + crm_warn("Stopping Resource (%s) on node %s", + rsc_id, + node_id); } } else if(safe_str_eq(node_id, new_node_id)){ - cl_log(LOG_DEBUG, - "No change for Resource %s (%s)", - rsc_id, - safe_val4(NULL, rsc, cur_node, details, id)); + crm_debug("No change for Resource %s (%s)", + rsc_id, + safe_val4(NULL, rsc, cur_node, details, id)); } else if(node_id == NULL) { - cl_log(LOG_INFO, - "Starting Resource %s on %s", - rsc_id, - new_node_id); + crm_info("Starting Resource %s on %s", + rsc_id, + new_node_id); } else { - cl_log(LOG_INFO, - "Moving Resource %s from %s to %s", - rsc_id, - node_id, - new_node_id); + crm_info("Moving Resource %s from %s to %s", + rsc_id, + node_id, + new_node_id); } ); return TRUE; } gboolean choose_node_from_list(GSListPtr colors, color_t *color, GSListPtr nodes) { int lpc; /* 1. Sort by weight 2. color.chosen_node = highest wieghted node 3. remove color.chosen_node from all other colors */ nodes = g_slist_sort(nodes, sort_node_weight); color->details->chosen_node = node_copy((node_t*)g_slist_nth_data(nodes, 0)); if(color->details->chosen_node == NULL) { - cl_log(LOG_ERR, - "Could not allocate a node for color %d", - color->id); + crm_err("Could not allocate a node for color %d", + color->id); return FALSE; } slist_iter( color_n, color_t, colors, lpc, node_t *other_node = pe_find_node(color_n->details->candidate_nodes, color->details->chosen_node->details->id); if(color_n != color) { color_n->details->candidate_nodes = g_slist_remove(color_n->details->candidate_nodes, other_node); // crm_free(other_node); } ); return TRUE; } gboolean unpack_nodes(xmlNodePtr xml_nodes, GSListPtr *nodes) { - pdebug("Begining unpack... %s", __FUNCTION__); + crm_verbose("Begining unpack..."); while(xml_nodes != NULL) { xmlNodePtr xml_obj = xml_nodes; xmlNodePtr attrs = xml_obj->children; const char *id = xmlGetProp(xml_obj, XML_ATTR_ID); const char *type = xmlGetProp(xml_obj, XML_ATTR_TYPE); - pdebug("Processing node %s", id); + crm_verbose("Processing node %s", id); if(attrs != NULL) { attrs = attrs->children; } xml_nodes = xml_nodes->next; if(id == NULL) { - cl_log(LOG_ERR, "Must specify id tag in <node>"); + crm_err("Must specify id tag in <node>"); continue; } if(type == NULL) { - cl_log(LOG_ERR, "Must specify type tag in <node>"); + crm_err("Must specify type tag in <node>"); continue; } node_t *new_node = crm_malloc(sizeof(node_t)); new_node->weight = 1.0; new_node->fixed = FALSE; new_node->details = (struct node_shared_s*) crm_malloc(sizeof(struct node_shared_s)); new_node->details->online = FALSE; new_node->details->unclean = FALSE; new_node->details->shutdown = FALSE; new_node->details->running_rsc = NULL; new_node->details->id = crm_strdup(id); new_node->details->attrs = g_hash_table_new(g_str_hash, g_str_equal); new_node->details->type = node_ping; if(safe_str_eq(type, "node")) { new_node->details->type = node_member; } while(attrs != NULL){ const char *name = xmlGetProp( attrs, XML_NVPAIR_ATTR_NAME); const char *value = xmlGetProp( attrs, XML_NVPAIR_ATTR_VALUE); if(name != NULL && value != NULL) { g_hash_table_insert(new_node->details->attrs, crm_strdup(name), crm_strdup(value)); } attrs = attrs->next; } - pdebug("Done with node %s", xmlGetProp(xml_obj, "uname")); + crm_verbose("Done with node %s", xmlGetProp(xml_obj, "uname")); - pdebug_action(print_node("Added", new_node, FALSE)); + crm_debug_action(print_node("Added", new_node, FALSE)); *nodes = g_slist_append(*nodes, new_node); } *nodes = g_slist_sort(*nodes, sort_node_weight); return TRUE; } gboolean unpack_resources(xmlNodePtr xml_resources, GSListPtr *resources, GSListPtr *actions, GSListPtr *action_cons, GSListPtr all_nodes) { - pdebug("Begining unpack... %s", __FUNCTION__); + crm_verbose("Begining unpack..."); while(xml_resources != NULL) { xmlNodePtr xml_obj = xml_resources; const char *id = xmlGetProp(xml_obj, XML_ATTR_ID); const char *priority = xmlGetProp(xml_obj, XML_CIB_ATTR_PRIORITY); float priority_f = atof(priority); xml_resources = xml_resources->next; - pdebug("Processing resource..."); + crm_verbose("Processing resource..."); if(id == NULL) { - cl_log(LOG_ERR, "Must specify id tag in <resource>"); + crm_err("Must specify id tag in <resource>"); continue; } resource_t *new_rsc = crm_malloc(sizeof(resource_t)); new_rsc->xml = xml_obj; new_rsc->priority = priority_f; new_rsc->candidate_colors = NULL; new_rsc->color = NULL; new_rsc->runnable = TRUE; new_rsc->provisional = TRUE; new_rsc->allowed_nodes = node_list_dup(all_nodes); new_rsc->rsc_cons = NULL; new_rsc->node_cons = NULL; new_rsc->id = crm_strdup(id); new_rsc->cur_node = NULL; action_t *action_stop = action_new(action_id++, new_rsc, stop_rsc); action_t *action_start = action_new(action_id++, new_rsc, start_rsc); new_rsc->stop = action_stop; *actions = g_slist_append(*actions, action_stop); new_rsc->start = action_start; *actions = g_slist_append(*actions, action_start); order_constraint_t *order = (order_constraint_t*) crm_malloc(sizeof(order_constraint_t)); order->id = order_id++; order->lh_action = action_stop; order->rh_action = action_start; order->strength = startstop; *action_cons = g_slist_append(*action_cons, order); - pdebug_action(print_resource("Added", new_rsc, FALSE)); + crm_debug_action(print_resource("Added", new_rsc, FALSE)); *resources = g_slist_append(*resources, new_rsc); } *resources = g_slist_sort(*resources, sort_rsc_priority); return TRUE; } gboolean unpack_constraints(xmlNodePtr xml_constraints, GSListPtr nodes, GSListPtr resources, GSListPtr *node_constraints, GSListPtr *action_constraints) { - pdebug("Begining unpack... %s", __FUNCTION__); + crm_verbose("Begining unpack..."); while(xml_constraints != NULL) { const char *id = xmlGetProp(xml_constraints, XML_ATTR_ID); xmlNodePtr xml_obj = xml_constraints; xml_constraints = xml_constraints->next; if(id == NULL) { - cl_log(LOG_ERR, "Constraint must have an id"); + crm_err("Constraint must have an id"); continue; } - pdebug("Processing constraint %s %s", + crm_verbose("Processing constraint %s %s", xml_obj->name,id); if(safe_str_eq("rsc_to_rsc", xml_obj->name)) { unpack_rsc_to_rsc(xml_obj, resources, action_constraints); } else if(safe_str_eq("rsc_to_node", xml_obj->name)) { unpack_rsc_to_node(xml_obj, resources, nodes, node_constraints); } else if(safe_str_eq("rsc_to_attr", xml_obj->name)) { unpack_rsc_to_attr(xml_obj, resources, nodes, node_constraints); } else { - cl_log(LOG_ERR, "Unsupported constraint type: %s", + crm_err("Unsupported constraint type: %s", xml_obj->name); } } return TRUE; } gboolean apply_node_constraints(GSListPtr constraints, GSListPtr resources, GSListPtr nodes) { - pdebug("Applying constraints... %s", __FUNCTION__); + crm_verbose("Applying constraints..."); int lpc = 0; slist_iter( cons, rsc_to_node_t, constraints, lpc, - pdebug_action(print_rsc_to_node("Applying", cons, FALSE)); + crm_debug_action(print_rsc_to_node("Applying", cons, FALSE)); // take "lifetime" into account if(cons == NULL) { - cl_log(LOG_ERR, "Constraint (%d) is NULL", lpc); + crm_err("Constraint (%d) is NULL", lpc); continue; } else if(is_active(cons) == FALSE) { - cl_log(LOG_INFO, "Constraint (%d) is not active", lpc); + crm_info("Constraint (%d) is not active", lpc); // warning continue; } resource_t *rsc_lh = cons->rsc_lh; if(rsc_lh == NULL) { - cl_log(LOG_ERR, "LHS of rsc_to_node (%s) is NULL", cons->id); + crm_err("LHS of rsc_to_node (%s) is NULL", cons->id); continue; } cons->rsc_lh->node_cons = g_slist_append(cons->rsc_lh->node_cons, cons); if(cons->node_list_rh == NULL) { - cl_log(LOG_ERR, - "RHS of rsc_to_node (%s) is NULL", - cons->id); + crm_err("RHS of rsc_to_node (%s) is NULL", cons->id); continue; } else { int llpc = 0; slist_iter(node_rh, node_t, cons->node_list_rh, llpc, update_node_weight(cons, node_rh->details->id, nodes)); } /* dont add it to the resource, * the information is in the resouce's node list */ ); return TRUE; } // remove nodes that are down, stopping // create +ve rsc_to_node constraints between resources and the nodes they are running on // anything else? gboolean unpack_status(xmlNodePtr status, GSListPtr nodes, GSListPtr rsc_list, GSListPtr *node_constraints) { - pdebug("Begining unpack %s", __FUNCTION__); + crm_verbose("Begining unpack"); while(status != NULL) { const char *id = xmlGetProp( status, XML_ATTR_ID); const char *state = xmlGetProp( status, XML_LRM_ATTR_STATE); const char *exp_state = xmlGetProp( status, XML_CIB_ATTR_EXPSTATE); const char *join_state = xmlGetProp( status, XML_CIB_ATTR_JOINSTATE); // const char *crm_state = xmlGetProp( // status, XML_CIB_ATTR_CRMDSTATE); const char *ccm_state = xmlGetProp( status, XML_CIB_ATTR_INCCM); const char *shutdown = xmlGetProp( status, XML_CIB_ATTR_SHUTDOWN); const char *unclean = xmlGetProp( status, XML_CIB_ATTR_STONITH); xmlNodePtr lrm_state = find_xml_node(status, XML_CIB_TAG_LRM); xmlNodePtr attrs = find_xml_node(status, "attributes"); lrm_state = find_xml_node(lrm_state, XML_LRM_TAG_RESOURCES); lrm_state = find_xml_node(lrm_state, "lrm_resource"); status = status->next; - pdebug("Processing node %s", id); + crm_verbose("Processing node %s", id); if(id == NULL){ // error continue; } - pdebug("Processing node attrs"); + crm_verbose("Processing node attrs"); node_t *this_node = pe_find_node(nodes, id); if(this_node == NULL) { - cl_log(LOG_ERR, - "Node %s in status section no longer exists", - id); + crm_err("Node %s in status section no longer exists", + id); continue; } while(attrs != NULL){ const char *name = xmlGetProp( attrs, XML_NVPAIR_ATTR_NAME); const char *value = xmlGetProp( attrs, XML_NVPAIR_ATTR_VALUE); if(name != NULL && value != NULL && safe_val(NULL, this_node, details) != NULL) { - pdebug("Adding %s => %s", name, value); + crm_verbose("Adding %s => %s", name, value); g_hash_table_insert(this_node->details->attrs, crm_strdup(name), crm_strdup(value)); } attrs = attrs->next; } - pdebug("determining node state"); + crm_verbose("determining node state"); if(safe_str_eq(join_state, CRMD_JOINSTATE_MEMBER) && safe_str_eq(ccm_state, XML_BOOLEAN_YES) && shutdown == NULL) { // process resource, make +ve preference this_node->details->online = TRUE; } else { - pdebug("remove %s", __FUNCTION__); + crm_verbose("remove"); // remove node from contention this_node->weight = -1; this_node->fixed = TRUE; - pdebug("state %s, expected %s, shutdown %s", + crm_verbose("state %s, expected %s, shutdown %s", state, exp_state, shutdown); if(unclean != NULL) { this_node->details->unclean = TRUE; } else if(shutdown != NULL) { this_node->details->shutdown = TRUE; } else if(safe_str_eq(exp_state, CRMD_STATE_ACTIVE) && safe_str_eq( join_state, CRMD_JOINSTATE_DOWN) ){ // mark unclean in the xml this_node->details->unclean = TRUE; } if(this_node->details->unclean) { - pdebug("Node %s is due for STONITH", id); + crm_verbose("Node %s is due for STONITH", id); } if(this_node->details->shutdown) { - pdebug("Node %s is due for shutdown", id); + crm_verbose("Node %s is due for shutdown", id); } } - pdebug("Processing node lrm state"); + crm_verbose("Processing node lrm state"); process_node_lrm_state(this_node, lrm_state, rsc_list, nodes, node_constraints); } return TRUE; } gboolean is_active(rsc_to_node_t *cons) { return TRUE; } gboolean strict_preproc(rsc_to_rsc_t *constraint, color_t *local_color, color_t *other_color, GSListPtr *colors, GSListPtr resources) { resource_t * lh_resource = constraint->rsc_lh; switch(constraint->strength) { case must: if(constraint->rsc_rh->runnable == FALSE) { - cl_log(LOG_WARNING, - "Resource %s must run on the same node" - " as %s (cons %s), but %s is not" - " runnable.", - constraint->rsc_lh->id, - constraint->rsc_rh->id, - constraint->id, - constraint->rsc_rh->id); + crm_warn("Resource %s must run on the same" + " node as %s (cons %s), but %s is not" + " runnable.", + constraint->rsc_lh->id, + constraint->rsc_rh->id, + constraint->id, + constraint->rsc_rh->id); constraint->rsc_lh->runnable = FALSE; } break; // x * should * should_not = x case should: if(constraint->rsc_rh->provisional == FALSE) { local_color->local_weight = local_color->local_weight * 2.0; } break; case should_not: if(constraint->rsc_rh->provisional == FALSE) { local_color->local_weight = local_color->local_weight * 0.5; } - pdebug("# Colors %d, Nodes %d", + crm_verbose("# Colors %d, Nodes %d", g_slist_length(*colors), max_valid_nodes); if(g_slist_length(*colors) < max_valid_nodes // && g_slist_length(lh_resource->candidate_colors)==1 ) { create_color(colors, lh_resource->allowed_nodes, resources); } break; case must_not: if(constraint->rsc_rh->provisional == FALSE && local_color->id != no_color->id) { lh_resource->candidate_colors = g_slist_remove( lh_resource->candidate_colors, local_color); - pdebug_action( + crm_debug_action( print_color("Removed", local_color, FALSE)); // surely this is required... but mtrace says no... // crm_free(local_color); } break; default: // error break; } return TRUE; } gboolean strict_postproc(rsc_to_rsc_t *constraint, color_t *local_color, color_t *other_color, GSListPtr *colors, GSListPtr resources) { print_rsc_to_rsc("Post processing", constraint, FALSE); switch(constraint->strength) { case must: if(constraint->rsc_rh->provisional == TRUE) { constraint->rsc_rh->color = other_color; constraint->rsc_rh->provisional = FALSE; color_resource(constraint->rsc_rh, colors, resources); } // else check for error if(constraint->rsc_lh->runnable == FALSE) { - cl_log(LOG_WARNING, - "Resource %s must run on the same node" - " as %s (cons %s), but %s is not" - " runnable.", - constraint->rsc_rh->id, - constraint->rsc_lh->id, - constraint->id, - constraint->rsc_lh->id); + crm_warn("Resource %s must run on the same" + " node as %s (cons %s), but %s is not" + " runnable.", + constraint->rsc_rh->id, + constraint->rsc_lh->id, + constraint->id, + constraint->rsc_lh->id); constraint->rsc_rh->runnable = FALSE; } break; case should: break; case should_not: break; case must_not: if(constraint->rsc_rh->provisional == TRUE) { // check for error } break; default: // error break; } return TRUE; } gboolean choose_color(resource_t *lh_resource) { int lpc = 0; if(lh_resource->runnable == FALSE) { lh_resource->color = find_color(lh_resource->candidate_colors, no_color); lh_resource->provisional = FALSE; } if(lh_resource->provisional) { GSListPtr sorted_colors = g_slist_sort(lh_resource->candidate_colors, sort_color_weight); lh_resource->candidate_colors = sorted_colors; - pdebug("Choose a color from %d possibilities", + crm_verbose("Choose a color from %d possibilities", g_slist_length(sorted_colors)); slist_iter( this_color, color_t,lh_resource->candidate_colors, lpc, GSListPtr intersection = node_list_and( this_color->details->candidate_nodes, lh_resource->allowed_nodes); if(g_slist_length(intersection) != 0) { // TODO: merge node weights GSListPtr old_list = this_color->details->candidate_nodes; pe_free_shallow(old_list); this_color->details->candidate_nodes = intersection; lh_resource->color = this_color; lh_resource->provisional = FALSE; break; } else { pe_free_shallow(intersection); } ); } return !lh_resource->provisional; } gboolean unpack_rsc_to_node(xmlNodePtr xml_obj, GSListPtr rsc_list, GSListPtr node_list, GSListPtr *node_constraints) { xmlNodePtr node_ref = xml_obj->children; rsc_to_node_t *new_con = crm_malloc(sizeof(rsc_to_node_t)); const char *id_lh = xmlGetProp(xml_obj, "from"); const char *id = xmlGetProp(xml_obj, XML_ATTR_ID); const char *mod = xmlGetProp(xml_obj, "modifier"); const char *weight = xmlGetProp(xml_obj, "weight"); float weight_f = atof(weight); resource_t *rsc_lh = pe_find_resource(rsc_list, id_lh); if(rsc_lh == NULL) { - cl_log(LOG_ERR, "No resource (con=%s, rsc=%s)", + crm_err("No resource (con=%s, rsc=%s)", id, id_lh); } new_con->id = crm_strdup(id); new_con->rsc_lh = rsc_lh; new_con->weight = weight_f; if(safe_str_eq(mod, "set")){ new_con->modifier = set; } else if(safe_str_eq(mod, "inc")){ new_con->modifier = inc; } else if(safe_str_eq(mod, "dec")){ new_con->modifier = dec; } else { // error } /* <rsc_to_node> <node_ref id= type= name=/> <node_ref id= type= name=/> <node_ref id= type= name=/> */ // while(node_ref != NULL) { const char *xml_name = node_ref->name; const char *id_rh = xmlGetProp(node_ref, XML_NVPAIR_ATTR_NAME); node_t *node_rh = pe_find_node(node_list, id_rh); node_ref = node_ref->next; if(node_rh == NULL) { // error - cl_log(LOG_ERR, - "node %s (from %s) not found", - id_rh, xml_name); + crm_err("node %s (from %s) not found", + id_rh, xml_name); continue; } new_con->node_list_rh = g_slist_append(new_con->node_list_rh, node_rh); /* dont add it to the resource, * the information is in the resouce's node list */ } *node_constraints = g_slist_append(*node_constraints, new_con); return TRUE; } gboolean unpack_rsc_to_attr(xmlNodePtr xml_obj, GSListPtr rsc_list, GSListPtr node_list, GSListPtr *node_constraints) { /* <rsc_to_attr id="cons4" from="rsc2" weight="20.0" modifier="inc"> <attr_expression id="attr_exp_1"/> <node_match id="node_match_1" type="has_attr" target="cpu"/> <node_match id="node_match_2" type="attr_value" target="kernel" value="2.6"/> </attr_expression> <attr_expression id="attr_exp_2"/> <node_match id="node_match_3" type="has_attr" target="hdd"/> <node_match id="node_match_4" type="attr_value" target="kernel" value="2.4"/> </attr_expression> Translation: give any node a +ve weight of 20.0 to run rsc2 if: attr "cpu" is set _and_ "kernel"="2.6", _or_ attr "hdd" is set _and_ "kernel"="2.4" Further translation: 2 constraints that give any node a +ve weight of 20.0 to run rsc2 cons1: attr "cpu" is set and "kernel"="2.6" cons2: attr "hdd" is set and "kernel"="2.4" */ xmlNodePtr attr_exp = xml_obj->children; const char *id_lh = xmlGetProp(xml_obj, "from"); const char *mod = xmlGetProp(xml_obj, "modifier"); const char *weight = xmlGetProp(xml_obj, "weight"); const char *id = xmlGetProp(attr_exp, XML_ATTR_ID); float weight_f = atof(weight); enum con_modifier a_modifier = modifier_none; resource_t *rsc_lh = pe_find_resource(rsc_list, id_lh); if(rsc_lh == NULL) { - cl_log(LOG_ERR, "No resource (con=%s, rsc=%s)", + crm_err("No resource (con=%s, rsc=%s)", id, id_lh); return FALSE; } if(safe_str_eq(mod, "set")){ a_modifier = set; } else if(safe_str_eq(mod, "inc")){ a_modifier = inc; } else if(safe_str_eq(mod, "dec")){ a_modifier = dec; } else { // error } if(attr_exp == NULL) { - cl_log(LOG_WARNING, "no attrs for constraint %s", id); + crm_err("no attrs for constraint %s", id); } while(attr_exp != NULL) { const char *id_rh = xmlGetProp(attr_exp, XML_NVPAIR_ATTR_NAME); const char *id = xmlGetProp(attr_exp, XML_ATTR_ID); rsc_to_node_t *new_con = crm_malloc(sizeof(rsc_to_node_t)); new_con->id = crm_strdup(id); new_con->rsc_lh = rsc_lh; new_con->weight = weight_f; new_con->modifier = a_modifier; new_con->node_list_rh = match_attrs(attr_exp, node_list); if(new_con->node_list_rh == NULL) { // error - cl_log(LOG_ERR, - "node %s (from %s) not found", - id_rh, attr_exp->name); + crm_err("node %s (from %s) not found", + id_rh, attr_exp->name); } - pdebug_action(print_rsc_to_node("Added", new_con, FALSE)); + crm_debug_action(print_rsc_to_node("Added", new_con, FALSE)); *node_constraints = g_slist_append(*node_constraints, new_con); /* dont add it to the resource, * the information is in the resouce's node list */ attr_exp = attr_exp->next; } return TRUE; } gboolean update_node_weight(rsc_to_node_t *cons, char *id, GSListPtr nodes) { node_t *node_rh = pe_find_node(cons->rsc_lh->allowed_nodes, id); if(node_rh == NULL) { node_t *node_tmp = pe_find_node(nodes, id); node_rh = node_copy(node_tmp); cons->rsc_lh->allowed_nodes = g_slist_append(cons->rsc_lh->allowed_nodes, node_rh); } if(node_rh == NULL) { // error return FALSE; } if(node_rh->fixed) { // warning - cl_log(LOG_WARNING, - "Constraint %s is irrelevant as the" - " weight of node %s is fixed as %f.", - cons->id, - node_rh->details->id, - node_rh->weight); + crm_warn("Constraint %s is irrelevant as the" + " weight of node %s is fixed as %f.", + cons->id, + node_rh->details->id, + node_rh->weight); return TRUE; } - pdebug("Constraint %s: node %s weight %s %f.", + crm_verbose("Constraint %s: node %s weight %s %f.", cons->id, node_rh->details->id, modifier2text(cons->modifier), node_rh->weight); switch(cons->modifier) { case set: node_rh->weight = cons->weight; node_rh->fixed = TRUE; break; case inc: node_rh->weight += cons->weight; break; case dec: node_rh->weight -= cons->weight; break; case modifier_none: // warning break; } return TRUE; } gboolean process_node_lrm_state(node_t *node, xmlNodePtr lrm_state, GSListPtr rsc_list, GSListPtr nodes, GSListPtr *node_constraints) { while(lrm_state != NULL) { const char *rsc_id = xmlGetProp( lrm_state, XML_ATTR_ID); const char *node_id = xmlGetProp( lrm_state, XML_LRM_ATTR_TARGET); const char *rsc_state = xmlGetProp( lrm_state, XML_LRM_ATTR_STATE); resource_t *rsc_lh = pe_find_resource(rsc_list, rsc_id); - pdebug("[%s] Processing %s on %s (%s)", + crm_verbose("[%s] Processing %s on %s (%s)", lrm_state->name, rsc_id, node_id, rsc_state); lrm_state = lrm_state->next; if(rsc_lh == NULL) { - cl_log(LOG_ERR, - "Could not find a match for resource" - " %s in %s's status section", - rsc_id, node_id); + crm_err("Could not find a match for resource" + " %s in %s's status section", + rsc_id, node_id); continue; } - pdebug("Setting cur_node = %s for rsc = %s", + crm_verbose("Setting cur_node = %s for rsc = %s", node->details->id, rsc_lh->id); if(rsc_lh->cur_node != NULL) { - cl_log(LOG_ERR, + crm_err( "Resource %s running on multiple nodes %s & %s", rsc_lh->id, rsc_lh->cur_node->details->id, node->details->id); // TODO: some recovery action!! // like force a stop on the first node? continue; } rsc_lh->cur_node = node; node->details->running_rsc = g_slist_append(node->details->running_rsc, rsc_lh); if((safe_str_eq(rsc_state, "starting")) || (safe_str_eq(rsc_state, "started"))) { node_t *node_rh; rsc_to_node_t *new_cons = crm_malloc(sizeof(rsc_to_node_t)); new_cons->id = crm_strdup("create_me"); // genereate one new_cons->weight = 100.0; new_cons->modifier = inc; new_cons->rsc_lh = rsc_lh; node_rh = pe_find_node(nodes, node_id); new_cons->node_list_rh = g_slist_append(NULL, node_rh); *node_constraints = g_slist_append(*node_constraints, new_cons); - pdebug_action(print_rsc_to_node( + crm_debug_action(print_rsc_to_node( "Added", new_cons, FALSE)); } else if(safe_str_eq(rsc_state, "stop_fail")) { // do soemthing } // else no preference } return TRUE; } GSListPtr match_attrs(xmlNodePtr attr_exp, GSListPtr node_list) { int lpc = 0; GSListPtr result = NULL; slist_iter( node, node_t, node_list, lpc, xmlNodePtr node_match = attr_exp->children; gboolean accept = TRUE; while(accept && node_match != NULL) { const char *type = xmlGetProp( node_match, XML_ATTR_TYPE); const char *value= xmlGetProp( node_match, XML_NVPAIR_ATTR_VALUE); const char *name = xmlGetProp(node_match, "target"); node_match = node_match->next; if(name == NULL || type == NULL) { // error continue; } const char *h_val = (const char*) g_hash_table_lookup(node->details->attrs, name); if(h_val != NULL && safe_str_eq(type, "has_attr")){ accept = TRUE; } else if(h_val == NULL && safe_str_eq(type, "not_attr")) { accept = TRUE; } else if(h_val != NULL && safe_str_eq(type, "attr_value") && safe_str_eq(h_val, value)) { accept = TRUE; } else { accept = FALSE; } } if(accept) { result = g_slist_append(result, node); } ); return result; } gboolean create_rsc_to_rsc(const char *id, enum con_strength strength, resource_t *rsc_lh, resource_t *rsc_rh) { if(rsc_lh == NULL || rsc_rh == NULL){ // error return FALSE; } rsc_to_rsc_t *new_con = crm_malloc(sizeof(rsc_to_node_t)); rsc_to_rsc_t *inverted_con = NULL; new_con->id = crm_strdup(id); new_con->rsc_lh = rsc_lh; new_con->rsc_rh = rsc_rh; new_con->strength = strength; inverted_con = invert_constraint(new_con); rsc_lh->rsc_cons = g_slist_insert_sorted(rsc_lh->rsc_cons, new_con, sort_cons_strength); rsc_rh->rsc_cons = g_slist_insert_sorted(rsc_rh->rsc_cons, inverted_con, sort_cons_strength); return TRUE; } gboolean create_ordering(const char *id, enum con_strength strength, resource_t *rsc_lh, resource_t *rsc_rh, GSListPtr *action_constraints) { if(rsc_lh == NULL || rsc_rh == NULL){ // error return FALSE; } action_t *lh_stop = rsc_lh->stop; action_t *lh_start = rsc_lh->start; action_t *rh_stop = rsc_rh->stop; action_t *rh_start = rsc_rh->start; order_constraint_t *order = (order_constraint_t*) crm_malloc(sizeof(order_constraint_t)); order->id = order_id++; order->lh_action = lh_stop; order->rh_action = rh_stop; order->strength = strength; *action_constraints = g_slist_append(*action_constraints, order); order = (order_constraint_t*) crm_malloc(sizeof(order_constraint_t)); order->id = order_id++; order->lh_action = rh_start; order->rh_action = lh_start; order->strength = strength; *action_constraints = g_slist_append(*action_constraints, order); return TRUE; } gboolean unpack_rsc_to_rsc(xmlNodePtr xml_obj, GSListPtr rsc_list, GSListPtr *action_constraints) { const char *id_lh = xmlGetProp(xml_obj, "from"); const char *id = xmlGetProp(xml_obj, XML_ATTR_ID); resource_t *rsc_lh = pe_find_resource(rsc_list, id_lh); const char *id_rh = xmlGetProp(xml_obj, "to"); resource_t *rsc_rh = pe_find_resource(rsc_list, id_rh); const char *strength = xmlGetProp(xml_obj, "strength"); const char *type = xmlGetProp(xml_obj, XML_ATTR_TYPE); enum con_strength strength_e = ignore; if(rsc_lh == NULL) { - cl_log(LOG_ERR, "No resource (con=%s, rsc=%s)", + crm_err("No resource (con=%s, rsc=%s)", id, id_lh); return FALSE; } if(safe_str_eq(strength, XML_STRENGTH_VAL_MUST)) { strength_e = must; } else if(safe_str_eq(strength, XML_STRENGTH_VAL_SHOULD)) { strength_e = should; } else if(safe_str_eq(strength, XML_STRENGTH_VAL_SHOULDNOT)) { strength_e = should_not; } else if(safe_str_eq(strength, XML_STRENGTH_VAL_MUSTNOT)) { strength_e = must_not; } else { // error } if(safe_str_eq(type, "ordering")) { // make an action_cons instead return create_ordering(id, strength_e, rsc_lh, rsc_rh, action_constraints); } return create_rsc_to_rsc(id, strength_e, rsc_lh, rsc_rh); } GSListPtr create_action_set(action_t *action) { int lpc; GSListPtr tmp = NULL; GSListPtr result = NULL; gboolean preceeding_complete = FALSE; if(action->processed) { return NULL; } - pdebug_action(print_action("Create action set for", action, FALSE)); + crm_debug_action(print_action("Create action set for", action, FALSE)); // process actions_before if(action->seen_count == 0) { - pdebug("Processing \"before\" for action %d", action->id); + crm_verbose("Processing \"before\" for action %d", action->id); slist_iter( other, action_wrapper_t, action->actions_before, lpc, tmp = create_action_set(other->action); - pdebug("%d (%d total) \"before\" actions for %d)", + crm_verbose("%d (%d total) \"before\" actions for %d)", g_slist_length(tmp), g_slist_length(result), action->id); result = g_slist_concat(result, tmp); preceeding_complete = TRUE; ); } else { - pdebug("Already seen action %d", action->id); - pdebug("Processing \"before\" for action %d", action->id); + crm_verbose("Already seen action %d", action->id); + crm_verbose("Processing \"before\" for action %d", action->id); slist_iter( other, action_wrapper_t, action->actions_before, lpc, if(other->action->seen_count > action->seen_count && other->strength == must) { tmp = create_action_set(other->action); - pdebug("%d (%d total) \"before\" actions for %d)", + crm_verbose("%d (%d total) \"before\" actions for %d)", g_slist_length(tmp), g_slist_length(result), action->id); result = g_slist_concat(result, tmp); } ); } // add ourselves if(action->runnable) { if(action->processed == FALSE) { - pdebug("Adding self %d", action->id); + crm_verbose("Adding self %d", action->id); result = g_slist_append(result, action); } else { - pdebug("Already added self %d", action->id); + crm_verbose("Already added self %d", action->id); } } else { - pdebug("Skipping ourselves, we're not runnable"); + crm_verbose("Skipping ourselves, we're not runnable"); } action->processed = TRUE; if(preceeding_complete == FALSE) { // add strength == !MUST slist_iter( other, action_wrapper_t, action->actions_before, lpc, tmp = create_action_set(other->action); - pdebug("%d (%d total) post-self \"before\" actions for %d)", + crm_verbose("%d (%d total) post-self \"before\" actions for %d)", g_slist_length(tmp), g_slist_length(result),action->id); result = g_slist_concat(result, tmp); ); } action->seen_count = action->seen_count + 1; /* process actions_after * * do this regardless of whether we are runnable. Any direct or * indirect hard/XML_STRENGTH_VAL_MUST dependancies on us will have been picked * up earlier on in stage 7 */ - pdebug("Processing \"after\" for action %d", action->id); + crm_verbose("Processing \"after\" for action %d", action->id); slist_iter( other, action_wrapper_t, action->actions_after, lpc, tmp = create_action_set(other->action); - pdebug("%d (%d total) \"after\" actions for %d)", + crm_verbose("%d (%d total) \"after\" actions for %d)", g_slist_length(tmp), g_slist_length(result),action->id); result = g_slist_concat(result, tmp); ); return result; } gboolean update_runnable(GSListPtr actions) { int lpc = 0, lpc2 = 0; gboolean change = TRUE; while(change) { change = FALSE; slist_iter( action, action_t, actions, lpc, if(action->runnable) { continue; } else if(action->optional) { continue; } slist_iter( other, action_wrapper_t, action->actions_after, lpc2, if(other->action->runnable) { change = TRUE; - pdebug_action( + crm_debug_action( print_action( "Marking unrunnable", other->action, FALSE)); } other->action->runnable = FALSE; ); ); } return TRUE; } void color_resource(resource_t *lh_resource, GSListPtr *colors, GSListPtr resources) { int lpc = 0; - pdebug_action(print_resource("Coloring", lh_resource, FALSE)); + crm_debug_action(print_resource("Coloring", lh_resource, FALSE)); if(lh_resource->provisional == FALSE) { // already processed this resource return; } lh_resource->rsc_cons = g_slist_sort(lh_resource->rsc_cons, sort_cons_strength); - pdebug("=== Pre-processing"); + crm_verbose("=== Pre-processing"); //------ Pre-processing slist_iter( constraint, rsc_to_rsc_t, lh_resource->rsc_cons, lpc, color_t *other_color = NULL; color_t *local_color = NULL; if(lh_resource->runnable == FALSE) { break; } - pdebug_action(print_rsc_to_rsc( + crm_debug_action(print_rsc_to_rsc( "Processing constraint", constraint, FALSE)); if(constraint->rsc_rh == NULL) { - cl_log(LOG_ERR, - "rsc_rh was NULL for %s", - constraint->id); + crm_err("rsc_rh was NULL for %s", constraint->id); continue; } other_color = constraint->rsc_rh->color; local_color = find_color(lh_resource->candidate_colors, other_color); strict_preproc(constraint, local_color, other_color, colors, resources); ); // filter out nodes with a negative weight filter_nodes(lh_resource); /* Choose a color from the candidates or, * create a new one if no color is suitable * (this may need modification pending further napkin drawings) */ choose_color(lh_resource); - pdebug("* Colors %d, Nodes %d", + crm_verbose("* Colors %d, Nodes %d", g_slist_length(*colors), max_valid_nodes); if(lh_resource->provisional && g_slist_length(*colors) < max_valid_nodes) { // Create new color - pdebug("Create a new color"); + crm_verbose("Create a new color"); lh_resource->color = create_color(colors, lh_resource->allowed_nodes, resources); } else if(lh_resource->provisional) { - cl_log(LOG_ERR, "Could not color resource %s", lh_resource->id); + crm_err("Could not color resource %s", lh_resource->id); print_resource("ERROR: No color", lh_resource, FALSE); lh_resource->color = find_color(lh_resource->candidate_colors, no_color); } lh_resource->provisional = FALSE; - pdebug_action(print_resource("Post-processing", lh_resource, FALSE)); + crm_debug_action(print_resource("Post-processing", lh_resource, FALSE)); //------ Post-processing color_t *local_color = lh_resource->color; slist_iter( constraint, rsc_to_rsc_t, lh_resource->rsc_cons, lpc, color_t *other_color = find_color(constraint->rsc_rh->candidate_colors, local_color); strict_postproc(constraint, local_color, other_color, colors, resources); ); - pdebug_action(print_resource("Colored", lh_resource, FALSE)); + crm_debug_action(print_resource("Colored", lh_resource, FALSE)); } FILE *pemsg_strm = NULL; gboolean process_pe_message(xmlNodePtr msg, IPC_Channel *sender) { const char *op = get_xml_attr (msg, XML_TAG_OPTIONS, XML_ATTR_OP, TRUE); const char *ref = xmlGetProp(msg, XML_ATTR_REFERENCE); if(safe_str_eq(xmlGetProp(msg, XML_ATTR_MSGTYPE), XML_ATTR_REQUEST)) { - cl_log(LOG_INFO, + crm_info( "Message was a response not a request." " Discarding"); } - CRM_DEBUG("Processing %s op (ref=%s)...", op, ref); + crm_verbose("Processing %s op (ref=%s)...", op, ref); if(pemsg_strm == NULL) { pemsg_strm = fopen("/tmp/pemsg.log", "w"); } char *msg_buffer = dump_xml_node(msg, FALSE); fprintf(pemsg_strm, "%s: %s\n", "[in ]", msg_buffer); fflush(pemsg_strm); crm_free(msg_buffer); const char *sys_to = xmlGetProp(msg, XML_ATTR_SYSTO); if(op == NULL){ // error } else if(strcmp(op, CRM_OP_HELLO) == 0) { // ignore } else if(sys_to == NULL || strcmp(sys_to, CRM_SYSTEM_PENGINE) != 0) { - CRM_DEBUG("Bad sys-to %s", sys_to); + crm_verbose("Bad sys-to %s", sys_to); return FALSE; } else if(strcmp(op, CRM_OP_PECALC) == 0) { xmlNodePtr input_cib = find_xml_node(msg, XML_TAG_CIB); xmlNodePtr output = do_calculations(input_cib); if (send_ipc_reply(sender, msg, output) ==FALSE) { - cl_log(LOG_WARNING, + crm_warn( "Answer could not be sent"); } free_xml(output); } else if(strcmp(op, CRM_OP_QUIT) == 0) { - cl_log(LOG_WARNING, "Received quit message, terminating"); + crm_err("Received quit message, terminating"); exit(0); } return TRUE; } xmlNodePtr do_calculations(xmlNodePtr cib_object) { int lpc, lpc2; GSListPtr resources = NULL; GSListPtr nodes = NULL; GSListPtr node_constraints = NULL; GSListPtr actions = NULL; GSListPtr action_constraints = NULL; GSListPtr stonith_list = NULL; GSListPtr shutdown_list = NULL; GSListPtr colors = NULL; GSListPtr action_sets = NULL; xmlNodePtr graph = NULL; // pe_debug_on(); - pdebug("=#=#=#=#= Stage 0 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 0 =#=#=#=#="); stage0(cib_object, &resources, &nodes, &node_constraints, &actions, &action_constraints, &stonith_list, &shutdown_list); - pdebug("=#=#=#=#= Stage 1 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 1 =#=#=#=#="); stage1(node_constraints, nodes, resources); - pdebug("=#=#=#=#= Stage 2 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 2 =#=#=#=#="); stage2(resources, nodes, &colors); - pdebug("========= Nodes ========="); - pdebug_action( + crm_verbose("========= Nodes ========="); + crm_debug_action( slist_iter(node, node_t, nodes, lpc, print_node(NULL, node, TRUE) ) ); - pdebug("========= Resources ========="); - pdebug_action( + crm_verbose("========= Resources ========="); + crm_debug_action( slist_iter(resource, resource_t, resources, lpc, print_resource(NULL, resource, TRUE) ) ); - pdebug("=#=#=#=#= Stage 3 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 3 =#=#=#=#="); stage3(colors); - pdebug("=#=#=#=#= Stage 4 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 4 =#=#=#=#="); stage4(colors); - pdebug("========= Colors ========="); - pdebug_action( + crm_verbose("========= Colors ========="); + crm_debug_action( slist_iter(color, color_t, colors, lpc, print_color(NULL, color, FALSE) ) ); - pdebug("=#=#=#=#= Stage 5 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 5 =#=#=#=#="); stage5(resources); - pdebug("=#=#=#=#= Stage 6 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 6 =#=#=#=#="); stage6(&actions, &action_constraints, stonith_list, shutdown_list); - pdebug("========= Action List ========="); - pdebug_action( + crm_verbose("========= Action List ========="); + crm_debug_action( slist_iter(action, action_t, actions, lpc, print_action(NULL, action, TRUE) ) ); - pdebug("=#=#=#=#= Stage 7 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 7 =#=#=#=#="); stage7(resources, actions, action_constraints, &action_sets); - pdebug("=#=#=#=#= Summary =#=#=#=#="); + crm_verbose("=#=#=#=#= Summary =#=#=#=#="); summary(resources); - pdebug("========= Action Sets ========="); + crm_verbose("========= Action Sets ========="); - pdebug("\t========= Set %d (Un-runnable) =========", -1); - pdebug_action( + crm_verbose("\t========= Set %d (Un-runnable) =========", -1); + crm_debug_action( slist_iter(action, action_t, actions, lpc, if(action->optional == FALSE && action->runnable == FALSE) { print_action("\t", action, TRUE); } ) ); - pdebug_action( + crm_debug_action( slist_iter(action_set, GSList, action_sets, lpc, - pdebug("\t========= Set %d =========", lpc); + crm_verbose("\t========= Set %d =========", lpc); slist_iter(action, action_t, action_set, lpc2, print_action("\t", action, TRUE); ) ) ); - pdebug("========= Stonith List ========="); - pdebug_action( + crm_verbose("========= Stonith List ========="); + crm_debug_action( slist_iter(node, node_t, stonith_list, lpc, print_node(NULL, node, FALSE); ) ); - pdebug("========= Shutdown List ========="); - pdebug_action( + crm_verbose("========= Shutdown List ========="); + crm_debug_action( slist_iter(node, node_t, shutdown_list, lpc, print_node(NULL, node, FALSE); ) ); - pdebug("=#=#=#=#= Stage 8 =#=#=#=#="); + crm_verbose("=#=#=#=#= Stage 8 =#=#=#=#="); stage8(action_sets, &graph); - pdebug("=#=#=#=#= Cleanup =#=#=#=#="); + crm_verbose("=#=#=#=#= Cleanup =#=#=#=#="); - pdebug("deleting node cons"); + crm_verbose("deleting node cons"); while(node_constraints) { pe_free_rsc_to_node((rsc_to_node_t*)node_constraints->data); node_constraints = node_constraints->next; } g_slist_free(node_constraints); - pdebug("deleting order cons"); + crm_verbose("deleting order cons"); pe_free_shallow(action_constraints); - pdebug("deleting action sets"); + crm_verbose("deleting action sets"); slist_iter(action_set, GSList, action_sets, lpc, pe_free_shallow_adv(action_set, FALSE); ); pe_free_shallow_adv(action_sets, FALSE); - pdebug("deleting actions"); + crm_verbose("deleting actions"); pe_free_actions(actions); - pdebug("deleting resources"); + crm_verbose("deleting resources"); pe_free_resources(resources); - pdebug("deleting colors"); + crm_verbose("deleting colors"); pe_free_colors(colors); - pdebug("deleting nodes"); + crm_verbose("deleting nodes"); pe_free_nodes(nodes); g_slist_free(shutdown_list); g_slist_free(stonith_list); return graph; } diff --git a/crm/pengine/penginemain.c b/crm/pengine/penginemain.c index 94260db814..564fb687b3 100644 --- a/crm/pengine/penginemain.c +++ b/crm/pengine/penginemain.c @@ -1,226 +1,226 @@ -/* $Id: penginemain.c,v 1.15 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: penginemain.c,v 1.16 2004/06/02 15:25:11 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 */ #include <portability.h> #include <crm/crm.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <hb_api.h> #include <clplumbing/uids.h> #include <crm/common/ipc.h> #include <crm/common/ctrl.h> #include <crm/dmalloc_wrapper.h> #define SYS_NAME CRM_SYSTEM_PENGINE #define OPTARGS "skrh" #define PID_FILE WORKING_DIR "/"SYS_NAME".pid" #define DAEMON_LOG "/var/log/"SYS_NAME".log" #define DAEMON_DEBUG "/var/log/"SYS_NAME".debug" GMainLoop* mainloop = NULL; const char* crm_system_name = SYS_NAME; void usage(const char* cmd, int exit_status); int init_start(void); void pengine_shutdown(int nsig); extern gboolean process_pe_message(xmlNodePtr msg, IPC_Channel *sender); int main(int argc, char ** argv) { int req_restart = FALSE; int req_status = FALSE; int req_stop = FALSE; int argerr = 0; int flag; cl_log_set_entity(crm_system_name); cl_log_enable_stderr(TRUE); cl_log_set_facility(LOG_USER); if (0) { send_ipc_message(NULL, NULL); } while ((flag = getopt(argc, argv, OPTARGS)) != EOF) { switch(flag) { case 's': /* Status */ req_status = TRUE; break; case 'k': /* Stop (kill) */ req_stop = TRUE; break; case 'r': /* Restart */ req_restart = TRUE; break; case 'h': /* Help message */ usage(crm_system_name, LSB_EXIT_OK); break; default: ++argerr; break; } } if (optind > argc) { ++argerr; } if (argerr) { usage(crm_system_name,LSB_EXIT_GENERIC); } // read local config file if (req_status){ return init_status(PID_FILE, crm_system_name); } if (req_stop){ return init_stop(PID_FILE); } if (req_restart) { init_stop(PID_FILE); } return init_start(); } int init_start(void) { long pid; ll_cluster_t* hb_fd = NULL; int facility; IPC_Channel *crm_ch = NULL; #ifdef REALTIME_SUPPORT static int crm_realtime = 1; #endif if ((pid = get_running_pid(PID_FILE, NULL)) > 0) { - cl_log(LOG_CRIT, "already running: [pid %ld].", pid); + crm_crit("already running: [pid %ld].", pid); exit(LSB_EXIT_OK); } cl_log_set_logfile(DAEMON_LOG); -// if (crm_debug()) { +// if (crm_verbose()) { cl_log_set_debugfile(DAEMON_DEBUG); // } /* change the logging facility to the one used by heartbeat daemon */ hb_fd = ll_cluster_new("heartbeat"); - cl_log(LOG_INFO, "Switching to Heartbeat logger"); + crm_info("Switching to Heartbeat logger"); if ((facility = hb_fd->llc_ops->get_logfacility(hb_fd))>0) { cl_log_set_facility(facility); } - cl_log(LOG_INFO, "Register PID"); + crm_info("Register PID"); register_pid(PID_FILE, FALSE, pengine_shutdown); crm_ch = init_client_ipc_comms(CRM_SYSTEM_CRMD, subsystem_input_dispatch, (void*)process_pe_message); if(crm_ch != NULL) { send_hello_message(crm_ch, "1234", CRM_SYSTEM_PENGINE, "0", "1"); /* Create the mainloop and run it... */ mainloop = g_main_new(FALSE); - cl_log(LOG_INFO, "Starting %s", crm_system_name); + crm_info("Starting %s", crm_system_name); #ifdef REALTIME_SUPPORT if (crm_realtime == 1){ cl_enable_realtime(); }else if (crm_realtime == 0){ cl_disable_realtime(); } cl_make_realtime(SCHED_RR, 5, 64, 64); #endif g_main_run(mainloop); } else { - cl_log(LOG_ERR, "Could not connect to the CRMd"); + crm_err("Could not connect to the CRMd"); } return_to_orig_privs(); if (unlink(PID_FILE) == 0) { - cl_log(LOG_INFO, "[%s] stopped", crm_system_name); + crm_info("[%s] stopped", crm_system_name); } if(crm_ch != NULL) return 0; return 1; } void usage(const char* cmd, int exit_status) { FILE* stream; stream = exit_status ? stderr : stdout; fprintf(stream, "usage: %s [-srkh]" "[-c configure file]\n", cmd); /* fprintf(stream, "\t-d\tsets debug level\n"); */ /* fprintf(stream, "\t-s\tgets daemon status\n"); */ /* fprintf(stream, "\t-r\trestarts daemon\n"); */ /* fprintf(stream, "\t-k\tstops daemon\n"); */ /* fprintf(stream, "\t-h\thelp message\n"); */ fflush(stream); exit(exit_status); } void pengine_shutdown(int nsig) { static int shuttingdown = 0; CL_SIGNAL(nsig, pengine_shutdown); if (!shuttingdown) { shuttingdown = 1; } if (mainloop != NULL && g_main_is_running(mainloop)) { g_main_quit(mainloop); }else{ exit(LSB_EXIT_OK); } } diff --git a/crm/pengine/ptest.c b/crm/pengine/ptest.c index 05e20ba216..1109f59b65 100644 --- a/crm/pengine/ptest.c +++ b/crm/pengine/ptest.c @@ -1,295 +1,295 @@ -/* $Id: ptest.c,v 1.17 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: ptest.c,v 1.18 2004/06/02 15:25:11 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 */ #include <portability.h> #include <crm/crm.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <crm/common/xml.h> #include <crm/msg_xml.h> #include <crm/cib.h> #define OPTARGS "V?i:o:D:C:S:HA:U:M:I:EWRFt:m:a:d:w:c:r:p:s:" #include <getopt.h> #include <glib.h> #include <pengine.h> #include <pe_utils.h> int main(int argc, char **argv) { xmlNodePtr cib_object = NULL; int lpc = 0; int argerr = 0; int flag; cl_log_set_entity("ptest"); cl_log_enable_stderr(TRUE); cl_log_set_facility(LOG_USER); while (1) { int option_index = 0; static struct option long_options[] = { // Top-level Options {"daemon", 0, 0, 0}, {0, 0, 0, 0} }; flag = getopt_long(argc, argv, OPTARGS, long_options, &option_index); if (flag == -1) break; switch(flag) { case 0: printf("option %s", long_options[option_index].name); if (optarg) printf(" with arg %s", optarg); printf("\n"); break; /* a sample test for multiple instance if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); */ case 'V': printf("option %d", flag); break; default: printf("?? getopt returned character code 0%o ??\n", flag); ++argerr; break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); } if (optind > argc) { ++argerr; } if (argerr) { - cl_log(LOG_ERR, "%d errors in option parsing", argerr); + crm_err("%d errors in option parsing", argerr); } - cl_log(LOG_INFO, "=#=#=#=#= Getting XML =#=#=#=#="); + crm_info("=#=#=#=#= Getting XML =#=#=#=#="); cib_object = file2xml(stdin); - cl_log(LOG_INFO, "=#=#=#=#= Stage 0 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 0 =#=#=#=#="); GSListPtr resources = NULL; GSListPtr nodes = NULL; GSListPtr node_constraints = NULL; GSListPtr actions = NULL; GSListPtr action_constraints = NULL; GSListPtr stonith_list = NULL; GSListPtr shutdown_list = NULL; GSListPtr colors = NULL; GSListPtr action_sets = NULL; xmlNodePtr graph = NULL; mtrace(); pe_debug_on(); stage0(cib_object, &resources, &nodes, &node_constraints, &actions, &action_constraints, &stonith_list, &shutdown_list); - cl_log(LOG_INFO, "========= Nodes ========="); + crm_info("========= Nodes ========="); slist_iter(node, node_t, nodes, lpc, print_node(NULL, node, TRUE)); - cl_log(LOG_INFO, "========= Resources ========="); + crm_info("========= Resources ========="); slist_iter(resource, resource_t, resources, lpc, print_resource(NULL, resource, TRUE)); - cl_log(LOG_INFO, "========= Constraints ========="); + crm_info("========= Constraints ========="); slist_iter(constraint, rsc_to_node_t, node_constraints, lpc, print_rsc_to_node(NULL, constraint, FALSE)); - cl_log(LOG_INFO, "=#=#=#=#= Stage 1 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 1 =#=#=#=#="); stage1(node_constraints, nodes, resources); - cl_log(LOG_INFO, "========= Nodes ========="); + crm_info("========= Nodes ========="); slist_iter(node, node_t, nodes, lpc, print_node(NULL, node, TRUE)); - cl_log(LOG_INFO, "========= Resources ========="); + crm_info("========= Resources ========="); slist_iter(resource, resource_t, resources, lpc, print_resource(NULL, resource, TRUE)); - cl_log(LOG_INFO, "=#=#=#=#= Stage 2 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 2 =#=#=#=#="); // pe_debug_on(); stage2(resources, nodes, &colors); // pe_debug_off(); - cl_log(LOG_INFO, "========= Nodes ========="); + crm_info("========= Nodes ========="); slist_iter(node, node_t, nodes, lpc, print_node(NULL, node, TRUE)); - cl_log(LOG_INFO, "========= Resources ========="); + crm_info("========= Resources ========="); slist_iter(resource, resource_t, resources, lpc, print_resource(NULL, resource, TRUE)); - cl_log(LOG_INFO, "========= Colors ========="); + crm_info("========= Colors ========="); slist_iter(color, color_t, colors, lpc, print_color(NULL, color, FALSE)); - cl_log(LOG_INFO, "=#=#=#=#= Stage 3 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 3 =#=#=#=#="); stage3(colors); - cl_log(LOG_INFO, "========= Colors ========="); + crm_info("========= Colors ========="); slist_iter(color, color_t, colors, lpc, print_color(NULL, color, FALSE)); - cl_log(LOG_INFO, "=#=#=#=#= Stage 4 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 4 =#=#=#=#="); stage4(colors); - cl_log(LOG_INFO, "========= Colors ========="); + crm_info("========= Colors ========="); slist_iter(color, color_t, colors, lpc, print_color(NULL, color, FALSE)); - cl_log(LOG_INFO, "=#=#=#=#= Summary =#=#=#=#="); + crm_info("=#=#=#=#= Summary =#=#=#=#="); summary(resources); - cl_log(LOG_INFO, "========= Action List ========="); + crm_info("========= Action List ========="); slist_iter(action, action_t, actions, lpc, print_action(NULL, action, FALSE)); - cl_log(LOG_INFO, "=#=#=#=#= Stage 5 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 5 =#=#=#=#="); stage5(resources); - cl_log(LOG_INFO, "=#=#=#=#= Stage 6 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 6 =#=#=#=#="); stage6(&actions, &action_constraints, stonith_list, shutdown_list); - cl_log(LOG_INFO, "========= Action List ========="); + crm_info("========= Action List ========="); slist_iter(action, action_t, actions, lpc, print_action(NULL, action, TRUE)); - cl_log(LOG_INFO, "=#=#=#=#= Stage 7 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 7 =#=#=#=#="); stage7(resources, actions, action_constraints, &action_sets); - cl_log(LOG_INFO, "=#=#=#=#= Summary =#=#=#=#="); + crm_info("=#=#=#=#= Summary =#=#=#=#="); summary(resources); - cl_log(LOG_INFO, "========= All Actions ========="); + crm_info("========= All Actions ========="); slist_iter(action, action_t, actions, lpc, print_action("\t", action, TRUE); ); - cl_log(LOG_INFO, "========= Action Sets ========="); + crm_info("========= Action Sets ========="); - cl_log(LOG_INFO, "\t========= Set %d (Un-runnable) =========", -1); + crm_info("\t========= Set %d (Un-runnable) =========", -1); slist_iter(action, action_t, actions, lpc, if(action->optional == FALSE && action->runnable == FALSE) { print_action("\t", action, TRUE); } ); int lpc2; slist_iter(action_set, GSList, action_sets, lpc, - cl_log(LOG_INFO, "\t========= Set %d =========", lpc); + crm_info("\t========= Set %d =========", lpc); slist_iter(action, action_t, action_set, lpc2, print_action("\t", action, TRUE))); - cl_log(LOG_INFO, "========= Stonith List ========="); + crm_info("========= Stonith List ========="); slist_iter(node, node_t, stonith_list, lpc, print_node(NULL, node, FALSE)); - cl_log(LOG_INFO, "========= Shutdown List ========="); + crm_info("========= Shutdown List ========="); slist_iter(node, node_t, shutdown_list, lpc, print_node(NULL, node, FALSE)); - cl_log(LOG_INFO, "=#=#=#=#= Stage 8 =#=#=#=#="); + crm_info("=#=#=#=#= Stage 8 =#=#=#=#="); stage8(action_sets, &graph); // GSListPtr action_sets = NULL; - pdebug("deleting node cons"); + crm_verbose("deleting node cons"); while(node_constraints) { pe_free_rsc_to_node((rsc_to_node_t*)node_constraints->data); node_constraints = node_constraints->next; } g_slist_free(node_constraints); - pdebug("deleting order cons"); + crm_verbose("deleting order cons"); pe_free_shallow(action_constraints); - pdebug("deleting action sets"); + crm_verbose("deleting action sets"); slist_iter(action_set, GSList, action_sets, lpc, pe_free_shallow_adv(action_set, FALSE); ); pe_free_shallow_adv(action_sets, FALSE); - pdebug("deleting actions"); + crm_verbose("deleting actions"); pe_free_actions(actions); - pdebug("deleting resources"); + crm_verbose("deleting resources"); pe_free_resources(resources); - pdebug("deleting colors"); + crm_verbose("deleting colors"); pe_free_colors(colors); crm_free(no_color->details); crm_free(no_color); - pdebug("deleting nodes"); + crm_verbose("deleting nodes"); pe_free_nodes(nodes); g_slist_free(shutdown_list); g_slist_free(stonith_list); pe_debug_off(); muntrace(); char *msg_buffer = dump_xml_node(graph, FALSE); fprintf(stdout, "%s\n", msg_buffer); fflush(stdout); crm_free(msg_buffer); return 0; } diff --git a/crm/pengine/utils.c b/crm/pengine/utils.c index a901787e2a..a1b8732fb6 100644 --- a/crm/pengine/utils.c +++ b/crm/pengine/utils.c @@ -1,1009 +1,998 @@ #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/util.h> #include <glib.h> #include <pengine.h> #include <pe_utils.h> void print_str_str(gpointer key, gpointer value, gpointer user_data); /* only for rsc_to_rsc constraints */ rsc_to_rsc_t * invert_constraint(rsc_to_rsc_t *constraint) { - pdebug("Inverting constraint"); + crm_verbose("Inverting constraint"); rsc_to_rsc_t *inverted_con = crm_malloc(sizeof(rsc_to_node_t)); inverted_con->id = crm_strdup(constraint->id); inverted_con->strength = constraint->strength; // swap the direction inverted_con->rsc_lh = constraint->rsc_rh; inverted_con->rsc_rh = constraint->rsc_lh; - pdebug_action( + crm_debug_action( print_rsc_to_rsc("Inverted constraint", inverted_con, FALSE) ); return inverted_con; } rsc_to_node_t * copy_constraint(rsc_to_node_t *constraint) { rsc_to_node_t *copied_con = crm_malloc(sizeof(rsc_to_node_t)); copied_con->id = crm_strdup(constraint->id); copied_con->rsc_lh = constraint->rsc_lh; copied_con->node_list_rh = constraint->node_list_rh; copied_con->modifier = constraint->modifier; copied_con->weight = constraint->weight; return copied_con; } /* are the contents of list1 and list2 equal */ /* nodes with weight < 0 are ignored */ gboolean node_list_eq(GSListPtr list1, GSListPtr list2) { GSListPtr result = NULL; if(g_slist_length(list1) != g_slist_length(list2)) { return FALSE; } // do stuff - cl_log(LOG_ERR, "Not yet implemented"); + crm_err("Not yet implemented"); return g_slist_length(result) != 0; } /* the intersection of list1 and list2 * when merging weights, nodes set to < 0 in either list will always * have their weight set to -1 in the result */ GSListPtr node_list_and(GSListPtr list1, GSListPtr list2) { GSListPtr result = NULL; int lpc = 0; for(lpc = 0; lpc < g_slist_length(list1); lpc++) { node_t *node = (node_t*)g_slist_nth_data(list1, lpc); node_t *new_node = NULL; node_t *other_node = find_list_node(list2, node->details->id); if(node == NULL || other_node == NULL) { continue; // merge node weights } else if(node->weight < 0 || other_node->weight < 0) { new_node = node_copy(node); new_node->weight = -1; } else { new_node = node_copy(node); new_node->weight = node->weight + other_node->weight; if(new_node->weight != 0) { new_node->weight = new_node->weight /2.0; } } result = g_slist_append(result, new_node); } return result; } node_t * find_list_node(GSListPtr list, const char *id) { int lpc = 0; slist_iter( thing, node_t, list, lpc, if(safe_str_eq(thing->details->id, id)) { return thing; } ); return NULL; } /* list1 - list2 */ GSListPtr node_list_minus(GSListPtr list1, GSListPtr list2) { GSListPtr result = NULL; int lpc = 0; slist_iter( node, node_t, list1, lpc, node_t *other_node = find_list_node(list2, node->details->id); if(node == NULL || other_node != NULL) { continue; } node_t *new_node = node_copy(node); result = g_slist_append(result, new_node); ); - pdebug("Minus result len: %d", + crm_verbose("Minus result len: %d", g_slist_length(result)); return result; } /* list1 + list2 - (intersection of list1 and list2) */ GSListPtr node_list_xor(GSListPtr list1, GSListPtr list2) { GSListPtr result = NULL; int lpc = 0; slist_iter( node, node_t, list1, lpc, node_t *other_node = (node_t*)find_list_node(list2, node->details->id); if(node == NULL || other_node != NULL) { continue; } node_t *new_node = node_copy(node); result = g_slist_append(result, new_node); ); slist_iter( node, node_t, list1, lpc, node_t *other_node = (node_t*)find_list_node(list1, node->details->id); if(node == NULL || other_node != NULL) { continue; } node_t *new_node = node_copy(node); result = g_slist_append(result, new_node); ); - pdebug("Xor result len: %d", g_slist_length(result)); + crm_verbose("Xor result len: %d", g_slist_length(result)); return result; } GSListPtr node_list_dup(GSListPtr list1) { GSListPtr result = NULL; int lpc = 0; slist_iter( this_node, node_t, list1, lpc, node_t *new_node = node_copy(this_node); if(new_node != NULL) { result = g_slist_append(result, new_node); } ); return result; } node_t * node_copy(node_t *this_node) { if(this_node == NULL) { print_node("Failed copy of", this_node, TRUE); return NULL; } node_t *new_node = crm_malloc(sizeof(node_t)); new_node->weight = this_node->weight; new_node->fixed = this_node->fixed; new_node->details = this_node->details; return new_node; } static int color_id = 0; /* * Create a new color with the contents of "nodes" as the list of * possible nodes that resources with this color can be run on. * * Typically, when creating a color you will provide the node list from * the resource you will first assign the color to. * * If "colors" != NULL, it will be added to that list * If "resources" != NULL, it will be added to every provisional resource * in that list */ color_t * create_color(GSListPtr *colors, GSListPtr nodes, GSListPtr resources) { color_t *new_color = crm_malloc(sizeof(color_t)); new_color->id = color_id++; new_color->local_weight = 1.0; new_color->details = crm_malloc(sizeof(struct color_shared_s)); new_color->details->id = new_color->id; new_color->details->chosen_node = NULL; new_color->details->candidate_nodes = node_list_dup(nodes); - pdebug_action(print_color("Created color", new_color, TRUE)); + crm_debug_action(print_color("Created color", new_color, TRUE)); if(colors != NULL) { *colors = g_slist_append(*colors, new_color); } if(resources != NULL) { /* Add any new color to the list of candidate_colors for * resources that havent been decided yet */ int lpc; slist_iter( rsc, resource_t, resources, lpc, if(rsc->provisional && rsc->runnable) { color_t *color_copy = (color_t *) cl_malloc(sizeof(color_t)); color_copy->id = new_color->id; color_copy->details = new_color->details; color_copy->local_weight = 1.0; rsc->candidate_colors = g_slist_append(rsc->candidate_colors, color_copy); } ); } return new_color; } /* * Remove any nodes with a -ve weight */ gboolean filter_nodes(resource_t *rsc) { int lpc2 = 0; - pdebug_action(print_resource("Filtering nodes for", rsc, FALSE)); + crm_debug_action(print_resource("Filtering nodes for", rsc, FALSE)); slist_iter( node, node_t, rsc->allowed_nodes, lpc2, if(node == NULL) { - cl_log(LOG_ERR, "Invalid NULL node"); + crm_err("Invalid NULL node"); } else if(node->weight < 0.0 || node->details->online == FALSE || node->details->type == node_ping) { - pdebug_action(print_node("Removing", node, FALSE)); + crm_debug_action(print_node("Removing", node, FALSE)); rsc->allowed_nodes = g_slist_remove(rsc->allowed_nodes,node); crm_free(node); lpc2--; } ); return TRUE; } resource_t * pe_find_resource(GSListPtr rsc_list, const char *id_rh) { int lpc = 0; for(lpc = 0; lpc < g_slist_length(rsc_list); lpc++) { resource_t *rsc = g_slist_nth_data(rsc_list, lpc); if(rsc != NULL && safe_str_eq(rsc->id, id_rh)){ return rsc; } } // error return NULL; } node_t * pe_find_node(GSListPtr nodes, const char *id) { int lpc = 0; for(lpc = 0; lpc < g_slist_length(nodes); lpc++) { node_t *node = g_slist_nth_data(nodes, lpc); if(safe_str_eq(node->details->id, id)) { return node; } } // error return NULL; } gint gslist_color_compare(gconstpointer a, gconstpointer b); color_t * find_color(GSListPtr candidate_colors, color_t *other_color) { GSListPtr tmp = g_slist_find_custom(candidate_colors, other_color, gslist_color_compare); if(tmp != NULL) { return (color_t *)tmp->data; } return NULL; } gint gslist_color_compare(gconstpointer a, gconstpointer b) { const color_t *color_a = (const color_t*)a; const color_t *color_b = (const color_t*)b; if(a == b) { return 0; } else if(a == NULL || b == NULL) { return 1; } else if(color_a->id == color_b->id) { return 0; } return 1; } gint sort_rsc_priority(gconstpointer a, gconstpointer b) { const resource_t *resource1 = (const resource_t*)a; const resource_t *resource2 = (const resource_t*)b; if(a == NULL) return 1; if(b == NULL) return -1; if(resource1->priority > resource2->priority) return -1; if(resource1->priority < resource2->priority) return 1; return 0; } gint sort_cons_strength(gconstpointer a, gconstpointer b) { const rsc_to_rsc_t *rsc_constraint1 = (const rsc_to_rsc_t*)a; const rsc_to_rsc_t *rsc_constraint2 = (const rsc_to_rsc_t*)b; if(a == NULL) return 1; if(b == NULL) return -1; if(rsc_constraint1->strength > rsc_constraint2->strength) return 1; if(rsc_constraint1->strength < rsc_constraint2->strength) return -1; return 0; } gint sort_color_weight(gconstpointer a, gconstpointer b) { const color_t *color1 = (const color_t*)a; const color_t *color2 = (const color_t*)b; if(a == NULL) return 1; if(b == NULL) return -1; if(color1->local_weight > color2->local_weight) return -1; if(color1->local_weight < color2->local_weight) return 1; return 0; } gint sort_node_weight(gconstpointer a, gconstpointer b) { const node_t *node1 = (const node_t*)a; const node_t *node2 = (const node_t*)b; if(a == NULL) return 1; if(b == NULL) return -1; if(node1->weight > node2->weight) return -1; if(node1->weight < node2->weight) return 1; return 0; } action_t * action_new(int id, resource_t *rsc, enum action_tasks task) { action_t *action = (action_t*)crm_malloc(sizeof(action_t)); action->id = id; action->rsc = rsc; action->task = task; action->node = NULL; // fill node in later action->actions_before = NULL; action->actions_after = NULL; action->failure_is_fatal = TRUE; action->discard = FALSE; action->runnable = FALSE; action->processed = FALSE; action->optional = FALSE; action->seen_count = 0; return action; } const char * contype2text(enum con_type type) { const char *result = "<unknown>"; switch(type) { case type_none: result = "none"; break; case rsc_to_rsc: result = "rsc_to_rsc"; break; case rsc_to_node: result = "rsc_to_node"; break; case rsc_to_attr: result = "rsc_to_attr"; break; case base_weight: result = "base_weight"; break; } return result; }; const char * strength2text(enum con_strength strength) { const char *result = "<unknown>"; switch(strength) { case ignore: result = "ignore"; break; case must: result = XML_STRENGTH_VAL_MUST; break; case should: result = XML_STRENGTH_VAL_SHOULD; break; case should_not: result = XML_STRENGTH_VAL_SHOULDNOT; break; case must_not: result = XML_STRENGTH_VAL_MUSTNOT; break; case startstop: result = "start/stop"; break; } return result; }; const char * modifier2text(enum con_modifier modifier) { const char *result = "<unknown>"; switch(modifier) { case modifier_none: result = "modifier_none"; break; case set: result = "set"; break; case inc: result = "inc"; break; case dec: result = "dec"; break; } return result; }; const char * task2text(enum action_tasks task) { const char *result = "<unknown>"; switch(task) { case no_action: result = "no_action"; break; case stop_rsc: result = "stop"; break; case start_rsc: result = "start"; break; case shutdown_crm: result = "shutdown_crm"; break; case stonith_op: result = "stonith"; break; } return result; }; void print_node(const char *pre_text, node_t *node, gboolean details) { if(node == NULL) { - cl_log(LOG_DEBUG, "%s%s%s: <NULL>", + crm_debug("%s%s: <NULL>", pre_text==NULL?"":pre_text, - pre_text==NULL?"":": ", - __FUNCTION__); + pre_text==NULL?"":": "); return; } - cl_log(LOG_DEBUG, "%s%s%sNode %s: (weight=%f, fixed=%s)", + crm_debug("%s%s%sNode %s: (weight=%f, fixed=%s)", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", node->details==NULL?"error ":node->details->online?"":"Unavailable/Unclean ", node->details->id, node->weight, node->fixed?"True":"False"); if(details && node->details != NULL) { char *mutable = crm_strdup("\t\t"); - cl_log(LOG_DEBUG, "\t\t===Node Attributes"); + crm_debug("\t\t===Node Attributes"); g_hash_table_foreach(node->details->attrs, print_str_str, mutable); crm_free(mutable); } if(details) { int lpc = 0; - cl_log(LOG_DEBUG, "\t\t===Node Attributes"); + crm_debug("\t\t===Node Attributes"); slist_iter( rsc, resource_t, node->details->running_rsc, lpc, print_resource("\t\t", rsc, FALSE); ); } }; /* * Used by the HashTable for-loop */ void print_str_str(gpointer key, gpointer value, gpointer user_data) { - cl_log(LOG_DEBUG, "%s%s %s ==> %s", + crm_debug("%s%s %s ==> %s", user_data==NULL?"":(char*)user_data, user_data==NULL?"":": ", (char*)key, (char*)value); } void print_color_details(const char *pre_text, struct color_shared_s *color, gboolean details) { if(color == NULL) { - cl_log(LOG_DEBUG, "%s%s%s: <NULL>", + crm_debug("%s%s: <NULL>", pre_text==NULL?"":pre_text, - pre_text==NULL?"":": ", - __FUNCTION__); + pre_text==NULL?"":": "); return; } - cl_log(LOG_DEBUG, "%s%sColor %d: node=%s (from %d candidates)", + crm_debug("%s%sColor %d: node=%s (from %d candidates)", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", color->id, color->chosen_node==NULL?"<unset>":color->chosen_node->details->id, g_slist_length(color->candidate_nodes)); if(details) { int lpc = 0; slist_iter(node, node_t, color->candidate_nodes, lpc, print_node("\t", node, FALSE)); } } void print_color(const char *pre_text, color_t *color, gboolean details) { if(color == NULL) { - cl_log(LOG_DEBUG, "%s%s%s: <NULL>", + crm_debug("%s%s: <NULL>", pre_text==NULL?"":pre_text, - pre_text==NULL?"":": ", - __FUNCTION__); + pre_text==NULL?"":": "); return; } - cl_log(LOG_DEBUG, "%s%sColor %d: (weight=%f, node=%s, possible=%d)", + crm_debug("%s%sColor %d: (weight=%f, node=%s, possible=%d)", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", color->id, color->local_weight, color->details->chosen_node==NULL?"<unset>":color->details->chosen_node->details->id, g_slist_length(color->details->candidate_nodes)); if(details) { print_color_details("\t", color->details, details); } } void print_rsc_to_node(const char *pre_text, rsc_to_node_t *cons, gboolean details) { if(cons == NULL) { - cl_log(LOG_DEBUG, "%s%s%s: <NULL>", + crm_debug("%s%s: <NULL>", pre_text==NULL?"":pre_text, - pre_text==NULL?"":": ", - __FUNCTION__); + pre_text==NULL?"":": "); return; } - cl_log(LOG_DEBUG, "%s%s%s Constraint %s (%p):", + crm_debug("%s%s%s Constraint %s (%p):", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", "rsc_to_node", cons->id, cons); if(details == FALSE) { - cl_log(LOG_DEBUG, - "\t%s --> %s, %f (node placement rule)", + crm_debug("\t%s --> %s, %f (node placement rule)", cons->rsc_lh->id, modifier2text(cons->modifier), cons->weight); int lpc = 0; slist_iter( node, node_t, cons->node_list_rh, lpc, print_node("\t\t-->", node, FALSE) ); } } void print_rsc_to_rsc(const char *pre_text, rsc_to_rsc_t *cons, gboolean details) { if(cons == NULL) { - cl_log(LOG_DEBUG, "%s%s%s: <NULL>", + crm_debug("%s%s: <NULL>", pre_text==NULL?"":pre_text, - pre_text==NULL?"":": ", - __FUNCTION__); + pre_text==NULL?"":": "); return; } - cl_log(LOG_DEBUG, "%s%s%s Constraint %s (%p):", + crm_debug("%s%s%s Constraint %s (%p):", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", "rsc_to_rsc", cons->id, cons); if(details == FALSE) { - cl_log(LOG_DEBUG, - "\t%s --> %s, %s", - cons->rsc_lh==NULL?"null":cons->rsc_lh->id, - cons->rsc_rh==NULL?"null":cons->rsc_rh->id, - strength2text(cons->strength)); + crm_debug("\t%s --> %s, %s", + cons->rsc_lh==NULL?"null":cons->rsc_lh->id, + cons->rsc_rh==NULL?"null":cons->rsc_rh->id, + strength2text(cons->strength)); } } void print_resource(const char *pre_text, resource_t *rsc, gboolean details) { if(rsc == NULL) { - cl_log(LOG_DEBUG, "%s%s%s: <NULL>", + crm_debug("%s%s: <NULL>", pre_text==NULL?"":pre_text, - pre_text==NULL?"":": ", - __FUNCTION__); + pre_text==NULL?"":": "); return; } - cl_log(LOG_DEBUG, - "%s%s%s%sResource %s: (priority=%f, color=%d, now=%s)", + crm_debug("%s%s%s%sResource %s: (priority=%f, color=%d, now=%s)", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", rsc->provisional?"Provisional ":"", rsc->runnable?"":"(Non-Startable) ", rsc->id, (double)rsc->priority, safe_val3(-1, rsc, color, id), safe_val4(NULL, rsc, cur_node, details, id)); - cl_log(LOG_DEBUG, - "\t%d candidate colors, %d allowed nodes, %d rsc_cons and %d node_cons", + crm_debug("\t%d candidate colors, %d allowed nodes, %d rsc_cons and %d node_cons", g_slist_length(rsc->candidate_colors), g_slist_length(rsc->allowed_nodes), g_slist_length(rsc->rsc_cons), g_slist_length(rsc->node_cons)); if(details) { int lpc = 0; - cl_log(LOG_DEBUG, "\t=== Actions"); + crm_debug("\t=== Actions"); print_action("\tStop: ", rsc->stop, FALSE); print_action("\tStart: ", rsc->start, FALSE); - cl_log(LOG_DEBUG, "\t=== Colors"); + crm_debug("\t=== Colors"); slist_iter( color, color_t, rsc->candidate_colors, lpc, print_color("\t", color, FALSE) ); - cl_log(LOG_DEBUG, "\t=== Allowed Nodes"); + crm_debug("\t=== Allowed Nodes"); slist_iter( node, node_t, rsc->allowed_nodes, lpc, print_node("\t", node, FALSE); ); } } void print_action(const char *pre_text, action_t *action, gboolean details) { if(action == NULL) { - cl_log(LOG_DEBUG, "%s%s%s: <NULL>", + crm_debug("%s%s: <NULL>", pre_text==NULL?"":pre_text, - pre_text==NULL?"":": ", - __FUNCTION__); + pre_text==NULL?"":": "); return; } switch(action->task) { case stonith_op: case shutdown_crm: - cl_log(LOG_DEBUG, "%s%s%sAction %d: %s @ %s", + crm_debug("%s%s%sAction %d: %s @ %s", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", action->discard?"Discarded ":action->optional?"Optional ":action->runnable?action->processed?"":"(Provisional) ":"!!Non-Startable!! ", action->id, task2text(action->task), safe_val4(NULL, action, node, details, id)); break; default: - cl_log(LOG_DEBUG, "%s%s%sAction %d: %s %s @ %s", + crm_debug("%s%s%sAction %d: %s %s @ %s", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", action->optional?"Optional ":action->runnable?action->processed?"":"(Provisional) ":"!!Non-Startable!! ", action->id, task2text(action->task), safe_val3(NULL, action, rsc, id), safe_val4(NULL, action, node, details, id)); break; } if(details) { int lpc = 0; #if 1 - cl_log(LOG_DEBUG, "\t\t====== Preceeding Actions"); + crm_debug("\t\t====== Preceeding Actions"); slist_iter( other, action_wrapper_t, action->actions_before, lpc, print_action("\t\t", other->action, FALSE); ); - cl_log(LOG_DEBUG, "\t\t====== Subsequent Actions"); + crm_debug("\t\t====== Subsequent Actions"); slist_iter( other, action_wrapper_t, action->actions_after, lpc, print_action("\t\t", other->action, FALSE); ); #else - cl_log(LOG_DEBUG, "\t\t====== Subsequent Actions"); + crm_debug("\t\t====== Subsequent Actions"); slist_iter( other, action_wrapper_t, action->actions_after, lpc, print_action("\t\t", other->action, FALSE); ); #endif - cl_log(LOG_DEBUG, "\t\t====== End"); + crm_debug("\t\t====== End"); } else { - cl_log(LOG_DEBUG, "\t\t(seen=%d, before=%d, after=%d)", + crm_debug("\t\t(seen=%d, before=%d, after=%d)", action->seen_count, g_slist_length(action->actions_before), g_slist_length(action->actions_after)); } } xmlNodePtr action2xml(action_t *action) { xmlNodePtr action_xml = NULL; if(action == NULL) { return NULL; } switch(action->task) { case stonith_op: action_xml = create_xml_node(NULL, "pseduo_event"); break; case shutdown_crm: action_xml = create_xml_node(NULL, "crm_event"); break; default: action_xml = create_xml_node(NULL, "rsc_op"); add_node_copy(action_xml, action->rsc->xml); break; } set_xml_property_copy(action_xml, XML_LRM_ATTR_TARGET, safe_val4(NULL, action, node, details, id)); set_xml_property_copy(action_xml, XML_ATTR_ID, crm_itoa(action->id)); set_xml_property_copy(action_xml, XML_LRM_ATTR_RUNNABLE, action->runnable?XML_BOOLEAN_TRUE:XML_BOOLEAN_FALSE); set_xml_property_copy(action_xml, XML_LRM_ATTR_OPTIONAL, action->optional?XML_BOOLEAN_TRUE:XML_BOOLEAN_FALSE); set_xml_property_copy(action_xml, XML_LRM_ATTR_TASK, task2text(action->task)); set_xml_property_copy(action_xml, XML_LRM_ATTR_DISCARD, action->discard?XML_BOOLEAN_TRUE:XML_BOOLEAN_FALSE); set_xml_property_copy(action_xml, "allow_fail", action->failure_is_fatal?XML_BOOLEAN_FALSE:XML_BOOLEAN_TRUE); return action_xml; } gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data); void pe_free_nodes(GSListPtr nodes) { while(nodes != NULL){ GSListPtr list_item = nodes; node_t *node = (node_t*)list_item->data; struct node_shared_s *details = node->details; nodes = nodes->next; if(details != NULL) { crm_free(details->id); g_hash_table_foreach_remove(details->attrs, ghash_free_str_str, NULL); crm_free(details); } crm_free(node); } g_slist_free(nodes); } gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data) { crm_free(key); crm_free(value); return TRUE; } void pe_free_colors(GSListPtr colors) { while(colors != NULL) { GSListPtr list_item = colors; color_t *color = (color_t *)list_item->data; struct color_shared_s *details = color->details; colors = colors->next; if(details != NULL) { pe_free_shallow(details->candidate_nodes); crm_free(details->chosen_node); crm_free(details); } crm_free(color); } g_slist_free(colors); } void pe_free_shallow(GSListPtr alist) { pe_free_shallow_adv(alist, TRUE); } void pe_free_shallow_adv(GSListPtr alist, gboolean with_data) { GSListPtr item; GSListPtr item_next = alist; while(item_next != NULL) { item = item_next; item_next = item_next->next; if(with_data) { crm_free(item->data); } item->data = NULL; item->next = NULL; g_slist_free(item); } } void pe_free_resources(GSListPtr resources) { volatile GSListPtr list_item = NULL; resource_t *rsc = NULL; while(resources != NULL) { list_item = resources; rsc = (resource_t *)list_item->data; resources = resources->next; crm_free(rsc->id); -// pdebug("color"); +// crm_verbose("color"); // crm_free(rsc->color); int lpc; slist_iter(clr, color_t, rsc->candidate_colors, lpc, print_color("deleting", clr, FALSE)); // pe_free_shallow(rsc->candidate_colors); pe_free_shallow(rsc->allowed_nodes); while(rsc->rsc_cons) { pe_free_rsc_to_rsc((rsc_to_rsc_t*)rsc->rsc_cons->data); rsc->rsc_cons = rsc->rsc_cons->next; } g_slist_free(rsc->rsc_cons); crm_free(rsc); } g_slist_free(resources); } void pe_free_actions(GSListPtr actions) { while(actions != NULL) { GSListPtr list_item = actions; action_t *action = (action_t *)list_item->data; actions = actions->next; pe_free_shallow(action->actions_before); // action_warpper_t* pe_free_shallow(action->actions_after); // action_warpper_t* action->actions_before = NULL; action->actions_after = NULL; crm_free(action); } g_slist_free(actions); } void pe_free_rsc_to_rsc(rsc_to_rsc_t *cons) { if(cons != NULL) { crm_free(cons->id); crm_free(cons); } } void pe_free_rsc_to_node(rsc_to_node_t *cons) { if(cons != NULL) { crm_free(cons->id); pe_free_shallow(cons->node_list_rh); // node_t* crm_free(cons); } } diff --git a/crm/tengine/tengine.c b/crm/tengine/tengine.c index a606bf3cf2..49644aec37 100644 --- a/crm/tengine/tengine.c +++ b/crm/tengine/tengine.c @@ -1,703 +1,684 @@ -/* $Id: tengine.c,v 1.14 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: tengine.c,v 1.15 2004/06/02 15:25:12 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 */ #include <crm/crm.h> #include <crm/cib.h> #include <crm/msg_xml.h> #include <crm/common/msg.h> #include <crm/common/xml.h> #include <tengine.h> GSListPtr graph = NULL; IPC_Channel *crm_ch = NULL; typedef struct action_list_s { gboolean force; int index; int index_max; GSListPtr actions; } action_list_t; void print_state(void); gboolean initialize_graph(void); gboolean unpack_graph(xmlNodePtr xml_graph); gboolean extract_event(xmlNodePtr msg); gboolean initiate_transition(void); gboolean initiate_action(action_list_t *list); gboolean process_graph_event(const char *event_node, const char *event_rsc, const char *event_action, const char *event_status, const char *event_rc); void send_success(void); void send_abort(xmlNodePtr msg); gboolean initialize_graph(void) { while(g_slist_length(graph) > 0) { action_list_t *action_list = g_slist_nth_data(graph, 0); while(g_slist_length(action_list->actions) > 0) { xmlNodePtr action = g_slist_nth_data(action_list->actions, 0); action_list->actions = g_slist_remove(action_list->actions, action); free_xml(action); } graph = g_slist_remove(graph, action_list); crm_free(action_list); } graph = NULL; return TRUE; } gboolean unpack_graph(xmlNodePtr xml_graph) { /* <transition_graph> <actions id="0"> <rsc_op id="5" runnable=XML_BOOLEAN_FALSE optional=XML_BOOLEAN_TRUE task="stop"> <resource id="rsc3" priority="3.0"/> </rsc_op> */ xmlNodePtr xml_action_list = xml_graph?xml_graph->children:NULL; if(xml_action_list == NULL) { // nothing to do return FALSE; } while(xml_action_list != NULL) { xmlNodePtr xml_obj = xml_action_list; xmlNodePtr xml_action = xml_obj->children; action_list_t *action_list = (action_list_t*) crm_malloc(sizeof(action_list_t)); xml_action_list = xml_action_list->next; action_list->force = FALSE; action_list->index = -1; action_list->index_max = 0; action_list->actions = NULL; while(xml_action != NULL) { xmlNodePtr action = copy_xml_node_recursive(xml_action); action_list->actions = g_slist_append(action_list->actions, action); action_list->index_max++; xml_action = xml_action->next; } graph = g_slist_append(graph, action_list); } return TRUE; } gboolean extract_event(xmlNodePtr msg) { gboolean abort = FALSE; xmlNodePtr iter = NULL; const char *section = NULL; const char *event_action = NULL; const char *event_node = NULL; const char *event_rsc = NULL; const char *event_status = NULL; const char *event_rc = NULL; /* [cib fragment] ... <status> <node_state id="node1" state=CRMD_STATE_ACTIVE exp_state="active"> <lrm> <lrm_resources> <rsc_state id="" rsc_id="rsc4" node_id="node1" rsc_state="stopped"/> */ iter = find_xml_node(msg, XML_TAG_FRAGMENT); section = xmlGetProp(iter, XML_ATTR_SECTION); if(safe_str_neq(section, XML_CIB_TAG_STATUS)) { // these too are never expected return FALSE; } iter = find_xml_node(iter, XML_TAG_CIB); iter = get_object_root(XML_CIB_TAG_STATUS, iter); iter = iter->children; while(abort == FALSE && iter != NULL) { xmlNodePtr node_state = iter; xmlNodePtr child = iter->children; const char *state = xmlGetProp( node_state, XML_CIB_ATTR_JOINSTATE); iter = iter->next; if(xmlGetProp(node_state, XML_CIB_ATTR_SHUTDOWN) != NULL || xmlGetProp(node_state, XML_CIB_ATTR_STONITH) != NULL) { abort = TRUE; } else if(state != NULL && child == NULL) { /* node state update, * possibly from a shutdown we requested */ event_status = state; event_node = xmlGetProp(node_state, XML_ATTR_ID); if(safe_str_eq(event_status, CRMD_JOINSTATE_DOWN)) { event_action = XML_CIB_ATTR_SHUTDOWN; } else { // never expected... yet. STONITH? event_action = "startup"; } abort = !process_graph_event(event_node, event_rsc, event_action, event_status, event_rc); } else if(state == NULL && child != NULL) { 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; } while(abort == FALSE && child != NULL) { event_action = xmlGetProp( child, XML_LRM_ATTR_LASTOP); event_node = xmlGetProp( child, XML_LRM_ATTR_TARGET); event_rsc = xmlGetProp( child, XML_ATTR_ID); event_status = xmlGetProp( child, XML_LRM_ATTR_OPSTATE); event_rc = xmlGetProp( child, XML_LRM_ATTR_OPCODE); abort = !process_graph_event(event_node, event_rsc, event_action, event_status, event_rc); 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 */ abort = TRUE; } else { /* ignore */ } } return !abort; } gboolean process_graph_event(const char *event_node, const char *event_rsc, const char *event_action, const char *event_status, const char *event_rc) { int lpc; xmlNodePtr action = NULL; // <rsc_op> or <crm_event> xmlNodePtr next_action = NULL; action_list_t *matched_action_list = NULL; // Find the action corresponding to this event slist_iter( action_list, action_list_t, graph, lpc, action = g_slist_nth_data(action_list->actions, action_list->index); if(action == NULL) { continue; } /* <rsc_op id= runnable= optional= task= on_node= > <resource id="rsc3" priority="3.0"/> </rsc_op> */ const char *this_action = xmlGetProp( action, XML_LRM_ATTR_TASK); const char *this_node = xmlGetProp( action, XML_LRM_ATTR_TARGET); const char *this_rsc = xmlGetProp( action->children, XML_ATTR_ID); if(safe_str_neq(this_node, event_node)) { continue; } else if(safe_str_neq(this_action, event_action)) { continue; } else if(safe_str_eq(action->name, "rsc_op") && safe_str_eq(this_rsc, event_rsc)) { matched_action_list = action_list; } else if(safe_str_eq(action->name, "crm_event")) { matched_action_list = action_list; } ); if(matched_action_list == NULL) { // unexpected event, trigger a pe-recompute // possibly do this only for certain types of actions - cl_log(LOG_ERR, - "Unexpected event... matched action list was NULL"); + crm_err("Unexpected event... matched action list was NULL"); return FALSE; } // how do we distinguish action failure? if(safe_str_neq(event_rc, "0")){ if(safe_str_neq((const char*)xmlGetProp(action, "allow_fail"), XML_BOOLEAN_TRUE)) { - cl_log(LOG_ERR, - "Action %s to %s on %s resulted in failure..." + crm_err("Action %s to %s on %s resulted in failure..." " aborting transition.", event_action, event_rsc, event_node); return FALSE; } } while(matched_action_list->index <= matched_action_list->index_max) { gboolean passed = FALSE; next_action = g_slist_nth_data(matched_action_list->actions, matched_action_list->index); passed = initiate_action(matched_action_list); if(passed == FALSE) { - cl_log(LOG_ERR, - "Initiation of next event failed"); + crm_err("Initiation of next event failed"); return FALSE; } else if(matched_action_list->index > matched_action_list->index_max) { /* last action in that list, check if there are * anymore actions at all */ slist_iter( action_list, action_list_t, graph, lpc, if(action_list->index <= action_list->index_max){ return TRUE; } ); } else { return TRUE; } } - cl_log(LOG_INFO, "Transition complete..."); + crm_info("Transition complete..."); send_success(); return TRUE; } gboolean initiate_transition(void) { int lpc; gboolean anything = FALSE; FNIN(); slist_iter( action_list, action_list_t, graph, lpc, if(initiate_action(action_list) && action_list->index <= action_list->index_max) { anything = TRUE; } ); FNRET(anything); } gboolean initiate_action(action_list_t *list) { gboolean is_optional = TRUE; xmlNodePtr xml_action = NULL; const char *on_node = NULL; const char *id = NULL; const char *runnable = NULL; const char *optional = NULL; const char *task = NULL; const char *discard = NULL; while(TRUE) { list->index++; xml_action = g_slist_nth_data(list->actions, list->index); if(xml_action == NULL) { - cl_log(LOG_INFO, "No tasks left on this list"); + crm_info("No tasks left on this list"); list->index = list->index_max + 1; return TRUE; } discard = xmlGetProp(xml_action, XML_LRM_ATTR_DISCARD); on_node = xmlGetProp(xml_action, XML_LRM_ATTR_TARGET); id = xmlGetProp(xml_action, XML_ATTR_ID); runnable = xmlGetProp(xml_action, XML_LRM_ATTR_RUNNABLE); optional = xmlGetProp(xml_action, XML_LRM_ATTR_OPTIONAL); task = xmlGetProp(xml_action, XML_LRM_ATTR_TASK); if(safe_str_eq(discard, XML_BOOLEAN_TRUE)) { - cl_log(LOG_INFO, - "Skipping discarded rsc-op (%s): %s %s on %s", - id, task, - xmlGetProp(xml_action->children, XML_ATTR_ID), - on_node); + crm_info("Skipping discarded rsc-op (%s): %s %s on %s", + id, task, + xmlGetProp(xml_action->children, XML_ATTR_ID), + on_node); continue; } if(safe_str_neq(optional, XML_BOOLEAN_TRUE)) { is_optional = FALSE; } list->force = list->force || !is_optional; - /* - cl_log(LOG_DEBUG, - "Processing action %s (id=%s) on %s", + crm_verbose("Processing action %s (id=%s) on %s", task, id, on_node); - */ if(list->force && is_optional) { - cl_log(LOG_INFO, - "Forcing execution of otherwise optional task " - "due to a dependancy on a previous action"); + crm_info("Forcing execution of otherwise optional task " + "due to a dependancy on a previous action"); } if(list->force == FALSE && is_optional) { if(safe_str_eq(xml_action->name, "rsc_op")){ - cl_log(LOG_INFO, - "Skipping optional rsc-op (%s):" - " %s %s on %s", - id, task, - xmlGetProp(xml_action->children, - XML_ATTR_ID), + crm_info("Skipping optional rsc-op (%s):" + " %s %s on %s", + id, task, + xmlGetProp(xml_action->children, + XML_ATTR_ID), on_node); } else { - cl_log(LOG_INFO, - "Skipping optional command" - " %s (id=%s) on %s", - task, id, on_node); + crm_info("Skipping optional command" + " %s (id=%s) on %s", + task, id, on_node); } } else if(safe_str_eq(runnable, XML_BOOLEAN_FALSE)) { - cl_log(LOG_ERR, - "Terminated transition on un-runnable command:" - " %s (id=%s) on %s", - task, id, on_node); + crm_err("Terminated transition on un-runnable command:" + " %s (id=%s) on %s", + task, id, on_node); return FALSE; } else if(id == NULL || strlen(id) == 0 || on_node == NULL || strlen(on_node) == 0 || task == NULL || strlen(task) == 0) { // error - cl_log(LOG_ERR, - "Failed on corrupted command: %s (id=%s) on %s", - task, id, on_node); + crm_err("Failed on corrupted command: %s (id=%s) on %s", + task, id, on_node); return FALSE; } else if(safe_str_eq(xml_action->name, "pseduo_event")){ if(safe_str_eq(task, "stonith")){ - cl_log(LOG_INFO, - "Executing %s (%s) of node %s", - task, id, on_node); + crm_info("Executing %s (%s) of node %s", + task, id, on_node); /* translate this into a stonith op by deisgnated node may need the CIB to determine who is running the stonith resource for this node more liekly, have the pengine find and supply that info */ } else { - cl_log(LOG_ERR, - "Failed on unsupported %s: " - "%s (id=%s) on %s", - xml_action->name, task, id, on_node); + crm_err("Failed on unsupported %s: " + "%s (id=%s) on %s", + xml_action->name, task, id, on_node); return FALSE; } } else if(safe_str_eq(xml_action->name, "crm_event")){ /* <crm_msg op=XML_LRM_ATTR_TASK to=XML_RES_ATTR_TARGET> */ - cl_log(LOG_INFO, - "Executing crm-event (%s): %s on %s", - id, task, on_node); + crm_info("Executing crm-event (%s): %s on %s", + id, task, on_node); #ifndef TESTING xmlNodePtr options = create_xml_node( NULL, XML_TAG_OPTIONS); set_xml_property_copy(options, XML_ATTR_OP, task); send_ipc_request(crm_ch, options, NULL, on_node, CRM_SYSTEM_CRMD, CRM_SYSTEM_TENGINE, NULL, NULL); free_xml(options); return TRUE; #endif } else if(safe_str_eq(xml_action->name, "rsc_op")){ - cl_log(LOG_INFO, - "Executing rsc-op (%s): %s %s on %s", - id, task, - xmlGetProp(xml_action->children, XML_ATTR_ID), - on_node); + crm_info("Executing rsc-op (%s): %s %s on %s", + id, task, + xmlGetProp(xml_action->children, XML_ATTR_ID), + on_node); #ifndef TESTING /* <msg_data> <rsc_op id="operation number" on_node="" task=""> <resource>...</resource> */ xmlNodePtr options = create_xml_node( NULL, XML_TAG_OPTIONS); xmlNodePtr data = create_xml_node(NULL, "msg_data"); xmlNodePtr rsc_op = create_xml_node(data, "rsc_op"); set_xml_property_copy(options, XML_ATTR_OP, "rsc_op"); set_xml_property_copy(rsc_op, XML_ATTR_ID, id); set_xml_property_copy( rsc_op, XML_LRM_ATTR_TASK, task); set_xml_property_copy( rsc_op, XML_LRM_ATTR_TARGET, on_node); add_node_copy(rsc_op, xml_action->children); send_ipc_request(crm_ch, options, data, on_node, "lrmd", CRM_SYSTEM_TENGINE, NULL, NULL); free_xml(options); free_xml(data); return TRUE; #endif } else { // error - cl_log(LOG_ERR, - "Failed on unsupported command type: " - "%s, %s (id=%s) on %s", - xml_action->name, task, id, on_node); + crm_err("Failed on unsupported command type: " + "%s, %s (id=%s) on %s", + xml_action->name, task, id, on_node); return FALSE; } } return FALSE; } FILE *msg_te_strm = NULL; gboolean process_te_message(xmlNodePtr msg, IPC_Channel *sender) { const char *op = get_xml_attr (msg, XML_TAG_OPTIONS, XML_ATTR_OP, FALSE); const char *sys_to = xmlGetProp(msg, XML_ATTR_SYSTO); const char *ref = xmlGetProp(msg, XML_ATTR_REFERENCE); - cl_log(LOG_DEBUG, "Processing %s (%s) message", op, ref); + crm_debug("Processing %s (%s) message", op, ref); #ifdef MSG_LOG if(msg_te_strm == NULL) { msg_te_strm = fopen("/tmp/te.log", "w"); } fprintf(msg_te_strm, "[Input %s]\t%s\n", op, dump_xml_node(msg, FALSE)); fflush(msg_te_strm); #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 - cl_log(LOG_INFO, - "Message was a response not a request. Discarding"); + crm_info("Message was a response not a request. Discarding"); return TRUE; } 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_DEBUG("Bad sys-to %s", sys_to); + crm_verbose("Bad sys-to %s", sys_to); return FALSE; } else if(strcmp(op, CRM_OP_TRANSITION) == 0) { - CRM_NOTE("Initializing graph..."); + crm_trace("Initializing graph..."); initialize_graph(); xmlNodePtr graph = find_xml_node(msg, "transition_graph"); - CRM_NOTE("Unpacking graph..."); + crm_trace("Unpacking graph..."); unpack_graph(graph); - CRM_NOTE("Initiating transition..."); + crm_trace("Initiating transition..."); if(initiate_transition() == FALSE) { // nothing to be done.. means we're done. - cl_log(LOG_INFO, "No actions to be taken..." + crm_info("No actions to be taken..." " transition compelte."); send_success(); } - CRM_NOTE("Processing complete..."); + crm_trace("Processing complete..."); } else if(strcmp(op, CRM_OP_EVENTCC) == 0) { const char *true_op = get_xml_attr (msg, XML_TAG_OPTIONS, XML_ATTR_TRUEOP, TRUE); if(true_op == NULL) { - cl_log(LOG_ERR, + crm_err( "Illegal update," " the original operation must be specified"); send_abort(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(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 { - cl_log(LOG_ERR, + crm_err( "Did not expect copy of action %s", op); } } else if(strcmp(op, CRM_OP_ABORT) == 0) { initialize_graph(); } else if(strcmp(op, CRM_OP_QUIT) == 0) { - cl_log(LOG_WARNING, "Received quit message, terminating"); + crm_err("Received quit message, terminating"); exit(0); } return TRUE; } void send_abort(xmlNodePtr msg) { xmlNodePtr options = create_xml_node(NULL, XML_TAG_OPTIONS); print_state(); - CRM_NOTE("Sending \"abort\" message"); + crm_trace("Sending \"abort\" message"); #ifdef MSG_LOG fprintf(msg_te_strm, "[Result ]\tTransition aborted\n"); fflush(msg_te_strm); #endif set_xml_property_copy(options, XML_ATTR_OP, CRM_OP_TEABORT); send_ipc_request(crm_ch, options, NULL, NULL, CRM_SYSTEM_DC, CRM_SYSTEM_TENGINE, NULL, NULL); free_xml(options); } void send_success(void) { xmlNodePtr options = create_xml_node(NULL, XML_TAG_OPTIONS); print_state(); - CRM_NOTE("Sending \"complete\" message"); + crm_trace("Sending \"complete\" message"); #ifdef MSG_LOG fprintf(msg_te_strm, "[Result ]\tTransition complete\n"); fflush(msg_te_strm); #endif set_xml_property_copy(options, XML_ATTR_OP, CRM_OP_TECOMPLETE); send_ipc_request(crm_ch, options, NULL, NULL, CRM_SYSTEM_DC, CRM_SYSTEM_TENGINE, NULL, NULL); free_xml(options); } void print_state(void) { int lpc = 0; - cl_log(LOG_DEBUG, "#!!#!!# Start Transitioner state"); + crm_debug("#!!#!!# Start Transitioner state"); if(graph == NULL) { - cl_log(LOG_DEBUG, "\tEmpty transition graph"); + crm_debug("\tEmpty transition graph"); } else { slist_iter( action_list, action_list_t, graph, lpc, - cl_log(LOG_DEBUG, - "\tAction set %d: %d of %d actions invoked", - lpc, action_list->index, - action_list->index_max); + crm_debug("\tAction set %d: %d of %d actions invoked", + lpc, action_list->index, + action_list->index_max); ); } - cl_log(LOG_DEBUG, "#!!#!!# End Transitioner state"); + crm_debug("#!!#!!# End Transitioner state"); } diff --git a/crm/tengine/tenginemain.c b/crm/tengine/tenginemain.c index c72b832f4a..05b9390907 100644 --- a/crm/tengine/tenginemain.c +++ b/crm/tengine/tenginemain.c @@ -1,225 +1,225 @@ -/* $Id: tenginemain.c,v 1.15 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: tenginemain.c,v 1.16 2004/06/02 15:25:12 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 */ #include <portability.h> #include <crm/crm.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <hb_api.h> #include <clplumbing/uids.h> #include <crm/common/ctrl.h> #include <crm/common/ipc.h> #include <tengine.h> #include <crm/dmalloc_wrapper.h> #define OPTARGS "skrh" #define PID_FILE WORKING_DIR "/transitioner.pid" #define DAEMON_LOG "/var/log/transitioner.log" #define DAEMON_DEBUG "/var/log/transitioner.debug" GMainLoop* mainloop = NULL; const char* crm_system_name = "transitioner"; void usage(const char* cmd, int exit_status); int init_start(void); void tengine_shutdown(int nsig); int main(int argc, char ** argv) { int req_restart = FALSE; int req_status = FALSE; int req_stop = FALSE; int argerr = 0; int flag; cl_log_set_entity(crm_system_name); cl_log_enable_stderr(TRUE); cl_log_set_facility(LOG_USER); if (0) { send_ipc_message(NULL, NULL); } while ((flag = getopt(argc, argv, OPTARGS)) != EOF) { switch(flag) { case 's': /* Status */ req_status = TRUE; break; case 'k': /* Stop (kill) */ req_stop = TRUE; break; case 'r': /* Restart */ req_restart = TRUE; break; case 'h': /* Help message */ usage(crm_system_name, LSB_EXIT_OK); break; default: ++argerr; break; } } if (optind > argc) { ++argerr; } if (argerr) { usage(crm_system_name,LSB_EXIT_GENERIC); } // read local config file if (req_status){ return init_status(PID_FILE, crm_system_name); } if (req_stop){ return init_stop(PID_FILE); } if (req_restart) { init_stop(PID_FILE); } return init_start(); } int init_start(void) { long pid; ll_cluster_t* hb_fd = NULL; int facility; #ifdef REALTIME_SUPPORT static int crm_realtime = 1; #endif if ((pid = get_running_pid(PID_FILE, NULL)) > 0) { - cl_log(LOG_CRIT, "already running: [pid %ld].", pid); + crm_crit("already running: [pid %ld].", pid); exit(LSB_EXIT_OK); } cl_log_set_logfile(DAEMON_LOG); -// if (crm_debug()) { +// if (crm_verbose()) { cl_log_set_debugfile(DAEMON_DEBUG); // } /* change the logging facility to the one used by heartbeat daemon */ hb_fd = ll_cluster_new("heartbeat"); - cl_log(LOG_INFO, "Switching to Heartbeat logger"); + crm_info("Switching to Heartbeat logger"); if ((facility = hb_fd->llc_ops->get_logfacility(hb_fd))>0) { cl_log_set_facility(facility); } - cl_log(LOG_INFO, "Register PID"); + crm_info("Register PID"); register_pid(PID_FILE, FALSE, tengine_shutdown); crm_ch = init_client_ipc_comms(CRM_SYSTEM_CRMD, subsystem_input_dispatch, (void*)process_te_message); if(crm_ch != NULL) { send_hello_message(crm_ch, "1234", CRM_SYSTEM_TENGINE, "0", "1"); /* Create the mainloop and run it... */ mainloop = g_main_new(FALSE); - cl_log(LOG_INFO, "Starting %s", crm_system_name); + crm_info("Starting %s", crm_system_name); #ifdef REALTIME_SUPPORT if (crm_realtime == 1){ cl_enable_realtime(); }else if (crm_realtime == 0){ cl_disable_realtime(); } cl_make_realtime(SCHED_RR, 5, 64, 64); #endif g_main_run(mainloop); } else { - cl_log(LOG_ERR, "Could not connect to the CRMd"); + crm_err("Could not connect to the CRMd"); } return_to_orig_privs(); if (unlink(PID_FILE) == 0) { - cl_log(LOG_INFO, "[%s] stopped", crm_system_name); + crm_info("[%s] stopped", crm_system_name); } if(crm_ch != NULL) return 0; return 1; } void usage(const char* cmd, int exit_status) { FILE* stream; stream = exit_status ? stderr : stdout; fprintf(stream, "usage: %s [-srkh]" "[-c configure file]\n", cmd); /* fprintf(stream, "\t-d\tsets debug level\n"); */ /* fprintf(stream, "\t-s\tgets daemon status\n"); */ /* fprintf(stream, "\t-r\trestarts daemon\n"); */ /* fprintf(stream, "\t-k\tstops daemon\n"); */ /* fprintf(stream, "\t-h\thelp message\n"); */ fflush(stream); exit(exit_status); } void tengine_shutdown(int nsig) { static int shuttingdown = 0; CL_SIGNAL(nsig, tengine_shutdown); if (!shuttingdown) { shuttingdown = 1; } if (mainloop != NULL && g_main_is_running(mainloop)) { g_main_quit(mainloop); }else{ exit(LSB_EXIT_OK); } } diff --git a/crm/tengine/ttest.c b/crm/tengine/ttest.c index d27c7f126c..663520af35 100644 --- a/crm/tengine/ttest.c +++ b/crm/tengine/ttest.c @@ -1,139 +1,139 @@ -/* $Id: ttest.c,v 1.4 2004/06/02 11:48:10 andrew Exp $ */ +/* $Id: ttest.c,v 1.5 2004/06/02 15:25:12 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 */ #include <portability.h> #include <crm/crm.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <crm/common/xml.h> #include <crm/msg_xml.h> #include <crm/cib.h> #define OPTARGS "V?i:o:D:C:S:HA:U:M:I:EWRFt:m:a:d:w:c:r:p:s:" #include <getopt.h> #include <glib.h> #include <tengine.h> extern gboolean unpack_graph(xmlNodePtr xml_graph); extern gboolean initiate_transition(void); extern gboolean initialize_graph(void); int main(int argc, char **argv) { int argerr = 0; int flag; cl_log_set_entity("ttest"); cl_log_enable_stderr(TRUE); cl_log_set_facility(LOG_USER); while (1) { int option_index = 0; static struct option long_options[] = { // Top-level Options {"daemon", 0, 0, 0}, {0, 0, 0, 0} }; flag = getopt_long(argc, argv, OPTARGS, long_options, &option_index); if (flag == -1) break; switch(flag) { case 0: printf("option %s", long_options[option_index].name); if (optarg) printf(" with arg %s", optarg); printf("\n"); break; /* a sample test for multiple instance if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); */ case 'V': printf("option %d", flag); break; default: printf("?? getopt returned character code 0%o ??\n", flag); ++argerr; break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); } if (optind > argc) { ++argerr; } if (argerr) { - cl_log(LOG_ERR, "%d errors in option parsing", argerr); + crm_err("%d errors in option parsing", argerr); } - cl_log(LOG_INFO, "=#=#=#=#= Getting XML =#=#=#=#="); + crm_info("=#=#=#=#= Getting XML =#=#=#=#="); mtrace(); - CRM_NOTE("Initializing graph..."); + crm_trace("Initializing graph..."); initialize_graph(); xmlNodePtr xml_graph = file2xml(stdin); - CRM_NOTE("Unpacking graph..."); + crm_trace("Unpacking graph..."); unpack_graph(xml_graph); - CRM_NOTE("Initiating transition..."); + crm_trace("Initiating transition..."); if(initiate_transition() == FALSE) { // nothing to be done.. means we're done. - cl_log(LOG_INFO, "No actions to be taken..." + crm_info("No actions to be taken..." " transition compelte."); } initialize_graph(); free_xml(xml_graph); muntrace(); - CRM_NOTE("Transition complete..."); + crm_trace("Transition complete..."); return 0; } diff --git a/include/crm/common/util.h b/include/crm/common/util.h index c9f8595581..c4d89fb26d 100644 --- a/include/crm/common/util.h +++ b/include/crm/common/util.h @@ -1,41 +1,51 @@ -/* $Id: util.h,v 1.1 2004/06/02 11:40:50 andrew Exp $ */ +/* $Id: util.h,v 1.2 2004/06/02 15:25:10 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 CRM_COMMON_UTIL__H #define CRM_COMMON_UTIL__H +extern unsigned int crm_log_level; + +extern void do_crm_log(int log_level, const char *function, + const char *format, ...) G_GNUC_PRINTF(3,4); + +/* returns the old value */ +extern unsigned int set_crm_log_level(unsigned int level); + +extern unsigned int get_crm_log_level(unsigned int level); + extern char *crm_itoa(int an_int); extern char *generate_hash_key(const char *crm_msg_reference, const char *sys); extern char *generate_hash_value(const char *src_node, const char *src_subsys); extern gboolean decode_hash_value(gpointer value, char **node, char **subsys); gboolean decodeNVpair(const char *srcstring, char separator, char **name, char **value); extern const char *generateReference(const char *custom1, const char *custom2); #endif diff --git a/include/crm/crm.h b/include/crm/crm.h index df2ab820fd..70c5a5de4d 100644 --- a/include/crm/crm.h +++ b/include/crm/crm.h @@ -1,138 +1,162 @@ -/* $Id: crm.h,v 1.9 2004/06/01 15:56:13 andrew Exp $ */ +/* $Id: crm.h,v 1.10 2004/06/02 15:25:09 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 CRM__H #define CRM__H #include <stdlib.h> #include <ha_config.h> #include <glib.h> #include <string.h> #include <clplumbing/cl_log.h> #include <clplumbing/cl_malloc.h> #include <mcheck.h> +#include <crm/common/util.h> + /* Clean these up at some point, some probably should be runtime options */ #define WORKING_DIR HA_VARLIBDIR"/heartbeat/crm" #define BIN_DIR "/usr/lib/heartbeat" #define MAXDATASIZE 65535 // ipc comms #define SOCKET_LEN 1024 #define APPNAME_LEN 256 #define LOG_DIR "/var/log" #define MAX_IPC_FAIL 5 #define CIB_FILENAME WORKING_DIR"/cib.xml" #define CIB_BACKUP WORKING_DIR"/cib_backup.xml" #define MSG_LOG 1 #define INTEGRATED_CIB 1 #define DOT_FSA_ACTIONS 1 #define DOT_ALL_FSA_INPUTS 1 //#define FSA_TRACE 1 #define USE_FAKE_LRM 1 /* Throttle announce messages to work around what appears to be a bug in * the send_ordered_*_message() code. node messages are taking approx 15s * longer to be sent than their cluster counterparts */ #define THROTTLE_ANNOUNCE 1 /* Sub-systems */ #define CRM_SYSTEM_DC "dc" #define CRM_SYSTEM_DCIB "dcib" // The master CIB #define CRM_SYSTEM_CIB "cib" #define CRM_SYSTEM_CRMD "crmd" #define CRM_SYSTEM_LRMD "lrmd" #define CRM_SYSTEM_PENGINE "pengine" #define CRM_SYSTEM_TENGINE "tengine" /* Valid operations */ #define CRM_OP_BUMP "bump" #define CRM_OP_QUERY "query" #define CRM_OP_CREATE "create" #define CRM_OP_UPDATE "update" #define CRM_OP_DELETE "delete" #define CRM_OP_ERASE "erase" #define CRM_OP_STORE "store" #define CRM_OP_REPLACE "replace" #define CRM_OP_FORWARD "forward" #define CRM_OP_JOINACK "join_ack" #define CRM_OP_WELCOME "welcome" #define CRM_OP_PING "ping" #define CRM_OP_VOTE "vote" #define CRM_OP_HELLO "hello" #define CRM_OP_ANNOUNCE "announce" #define CRM_OP_HBEAT "dc_beat" #define CRM_OP_PECALC "pe_calc" #define CRM_OP_ABORT "abort" #define CRM_OP_QUIT "quit" #define CRM_OP_SHUTDOWN "shutdown_crm" #define CRM_OP_EVENTCC "event_cc" #define CRM_OP_TEABORT "te_abort" #define CRM_OP_TRANSITION "transition" #define CRM_OP_TECOMPLETE "te_complete" #define CRM_OP_SHUTDOWN_REQ "req_shutdown" #define CRMD_STATE_ACTIVE "member" #define CRMD_STATE_INACTIVE "down" #define CRMD_JOINSTATE_DOWN "down" #define CRMD_JOINSTATE_PENDING "pending" #define CRMD_JOINSTATE_MEMBER "member" typedef GSList* GSListPtr; #define safe_str_eq(x, y) x!=NULL && y!=NULL && strcmp(x,y) == 0 #define safe_str_neq(x, y) x != y && (x==NULL || y==NULL || strcmp(x,y) != 0) #define slist_iter(w, x, y, z, a) for(z = 0; z < g_slist_length(y); z++) { \ x *w = (x*)g_slist_nth_data(y, z); \ a; \ } /* Developmental debug stuff */ -#define CRM_DEBUG(w, x...) cl_log(LOG_DEBUG, "(%s) " w, __FUNCTION__, x) -#define CRM_NOTE(w) cl_log(LOG_DEBUG, "(%s) " w, __FUNCTION__) +#define LOG_DEV LOG_DEBUG+1 +#define LOG_VERBOSE LOG_DEBUG+2 +#define LOG_TRACE LOG_DEBUG+3 + +#if 1 +# define crm_crit(w...) do_crm_log(LOG_CRIT, __FUNCTION__, w) +# define crm_err(w...) do_crm_log(LOG_ERR, __FUNCTION__, w) +# define crm_warn(w...) do_crm_log(LOG_WARNING, __FUNCTION__, w) +# define crm_notice(w...) do_crm_log(LOG_NOTICE, __FUNCTION__, w) +# define crm_info(w...) do_crm_log(LOG_INFO, __FUNCTION__, w) +# define crm_debug(w...) do_crm_log(LOG_DEBUG, __FUNCTION__, w) +# define crm_devel(w...) do_crm_log(LOG_DEV, __FUNCTION__, w) +# define crm_verbose(w...) do_crm_log(LOG_VERBOSE, __FUNCTION__, w) +# define crm_trace(w...) do_crm_log(LOG_TRACE, __FUNCTION__, w) +#else +# define crm_crit(w...) cl_log(LOG_CRIT, w) +# define crm_err(w...) cl_log(LOG_ERR, w) +# define crm_warn(w...) cl_log(LOG_WARNING, w) +# define crm_notice(w...) cl_log(LOG_NOTICE, w) +# define crm_info(w...) cl_log(LOG_INFO, w) +# define crm_debug(w...) cl_log(LOG_DEBUG, w) +# define crm_devel(w...) cl_log(LOG_DEV, w) +# define crm_vebose(w...) cl_log(LOG_VERBOSE, w) +# define crm_trace(w...) cl_log(LOG_TRACE, w) +#endif -extern gboolean crm_debug_state; -#define crm_debug(w...) if(crm_debug_state) { \ - cl_log(LOG_DEBUG, w); \ +#define crm_debug_action(x) if(crm_log_level >= LOG_DEBUG) { \ + x; \ } -#define crm_debug_action(x) if(crm_debug_state) { \ - x; \ +#define crm_info_action(x) if(crm_log_level >= LOG_INFO) { \ + x; \ } /* Seriously detailed debug stuff */ #if 0 -# define FNIN() cl_log(LOG_DEBUG, "#---#---# Entering %s...", __FUNCTION__) -# define FNOUT() { cl_log(LOG_DEBUG, "#---#---# Leaving %s...", __FUNCTION__); return; } -# define FNRET(x) { cl_log(LOG_DEBUG, "#---#---# Leaving %s...", __FUNCTION__); return x; } +# define FNIN() crm_trace("#---# Entering") +# define FNOUT() { crm_trace("#---# Leaving"); return; } +# define FNRET(x) { crm_trace("#---# Leaving"); return x; } #else # define FNIN() ; # define FNOUT() return; # define FNRET(x) return x; #endif #define crm_malloc(x) malloc(x) #define crm_free(x) if(x) { free(x); x=NULL; } #define crm_strdup(x) strdup(x) #endif