示例#1
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;
}
示例#2
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);
    }
示例#3
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;
}
示例#4
0
文件: pengine.c 项目: beess/pacemaker
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;
}
示例#5
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;
}
示例#6
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;
}