示例#1
0
文件: main.c 项目: beess/pacemaker
int
main(int argc, char **argv)
{
    int rc = pcmk_ok;
    int flag = 0;
    int index = 0;
    int argerr = 0;
    qb_ipcs_service_t *ipcs = NULL;

    mloop = g_main_new(FALSE);
    crm_log_preinit(NULL, argc, argv);
    crm_set_options(NULL, "[options]", long_options,
                    "Daemon for aggregating and atomically storing node attribute updates into the CIB");

    mainloop_add_signal(SIGTERM, attrd_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(flag, EX_OK);
                break;
            default:
                ++argerr;
                break;
        }
    }

    if (optind > argc) {
        ++argerr;
    }

    if (argerr) {
        crm_help('?', EX_USAGE);
    }

    crm_log_init(T_ATTRD, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
    crm_info("Starting up");
    attributes = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, free_attribute);

    attrd_cluster = malloc(sizeof(crm_cluster_t));

    attrd_cluster->destroy = attrd_cpg_destroy;
    attrd_cluster->cpg.cpg_deliver_fn = attrd_cpg_dispatch;
    attrd_cluster->cpg.cpg_confchg_fn = pcmk_cpg_membership;

    crm_set_status_callback(&attrd_peer_change_cb);

    if (crm_cluster_connect(attrd_cluster) == FALSE) {
        crm_err("Cluster connection failed");
        rc = DAEMON_RESPAWN_STOP;
        goto done;
    }
    crm_info("Cluster connection active");

    writer = election_init(T_ATTRD, attrd_cluster->uname, 120000, attrd_election_cb);
    attrd_ipc_server_init(&ipcs, &ipc_callbacks);
    crm_info("Accepting attribute updates");

    the_cib = attrd_cib_connect(10);
    if (the_cib == NULL) {
        rc = DAEMON_RESPAWN_STOP;
        goto done;
    }

    crm_info("CIB connection active");
    g_main_run(mloop);

  done:
    crm_info("Shutting down attribute manager");

    election_fini(writer);
    if (ipcs) {
        crm_client_disconnect_all(ipcs);
        qb_ipcs_destroy(ipcs);
        g_hash_table_destroy(attributes);
    }

    if (the_cib) {
        the_cib->cmds->signoff(the_cib);
        cib_delete(the_cib);
    }

    if(attrd_error) {
        return crm_exit(attrd_error);
    }
    return crm_exit(rc);
}
示例#2
0
int
main(int argc, char **argv)
{
    cib_t *the_cib = NULL;
    int rc = pcmk_ok;

    int cib_opts = cib_sync_call;
    int argerr = 0;
    int flag;

    int option_index = 0;
    int is_remote_node = 0;

    crm_log_cli_init("crm_attribute");
    crm_set_options(NULL, "command -n attribute [options]", long_options,
                    "Manage node's attributes and cluster options."
                    "\n\nAllows node attributes and cluster options to be queried, modified and deleted.\n");

    if (argc < 2) {
        crm_help('?', EX_USAGE);
    }

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

        switch (flag) {
            case 'V':
                crm_bump_log_level(argc, argv);
                break;
            case '$':
            case '?':
                crm_help(flag, EX_OK);
                break;
            case 'D':
            case 'G':
            case 'v':
                command = flag;
                attr_value = optarg;
                break;
            case 'q':
            case 'Q':
                BE_QUIET = TRUE;
                break;
            case 'U':
            case 'N':
                dest_uname = strdup(optarg);
                break;
            case 'u':
                dest_node = strdup(optarg);
                break;
            case 's':
                set_name = strdup(optarg);
                break;
            case 'l':
            case 't':
                type = optarg;
                break;
            case 'z':
                type = XML_CIB_TAG_NODES;
                set_type = XML_TAG_UTILIZATION;
                break;
            case 'n':
                attr_name = strdup(optarg);
                break;
            case 'i':
                attr_id = strdup(optarg);
                break;
            case 'r':
                rsc_id = optarg;
                break;
            case 'd':
                attr_default = optarg;
                break;
            case '!':
                crm_warn("Inhibiting notifications for this update");
                cib_opts |= cib_inhibit_notify;
                break;
            default:
                printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, 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_help('?', EX_USAGE);
    }

    the_cib = cib_new();
    rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command);

    if (rc != pcmk_ok) {
        fprintf(stderr, "Error signing on to the CIB service: %s\n", pcmk_strerror(rc));
        return crm_exit(rc);
    }

    if (safe_str_eq(type, "reboot")) {
        type = XML_CIB_TAG_STATUS;

    } else if (safe_str_eq(type, "forever")) {
        type = XML_CIB_TAG_NODES;
    }

    if (type == NULL && dest_uname == NULL) {
        /* we're updating cluster options - dont populate dest_node */
        type = XML_CIB_TAG_CRMCONFIG;

    } else if (safe_str_neq(type, XML_CIB_TAG_TICKETS)) {
        if (dest_uname == NULL) {
            dest_uname = get_local_node_name();
        }
        if (pcmk_ok != query_node_uuid(the_cib, dest_uname, &dest_node, &is_remote_node)) {
            fprintf(stderr, "Could not map name=%s to a UUID\n", dest_uname);
        }
    }

    if (is_remote_node && safe_str_neq(type, XML_CIB_TAG_STATUS)) {
        /* Only the status section can exists for remote_nodes */
        type = XML_CIB_TAG_STATUS;
        if (command == 'v') {
            fprintf(stderr, "Remote-nodes do not maintain permanent attributes, '%s=%s' will be removed after %s reboots.\n",
                attr_name, attr_value, dest_uname);
        }
    }

    if ((command == 'v' || command == 'D')
        && is_remote_node == FALSE /* always send remote node attr directly to cib */
        && safe_str_eq(type, XML_CIB_TAG_STATUS)
        && attrd_update_delegate(NULL, command, dest_uname, attr_name, attr_value, type, set_name,
                                 NULL, NULL)) {
        crm_info("Update %s=%s sent via attrd", attr_name, command == 'D' ? "<none>" : attr_value);

    } else if (command == 'D') {
        rc = delete_attr_delegate(the_cib, cib_opts, type, dest_node, set_type, set_name,
                                  attr_id, attr_name, attr_value, TRUE, NULL);

        if (rc == -ENXIO) {
            /* Nothing to delete...
             * which means its not there...
             * which is what the admin wanted
             */
            rc = pcmk_ok;
        } else if (rc != -EINVAL && safe_str_eq(crm_system_name, "crm_failcount")) {
            char *now_s = NULL;
            time_t now = time(NULL);

            now_s = crm_itoa(now);
            update_attr_delegate(the_cib, cib_sync_call, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL,
                                 NULL, "last-lrm-refresh", now_s, TRUE, NULL);
            free(now_s);
        }

    } else if (command == 'v') {
        CRM_LOG_ASSERT(type != NULL);
        CRM_LOG_ASSERT(attr_name != NULL);
        CRM_LOG_ASSERT(attr_value != NULL);

        rc = update_attr_delegate(the_cib, cib_opts, type, dest_node, set_type, set_name,
                                  attr_id, attr_name, attr_value, TRUE, NULL);

    } else {                    /* query */

        char *read_value = NULL;

        rc = read_attr_delegate(the_cib, type, dest_node, set_type, set_name,
                                attr_id, attr_name, &read_value, TRUE, NULL);

        if (rc == -ENXIO && attr_default) {
            read_value = strdup(attr_default);
            rc = pcmk_ok;
        }

        crm_info("Read %s=%s %s%s",
                 attr_name, crm_str(read_value), set_name ? "in " : "", set_name ? set_name : "");

        if (rc == -EINVAL) {
            rc = pcmk_ok;

        } else if (BE_QUIET == FALSE) {
            fprintf(stdout, "%s%s %s%s %s%s value=%s\n",
                    type ? "scope=" : "", type ? type : "",
                    attr_id ? "id=" : "", attr_id ? attr_id : "",
                    attr_name ? "name=" : "", attr_name ? attr_name : "",
                    read_value ? read_value : "(null)");

        } else if (read_value != NULL) {
            fprintf(stdout, "%s\n", read_value);
        }
    }

    if (rc == -EINVAL) {
        printf("Please choose from one of the matches above and suppy the 'id' with --attr-id\n");
    } else if (rc != pcmk_ok) {
        fprintf(stderr, "Error performing operation: %s\n", pcmk_strerror(rc));
    }

    the_cib->cmds->signoff(the_cib);
    cib_delete(the_cib);
    return crm_exit(rc);
}
示例#3
0
int
main(int argc, char **argv)
{
    int argerr = 0;
    int flag;
    const char *source = NULL;
    char *admin_input_xml = NULL;
    char *admin_input_file = NULL;
    gboolean dangerous_cmd = FALSE;
    gboolean admin_input_stdin = FALSE;
    xmlNode *output = NULL;
    xmlNode *input = NULL;

    int option_index = 0;

    crm_log_init(NULL, LOG_CRIT, FALSE, FALSE, argc, argv, FALSE);
    crm_set_options(NULL, "command [options] [data]", long_options,
                    "Provides direct access to the cluster configuration."
                    "\n\nAllows the configuration, or sections of it, to be queried, modified, replaced and deleted."
                    "\n\nWhere necessary, XML data will be obtained using the -X, -x, or -p options\n");

    if (argc < 2) {
        crm_help('?', LSB_EXIT_EINVAL);
    }

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

        switch (flag) {
            case 't':
                message_timeout_ms = atoi(optarg);
                if (message_timeout_ms < 1) {
                    message_timeout_ms = 30;
                }
                break;
            case 'A':
                obj_type = crm_strdup(optarg);
                command_options |= cib_xpath;
                break;
            case 'u':
                cib_action = CIB_OP_UPGRADE;
                dangerous_cmd = TRUE;
                break;
            case 'E':
                cib_action = CIB_OP_ERASE;
                dangerous_cmd = TRUE;
                break;
            case 'Q':
                cib_action = CIB_OP_QUERY;
                break;
            case 'P':
                cib_action = CIB_OP_APPLY_DIFF;
                break;
            case 'S':
                cib_action = CIB_OP_SYNC;
                break;
            case 'U':
            case 'M':
                cib_action = CIB_OP_MODIFY;
                break;
            case 'R':
                cib_action = CIB_OP_REPLACE;
                break;
            case 'C':
                cib_action = CIB_OP_CREATE;
                break;
            case 'D':
                cib_action = CIB_OP_DELETE;
                break;
            case '5':
                cib_action = "md5-sum";
                break;
            case '6':
                cib_action = "md5-sum-versioned";
                break;
            case 'c':
                command_options |= cib_can_create;
                break;
            case 'n':
                command_options |= cib_no_children;
                break;
            case 'm':
                cib_action = CIB_OP_ISMASTER;
                command_options |= cib_scope_local;
                break;
            case 'B':
                cib_action = CIB_OP_BUMP;
                break;
            case 'r':
                dangerous_cmd = TRUE;
                cib_action = CIB_OP_SLAVE;
                break;
            case 'w':
                dangerous_cmd = TRUE;
                cib_action = CIB_OP_MASTER;
                command_options |= cib_scope_local;
                break;
            case 'V':
                command_options = command_options | cib_verbose;
                crm_bump_log_level();
                break;
            case '?':
            case '$':
            case '!':
                crm_help(flag, LSB_EXIT_OK);
                break;
            case 'o':
                crm_trace("Option %c => %s", flag, optarg);
                obj_type = crm_strdup(optarg);
                break;
            case 'X':
                crm_trace("Option %c => %s", flag, optarg);
                admin_input_xml = crm_strdup(optarg);
                break;
            case 'x':
                crm_trace("Option %c => %s", flag, optarg);
                admin_input_file = crm_strdup(optarg);
                break;
            case 'p':
                admin_input_stdin = TRUE;
                break;
            case 'h':
                host = crm_strdup(optarg);
                break;
            case 'l':
                command_options |= cib_scope_local;
                break;
            case 'd':
                cib_action = CIB_OP_DELETE;
                command_options |= cib_multiple;
                dangerous_cmd = TRUE;
                break;
            case 'b':
                dangerous_cmd = TRUE;
                command_options |= cib_inhibit_bcast;
                command_options |= cib_scope_local;
                break;
            case 's':
                command_options |= cib_sync_call;
                break;
            case 'f':
                force_flag = TRUE;
                command_options |= cib_quorum_override;
                break;
            case 'a':
                output = createEmptyCib();
                crm_xml_add(output, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET);
                crm_xml_add(output, XML_ATTR_VALIDATION, LATEST_SCHEMA_VERSION);
                crm_xml_add_int(output, XML_ATTR_GENERATION_ADMIN, 1);
                crm_xml_add_int(output, XML_ATTR_GENERATION, 0);
                crm_xml_add_int(output, XML_ATTR_NUMUPDATES, 0);

                admin_input_xml = dump_xml_formatted(output);
                fprintf(stdout, "%s\n", crm_str(admin_input_xml));
                exit(0);
                break;
            default:
                printf("Argument code 0%o (%c)" " is not (?yet?) supported\n", flag, flag);
                ++argerr;
                break;
        }
    }

    if (optind < argc) {
        printf("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
        crm_help('?', LSB_EXIT_EINVAL);
    }

    if (optind > argc || cib_action == NULL) {
        ++argerr;
    }

    if (argerr) {
        crm_help('?', LSB_EXIT_GENERIC);
    }

    if (dangerous_cmd && force_flag == FALSE) {
        fprintf(stderr, "The supplied command is considered dangerous."
                "  To prevent accidental destruction of the cluster,"
                " the --force flag is required in order to proceed.\n");
        fflush(stderr);
        exit(LSB_EXIT_GENERIC);
    }

    if (admin_input_file != NULL) {
        input = filename2xml(admin_input_file);
        source = admin_input_file;

    } else if (admin_input_xml != NULL) {
        source = "input string";
        input = string2xml(admin_input_xml);

    } else if (admin_input_stdin) {
        source = "STDIN";
        input = stdin2xml();
    }

    if (input != NULL) {
        crm_log_xml_debug(input, "[admin input]");

    } else if (source) {
        fprintf(stderr, "Couldn't parse input from %s.\n", source);
        return 1;
    }

    if (safe_str_eq(cib_action, "md5-sum")) {
        char *digest = NULL;

        if (input == NULL) {
            fprintf(stderr, "Please supply XML to process with -X, -x or -p\n");
            exit(1);
        }

        digest = calculate_on_disk_digest(input);
        fprintf(stderr, "Digest: ");
        fprintf(stdout, "%s\n", crm_str(digest));
        crm_free(digest);
        exit(0);

    } else if (safe_str_eq(cib_action, "md5-sum-versioned")) {
        char *digest = NULL;
        const char *version = NULL;

        if (input == NULL) {
            fprintf(stderr, "Please supply XML to process with -X, -x or -p\n");
            exit(1);
        }

        version = crm_element_value(input, XML_ATTR_CRM_VERSION);
        digest = calculate_xml_versioned_digest(input, FALSE, TRUE, version);
        fprintf(stderr, "Versioned (%s) digest: ", version);
        fprintf(stdout, "%s\n", crm_str(digest));
        crm_free(digest);
        exit(0);
    }
    
    exit_code = do_init();
    if (exit_code != cib_ok) {
        crm_err("Init failed, could not perform requested operations");
        fprintf(stderr, "Init failed, could not perform requested operations\n");
        return -exit_code;
    }

    exit_code = do_work(input, command_options, &output);
    if (exit_code > 0) {
        /* wait for the reply by creating a mainloop and running it until
         * the callbacks are invoked...
         */
        request_id = exit_code;

        the_cib->cmds->register_callback(the_cib, request_id, message_timeout_ms, FALSE, NULL,
                                         "cibadmin_op_callback", cibadmin_op_callback);

        mainloop = g_main_new(FALSE);

        crm_trace("%s waiting for reply from the local CIB", crm_system_name);

        crm_info("Starting mainloop");
        g_main_run(mainloop);

    } else if (exit_code < 0) {
        crm_err("Call failed: %s", cib_error2string(exit_code));
        fprintf(stderr, "Call failed: %s\n", cib_error2string(exit_code));
        operation_status = exit_code;

        if (exit_code == cib_dtd_validation) {
            if (crm_str_eq(cib_action, CIB_OP_UPGRADE, TRUE)) {
                xmlNode *obj = NULL;
                int version = 0, rc = 0;

                rc = the_cib->cmds->query(the_cib, NULL, &obj, command_options);
                if (rc == cib_ok) {
                    update_validation(&obj, &version, TRUE, FALSE);
                }

            } else if (output) {
                validate_xml_verbose(output);
            }
        }
    }

    if (output != NULL) {
        char *buffer = dump_xml_formatted(output);

        fprintf(stdout, "%s\n", crm_str(buffer));
        crm_free(buffer);
        free_xml(output);
    }

    crm_trace("%s exiting normally", crm_system_name);

    free_xml(input);
    crm_free(admin_input_xml);
    crm_free(admin_input_file);
    the_cib->cmds->signoff(the_cib);
    cib_delete(the_cib);
    crm_xml_cleanup();

    return -exit_code;
}
示例#4
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;

    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) {
#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_trace("Option %c => %s", flag, optarg);
                xml_string = crm_strdup(optarg);
                break;
            case 'x':
                crm_trace("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':
                crm_bump_log_level();
                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 (get_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 (get_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;
}