Ejemplo n.º 1
0
xmlNode *
do_calculations(pe_working_set_t *data_set, xmlNode *xml_input, ha_time_t *now)
{
    int rsc_log_level = LOG_NOTICE;
    /*	pe_debug_on(); */
    set_working_set_defaults(data_set);
    data_set->input = xml_input;
    data_set->now = now;
    if(data_set->now == NULL) {
        data_set->now = new_ha_date(TRUE);
    }

#if MEMCHECK_STAGE_SETUP
    check_and_exit(-1);
#endif

    crm_debug_5("unpack constraints");
    stage0(data_set);

#if MEMCHECK_STAGE_0
    check_and_exit(0);
#endif

    slist_iter(rsc, resource_t, data_set->resources, lpc,
               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);
          );
Ejemplo n.º 2
0
int
print_simple_status(crm_data_t *cib) 
{
	node_t *dc = NULL;
	int nodes_online = 0;
	int nodes_standby = 0;
	pe_working_set_t data_set;

	set_working_set_defaults(&data_set);
	data_set.input = cib;
	cluster_status(&data_set);

	dc = data_set.dc_node;

	if(dc == NULL) {
		mon_warn("No DC ");
	}

	slist_iter(node, node_t, data_set.nodes, lpc2,
		   if(node->details->standby) {
			   nodes_standby++;
		   } else if(node->details->online) {
			   nodes_online++;
		   } else {
			   mon_warn("offline node: %s", node->details->uname);
		   }
	);
Ejemplo n.º 3
0
int32_t
pe_process_state(xmlDocPtr doc,
		 pe_resource_execute_t exec_fn,
		 pe_transition_completed_t done_fn,
		 void *user_data, int debug)
{
	crm_graph_t *transition = NULL;
	xmlNode *xml_input = xmlDocGetRootElement(doc);

	qb_enter();

	if (working_set) {
		qb_log(LOG_ERR, "Transition already in progress");
		qb_leave();
		return -EEXIST;
	}

	transition_count++;
	if (debug) {
		char filename[PATH_MAX];

		assert(validate_xml(xml_input, "pacemaker-1.2", FALSE) == TRUE);

		snprintf(filename, PATH_MAX, "/tmp/pe-%d-%d.xml",
			 getpid(), transition_count);
		xmlSaveFormatFileEnc(filename, doc, "UTF-8", 1);
		qb_log(LOG_INFO, "Executing deployable transition [%s]",
		       filename);
	} else {
		qb_log(LOG_INFO, "Executing deployable transition [%d]",
		       transition_count);
	}
	working_set = calloc(1, sizeof(pe_working_set_t));
	run_fn = exec_fn;
	completed_fn = done_fn;
	run_user_data = user_data;
	set_graph_functions(&graph_exec_fns);

	set_working_set_defaults(working_set);

	/* calculate output */
	do_calculations(working_set, xml_input, NULL);

	transition = unpack_graph(working_set->graph, __func__);
	//print_graph(LOG_INFO, transition);

	graph_updated = TRUE;

	qb_loop_job_add(NULL, QB_LOOP_HIGH, transition, process_next_job);

	qb_leave();
	return 0;
}
Ejemplo n.º 4
0
/**
 * Send query to the CIB and update the information of resource table v2.
 */
int
update_resource_table_v2(void)
{
    crm_data_t *cib_object = NULL;
    pe_working_set_t data_set;
    int rc = 0;
    int options =  cib_scope_local|cib_sync_call;
    int index;

    if (!gResourceTableV2) {
        cl_log(LOG_ERR, "resource table v2 is NULL.");
        return HA_FAIL;
    }
    free_resource_table_v2();

    rc = cib_conn->cmds->query(cib_conn, NULL, &cib_object, options);
    if (rc != 0) {
        cl_log(LOG_ERR, "CIB query failed: %s", pcmk_strerror(rc));
        return HA_FAIL;
    }
    if (cib_object == NULL) {
        cl_log(LOG_ERR, "CIB query failed: empty result.");
        return HA_FAIL;
    }

    cl_log(LOG_DEBUG, "CIB query done. Updating resource table v2.");

    set_working_set_defaults(&data_set);
    data_set.input = cib_object;
    /* parse cib xml info (cib_object). */
    cluster_status(&data_set);

    index = update_resources_recursively(data_set.resources, data_set.nodes, 1);
    if (index == HA_FAIL) {
        cl_log(LOG_ERR, "Update resources failed.");

        data_set.input = NULL;
        cleanup_calculations(&data_set);
        free_xml(cib_object);
        return HA_FAIL;
    }

    cl_log(LOG_DEBUG, "Updated %d resources.", index-1);


    data_set.input = NULL;
    cleanup_calculations(&data_set);
    free_xml(cib_object);
    return HA_OK;
}
Ejemplo n.º 5
0
void
cleanup_calculations(pe_working_set_t * data_set)
{
    pe_dataset = NULL;
    if (data_set == NULL) {
        return;
    }

    clear_bit(data_set->flags, pe_flag_have_status);
    if (data_set->config_hash != NULL) {
        g_hash_table_destroy(data_set->config_hash);
    }

    if (data_set->singletons != NULL) {
        g_hash_table_destroy(data_set->singletons);
    }

    if (data_set->tickets) {
        g_hash_table_destroy(data_set->tickets);
    }

    if (data_set->template_rsc_sets) {
        g_hash_table_destroy(data_set->template_rsc_sets);
    }

    if (data_set->tags) {
        g_hash_table_destroy(data_set->tags);
    }

    free(data_set->dc_uuid);

    crm_trace("deleting resources");
    pe_free_resources(data_set->resources);

    crm_trace("deleting actions");
    pe_free_actions(data_set->actions);

    crm_trace("deleting nodes");
    pe_free_nodes(data_set->nodes);

    free_xml(data_set->graph);
    crm_time_free(data_set->now);
    free_xml(data_set->input);
    free_xml(data_set->failed);

    set_working_set_defaults(data_set);

    CRM_CHECK(data_set->ordering_constraints == NULL,;
        );
Ejemplo n.º 6
0
static gboolean
mon_refresh_state(gpointer user_data)
{
    xmlNode *cib_copy = NULL;
    pe_working_set_t data_set;

    if(current_cib == NULL) {
        return FALSE;
    }

    if(user_data) {
        mainloop_timer_t *timer = user_data;

        mainloop_timer_stop(timer);
    }

    cib_copy = copy_xml(current_cib);
    if (cli_config_update(&cib_copy, NULL, FALSE) == FALSE) {
        cl_log(LOG_WARNING, "cli_config_update() failed - forcing reconnect to CIB");
        if (cib) {
            cib->cmds->signoff(cib);
        }

    } else {
        last_refresh = time(NULL);
        set_working_set_defaults(&data_set);
        data_set.input = cib_copy;
        data_set.flags |= pe_flag_have_stonith_resource;
        cluster_status(&data_set);

        compute_status(&data_set);

        cleanup_calculations(&data_set);
    }

    return FALSE;
}
Ejemplo n.º 7
0
int
main(int argc, char **argv)
{
    GListPtr lpc = NULL;
    gboolean process = TRUE;
    gboolean all_good = TRUE;
    enum transition_status graph_rc = -1;
    crm_graph_t *transition = NULL;
    ha_time_t *a_date = NULL;
    cib_t *cib_conn = NULL;

    xmlNode *cib_object = NULL;
    int argerr = 0;
    int flag;

    char *msg_buffer = NULL;
    gboolean optional = FALSE;
    pe_working_set_t data_set;

    const char *source = NULL;
    const char *xml_file = NULL;
    const char *dot_file = NULL;
    const char *graph_file = NULL;
    const char *input_file = NULL;
    const char *input_xml = NULL;

    /* disable glib's fancy allocators that can't be free'd */
    GMemVTable vtable;

    vtable.malloc = malloc;
    vtable.realloc = realloc;
    vtable.free = free;
    vtable.calloc = calloc;
    vtable.try_malloc = malloc;
    vtable.try_realloc = realloc;

    g_mem_set_vtable(&vtable);

    crm_log_init_quiet(NULL, LOG_CRIT, FALSE, FALSE, argc, argv);
    crm_set_options(NULL, "[-?Vv] -[Xxp] {other options}", long_options,
                    "Calculate the cluster's response to the supplied cluster state\n"
                    "\nSuperceeded by crm_simulate and likely to be removed in a future release\n\n");

    while (1) {
        int option_index = 0;

        flag = crm_get_option(argc, argv, &option_index);
        if (flag == -1)
            break;

        switch (flag) {
            case 'S':
                do_simulation = TRUE;
                break;
            case 'a':
                all_actions = TRUE;
                break;
            case 'w':
                inhibit_exit = TRUE;
                break;
            case 'X':
                /*use_stdin = TRUE;*/
                input_xml = optarg;
                break;
            case 's':
                show_scores = TRUE;
                break;
            case 'U':
                show_utilization = TRUE;
                break;
            case 'x':
                xml_file = optarg;
                break;
            case 'd':
                use_date = optarg;
                break;
            case 'D':
                dot_file = optarg;
                break;
            case 'G':
                graph_file = optarg;
                break;
            case 'I':
                input_file = optarg;
                break;
            case 'V':
                crm_bump_log_level();
                break;
            case 'L':
                USE_LIVE_CIB = TRUE;
                break;
            case '$':
            case '?':
                crm_help(flag, 0);
                break;
            default:
                fprintf(stderr, "Option -%c is not yet supported\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) {
        crm_err("%d errors in option parsing", argerr);
        crm_help('?', 1);
    }

    update_all_trace_data();    /* again, so we see which trace points got updated */

    if (USE_LIVE_CIB) {
        int rc = cib_ok;

        source = "live cib";
        cib_conn = cib_new();
        rc = cib_conn->cmds->signon(cib_conn, "ptest", cib_command);

        if (rc == cib_ok) {
            crm_info("Reading XML from: live cluster");
            cib_object = get_cib_copy(cib_conn);

        } else {
            fprintf(stderr, "Live CIB query failed: %s\n", cib_error2string(rc));
            return 3;
        }
        if (cib_object == NULL) {
            fprintf(stderr, "Live CIB query failed: empty result\n");
            return 3;
        }

    } else if (xml_file != NULL) {
        source = xml_file;
        cib_object = filename2xml(xml_file);

    } else if (use_stdin) {
        source = "stdin";
        cib_object = filename2xml(NULL);
    } else if (input_xml) {
        source = "input string";
        cib_object = string2xml(input_xml);
    }

    if (cib_object == NULL && source) {
        fprintf(stderr, "Could not parse configuration input from: %s\n", source);
        return 4;

    } else if (cib_object == NULL) {
        fprintf(stderr, "No configuration specified\n");
        crm_help('?', 1);
    }

    if (get_object_root(XML_CIB_TAG_STATUS, cib_object) == NULL) {
        create_xml_node(cib_object, XML_CIB_TAG_STATUS);
    }

    if (cli_config_update(&cib_object, NULL, FALSE) == FALSE) {
        free_xml(cib_object);
        return cib_STALE;
    }

    if (validate_xml(cib_object, NULL, FALSE) != TRUE) {
        free_xml(cib_object);
        return cib_dtd_validation;
    }

    if (input_file != NULL) {
        FILE *input_strm = fopen(input_file, "w");

        if (input_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", input_file);
        } else {
            msg_buffer = dump_xml_formatted(cib_object);
            if (fprintf(input_strm, "%s\n", msg_buffer) < 0) {
                crm_perror(LOG_ERR, "Write to %s failed", input_file);
            }
            fflush(input_strm);
            fclose(input_strm);
            crm_free(msg_buffer);
        }
    }

    if (use_date != NULL) {
        a_date = parse_date(&use_date);
        log_date(LOG_WARNING, "Set fake 'now' to", a_date, ha_log_date | ha_log_time);
        log_date(LOG_WARNING, "Set fake 'now' to (localtime)",
                 a_date, ha_log_date | ha_log_time | ha_log_local);
    }

    set_working_set_defaults(&data_set);
    if (process) {
        if (show_scores && show_utilization) {
            fprintf(stdout, "Allocation scores and utilization information:\n");
        } else if (show_scores) {
            fprintf(stdout, "Allocation scores:\n");
        } else if (show_utilization) {
            fprintf(stdout, "Utilization information:\n");
        }
        do_calculations(&data_set, cib_object, a_date);
    }

    msg_buffer = dump_xml_formatted(data_set.graph);
    if (safe_str_eq(graph_file, "-")) {
        fprintf(stdout, "%s\n", msg_buffer);
        fflush(stdout);
    } else if (graph_file != NULL) {
        FILE *graph_strm = fopen(graph_file, "w");

        if (graph_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", graph_file);
        } else {
            if (fprintf(graph_strm, "%s\n\n", msg_buffer) < 0) {
                crm_perror(LOG_ERR, "Write to %s failed", graph_file);
            }
            fflush(graph_strm);
            fclose(graph_strm);
        }
    }
    crm_free(msg_buffer);

    if (dot_file != NULL) {
        dot_strm = fopen(dot_file, "w");
        if (dot_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", dot_file);
        }
    }

    if (dot_strm == NULL) {
        goto simulate;
    }

    init_dotfile();
    for (lpc = data_set.actions; lpc != NULL; lpc = lpc->next) {
        action_t *action = (action_t *) lpc->data;
        const char *style = "filled";
        const char *font = "black";
        const char *color = "black";
        const char *fill = NULL;
        char *action_name = create_action_name(action);

        crm_trace("Action %d: %p", action->id, action);

        if (is_set(action->flags, pe_action_pseudo)) {
            font = "orange";
        }

        style = "dashed";
        if (is_set(action->flags, pe_action_dumped)) {
            style = "bold";
            color = "green";

        } else if (action->rsc != NULL && is_not_set(action->rsc->flags, pe_rsc_managed)) {
            color = "purple";
            if (all_actions == FALSE) {
                goto dont_write;
            }

        } else if (is_set(action->flags, pe_action_optional)) {
            color = "blue";
            if (all_actions == FALSE) {
                goto dont_write;
            }

        } else {
            color = "red";
            CRM_CHECK(is_set(action->flags, pe_action_runnable) == FALSE,;
                );
        }

        set_bit_inplace(action->flags, pe_action_dumped);
        dot_write("\"%s\" [ style=%s color=\"%s\" fontcolor=\"%s\"  %s%s]",
                  action_name, style, color, font, fill ? "fillcolor=" : "", fill ? fill : "");
  dont_write:
        crm_free(action_name);
    }
Ejemplo n.º 8
0
int
main(int argc, char **argv)
{
    xmlNode *cib_object = NULL;
    xmlNode *status = NULL;
    int argerr = 0;
    int flag;
    int option_index = 0;

    pe_working_set_t data_set;
    cib_t *cib_conn = NULL;
    int rc = cib_ok;

    gboolean xml_stdin = FALSE;
    const char *xml_tag = NULL;
    const char *xml_file = NULL;
    const char *xml_string = NULL;

    g_log_set_handler(NULL,
                      G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL
                      | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE
                      | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG
                      | G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL, cl_glib_msg_handler, NULL);

    /* and for good measure... - this enum is a bit field (!) */
    g_log_set_always_fatal((GLogLevelFlags) 0); /*value out of range */

    crm_log_init_quiet(NULL, LOG_ERR, FALSE, TRUE, argc, argv);
    crm_set_options(NULL, "[modifiers] data_source", long_options,
                    "Check a (complete) confiuration for syntax and common conceptual errors."
                    "\n\nChecks the well-formedness of an XML configuration, its conformance to the configured DTD/schema and for the presence of common misconfigurations."
                    "\n\nIt reports two classes of problems, errors and warnings."
                    " Errors must be fixed before the cluster will work properly."
                    " However, it is left up to the administrator to decide if the warnings should also be fixed.");

    while (1) {
        flag = crm_get_option(argc, argv, &option_index);
        if (flag == -1)
            break;

        switch (flag) {
#ifdef HAVE_GETOPT_H
            case 0:
                printf("option %s", long_options[option_index].name);
                if (optarg)
                    printf(" with arg %s", optarg);
                printf("\n");

                break;
#endif

            case 'X':
                crm_debug_2("Option %c => %s", flag, optarg);
                xml_string = crm_strdup(optarg);
                break;
            case 'x':
                crm_debug_2("Option %c => %s", flag, optarg);
                xml_file = crm_strdup(optarg);
                break;
            case 'p':
                xml_stdin = TRUE;
                break;
            case 'S':
                cib_save = crm_strdup(optarg);
                break;
            case 'V':
                alter_debug(DEBUG_INC);
                break;
            case 'L':
                USE_LIVE_CIB = TRUE;
                break;
            case '$':
            case '?':
                crm_help(flag, LSB_EXIT_OK);
                break;
            default:
                fprintf(stderr, "Option -%c is not yet supported\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) {
        crm_err("%d errors in option parsing", argerr);
        crm_help(flag, LSB_EXIT_GENERIC);
    }

    crm_info("=#=#=#=#= Getting XML =#=#=#=#=");

    if (USE_LIVE_CIB) {
        cib_conn = cib_new();
        rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command);
    }

    if (USE_LIVE_CIB) {
        if (rc == cib_ok) {
            int options = cib_scope_local | cib_sync_call;

            crm_info("Reading XML from: live cluster");
            rc = cib_conn->cmds->query(cib_conn, NULL, &cib_object, options);
        }

        if (rc != cib_ok) {
            fprintf(stderr, "Live CIB query failed: %s\n", cib_error2string(rc));
            return 3;
        }
        if (cib_object == NULL) {
            fprintf(stderr, "Live CIB query failed: empty result\n");
            return 3;
        }

    } else if (xml_file != NULL) {
        cib_object = filename2xml(xml_file);
        if (cib_object == NULL) {
            fprintf(stderr, "Couldn't parse input file: %s\n", xml_file);
            return 4;
        }

    } else if (xml_string != NULL) {
        cib_object = string2xml(xml_string);
        if (cib_object == NULL) {
            fprintf(stderr, "Couldn't parse input string: %s\n", xml_string);
            return 4;
        }
    } else if (xml_stdin) {
        cib_object = stdin2xml();
        if (cib_object == NULL) {
            fprintf(stderr, "Couldn't parse input from STDIN.\n");
            return 4;
        }

    } else {
        fprintf(stderr, "No configuration source specified."
                "  Use --help for usage information.\n");
        return 5;
    }

    xml_tag = crm_element_name(cib_object);
    if (safe_str_neq(xml_tag, XML_TAG_CIB)) {
        fprintf(stderr,
                "This tool can only check complete configurations (ie. those starting with <cib>).\n");
        return 6;
    }

    if (cib_save != NULL) {
        write_xml_file(cib_object, cib_save, FALSE);
    }

    status = get_object_root(XML_CIB_TAG_STATUS, cib_object);
    if (status == NULL) {
        create_xml_node(cib_object, XML_CIB_TAG_STATUS);
    }

    if (validate_xml(cib_object, NULL, FALSE) == FALSE) {
        crm_config_err("CIB did not pass DTD/schema validation");
        free_xml(cib_object);
        cib_object = NULL;

    } else if (cli_config_update(&cib_object, NULL, FALSE) == FALSE) {
        crm_config_error = TRUE;
        free_xml(cib_object);
        cib_object = NULL;
        fprintf(stderr, "The cluster will NOT be able to use this configuration.\n");
        fprintf(stderr, "Please manually update the configuration to conform to the %s syntax.\n",
                LATEST_SCHEMA_VERSION);
    }

    set_working_set_defaults(&data_set);
    if (cib_object == NULL) {
    } else if (USE_LIVE_CIB) {
        /* we will always have a status section and can do a full simulation */
        do_calculations(&data_set, cib_object, NULL);
        cleanup_alloc_calculations(&data_set);

    } else {
        data_set.now = new_ha_date(TRUE);
        data_set.input = cib_object;
        stage0(&data_set);
        cleanup_alloc_calculations(&data_set);
    }

    if (crm_config_error) {
        fprintf(stderr, "Errors found during check: config not valid\n");
        if (crm_log_level < LOG_WARNING) {
            fprintf(stderr, "  -V may provide more details\n");
        }
        rc = 2;

    } else if (crm_config_warning) {
        fprintf(stderr, "Warnings found during check: config may not be valid\n");
        if (crm_log_level < LOG_WARNING) {
            fprintf(stderr, "  Use -V for more details\n");
        }
        rc = 1;
    }

    if (USE_LIVE_CIB) {
        cib_conn->cmds->signoff(cib_conn);
        cib_delete(cib_conn);
    }

    return rc;
}
Ejemplo n.º 9
0
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;
        pe_working_set_t data_set;
        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;

        set_working_set_defaults(&data_set);

        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) {
            data_set.graph = create_xml_node(NULL, XML_TAG_GRAPH);
            crm_xml_add_int(data_set.graph, "transition_id", 0);
            crm_xml_add_int(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(&data_set, converted, NULL);
        }

        series_id = get_series();
        series_wrap = series[series_id].wrap;
        value = pe_pref(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);

        data_set.input = NULL;
        reply = create_reply(msg, 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) {
            crm_err("Couldn't send transition graph to peer, discarding");
        }

        free_xml(reply);
        cleanup_alloc_calculations(&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 PE 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;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
gboolean
process_pe_message(xmlNode *msg, xmlNode *xml_data, IPC_Channel *sender)
{
    gboolean send_via_disk = FALSE;
    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, XML_ATTR_REFERENCE);

    crm_debug_3("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_debug_3("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 *filename = NULL;
        char *graph_file = NULL;
        const char *value = NULL;
        pe_working_set_t data_set;
        xmlNode *converted = NULL;
        xmlNode *reply = NULL;
        gboolean process = TRUE;
#if HAVE_BZLIB_H
        gboolean compress = TRUE;
#else
        gboolean compress = FALSE;
#endif

        crm_config_error = FALSE;
        crm_config_warning = FALSE;

        was_processing_error = FALSE;
        was_processing_warning = FALSE;

        graph_file = crm_strdup(CRM_STATE_DIR"/graph.XXXXXX");
        graph_file = mktemp(graph_file);

        converted = copy_xml(xml_data);
        if(cli_config_update(&converted, NULL, TRUE) == FALSE) {
            set_working_set_defaults(&data_set);
            data_set.graph = create_xml_node(NULL, XML_TAG_GRAPH);
            crm_xml_add_int(data_set.graph, "transition_id", 0);
            crm_xml_add_int(data_set.graph, "cluster-delay", 0);
            process = FALSE;
        }

        if(process) {
            do_calculations(&data_set, converted, NULL);
        }

        series_id = get_series();
        series_wrap = series[series_id].wrap;
        value = pe_pref(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);

        data_set.input = NULL;
        reply = create_reply(msg, data_set.graph);
        CRM_ASSERT(reply != NULL);

        filename = generate_series_filename(
                       PE_STATE_DIR, series[series_id].name, seq, compress);
        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(send_ipc_message(sender, reply) == FALSE) {
            if(sender && sender->ops->get_chan_status(sender) == IPC_CONNECT) {
                send_via_disk = TRUE;
                crm_err("Answer could not be sent via IPC, send via the disk instead");
                crm_info("Writing the TE graph to %s", graph_file);
                if(write_xml_file(data_set.graph, graph_file, FALSE) < 0) {
                    crm_err("TE graph could not be written to disk");
                }
            } else {
                crm_info("Peer disconnected, discarding transition graph");
            }
        }

        free_xml(reply);
        cleanup_alloc_calculations(&data_set);

        if(series_wrap != 0) {
            write_xml_file(xml_data, filename, compress);
            write_last_sequence(PE_STATE_DIR, series[series_id].name,
                                seq+1, series_wrap);
        }

        if(was_processing_error) {
            crm_err("Transition %d:"
                    " ERRORs found during PE processing."
                    " PEngine Input stored in: %s",
                    transition_id, filename);

        } else if(was_processing_warning) {
            crm_warn("Transition %d:"
                     " WARNINGs found during PE processing."
                     " PEngine Input stored in: %s",
                     transition_id, filename);

        } else {
            crm_info("Transition %d: PEngine Input stored in: %s",
                     transition_id, filename);
        }

        if(crm_config_error) {
            crm_info("Configuration ERRORs found during PE processing."
                     "  Please run \"crm_verify -L\" to identify issues.");

        } else if(crm_config_warning) {
            crm_info("Configuration WARNINGs found during PE processing."
                     "  Please run \"crm_verify -L\" to identify issues.");
        }

        if(send_via_disk) {
            reply = create_reply(msg, NULL);
            crm_xml_add(reply, F_CRM_TGRAPH, graph_file);
            crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
            CRM_ASSERT(reply != NULL);
            if(send_ipc_message(sender, reply) == FALSE) {
                crm_err("Answer could not be sent");
            }
            free_xml(reply);
        }

        free_xml(converted);
        crm_free(graph_file);
        crm_free(filename);

    } else if(strcasecmp(op, CRM_OP_QUIT) == 0) {
        crm_warn("Received quit message, terminating");
        exit(0);
    }

    return TRUE;
}
Ejemplo n.º 12
0
int
main(int argc, char **argv)
{
    xmlNode *cib_object = NULL;
    xmlNode *status = NULL;
    int argerr = 0;
    int flag;
    int option_index = 0;

    pe_working_set_t data_set;
    cib_t *cib_conn = NULL;
    int rc = pcmk_ok;

    bool verbose = FALSE;
    gboolean xml_stdin = FALSE;
    const char *xml_tag = NULL;
    const char *xml_file = NULL;
    const char *xml_string = NULL;

    crm_log_cli_init("crm_verify");
    crm_set_options(NULL, "[modifiers] data_source", long_options,
                    "Check a (complete) confiuration for syntax and common conceptual errors."
                    "\n\nChecks the well-formedness of an XML configuration, its conformance to the configured DTD/schema and for the presence of common misconfigurations."
                    "\n\nIt reports two classes of problems, errors and warnings."
                    " Errors must be fixed before the cluster will work properly."
                    " However, it is left up to the administrator to decide if the warnings should also be fixed.");

    while (1) {
        flag = crm_get_option(argc, argv, &option_index);
        if (flag == -1)
            break;

        switch (flag) {
            case 'X':
                crm_trace("Option %c => %s", flag, optarg);
                xml_string = optarg;
                break;
            case 'x':
                crm_trace("Option %c => %s", flag, optarg);
                xml_file = optarg;
                break;
            case 'p':
                xml_stdin = TRUE;
                break;
            case 'S':
                cib_save = optarg;
                break;
            case 'V':
                verbose = TRUE;
                crm_bump_log_level(argc, argv);
                break;
            case 'L':
                USE_LIVE_CIB = TRUE;
                break;
            case '$':
            case '?':
                crm_help(flag, EX_OK);
                break;
            default:
                fprintf(stderr, "Option -%c is not yet supported\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) {
        crm_err("%d errors in option parsing", argerr);
        crm_help(flag, EX_USAGE);
    }

    crm_info("=#=#=#=#= Getting XML =#=#=#=#=");

    if (USE_LIVE_CIB) {
        cib_conn = cib_new();
        rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command);
    }

    if (USE_LIVE_CIB) {
        if (rc == pcmk_ok) {
            int options = cib_scope_local | cib_sync_call;

            crm_info("Reading XML from: live cluster");
            rc = cib_conn->cmds->query(cib_conn, NULL, &cib_object, options);
        }

        if (rc != pcmk_ok) {
            fprintf(stderr, "Live CIB query failed: %s\n", pcmk_strerror(rc));
            goto done;
        }
        if (cib_object == NULL) {
            fprintf(stderr, "Live CIB query failed: empty result\n");
            rc = -ENOMSG;
            goto done;
        }

    } else if (xml_file != NULL) {
        cib_object = filename2xml(xml_file);
        if (cib_object == NULL) {
            fprintf(stderr, "Couldn't parse input file: %s\n", xml_file);
            rc = -ENODATA;
            goto done;
        }

    } else if (xml_string != NULL) {
        cib_object = string2xml(xml_string);
        if (cib_object == NULL) {
            fprintf(stderr, "Couldn't parse input string: %s\n", xml_string);
            rc = -ENODATA;
            goto done;
        }
    } else if (xml_stdin) {
        cib_object = stdin2xml();
        if (cib_object == NULL) {
            fprintf(stderr, "Couldn't parse input from STDIN.\n");
            rc = -ENODATA;
            goto done;
        }

    } else {
        fprintf(stderr, "No configuration source specified."
                "  Use --help for usage information.\n");
        rc = -ENODATA;
        goto done;
    }

    xml_tag = crm_element_name(cib_object);
    if (safe_str_neq(xml_tag, XML_TAG_CIB)) {
        fprintf(stderr,
                "This tool can only check complete configurations (ie. those starting with <cib>).\n");
        rc = -EBADMSG;
        goto done;
    }

    if (cib_save != NULL) {
        write_xml_file(cib_object, cib_save, FALSE);
    }

    status = get_object_root(XML_CIB_TAG_STATUS, cib_object);
    if (status == NULL) {
        create_xml_node(cib_object, XML_CIB_TAG_STATUS);
    }

    if (validate_xml(cib_object, NULL, FALSE) == FALSE) {
        crm_config_err("CIB did not pass DTD/schema validation");
        free_xml(cib_object);
        cib_object = NULL;

    } else if (cli_config_update(&cib_object, NULL, FALSE) == FALSE) {
        crm_config_error = TRUE;
        free_xml(cib_object);
        cib_object = NULL;
        fprintf(stderr, "The cluster will NOT be able to use this configuration.\n");
        fprintf(stderr, "Please manually update the configuration to conform to the %s syntax.\n",
                xml_latest_schema());
    }

    set_working_set_defaults(&data_set);
    if (cib_object == NULL) {
    } else if (USE_LIVE_CIB) {
        /* we will always have a status section and can do a full simulation */
        do_calculations(&data_set, cib_object, NULL);
        cleanup_alloc_calculations(&data_set);

    } else {
        data_set.now = crm_time_new(NULL);
        data_set.input = cib_object;
        stage0(&data_set);
        cleanup_alloc_calculations(&data_set);
    }

    if (crm_config_error) {
        fprintf(stderr, "Errors found during check: config not valid\n");
        if (verbose == FALSE) {
            fprintf(stderr, "  -V may provide more details\n");
        }
        rc = -pcmk_err_generic;

    } else if (crm_config_warning) {
        fprintf(stderr, "Warnings found during check: config may not be valid\n");
        if (verbose == FALSE) {
            fprintf(stderr, "  Use -V for more details\n");
        }
        rc = -pcmk_err_generic;
    }

    if (USE_LIVE_CIB && cib_conn) {
        cib_conn->cmds->signoff(cib_conn);
        cib_delete(cib_conn);
    }

  done:
    return rc;
}