diff --git a/daemons/schedulerd/pacemaker-schedulerd.c b/daemons/schedulerd/pacemaker-schedulerd.c index 1139b515f3..3b896dd895 100644 --- a/daemons/schedulerd/pacemaker-schedulerd.c +++ b/daemons/schedulerd/pacemaker-schedulerd.c @@ -1,188 +1,377 @@ /* * Copyright 2004-2019 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU General Public License version 2 * or later (GPLv2+) WITHOUT ANY WARRANTY. */ #include #include #include +#include #include #include #include #include #include #include #include #include #include #include #include #define OPTARGS "hVc" static GMainLoop *mainloop = NULL; static qb_ipcs_service_t *ipcs = NULL; +static pe_working_set_t *sched_data_set = NULL; +extern int transition_id; + +#define get_series() was_processing_error?1:was_processing_warning?2:3 + +typedef struct series_s { + const char *name; + const char *param; + int wrap; +} series_t; + +series_t series[] = { + {"pe-unknown", "_dont_match_anything_", -1}, + {"pe-error", "pe-error-series-max", -1}, + {"pe-warn", "pe-warn-series-max", 200}, + {"pe-input", "pe-input-series-max", 400}, +}; void pengine_shutdown(int nsig); +extern xmlNode *do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, crm_time_t * now); + +static gboolean +process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender) +{ + static char *last_digest = NULL; + static char *filename = NULL; + + time_t execution_date = time(NULL); + const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO); + const char *op = crm_element_value(msg, F_CRM_TASK); + const char *ref = crm_element_value(msg, F_CRM_REFERENCE); + + crm_trace("Processing %s op (ref=%s)...", op, ref); + + if (op == NULL) { + /* error */ + + } else if (strcasecmp(op, CRM_OP_HELLO) == 0) { + /* ignore */ + + } else if (safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE)) { + /* ignore */ + + } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) { + crm_trace("Bad sys-to %s", crm_str(sys_to)); + return FALSE; + + } else if (strcasecmp(op, CRM_OP_PECALC) == 0) { + int seq = -1; + int series_id = 0; + int series_wrap = 0; + char *digest = NULL; + const char *value = NULL; + xmlNode *converted = NULL; + xmlNode *reply = NULL; + gboolean is_repoke = FALSE; + gboolean process = TRUE; + + crm_config_error = FALSE; + crm_config_warning = FALSE; + + was_processing_error = FALSE; + was_processing_warning = FALSE; + + if (sched_data_set == NULL) { + sched_data_set = pe_new_working_set(); + CRM_ASSERT(sched_data_set != NULL); + } + + digest = calculate_xml_versioned_digest(xml_data, FALSE, FALSE, CRM_FEATURE_SET); + converted = copy_xml(xml_data); + if (cli_config_update(&converted, NULL, TRUE) == FALSE) { + sched_data_set->graph = create_xml_node(NULL, XML_TAG_GRAPH); + crm_xml_add_int(sched_data_set->graph, "transition_id", 0); + crm_xml_add_int(sched_data_set->graph, "cluster-delay", 0); + process = FALSE; + free(digest); + + } else if (safe_str_eq(digest, last_digest)) { + crm_info("Input has not changed since last time, not saving to disk"); + is_repoke = TRUE; + free(digest); + + } else { + free(last_digest); + last_digest = digest; + } + + if (process) { + do_calculations(sched_data_set, converted, NULL); + } + + series_id = get_series(); + series_wrap = series[series_id].wrap; + value = pe_pref(sched_data_set->config_hash, series[series_id].param); + + if (value != NULL) { + series_wrap = crm_int_helper(value, NULL); + if (errno != 0) { + series_wrap = series[series_id].wrap; + } + + } else { + crm_config_warn("No value specified for cluster" + " preference: %s", series[series_id].param); + } + + seq = get_last_sequence(PE_STATE_DIR, series[series_id].name); + crm_trace("Series %s: wrap=%d, seq=%d, pref=%s", + series[series_id].name, series_wrap, seq, value); + + sched_data_set->input = NULL; + reply = create_reply(msg, sched_data_set->graph); + CRM_ASSERT(reply != NULL); + + if (is_repoke == FALSE) { + free(filename); + filename = + generate_series_filename(PE_STATE_DIR, series[series_id].name, seq, HAVE_BZLIB_H); + } + + crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename); + crm_xml_add_int(reply, "graph-errors", was_processing_error); + crm_xml_add_int(reply, "graph-warnings", was_processing_warning); + crm_xml_add_int(reply, "config-errors", crm_config_error); + crm_xml_add_int(reply, "config-warnings", crm_config_warning); + + if (crm_ipcs_send(sender, 0, reply, crm_ipc_server_event) == FALSE) { + int graph_file_fd = 0; + char *graph_file = NULL; + umask(S_IWGRP | S_IWOTH | S_IROTH); + + graph_file = crm_strdup_printf("%s/pengine.graph.XXXXXX", + PE_STATE_DIR); + graph_file_fd = mkstemp(graph_file); + + crm_err("Couldn't send transition graph to peer, writing to %s instead", + graph_file); + + crm_xml_add(reply, F_CRM_TGRAPH, graph_file); + write_xml_fd(sched_data_set->graph, graph_file, graph_file_fd, FALSE); + + free(graph_file); + free_xml(first_named_child(reply, F_CRM_DATA)); + CRM_ASSERT(crm_ipcs_send(sender, 0, reply, crm_ipc_server_event)); + } + + free_xml(reply); + pe_reset_working_set(sched_data_set); + + if (was_processing_error) { + crm_err("Calculated transition %d (with errors), saving inputs in %s", + transition_id, filename); + + } else if (was_processing_warning) { + crm_warn("Calculated transition %d (with warnings), saving inputs in %s", + transition_id, filename); + + } else { + crm_notice("Calculated transition %d, saving inputs in %s", + transition_id, filename); + } + + if (crm_config_error) { + crm_notice("Configuration errors found during scheduler processing," + " please run \"crm_verify -L\" to identify issues"); + } + + if (is_repoke == FALSE && series_wrap != 0) { + unlink(filename); + crm_xml_add_int(xml_data, "execution-date", execution_date); + write_xml_file(xml_data, filename, HAVE_BZLIB_H); + write_last_sequence(PE_STATE_DIR, series[series_id].name, seq + 1, series_wrap); + } else { + crm_trace("Not writing out %s: %d & %d", filename, is_repoke, series_wrap); + } + + free_xml(converted); + } + + return TRUE; +} + +// only needed if process_pe_message() is called +static void +libpengine_fini() +{ + pe_free_working_set(sched_data_set); + sched_data_set = NULL; +} static int32_t pe_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid) { crm_trace("Connection %p", c); if (crm_client_new(c, uid, gid) == NULL) { return -EIO; } return 0; } static void pe_ipc_created(qb_ipcs_connection_t * c) { crm_trace("Connection %p", c); } gboolean process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender); static int32_t pe_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size) { uint32_t id = 0; uint32_t flags = 0; crm_client_t *c = crm_client_get(qbc); xmlNode *msg = crm_ipcs_recv(c, data, size, &id, &flags); crm_ipcs_send_ack(c, id, flags, "ack", __FUNCTION__, __LINE__); if (msg != NULL) { xmlNode *data_xml = get_message_xml(msg, F_CRM_DATA); process_pe_message(msg, data_xml, c); free_xml(msg); } return 0; } /* Error code means? */ static int32_t pe_ipc_closed(qb_ipcs_connection_t * c) { crm_client_t *client = crm_client_get(c); if (client == NULL) { return 0; } crm_trace("Connection %p", c); crm_client_destroy(client); return 0; } static void pe_ipc_destroy(qb_ipcs_connection_t * c) { crm_trace("Connection %p", c); pe_ipc_closed(c); } struct qb_ipcs_service_handlers ipc_callbacks = { .connection_accept = pe_ipc_accept, .connection_created = pe_ipc_created, .msg_process = pe_ipc_dispatch, .connection_closed = pe_ipc_closed, .connection_destroyed = pe_ipc_destroy }; /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { int flag; int index = 0; int argerr = 0; crm_log_preinit(NULL, argc, argv); crm_set_options(NULL, "[options]", long_options, "Daemon for calculating the cluster's response to events"); mainloop_add_signal(SIGTERM, pengine_shutdown); while (1) { flag = crm_get_option(argc, argv, &index); if (flag == -1) break; switch (flag) { case 'V': crm_bump_log_level(argc, argv); break; case 'h': /* Help message */ crm_help('?', CRM_EX_OK); break; default: ++argerr; break; } } if (argc - optind == 1 && safe_str_eq("metadata", argv[optind])) { pe_metadata(); return CRM_EX_OK; } if (optind > argc) { ++argerr; } if (argerr) { crm_help('?', CRM_EX_USAGE); } crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE); if (pcmk__daemon_can_write(PE_STATE_DIR, NULL) == FALSE) { crm_err("Terminating due to bad permissions on " PE_STATE_DIR); fprintf(stderr, "ERROR: Bad permissions on " PE_STATE_DIR " (see logs for details)\n"); fflush(stderr); return CRM_EX_FATAL; } crm_debug("Init server comms"); ipcs = mainloop_add_ipc_server(CRM_SYSTEM_PENGINE, QB_IPC_SHM, &ipc_callbacks); if (ipcs == NULL) { crm_err("Failed to create IPC server: shutting down and inhibiting respawn"); crm_exit(CRM_EX_FATAL); } /* Create the mainloop and run it... */ crm_info("Starting %s", crm_system_name); mainloop = g_main_loop_new(NULL, FALSE); g_main_loop_run(mainloop); libpengine_fini(); crm_info("Exiting %s", crm_system_name); crm_exit(CRM_EX_OK); } void pengine_shutdown(int nsig) { mainloop_del_ipc_server(ipcs); libpengine_fini(); crm_exit(CRM_EX_OK); } diff --git a/include/pcmki/pcmki_sched_allocate.h b/include/pcmki/pcmki_sched_allocate.h index f18c937587..9890b339ed 100644 --- a/include/pcmki/pcmki_sched_allocate.h +++ b/include/pcmki/pcmki_sched_allocate.h @@ -1,181 +1,179 @@ /* * Copyright 2004-2019 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef SCHED_ALLOCATE__H # define SCHED_ALLOCATE__H # include # include # include # include # include # include struct resource_alloc_functions_s { GHashTable *(*merge_weights) (resource_t *, const char *, GHashTable *, const char *, float, enum pe_weights); node_t *(*allocate) (resource_t *, node_t *, pe_working_set_t *); void (*create_actions) (resource_t *, pe_working_set_t *); gboolean(*create_probe) (resource_t *, node_t *, action_t *, gboolean, pe_working_set_t *); void (*internal_constraints) (resource_t *, pe_working_set_t *); void (*rsc_colocation_lh) (pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *); void (*rsc_colocation_rh) (pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *); void (*rsc_location) (pe_resource_t *, pe__location_t *); enum pe_action_flags (*action_flags) (action_t *, node_t *); enum pe_graph_flags (*update_actions) (pe_action_t *, pe_action_t *, pe_node_t *, enum pe_action_flags, enum pe_action_flags, enum pe_ordering, pe_working_set_t *data_set); void (*expand) (resource_t *, pe_working_set_t *); void (*append_meta) (resource_t * rsc, xmlNode * xml); }; extern GHashTable *rsc_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes, const char *attr, float factor, enum pe_weights flags); extern GHashTable *clone_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes, const char *attr, float factor, enum pe_weights flags); extern GHashTable *container_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes, const char *attr, float factor, enum pe_weights flags); extern GHashTable *native_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes, const char *attr, float factor, enum pe_weights flags); extern GHashTable *group_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes, const char *attr, float factor, enum pe_weights flags); extern node_t *native_color(resource_t * rsc, node_t * preferred, pe_working_set_t * data_set); extern void native_create_actions(resource_t * rsc, pe_working_set_t * data_set); extern void native_internal_constraints(resource_t * rsc, pe_working_set_t * data_set); void native_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); void native_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); extern void rsc_ticket_constraint(resource_t * lh_rsc, rsc_ticket_t * rsc_ticket, pe_working_set_t * data_set); extern enum pe_action_flags native_action_flags(action_t * action, node_t * node); void native_rsc_location(pe_resource_t *rsc, pe__location_t *constraint); extern void native_expand(resource_t * rsc, pe_working_set_t * data_set); extern gboolean native_create_probe(resource_t * rsc, node_t * node, action_t * complete, gboolean force, pe_working_set_t * data_set); extern void native_append_meta(resource_t * rsc, xmlNode * xml); extern node_t *group_color(resource_t * rsc, node_t * preferred, pe_working_set_t * data_set); extern void group_create_actions(resource_t * rsc, pe_working_set_t * data_set); extern void group_internal_constraints(resource_t * rsc, pe_working_set_t * data_set); void group_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); void group_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); extern enum pe_action_flags group_action_flags(action_t * action, node_t * node); void group_rsc_location(pe_resource_t *rsc, pe__location_t *constraint); extern void group_expand(resource_t * rsc, pe_working_set_t * data_set); extern void group_append_meta(resource_t * rsc, xmlNode * xml); extern node_t *container_color(resource_t * rsc, node_t * preferred, pe_working_set_t * data_set); extern void container_create_actions(resource_t * rsc, pe_working_set_t * data_set); extern void container_internal_constraints(resource_t * rsc, pe_working_set_t * data_set); void container_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); void container_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); void container_rsc_location(pe_resource_t *rsc, pe__location_t *constraint); extern enum pe_action_flags container_action_flags(action_t * action, node_t * node); extern void container_expand(resource_t * rsc, pe_working_set_t * data_set); extern gboolean container_create_probe(resource_t * rsc, node_t * node, action_t * complete, gboolean force, pe_working_set_t * data_set); extern void container_append_meta(resource_t * rsc, xmlNode * xml); extern node_t *clone_color(resource_t * rsc, node_t * preferred, pe_working_set_t * data_set); extern void clone_create_actions(resource_t * rsc, pe_working_set_t * data_set); extern void clone_internal_constraints(resource_t * rsc, pe_working_set_t * data_set); void clone_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); void clone_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); void clone_rsc_location(pe_resource_t *rsc, pe__location_t *constraint); extern enum pe_action_flags clone_action_flags(action_t * action, node_t * node); extern void clone_expand(resource_t * rsc, pe_working_set_t * data_set); extern gboolean clone_create_probe(resource_t * rsc, node_t * node, action_t * complete, gboolean force, pe_working_set_t * data_set); extern void clone_append_meta(resource_t * rsc, xmlNode * xml); void apply_master_prefs(resource_t *rsc); node_t *color_promotable(resource_t *rsc, pe_working_set_t *data_set); void create_promotable_actions(resource_t *rsc, pe_working_set_t *data_set); void promote_demote_constraints(resource_t *rsc, pe_working_set_t *data_set); void promotable_constraints(resource_t *rsc, pe_working_set_t *data_set); void promotable_colocation_rh(resource_t *lh_rsc, resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set); /* extern resource_object_functions_t resource_variants[]; */ extern resource_alloc_functions_t resource_class_alloc_functions[]; gboolean is_active(pe__location_t *cons); extern gboolean unpack_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set); extern gboolean unpack_rsc_colocation(xmlNode * xml_obj, pe_working_set_t * data_set); extern gboolean unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set); extern gboolean unpack_rsc_ticket(xmlNode * xml_obj, pe_working_set_t * data_set); void LogNodeActions(pe_working_set_t * data_set, gboolean terminal); void LogActions(resource_t * rsc, pe_working_set_t * data_set, gboolean terminal); void container_LogActions(resource_t * rsc, pe_working_set_t * data_set, gboolean terminal); extern void rsc_stonith_ordering(resource_t * rsc, action_t * stonith_op, pe_working_set_t * data_set); enum pe_graph_flags native_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set); enum pe_graph_flags group_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set); enum pe_graph_flags container_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set); gboolean update_action_flags(action_t * action, enum pe_action_flags flags, const char *source, int line); gboolean update_action(pe_action_t *action, pe_working_set_t *data_set); void complex_set_cmds(resource_t * rsc); void clone_create_pseudo_actions( resource_t * rsc, GListPtr children, notify_data_t **start_notify, notify_data_t **stop_notify, pe_working_set_t * data_set); - -void libpengine_fini(void); #endif diff --git a/lib/pacemaker/pcmk_sched_messages.c b/lib/pacemaker/pcmk_sched_messages.c index 48a2e88085..780fe826b7 100644 --- a/lib/pacemaker/pcmk_sched_messages.c +++ b/lib/pacemaker/pcmk_sched_messages.c @@ -1,300 +1,109 @@ /* * Copyright 2004-2018 Andrew Beekhof * * This source code is licensed under the GNU General Public License version 2 * or later (GPLv2+) WITHOUT ANY WARRANTY. */ #include -#include #include #include #include #include #include #include #include #include #include xmlNode *do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, crm_time_t * now); gboolean show_scores = FALSE; int scores_log_level = LOG_TRACE; gboolean show_utilization = FALSE; int utilization_log_level = LOG_TRACE; -extern int transition_id; - -static pe_working_set_t *sched_data_set = NULL; - -#define get_series() was_processing_error?1:was_processing_warning?2:3 - -typedef struct series_s { - const char *name; - const char *param; - int wrap; -} series_t; - -series_t series[] = { - {"pe-unknown", "_dont_match_anything_", -1}, - {"pe-error", "pe-error-series-max", -1}, - {"pe-warn", "pe-warn-series-max", 200}, - {"pe-input", "pe-input-series-max", 400}, -}; - -gboolean process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender); - -gboolean -process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender) -{ - static char *last_digest = NULL; - static char *filename = NULL; - - time_t execution_date = time(NULL); - const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO); - const char *op = crm_element_value(msg, F_CRM_TASK); - const char *ref = crm_element_value(msg, F_CRM_REFERENCE); - - crm_trace("Processing %s op (ref=%s)...", op, ref); - - if (op == NULL) { - /* error */ - - } else if (strcasecmp(op, CRM_OP_HELLO) == 0) { - /* ignore */ - - } else if (safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE)) { - /* ignore */ - - } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) { - crm_trace("Bad sys-to %s", crm_str(sys_to)); - return FALSE; - - } else if (strcasecmp(op, CRM_OP_PECALC) == 0) { - int seq = -1; - int series_id = 0; - int series_wrap = 0; - char *digest = NULL; - const char *value = NULL; - xmlNode *converted = NULL; - xmlNode *reply = NULL; - gboolean is_repoke = FALSE; - gboolean process = TRUE; - - crm_config_error = FALSE; - crm_config_warning = FALSE; - - was_processing_error = FALSE; - was_processing_warning = FALSE; - - if (sched_data_set == NULL) { - sched_data_set = pe_new_working_set(); - CRM_ASSERT(sched_data_set != NULL); - } - - digest = calculate_xml_versioned_digest(xml_data, FALSE, FALSE, CRM_FEATURE_SET); - converted = copy_xml(xml_data); - if (cli_config_update(&converted, NULL, TRUE) == FALSE) { - sched_data_set->graph = create_xml_node(NULL, XML_TAG_GRAPH); - crm_xml_add_int(sched_data_set->graph, "transition_id", 0); - crm_xml_add_int(sched_data_set->graph, "cluster-delay", 0); - process = FALSE; - free(digest); - - } else if (safe_str_eq(digest, last_digest)) { - crm_info("Input has not changed since last time, not saving to disk"); - is_repoke = TRUE; - free(digest); - - } else { - free(last_digest); - last_digest = digest; - } - - if (process) { - do_calculations(sched_data_set, converted, NULL); - } - - series_id = get_series(); - series_wrap = series[series_id].wrap; - value = pe_pref(sched_data_set->config_hash, series[series_id].param); - - if (value != NULL) { - series_wrap = crm_int_helper(value, NULL); - if (errno != 0) { - series_wrap = series[series_id].wrap; - } - - } else { - crm_config_warn("No value specified for cluster" - " preference: %s", series[series_id].param); - } - - seq = get_last_sequence(PE_STATE_DIR, series[series_id].name); - crm_trace("Series %s: wrap=%d, seq=%d, pref=%s", - series[series_id].name, series_wrap, seq, value); - - sched_data_set->input = NULL; - reply = create_reply(msg, sched_data_set->graph); - CRM_ASSERT(reply != NULL); - - if (is_repoke == FALSE) { - free(filename); - filename = - generate_series_filename(PE_STATE_DIR, series[series_id].name, seq, HAVE_BZLIB_H); - } - - crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename); - crm_xml_add_int(reply, "graph-errors", was_processing_error); - crm_xml_add_int(reply, "graph-warnings", was_processing_warning); - crm_xml_add_int(reply, "config-errors", crm_config_error); - crm_xml_add_int(reply, "config-warnings", crm_config_warning); - - if (crm_ipcs_send(sender, 0, reply, crm_ipc_server_event) == FALSE) { - int graph_file_fd = 0; - char *graph_file = NULL; - umask(S_IWGRP | S_IWOTH | S_IROTH); - - graph_file = crm_strdup_printf("%s/pengine.graph.XXXXXX", - PE_STATE_DIR); - graph_file_fd = mkstemp(graph_file); - - crm_err("Couldn't send transition graph to peer, writing to %s instead", - graph_file); - - crm_xml_add(reply, F_CRM_TGRAPH, graph_file); - write_xml_fd(sched_data_set->graph, graph_file, graph_file_fd, FALSE); - - free(graph_file); - free_xml(first_named_child(reply, F_CRM_DATA)); - CRM_ASSERT(crm_ipcs_send(sender, 0, reply, crm_ipc_server_event)); - } - - free_xml(reply); - pe_reset_working_set(sched_data_set); - - if (was_processing_error) { - crm_err("Calculated transition %d (with errors), saving inputs in %s", - transition_id, filename); - - } else if (was_processing_warning) { - crm_warn("Calculated transition %d (with warnings), saving inputs in %s", - transition_id, filename); - - } else { - crm_notice("Calculated transition %d, saving inputs in %s", - transition_id, filename); - } - - if (crm_config_error) { - crm_notice("Configuration errors found during scheduler processing," - " please run \"crm_verify -L\" to identify issues"); - } - - if (is_repoke == FALSE && series_wrap != 0) { - unlink(filename); - crm_xml_add_int(xml_data, "execution-date", execution_date); - write_xml_file(xml_data, filename, HAVE_BZLIB_H); - write_last_sequence(PE_STATE_DIR, series[series_id].name, seq + 1, series_wrap); - } else { - crm_trace("Not writing out %s: %d & %d", filename, is_repoke, series_wrap); - } - - free_xml(converted); - } - - return TRUE; -} - -// only needed if process_pe_message() is called -void -libpengine_fini() -{ - pe_free_working_set(sched_data_set); - sched_data_set = NULL; -} xmlNode * do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, crm_time_t * now) { GListPtr gIter = NULL; int rsc_log_level = LOG_INFO; /* pe_debug_on(); */ CRM_ASSERT(xml_input || is_set(data_set->flags, pe_flag_have_status)); if (is_set(data_set->flags, pe_flag_have_status) == FALSE) { set_working_set_defaults(data_set); data_set->input = xml_input; data_set->now = now; } else { crm_trace("Already have status - reusing"); } if (data_set->now == NULL) { data_set->now = crm_time_new(NULL); } crm_trace("Calculate cluster status"); stage0(data_set); if(is_not_set(data_set->flags, pe_flag_quick_location)) { gIter = data_set->resources; for (; gIter != NULL; gIter = gIter->next) { resource_t *rsc = (resource_t *) gIter->data; if (is_set(rsc->flags, pe_rsc_orphan) && rsc->role == RSC_ROLE_STOPPED) { continue; } rsc->fns->print(rsc, NULL, pe_print_log, &rsc_log_level); } } crm_trace("Applying placement constraints"); stage2(data_set); if(is_set(data_set->flags, pe_flag_quick_location)){ return NULL; } crm_trace("Create internal constraints"); stage3(data_set); crm_trace("Check actions"); stage4(data_set); crm_trace("Allocate resources"); stage5(data_set); crm_trace("Processing fencing and shutdown cases"); stage6(data_set); crm_trace("Applying ordering constraints"); stage7(data_set); crm_trace("Create transition graph"); stage8(data_set); crm_trace("=#=#=#=#= Summary =#=#=#=#="); crm_trace("\t========= Set %d (Un-runnable) =========", -1); if (get_crm_log_level() >= LOG_TRACE) { gIter = data_set->actions; for (; gIter != NULL; gIter = gIter->next) { action_t *action = (action_t *) gIter->data; if (is_set(action->flags, pe_action_optional) == FALSE && is_set(action->flags, pe_action_runnable) == FALSE && is_set(action->flags, pe_action_pseudo) == FALSE) { log_action(LOG_TRACE, "\t", action, TRUE); } } } return data_set->graph; }