示例#1
0
crm_graph_t *
unpack_graph(xmlNode * xml_graph, const char *reference)
{
/*
  <transition_graph>
  <synapse>
  <action_set>
  <rsc_op id="2"
  ... 
  <inputs>
  <rsc_op id="2"
  ... 
*/
    crm_graph_t *new_graph = NULL;
    const char *t_id = NULL;
    const char *time = NULL;
    xmlNode *synapse = NULL;

    crm_malloc0(new_graph, sizeof(crm_graph_t));

    new_graph->id = -1;
    new_graph->abort_priority = 0;
    new_graph->network_delay = -1;
    new_graph->transition_timeout = -1;
    new_graph->stonith_timeout = -1;
    new_graph->completion_action = tg_done;

    new_graph->migrating = g_hash_table_new_full(crm_str_hash, g_str_equal,
                                                 g_hash_destroy_str, g_hash_destroy_str);

    if (reference) {
        new_graph->source = crm_strdup(reference);
    } else {
        new_graph->source = crm_strdup("unknown");
    }

    if (xml_graph != NULL) {
        t_id = crm_element_value(xml_graph, "transition_id");
        CRM_CHECK(t_id != NULL, crm_free(new_graph);
                  return NULL);
        new_graph->id = crm_parse_int(t_id, "-1");

        time = crm_element_value(xml_graph, "cluster-delay");
        CRM_CHECK(time != NULL, crm_free(new_graph);
                  return NULL);
        new_graph->network_delay = crm_get_msec(time);

        time = crm_element_value(xml_graph, "stonith-timeout");
        if (time == NULL) {
            new_graph->stonith_timeout = new_graph->network_delay;
        } else {
            new_graph->stonith_timeout = crm_get_msec(time);
        }

        t_id = crm_element_value(xml_graph, "batch-limit");
        new_graph->batch_limit = crm_parse_int(t_id, "0");

        t_id = crm_element_value(xml_graph, "migration-limit");
        new_graph->migration_limit = crm_parse_int(t_id, "-1");
    }
示例#2
0
gboolean
check_sbd_timeout(const char *value)
{
    long st_timeout = value? crm_get_msec(value) : 0;

    if (st_timeout <= 0) {
        crm_debug("Watchdog may be enabled but stonith-watchdog-timeout is disabled (%s)",
                  value? value : "default");

    } else if (pcmk_locate_sbd() == 0) {
        do_crm_log_always(LOG_EMERG,
                          "Shutting down: stonith-watchdog-timeout configured (%s) but SBD not active",
                          value);
        crm_exit(DAEMON_RESPAWN_STOP);
        return FALSE;

    } else {
        long sbd_timeout = crm_get_sbd_timeout();

        if (st_timeout < sbd_timeout) {
            do_crm_log_always(LOG_EMERG,
                              "Shutting down: stonith-watchdog-timeout (%s) too short (must be >%ldms)",
                              value, sbd_timeout);
            crm_exit(DAEMON_RESPAWN_STOP);
            return FALSE;
        }
        crm_info("Watchdog configured with stonith-watchdog-timeout %s and SBD timeout %ldms",
                 value, sbd_timeout);
    }
    return TRUE;
}
示例#3
0
static attribute_t *
create_attribute(xmlNode *xml)
{
    int dampen = 0;
    const char *value = crm_element_value_copy(xml, F_ATTRD_DAMPEN);
    attribute_t *a = calloc(1, sizeof(attribute_t));

    a->id      = crm_element_value_copy(xml, F_ATTRD_ATTRIBUTE);
    a->set     = crm_element_value_copy(xml, F_ATTRD_SET);
    a->uuid    = crm_element_value_copy(xml, F_ATTRD_KEY);
    a->values = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, free_attribute_value);

#if ENABLE_ACL
    crm_trace("Performing all %s operations as user '%s'", a->id, a->user);
    a->user = crm_element_value_copy(xml, F_ATTRD_USER);
#endif

    if(value) {
        dampen = crm_get_msec(value);
        crm_trace("Created attribute %s with delay %dms (%s)", a->id, dampen, value);
    } else {
        crm_trace("Created attribute %s with no delay", a->id);
    }

    if(dampen > 0) {
        a->timeout_ms = dampen;
        a->timer = mainloop_timer_add(strdup(a->id), a->timeout_ms, FALSE, attribute_timer_cb, a);
    }

    g_hash_table_replace(attributes, a->id, a);
    return a;
}
示例#4
0
gboolean
check_timer(const char *value) 
{
	if(crm_get_msec(value) < 0) {
		return FALSE;
	}
	return TRUE;
}
示例#5
0
long
crm_get_sbd_timeout(void)
{
    const char *env_value = getenv("SBD_WATCHDOG_TIMEOUT");
    long sbd_timeout = crm_get_msec(env_value);

    return sbd_timeout;
}
示例#6
0
static gboolean
is_matched_failure(const char *rsc_id, xmlNode *conf_op_xml,
                   xmlNode *lrm_op_xml)
{
    gboolean matched = FALSE;
    const char *conf_op_name = NULL;
    int conf_op_interval = 0;
    const char *lrm_op_task = NULL;
    int lrm_op_interval = 0;
    const char *lrm_op_id = NULL;
    char *last_failure_key = NULL;

    if (rsc_id == NULL || conf_op_xml == NULL || lrm_op_xml == NULL) {
        return FALSE;
    }

    conf_op_name = crm_element_value(conf_op_xml, "name");
    conf_op_interval = crm_get_msec(crm_element_value(conf_op_xml, "interval"));
    lrm_op_task = crm_element_value(lrm_op_xml, XML_LRM_ATTR_TASK);
    crm_element_value_int(lrm_op_xml, XML_LRM_ATTR_INTERVAL, &lrm_op_interval);

    if (safe_str_eq(conf_op_name, lrm_op_task) == FALSE
        || conf_op_interval != lrm_op_interval) {
        return FALSE;
    }

    lrm_op_id = ID(lrm_op_xml);
    last_failure_key = generate_op_key(rsc_id, "last_failure", 0);

    if (safe_str_eq(last_failure_key, lrm_op_id)) {
        matched = TRUE;

    } else {
        char *expected_op_key = generate_op_key(rsc_id, conf_op_name,
                                                conf_op_interval);

        if (safe_str_eq(expected_op_key, lrm_op_id)) {
            int rc = 0;
            int target_rc = get_target_rc(lrm_op_xml);

            crm_element_value_int(lrm_op_xml, XML_LRM_ATTR_RC, &rc);
            if (rc != target_rc) {
                matched = TRUE;
            }
        }
        free(expected_op_key);
    }

    free(last_failure_key);
    return matched;
}
示例#7
0
unsigned long long
crm_get_interval(const char * input)
{
    ha_time_t *interval = NULL;
    char *input_copy = crm_strdup(input);
    char *input_copy_mutable = input_copy;
    unsigned long long msec = 0;
    
    if(input == NULL) {
	return 0;

    } else if(input[0] != 'P') {
	crm_free(input_copy);
	return crm_get_msec(input);
    }
    
    interval = parse_time_duration(&input_copy_mutable);
    msec = date_in_seconds(interval);
    free_ha_date(interval);
    crm_free(input_copy);
    return msec * 1000;
}
示例#8
0
文件: utils.c 项目: beekhof/pacemaker
unsigned long long
crm_get_interval(const char *input)
{
    unsigned long long msec = 0;

    if (input == NULL) {
        return msec;

    } else if (input[0] != 'P') {
        long long tmp = crm_get_msec(input);

        if(tmp > 0) {
            msec = tmp;
        }

    } else {
        crm_time_t *interval = crm_time_parse_duration(input);

        msec = 1000 * crm_time_get_seconds(interval);
        crm_time_free(interval);
    }

    return msec;
}
示例#9
0
gboolean
check_sbd_timeout(const char *value)
{
    long sbd_timeout = crm_get_sbd_timeout();
    long st_timeout = crm_get_msec(value);

    if(value == NULL || st_timeout <= 0) {
        crm_notice("Watchdog may be enabled but stonith-watchdog-timeout is disabled: %s", value);

    } else if(pcmk_locate_sbd() == 0) {
        do_crm_log_always(LOG_EMERG, "Shutting down: stonith-watchdog-timeout is configured (%ldms) but SBD is not active", st_timeout);
        crm_exit(DAEMON_RESPAWN_STOP);
        return FALSE;

    } else if(st_timeout < sbd_timeout) {
        do_crm_log_always(LOG_EMERG, "Shutting down: stonith-watchdog-timeout (%ldms) is too short (must be greater than %ldms)",
                          st_timeout, sbd_timeout);
        crm_exit(DAEMON_RESPAWN_STOP);
        return FALSE;
    }

    crm_info("Watchdog functionality is consistent: %s delay exceeds timeout of %ldms", value, sbd_timeout);
    return TRUE;
}
示例#10
0
文件: commands.c 项目: lge/pacemaker
void
attrd_peer_update(crm_node_t *peer, xmlNode *xml, const char *host, bool filter)
{
    bool changed = FALSE;
    attribute_t *a;
    attribute_value_t *v = NULL;
    int dampen = 0;

    const char *op = crm_element_value(xml, F_ATTRD_TASK);
    const char *attr = crm_element_value(xml, F_ATTRD_ATTRIBUTE);
    const char *value = crm_element_value(xml, F_ATTRD_VALUE);
    const char *dvalue = crm_element_value(xml, F_ATTRD_DAMPEN);

    if (attr == NULL) {
        crm_warn("Peer update did not specify attribute");
        return;
    }

    a = g_hash_table_lookup(attributes, attr);
    if(a == NULL) {
        if (op == NULL /* The xml children from an ATTRD_OP_SYNC_RESPONSE have no F_ATTRD_TASK */
            || safe_str_eq(op, ATTRD_OP_UPDATE)
            || safe_str_eq(op, ATTRD_OP_UPDATE_BOTH)) {
            a = create_attribute(xml);
        } else {
            crm_warn("Update error (attribute %s not found)", attr);
            return;
        }
    }
    
    if (op == NULL /* The xml children from an ATTRD_OP_SYNC_RESPONSE have no F_ATTRD_TASK */
        || safe_str_eq(op, ATTRD_OP_UPDATE_BOTH)
        || safe_str_eq(op, ATTRD_OP_UPDATE_DELAY)) {
        if (dvalue) {
            dampen = crm_get_msec(dvalue); 
            if (dampen >= 0) {
                if (a->timeout_ms != dampen) {
                    mainloop_timer_stop(a->timer);
                    mainloop_timer_del(a->timer);
                    a->timeout_ms = dampen;
                    if (dampen > 0) {
                        a->timer = mainloop_timer_add(a->id, a->timeout_ms, FALSE, attribute_timer_cb, a);
                        crm_info("Update attribute %s with delay %dms (%s)", a->id, dampen, dvalue);
                    } else {
                        a->timer = NULL;
                        crm_info("Update attribute %s with not delay", a->id);
                    }
                    //if dampen is changed, attrd writes in a current value immediately.
                    write_or_elect_attribute(a);
                    if (safe_str_eq(op, ATTRD_OP_UPDATE_DELAY)) {
                        return;
                    }
                } else {
                    if (safe_str_eq(op, ATTRD_OP_UPDATE_DELAY)) {
                        crm_trace("Unchanged attribute %s with delay %dms (%s).(ATTRD_OP_UPDATE_DELAY)", a->id, dampen, dvalue);
                        return;
                    }
                }
            } else {
                crm_warn("Update error (A positive number is necessary for delay parameter. attribute %s : %dms (%s))", a->id, dampen, dvalue);
                return;
            }
        } else {
            crm_warn("Update error (delay parameter is necessary for the update of the attribute %s)", a->id);
            return;
        }
    }

    if(host == NULL) {
        GHashTableIter vIter;
        g_hash_table_iter_init(&vIter, a->values);

        crm_debug("Setting %s for all hosts to %s", attr, value);

        xml_remove_prop(xml, F_ATTRD_HOST_ID);
        while (g_hash_table_iter_next(&vIter, (gpointer *) & host, NULL)) {
            attrd_peer_update(peer, xml, host, filter);
        }
        return;
    }

    v = attrd_lookup_or_create_value(a->values, host, xml);

    if(filter
              && safe_str_neq(v->current, value)
              && safe_str_eq(host, attrd_cluster->uname)) {
        xmlNode *sync = create_xml_node(NULL, __FUNCTION__);
        crm_notice("%s[%s]: local value '%s' takes priority over '%s' from %s",
                   a->id, host, v->current, value, peer->uname);

        crm_xml_add(sync, F_ATTRD_TASK, ATTRD_OP_SYNC_RESPONSE);
        v = g_hash_table_lookup(a->values, host);
        build_attribute_xml(sync, a->id, a->set, a->uuid, a->timeout_ms, a->user, a->is_private,
                            v->nodename, v->nodeid, v->current);

        crm_xml_add_int(sync, F_ATTRD_WRITER, election_state(writer));
        send_attrd_message(peer, sync);
        free_xml(sync);

    } else if(safe_str_neq(v->current, value)) {
        crm_info("Setting %s[%s]: %s -> %s from %s", attr, host, v->current, value, peer->uname);
        free(v->current);
        if(value) {
            v->current = strdup(value);
        } else {
            v->current = NULL;
        }
        changed = TRUE;
    } else {
        crm_trace("Unchanged %s[%s] from %s is %s", attr, host, peer->uname, value);
    }

    a->changed |= changed;

    if(changed) {
        if(a->timer) {
            crm_trace("Delayed write out (%dms) for %s", a->timeout_ms, a->id);
            mainloop_timer_start(a->timer);
        } else {
            write_or_elect_attribute(a);
        }
    }

    /* this only involves cluster nodes. */
    if(v->nodeid == 0 && (v->is_remote == FALSE)) {
        if(crm_element_value_int(xml, F_ATTRD_HOST_ID, (int*)&v->nodeid) == 0) {
            /* Create the name/id association */
            crm_node_t *peer = crm_get_peer(v->nodeid, host);
            crm_trace("We know %s's node id now: %s", peer->uname, peer->uuid);
            if(election_state(writer) == election_won) {
                write_attributes(FALSE, TRUE);
                return;
            }
        }
    }
}
示例#11
0
static gboolean
pcmk_shutdown_worker(gpointer user_data)
{
    static int phase = 0;
    static time_t next_log = 0;
    static int max = SIZEOF(pcmk_children);

    int lpc = 0;

    if (phase == 0) {
        crm_notice("Shuting down Pacemaker");
        phase = max;

        /* Add a second, more frequent, check to speed up shutdown */
        g_timeout_add_seconds(5, check_active_before_startup_processes, NULL);
    }

    for (; phase > 0; phase--) {
        /* dont stop anything with start_seq < 1 */

        for (lpc = max - 1; lpc >= 0; lpc--) {
            pcmk_child_t *child = &(pcmk_children[lpc]);

            if (phase != child->start_seq) {
                continue;
            }

            if (child->pid) {
                time_t now = time(NULL);

                if (child->respawn) {
                    next_log = now + 30;
                    child->respawn = FALSE;
                    stop_child(child, SIGTERM);
                    if (phase < pcmk_children[pcmk_child_crmd].start_seq) {
                        g_timeout_add(180000 /* 3m */ , escalate_shutdown, child);
                    }

                } else if (now >= next_log) {
                    next_log = now + 30;
                    crm_notice("Still waiting for %s (pid=%d, seq=%d) to terminate...",
                               child->name, child->pid, child->start_seq);
                }
                return TRUE;
            }

            /* cleanup */
            crm_debug("%s confirmed stopped", child->name);
            child->pid = 0;
        }
    }

    /* send_cluster_id(); */
    crm_notice("Shutdown complete");

    {
        const char *delay = daemon_option("shutdown_delay");
        if(delay) {
            sync();
            sleep(crm_get_msec(delay) / 1000);
        }
    }

    g_main_loop_quit(mainloop);

    if (fatal_error) {
        crm_notice("Attempting to inhibit respawning after fatal error");
        crm_exit(DAEMON_RESPAWN_STOP);
    }

    return TRUE;
}
示例#12
0
static gboolean
block_failure(node_t *node, resource_t *rsc, xmlNode *xml_op,
              pe_working_set_t *data_set)
{
    char *xml_name = clone_strip(rsc->id);
    char *xpath = crm_strdup_printf("//primitive[@id='%s']//op[@on-fail='block']",
                                    xml_name);
    xmlXPathObject *xpathObj = xpath_search(rsc->xml, xpath);
    gboolean should_block = FALSE;

    free(xpath);

#if 0
    /* A good idea? */
    if (rsc->container == NULL && is_not_set(data_set->flags, pe_flag_stonith_enabled)) {
        /* In this case, stop on-fail defaults to block in unpack_operation() */
        return TRUE;
    }
#endif

    if (xpathObj) {
        int max = numXpathResults(xpathObj);
        int lpc = 0;

        for (lpc = 0; lpc < max; lpc++) {
            xmlNode *pref = getXpathResult(xpathObj, lpc);

            if (xml_op) {
                should_block = is_matched_failure(xml_name, pref, xml_op);
                if (should_block) {
                    break;
                }

            } else {
                const char *conf_op_name = NULL;
                int conf_op_interval = 0;
                char *lrm_op_xpath = NULL;
                xmlXPathObject *lrm_op_xpathObj = NULL;

                conf_op_name = crm_element_value(pref, "name");
                conf_op_interval = crm_get_msec(crm_element_value(pref, "interval"));

                lrm_op_xpath = crm_strdup_printf("//node_state[@uname='%s']"
                                               "//lrm_resource[@id='%s']"
                                               "/lrm_rsc_op[@operation='%s'][@interval='%d']",
                                               node->details->uname, xml_name,
                                               conf_op_name, conf_op_interval);
                lrm_op_xpathObj = xpath_search(data_set->input, lrm_op_xpath);

                free(lrm_op_xpath);

                if (lrm_op_xpathObj) {
                    int max2 = numXpathResults(lrm_op_xpathObj);
                    int lpc2 = 0;

                    for (lpc2 = 0; lpc2 < max2; lpc2++) {
                        xmlNode *lrm_op_xml = getXpathResult(lrm_op_xpathObj,
                                                             lpc2);

                        should_block = is_matched_failure(xml_name, pref,
                                                          lrm_op_xml);
                        if (should_block) {
                            break;
                        }
                    }
                }
                freeXpathObject(lrm_op_xpathObj);

                if (should_block) {
                    break;
                }
            }
        }
    }

    free(xml_name);
    freeXpathObject(xpathObj);

    return should_block;
}
示例#13
0
int
main(int argc, char **argv)
{
    char rsc_cmd = 'L';

    const char *v_class = NULL;
    const char *v_agent = NULL;
    const char *v_provider = NULL;
    char *name = NULL;
    char *value = NULL;
    GHashTable *validate_options = NULL;

    const char *rsc_id = NULL;
    const char *host_uname = NULL;
    const char *prop_name = NULL;
    const char *prop_value = NULL;
    const char *rsc_type = NULL;
    const char *prop_id = NULL;
    const char *prop_set = NULL;
    const char *rsc_long_cmd = NULL;
    const char *longname = NULL;
    const char *operation = NULL;
    const char *interval_spec = NULL;
    const char *cib_file = getenv("CIB_file");
    GHashTable *override_params = NULL;

    char *xml_file = NULL;
    crm_ipc_t *crmd_channel = NULL;
    pe_working_set_t *data_set = NULL;
    xmlNode *cib_xml_copy = NULL;
    cib_t *cib_conn = NULL;
    resource_t *rsc = NULL;
    bool recursive = FALSE;
    char *our_pid = NULL;

    bool validate_cmdline = FALSE; /* whether we are just validating based on command line options */
    bool require_resource = TRUE; /* whether command requires that resource be specified */
    bool require_dataset = TRUE;  /* whether command requires populated dataset instance */
    bool require_crmd = FALSE;    // whether command requires controller connection
    bool clear_expired = FALSE;

    int rc = pcmk_ok;
    int is_ocf_rc = 0;
    int option_index = 0;
    int timeout_ms = 0;
    int argerr = 0;
    int flag;
    int find_flags = 0;           // Flags to use when searching for resource
    crm_exit_t exit_code = CRM_EX_OK;

    crm_log_cli_init("crm_resource");
    crm_set_options(NULL, "(query|command) [options]", long_options,
                    "Perform tasks related to cluster resources.\nAllows resources to be queried (definition and location), modified, and moved around the cluster.\n");

    validate_options = crm_str_table_new();

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

        switch (flag) {
            case 0: /* long options with no short equivalent */
                if (safe_str_eq("master", longname)) {
                    scope_master = TRUE;

                } else if(safe_str_eq(longname, "recursive")) {
                    recursive = TRUE;

                } else if (safe_str_eq("wait", longname)) {
                    rsc_cmd = flag;
                    rsc_long_cmd = longname;
                    require_resource = FALSE;
                    require_dataset = FALSE;

                } else if (
                    safe_str_eq("validate", longname)
                    || safe_str_eq("restart", longname)
                    || safe_str_eq("force-demote",  longname)
                    || safe_str_eq("force-stop",    longname)
                    || safe_str_eq("force-start",   longname)
                    || safe_str_eq("force-promote", longname)
                    || safe_str_eq("force-check",   longname)) {
                    rsc_cmd = flag;
                    rsc_long_cmd = longname;
                    find_flags = pe_find_renamed|pe_find_anon;
                    crm_log_args(argc, argv);

                } else if (safe_str_eq("list-ocf-providers", longname)
                           || safe_str_eq("list-ocf-alternatives", longname)
                           || safe_str_eq("list-standards", longname)) {
                    const char *text = NULL;
                    lrmd_list_t *list = NULL;
                    lrmd_list_t *iter = NULL;
                    lrmd_t *lrmd_conn = lrmd_api_new();

                    if (safe_str_eq("list-ocf-providers", longname)
                        || safe_str_eq("list-ocf-alternatives", longname)) {
                        rc = lrmd_conn->cmds->list_ocf_providers(lrmd_conn, optarg, &list);
                        text = "OCF providers";

                    } else if (safe_str_eq("list-standards", longname)) {
                        rc = lrmd_conn->cmds->list_standards(lrmd_conn, &list);
                        text = "standards";
                    }

                    if (rc > 0) {
                        for (iter = list; iter != NULL; iter = iter->next) {
                            printf("%s\n", iter->val);
                        }
                        lrmd_list_freeall(list);

                    } else if (optarg) {
                        fprintf(stderr, "No %s found for %s\n", text, optarg);
                        exit_code = CRM_EX_NOSUCH;

                    } else {
                        fprintf(stderr, "No %s found\n", text);
                        exit_code = CRM_EX_NOSUCH;
                    }

                    lrmd_api_delete(lrmd_conn);
                    crm_exit(exit_code);

                } else if (safe_str_eq("show-metadata", longname)) {
                    char *standard = NULL;
                    char *provider = NULL;
                    char *type = NULL;
                    char *metadata = NULL;
                    lrmd_t *lrmd_conn = lrmd_api_new();

                    rc = crm_parse_agent_spec(optarg, &standard, &provider, &type);
                    if (rc == pcmk_ok) {
                        rc = lrmd_conn->cmds->get_metadata(lrmd_conn, standard,
                                                           provider, type,
                                                           &metadata, 0);
                    } else {
                        fprintf(stderr,
                                "'%s' is not a valid agent specification\n",
                                optarg);
                        rc = -ENXIO;
                    }

                    if (metadata) {
                        printf("%s\n", metadata);
                    } else {
                        fprintf(stderr, "Metadata query for %s failed: %s\n",
                                optarg, pcmk_strerror(rc));
                        exit_code = crm_errno2exit(rc);
                    }
                    lrmd_api_delete(lrmd_conn);
                    crm_exit(exit_code);

                } else if (safe_str_eq("list-agents", longname)) {
                    lrmd_list_t *list = NULL;
                    lrmd_list_t *iter = NULL;
                    char *provider = strchr (optarg, ':');
                    lrmd_t *lrmd_conn = lrmd_api_new();

                    if (provider) {
                        *provider++ = 0;
                    }
                    rc = lrmd_conn->cmds->list_agents(lrmd_conn, &list, optarg, provider);

                    if (rc > 0) {
                        for (iter = list; iter != NULL; iter = iter->next) {
                            printf("%s\n", iter->val);
                        }
                        lrmd_list_freeall(list);
                    } else {
                        fprintf(stderr, "No agents found for standard=%s, provider=%s\n",
                                optarg, (provider? provider : "*"));
                        exit_code = CRM_EX_NOSUCH;
                    }
                    lrmd_api_delete(lrmd_conn);
                    crm_exit(exit_code);

                } else if (safe_str_eq("class", longname)) {
                    if (!(pcmk_get_ra_caps(optarg) & pcmk_ra_cap_params)) {
                        if (BE_QUIET == FALSE) {
                            fprintf(stdout, "Standard %s does not support parameters\n",
                                    optarg);
                        }

                        crm_exit(exit_code);
                    } else {
                        v_class = optarg;
                    }

                    validate_cmdline = TRUE;
                    require_resource = FALSE;

                } else if (safe_str_eq("agent", longname)) {
                    validate_cmdline = TRUE;
                    require_resource = FALSE;
                    v_agent = optarg;

                } else if (safe_str_eq("provider", longname)) {
                    validate_cmdline = TRUE;
                    require_resource = FALSE;
                    v_provider = optarg;

                } else if (safe_str_eq("option", longname)) {
                    crm_info("Scanning: --option %s", optarg);
                    rc = pcmk_scan_nvpair(optarg, &name, &value);
                    if (rc != 2) {
                        fprintf(stderr, "Invalid option: --option %s: %s", optarg, pcmk_strerror(rc));
                        argerr++;
                    } else {
                        crm_info("Got: '%s'='%s'", name, value);
                    }

                    g_hash_table_replace(validate_options, name, value);

                } else {
                    crm_err("Unhandled long option: %s", longname);
                }
                break;
            case 'V':
                resource_verbose++;
                crm_bump_log_level(argc, argv);
                break;
            case '$':
            case '?':
                crm_help(flag, CRM_EX_OK);
                break;
            case 'x':
                xml_file = strdup(optarg);
                break;
            case 'Q':
                BE_QUIET = TRUE;
                break;
            case 'm':
                attr_set_type = XML_TAG_META_SETS;
                break;
            case 'z':
                attr_set_type = XML_TAG_UTILIZATION;
                break;
            case 'u':
                move_lifetime = strdup(optarg);
                break;
            case 'f':
                do_force = TRUE;
                crm_log_args(argc, argv);
                break;
            case 'i':
                prop_id = optarg;
                break;
            case 's':
                prop_set = optarg;
                break;
            case 'r':
                rsc_id = optarg;
                break;
            case 'v':
                prop_value = optarg;
                break;
            case 't':
                rsc_type = optarg;
                break;
            case 'T':
                timeout_ms = crm_get_msec(optarg);
                break;
            case 'e':
                clear_expired = TRUE;
                require_resource = FALSE;
                break;

            case 'C':
            case 'R':
                crm_log_args(argc, argv);
                require_resource = FALSE;
                if (cib_file == NULL) {
                    require_crmd = TRUE;
                }
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_anon;
                break;

            case 'n':
                operation = optarg;
                break;

            case 'I':
                interval_spec = optarg;
                break;

            case 'D':
                require_dataset = FALSE;
                crm_log_args(argc, argv);
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_any;
                break;

            case 'F':
                require_crmd = TRUE;
                crm_log_args(argc, argv);
                rsc_cmd = flag;
                break;

            case 'U':
            case 'B':
            case 'M':
                crm_log_args(argc, argv);
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_anon;
                break;

            case 'c':
            case 'L':
            case 'l':
            case 'O':
            case 'o':
                require_resource = FALSE;
                rsc_cmd = flag;
                break;

            case 'Y':
                require_resource = FALSE;
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_anon;
                break;

            case 'q':
            case 'w':
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_any;
                break;

            case 'W':
            case 'A':
            case 'a':
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_anon;
                break;

            case 'S':
                require_dataset = FALSE;
                crm_log_args(argc, argv);
                prop_name = optarg;
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_any;
                break;

            case 'p':
            case 'd':
                crm_log_args(argc, argv);
                prop_name = optarg;
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_any;
                break;

            case 'G':
            case 'g':
                prop_name = optarg;
                rsc_cmd = flag;
                find_flags = pe_find_renamed|pe_find_any;
                break;

            case 'H':
            case 'N':
                crm_trace("Option %c => %s", flag, optarg);
                host_uname = optarg;
                break;

            default:
                CMD_ERR("Argument code 0%o (%c) is not (?yet?) supported", flag, flag);
                ++argerr;
                break;
        }
    }

    // Catch the case where the user didn't specify a command
    if (rsc_cmd == 'L') {
        require_resource = FALSE;
    }

    // --expired without --clear/-U doesn't make sense
    if (clear_expired == TRUE && rsc_cmd != 'U') {
        CMD_ERR("--expired requires --clear or -U");
        argerr++;
    }

    if (optind < argc
        && argv[optind] != NULL
        && rsc_cmd == 0
        && rsc_long_cmd) {

        override_params = crm_str_table_new();
        while (optind < argc && argv[optind] != NULL) {
            char *name = calloc(1, strlen(argv[optind]));
            char *value = calloc(1, strlen(argv[optind]));
            int rc = sscanf(argv[optind], "%[^=]=%s", name, value);

            if(rc == 2) {
                g_hash_table_replace(override_params, name, value);

            } else {
                CMD_ERR("Error parsing '%s' as a name=value pair for --%s", argv[optind], rsc_long_cmd);
                free(value);
                free(name);
                argerr++;
            }
            optind++;
        }

    } else if (optind < argc && argv[optind] != NULL && rsc_cmd == 0) {
        CMD_ERR("non-option ARGV-elements: ");
        while (optind < argc && argv[optind] != NULL) {
            CMD_ERR("[%d of %d] %s ", optind, argc, argv[optind]);
            optind++;
            argerr++;
        }
    }

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

    // Sanity check validating from command line parameters.  If everything checks out,
    // go ahead and run the validation.  This way we don't need a CIB connection.
    if (validate_cmdline == TRUE) {
        // -r cannot be used with any of --class, --agent, or --provider
        if (rsc_id != NULL) {
            CMD_ERR("--resource cannot be used with --class, --agent, and --provider");
            argerr++;

        // If --class, --agent, or --provider are given, --validate must also be given.
        } else if (!safe_str_eq(rsc_long_cmd, "validate")) {
            CMD_ERR("--class, --agent, and --provider require --validate");
            argerr++;

        // Not all of --class, --agent, and --provider need to be given.  Not all
        // classes support the concept of a provider.  Check that what we were given
        // is valid.
        } else if (crm_str_eq(v_class, "stonith", TRUE)) {
            if (v_provider != NULL) {
                CMD_ERR("stonith does not support providers");
                argerr++;

            } else if (stonith_agent_exists(v_agent, 0) == FALSE) {
                CMD_ERR("%s is not a known stonith agent", v_agent ? v_agent : "");
                argerr++;
            }

        } else if (resources_agent_exists(v_class, v_provider, v_agent) == FALSE) {
            CMD_ERR("%s:%s:%s is not a known resource",
                    v_class ? v_class : "",
                    v_provider ? v_provider : "",
                    v_agent ? v_agent : "");
            argerr++;
        }

        if (argerr == 0) {
            rc = cli_resource_execute_from_params("test", v_class, v_provider, v_agent,
                                                  "validate-all", validate_options,
                                                  override_params, timeout_ms);
            exit_code = crm_errno2exit(rc);
            return crm_exit(exit_code);
        }
    }

    if (argerr) {
        CMD_ERR("Invalid option(s) supplied, use --help for valid usage");
        crm_exit(CRM_EX_USAGE);
    }

    our_pid = crm_getpid_s();

    if (do_force) {
        crm_debug("Forcing...");
        cib_options |= cib_quorum_override;
    }

    if (require_resource && !rsc_id) {
        CMD_ERR("Must supply a resource id with -r");
        rc = -ENXIO;
        goto bail;
    }

    if (find_flags && rsc_id) {
        require_dataset = TRUE;
    }

    /* Establish a connection to the CIB manager */
    cib_conn = cib_new();
    rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command);
    if (rc != pcmk_ok) {
        CMD_ERR("Error connecting to the CIB manager: %s", pcmk_strerror(rc));
        goto bail;
    }

    /* Populate working set from XML file if specified or CIB query otherwise */
    if (require_dataset) {
        if (xml_file != NULL) {
            cib_xml_copy = filename2xml(xml_file);

        } else {
            rc = cib_conn->cmds->query(cib_conn, NULL, &cib_xml_copy, cib_scope_local | cib_sync_call);
        }

        if(rc != pcmk_ok) {
            goto bail;
        }

        /* Populate the working set instance */
        data_set = pe_new_working_set();
        if (data_set == NULL) {
            rc = -ENOMEM;
            goto bail;
        }
        rc = update_working_set_xml(data_set, &cib_xml_copy);
        if (rc != pcmk_ok) {
            goto bail;
        }
        cluster_status(data_set);
    }

    // If command requires that resource exist if specified, find it
    if (find_flags && rsc_id) {
        rsc = pe_find_resource_with_flags(data_set->resources, rsc_id,
                                          find_flags);
        if (rsc == NULL) {
            CMD_ERR("Resource '%s' not found", rsc_id);
            rc = -ENXIO;
            goto bail;
        }
    }

    // Establish a connection to the controller if needed
    if (require_crmd) {
        xmlNode *xml = NULL;
        mainloop_io_t *source =
            mainloop_add_ipc_client(CRM_SYSTEM_CRMD, G_PRIORITY_DEFAULT, 0, NULL, &crm_callbacks);
        crmd_channel = mainloop_get_ipc_client(source);

        if (crmd_channel == NULL) {
            CMD_ERR("Error connecting to the controller");
            rc = -ENOTCONN;
            goto bail;
        }

        xml = create_hello_message(our_pid, crm_system_name, "0", "1");
        crm_ipc_send(crmd_channel, xml, 0, 0, NULL);
        free_xml(xml);
    }

    /* Handle rsc_cmd appropriately */
    if (rsc_cmd == 'L') {
        rc = pcmk_ok;
        cli_resource_print_list(data_set, FALSE);

    } else if (rsc_cmd == 'l') {
        int found = 0;
        GListPtr lpc = NULL;

        rc = pcmk_ok;
        for (lpc = data_set->resources; lpc != NULL; lpc = lpc->next) {
            rsc = (resource_t *) lpc->data;

            found++;
            cli_resource_print_raw(rsc);
        }

        if (found == 0) {
            printf("NO resources configured\n");
            rc = -ENXIO;
        }

    } else if (rsc_cmd == 0 && rsc_long_cmd && safe_str_eq(rsc_long_cmd, "restart")) {
        /* We don't pass data_set because rsc needs to stay valid for the entire
         * lifetime of cli_resource_restart(), but it will reset and update the
         * working set multiple times, so it needs to use its own copy.
         */
        rc = cli_resource_restart(rsc, host_uname, timeout_ms, cib_conn);

    } else if (rsc_cmd == 0 && rsc_long_cmd && safe_str_eq(rsc_long_cmd, "wait")) {
        rc = wait_till_stable(timeout_ms, cib_conn);

    } else if (rsc_cmd == 0 && rsc_long_cmd) {
        // validate, force-(stop|start|demote|promote|check)
        rc = cli_resource_execute(rsc, rsc_id, rsc_long_cmd, override_params,
                                  timeout_ms, cib_conn, data_set);
        if (rc >= 0) {
            is_ocf_rc = 1;
        }

    } else if (rsc_cmd == 'A' || rsc_cmd == 'a') {
        GListPtr lpc = NULL;
        xmlNode *cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS,
                                                   data_set->input);

        unpack_constraints(cib_constraints, data_set);

        // Constraints apply to group/clone, not member/instance
        rsc = uber_parent(rsc);

        for (lpc = data_set->resources; lpc != NULL; lpc = lpc->next) {
            resource_t *r = (resource_t *) lpc->data;

            clear_bit(r->flags, pe_rsc_allocating);
        }

        cli_resource_print_colocation(rsc, TRUE, rsc_cmd == 'A', 1);

        fprintf(stdout, "* %s\n", rsc->id);
        cli_resource_print_location(rsc, NULL);

        for (lpc = data_set->resources; lpc != NULL; lpc = lpc->next) {
            resource_t *r = (resource_t *) lpc->data;

            clear_bit(r->flags, pe_rsc_allocating);
        }

        cli_resource_print_colocation(rsc, FALSE, rsc_cmd == 'A', 1);

    } else if (rsc_cmd == 'c') {
        GListPtr lpc = NULL;

        rc = pcmk_ok;
        for (lpc = data_set->resources; lpc != NULL; lpc = lpc->next) {
            rsc = (resource_t *) lpc->data;
            cli_resource_print_cts(rsc);
        }
        cli_resource_print_cts_constraints(data_set);

    } else if (rsc_cmd == 'F') {
        rc = cli_resource_fail(crmd_channel, host_uname, rsc_id, data_set);
        if (rc == pcmk_ok) {
            start_mainloop();
        }

    } else if (rsc_cmd == 'O') {
        rc = cli_resource_print_operations(rsc_id, host_uname, TRUE, data_set);

    } else if (rsc_cmd == 'o') {
        rc = cli_resource_print_operations(rsc_id, host_uname, FALSE, data_set);

    } else if (rsc_cmd == 'W') {
        rc = cli_resource_search(rsc, rsc_id, data_set);
        if (rc >= 0) {
            rc = pcmk_ok;
        }

    } else if (rsc_cmd == 'q') {
        rc = cli_resource_print(rsc, data_set, TRUE);

    } else if (rsc_cmd == 'w') {
        rc = cli_resource_print(rsc, data_set, FALSE);

    } else if (rsc_cmd == 'Y') {
        node_t *dest = NULL;

        if (host_uname) {
            dest = pe_find_node(data_set->nodes, host_uname);
            if (dest == NULL) {
                rc = -pcmk_err_node_unknown;
                goto bail;
            }
        }
        cli_resource_why(cib_conn, data_set->resources, rsc, dest);
        rc = pcmk_ok;

    } else if (rsc_cmd == 'U') {
        GListPtr before = NULL;
        GListPtr after = NULL;
        GListPtr remaining = NULL;
        GListPtr ele = NULL;
        node_t *dest = NULL;

        if (BE_QUIET == FALSE) {
            before = build_constraint_list(data_set->input);
        }

        if (clear_expired == TRUE) {
            rc = cli_resource_clear_all_expired(data_set->input, cib_conn, rsc_id, host_uname, scope_master);

        } else if (host_uname) {
            dest = pe_find_node(data_set->nodes, host_uname);
            if (dest == NULL) {
                rc = -pcmk_err_node_unknown;
                if (BE_QUIET == FALSE) {
                    g_list_free(before);
                }
                goto bail;
            }
            rc = cli_resource_clear(rsc_id, dest->details->uname, NULL, cib_conn, TRUE);

        } else {
            rc = cli_resource_clear(rsc_id, NULL, data_set->nodes, cib_conn, TRUE);
        }

        if (BE_QUIET == FALSE) {
            rc = cib_conn->cmds->query(cib_conn, NULL, &cib_xml_copy, cib_scope_local | cib_sync_call);
            if (rc != pcmk_ok) {
                CMD_ERR("Could not get modified CIB: %s\n", pcmk_strerror(rc));
                g_list_free(before);
                goto bail;
            }

            data_set->input = cib_xml_copy;
            cluster_status(data_set);

            after = build_constraint_list(data_set->input);
            remaining = subtract_lists(before, after, (GCompareFunc) strcmp);

            for (ele = remaining; ele != NULL; ele = ele->next) {
                printf("Removing constraint: %s\n", (char *) ele->data);
            }

            g_list_free(before);
            g_list_free(after);
            g_list_free(remaining);
        }

    } else if (rsc_cmd == 'M' && host_uname) {
        rc = cli_resource_move(rsc, rsc_id, host_uname, cib_conn, data_set);

    } else if (rsc_cmd == 'B' && host_uname) {
        node_t *dest = pe_find_node(data_set->nodes, host_uname);

        if (dest == NULL) {
            rc = -pcmk_err_node_unknown;
            goto bail;
        }
        rc = cli_resource_ban(rsc_id, dest->details->uname, NULL, cib_conn);

    } else if (rsc_cmd == 'B' || rsc_cmd == 'M') {
        pe_node_t *current = NULL;
        unsigned int nactive = 0;

        current = pe__find_active_requires(rsc, &nactive);

        if (nactive == 1) {
            rc = cli_resource_ban(rsc_id, current->details->uname, NULL, cib_conn);

        } else if (is_set(rsc->flags, pe_rsc_promotable)) {
            int count = 0;
            GListPtr iter = NULL;

            current = NULL;
            for(iter = rsc->children; iter; iter = iter->next) {
                resource_t *child = (resource_t *)iter->data;
                enum rsc_role_e child_role = child->fns->state(child, TRUE);

                if(child_role == RSC_ROLE_MASTER) {
                    count++;
                    current = pe__current_node(child);
                }
            }

            if(count == 1 && current) {
                rc = cli_resource_ban(rsc_id, current->details->uname, NULL, cib_conn);

            } else {
                rc = -EINVAL;
                exit_code = CRM_EX_USAGE;
                CMD_ERR("Resource '%s' not moved: active in %d locations (promoted in %d).",
                        rsc_id, nactive, count);
                CMD_ERR("To prevent '%s' from running on a specific location, "
                        "specify a node.", rsc_id);
                CMD_ERR("To prevent '%s' from being promoted at a specific "
                        "location, specify a node and the master option.",
                        rsc_id);
            }

        } else {
            rc = -EINVAL;
            exit_code = CRM_EX_USAGE;
            CMD_ERR("Resource '%s' not moved: active in %d locations.", rsc_id, nactive);
            CMD_ERR("To prevent '%s' from running on a specific location, "
                    "specify a node.", rsc_id);
        }

    } else if (rsc_cmd == 'G') {
        rc = cli_resource_print_property(rsc, prop_name, data_set);

    } else if (rsc_cmd == 'S') {
        xmlNode *msg_data = NULL;

        if ((rsc_type == NULL) || !strlen(rsc_type)) {
            CMD_ERR("Must specify -t with resource type");
            rc = -ENXIO;
            goto bail;

        } else if ((prop_value == NULL) || !strlen(prop_value)) {
            CMD_ERR("Must supply -v with new value");
            rc = -EINVAL;
            goto bail;
        }

        CRM_LOG_ASSERT(prop_name != NULL);

        msg_data = create_xml_node(NULL, rsc_type);
        crm_xml_add(msg_data, XML_ATTR_ID, rsc_id);
        crm_xml_add(msg_data, prop_name, prop_value);

        rc = cib_conn->cmds->modify(cib_conn, XML_CIB_TAG_RESOURCES, msg_data, cib_options);
        free_xml(msg_data);

    } else if (rsc_cmd == 'g') {
        rc = cli_resource_print_attribute(rsc, prop_name, data_set);

    } else if (rsc_cmd == 'p') {
        if (prop_value == NULL || strlen(prop_value) == 0) {
            CMD_ERR("You need to supply a value with the -v option");
            rc = -EINVAL;
            goto bail;
        }

        /* coverity[var_deref_model] False positive */
        rc = cli_resource_update_attribute(rsc, rsc_id, prop_set, prop_id,
                                           prop_name, prop_value, recursive,
                                           cib_conn, data_set);

    } else if (rsc_cmd == 'd') {
        /* coverity[var_deref_model] False positive */
        rc = cli_resource_delete_attribute(rsc, rsc_id, prop_set, prop_id,
                                           prop_name, cib_conn, data_set);

    } else if ((rsc_cmd == 'C') && rsc) {
        if (do_force == FALSE) {
            rsc = uber_parent(rsc);
        }
        crmd_replies_needed = 0;

        crm_debug("Erasing failures of %s (%s requested) on %s",
                  rsc->id, rsc_id, (host_uname? host_uname: "all nodes"));
        rc = cli_resource_delete(crmd_channel, host_uname, rsc,
                                 operation, interval_spec, TRUE, data_set);

        if ((rc == pcmk_ok) && !BE_QUIET) {
            // Show any reasons why resource might stay stopped
            cli_resource_check(cib_conn, rsc);
        }

        if (rc == pcmk_ok) {
            start_mainloop();
        }

    } else if (rsc_cmd == 'C') {
        rc = cli_cleanup_all(crmd_channel, host_uname, operation, interval_spec,
                             data_set);
        if (rc == pcmk_ok) {
            start_mainloop();
        }

    } else if ((rsc_cmd == 'R') && rsc) {
        if (do_force == FALSE) {
            rsc = uber_parent(rsc);
        }
        crmd_replies_needed = 0;

        crm_debug("Re-checking the state of %s (%s requested) on %s",
                  rsc->id, rsc_id, (host_uname? host_uname: "all nodes"));
        rc = cli_resource_delete(crmd_channel, host_uname, rsc,
                                 NULL, 0, FALSE, data_set);

        if ((rc == pcmk_ok) && !BE_QUIET) {
            // Show any reasons why resource might stay stopped
            cli_resource_check(cib_conn, rsc);
        }

        if (rc == pcmk_ok) {
            start_mainloop();
        }

    } else if (rsc_cmd == 'R') {
        const char *router_node = host_uname;
        xmlNode *msg_data = NULL;
        xmlNode *cmd = NULL;
        int attr_options = attrd_opt_none;

        if (host_uname) {
            node_t *node = pe_find_node(data_set->nodes, host_uname);

            if (node && is_remote_node(node)) {
                node = pe__current_node(node->details->remote_rsc);
                if (node == NULL) {
                    CMD_ERR("No cluster connection to Pacemaker Remote node %s detected",
                            host_uname);
                    rc = -ENXIO;
                    goto bail;
                }
                router_node = node->details->uname;
                attr_options |= attrd_opt_remote;
            }
        }

        if (crmd_channel == NULL) {
            printf("Dry run: skipping clean-up of %s due to CIB_file\n",
                   host_uname? host_uname : "all nodes");
            rc = pcmk_ok;
            goto bail;
        }

        msg_data = create_xml_node(NULL, "crm-resource-reprobe-op");
        crm_xml_add(msg_data, XML_LRM_ATTR_TARGET, host_uname);
        if (safe_str_neq(router_node, host_uname)) {
            crm_xml_add(msg_data, XML_LRM_ATTR_ROUTER_NODE, router_node);
        }

        cmd = create_request(CRM_OP_REPROBE, msg_data, router_node,
                             CRM_SYSTEM_CRMD, crm_system_name, our_pid);
        free_xml(msg_data);

        crm_debug("Re-checking the state of all resources on %s", host_uname?host_uname:"all nodes");

        rc = attrd_clear_delegate(NULL, host_uname, NULL, NULL, NULL, NULL,
                                  attr_options);

        if (crm_ipc_send(crmd_channel, cmd, 0, 0, NULL) > 0) {
            start_mainloop();
        }

        free_xml(cmd);

    } else if (rsc_cmd == 'D') {
        xmlNode *msg_data = NULL;

        if (rsc_type == NULL) {
            CMD_ERR("You need to specify a resource type with -t");
            rc = -ENXIO;
            goto bail;
        }

        msg_data = create_xml_node(NULL, rsc_type);
        crm_xml_add(msg_data, XML_ATTR_ID, rsc_id);

        rc = cib_conn->cmds->remove(cib_conn, XML_CIB_TAG_RESOURCES, msg_data, cib_options);
        free_xml(msg_data);

    } else {
        CMD_ERR("Unknown command: %c", rsc_cmd);
    }

  bail:

    free(our_pid);
    pe_free_working_set(data_set);
    if (cib_conn != NULL) {
        cib_conn->cmds->signoff(cib_conn);
        cib_delete(cib_conn);
    }

    if (is_ocf_rc) {
        exit_code = rc;

    } else if (rc != pcmk_ok) {
        CMD_ERR("Error performing operation: %s", pcmk_strerror(rc));
        if (rc == -pcmk_err_no_quorum) {
            CMD_ERR("To ignore quorum, use the force option");
        }
        if (exit_code == CRM_EX_OK) {
            exit_code = crm_errno2exit(rc);
        }
    }

    return crm_exit(exit_code);
}
示例#14
0
void
attrd_peer_update(crm_node_t *peer, xmlNode *xml, const char *host, bool filter)
{
    bool update_both = FALSE;
    attribute_t *a;
    attribute_value_t *v = NULL;
    gboolean is_force_write = FALSE;

    const char *op = crm_element_value(xml, F_ATTRD_TASK);
    const char *attr = crm_element_value(xml, F_ATTRD_ATTRIBUTE);
    const char *value = crm_element_value(xml, F_ATTRD_VALUE);
    crm_element_value_int(xml, F_ATTRD_IS_FORCE_WRITE, &is_force_write);

    if (attr == NULL) {
        crm_warn("Could not update attribute: peer did not specify name");
        return;
    }

    update_both = ((op == NULL) // ATTRD_OP_SYNC_RESPONSE has no F_ATTRD_TASK
                   || safe_str_eq(op, ATTRD_OP_UPDATE_BOTH));

    // Look up or create attribute entry
    a = g_hash_table_lookup(attributes, attr);
    if (a == NULL) {
        if (update_both || safe_str_eq(op, ATTRD_OP_UPDATE)) {
            a = create_attribute(xml);
        } else {
            crm_warn("Could not update %s: attribute not found", attr);
            return;
        }
    }

    // Update attribute dampening
    if (update_both || safe_str_eq(op, ATTRD_OP_UPDATE_DELAY)) {
        const char *dvalue = crm_element_value(xml, F_ATTRD_DAMPEN);
        int dampen = 0;

        if (dvalue == NULL) {
            crm_warn("Could not update %s: peer did not specify value for delay",
                     attr);
            return;
        }

        dampen = crm_get_msec(dvalue);
        if (dampen < 0) {
            crm_warn("Could not update %s: invalid delay value %dms (%s)",
                     attr, dampen, dvalue);
            return;
        }

        if (a->timeout_ms != dampen) {
            mainloop_timer_del(a->timer);
            a->timeout_ms = dampen;
            if (dampen > 0) {
                a->timer = mainloop_timer_add(attr, a->timeout_ms, FALSE,
                                              attribute_timer_cb, a);
                crm_info("Update attribute %s delay to %dms (%s)",
                         attr, dampen, dvalue);
            } else {
                a->timer = NULL;
                crm_info("Update attribute %s to remove delay", attr);
            }

            /* If dampening changed, do an immediate write-out,
             * otherwise repeated dampening changes would prevent write-outs
             */
            write_or_elect_attribute(a);
        }

        if (!update_both) {
            return;
        }
    }

    // If no host was specified, update all hosts recursively
    if (host == NULL) {
        GHashTableIter vIter;

        crm_debug("Setting %s for all hosts to %s", attr, value);
        xml_remove_prop(xml, F_ATTRD_HOST_ID);
        g_hash_table_iter_init(&vIter, a->values);
        while (g_hash_table_iter_next(&vIter, (gpointer *) & host, NULL)) {
            attrd_peer_update(peer, xml, host, filter);
        }
        return;
    }

    // Update attribute value for one host

    v = attrd_lookup_or_create_value(a->values, host, xml);

    if (filter && safe_str_neq(v->current, value)
        && safe_str_eq(host, attrd_cluster->uname)) {

        xmlNode *sync = create_xml_node(NULL, __FUNCTION__);

        crm_notice("%s[%s]: local value '%s' takes priority over '%s' from %s",
                   attr, host, v->current, value, peer->uname);

        crm_xml_add(sync, F_ATTRD_TASK, ATTRD_OP_SYNC_RESPONSE);
        v = g_hash_table_lookup(a->values, host);
        build_attribute_xml(sync, attr, a->set, a->uuid, a->timeout_ms, a->user,
                            a->is_private, v->nodename, v->nodeid, v->current, FALSE);

        attrd_xml_add_writer(sync);

        /* Broadcast in case any other nodes had the inconsistent value */
        send_attrd_message(NULL, sync);
        free_xml(sync);

    } else if (safe_str_neq(v->current, value)) {
        crm_info("Setting %s[%s]: %s -> %s from %s",
                 attr, host, v->current, value, peer->uname);
        free(v->current);
        v->current = (value? strdup(value) : NULL);
        a->changed = TRUE;

        // Write out new value or start dampening timer
        if (a->timeout_ms && a->timer) {
            crm_trace("Delayed write out (%dms) for %s", a->timeout_ms, attr);
            mainloop_timer_start(a->timer);
        } else {
            write_or_elect_attribute(a);
        }

    } else {
        if (is_force_write && a->timeout_ms && a->timer) {
            /* Save forced writing and set change flag. */
            /* The actual attribute is written by Writer after election. */
            crm_trace("Unchanged %s[%s] from %s is %s(Set the forced write flag)", attr, host, peer->uname, value);
            a->force_write = TRUE;
        } else {
            crm_trace("Unchanged %s[%s] from %s is %s", attr, host, peer->uname, value);
        }
    }

    /* Set the seen flag for attribute processing held only in the own node. */
    v->seen = TRUE;

    /* If this is a cluster node whose node ID we are learning, remember it */
    if ((v->nodeid == 0) && (v->is_remote == FALSE)
        && (crm_element_value_int(xml, F_ATTRD_HOST_ID, (int*)&v->nodeid) == 0)) {

        crm_node_t *known_peer = crm_get_peer(v->nodeid, host);

        crm_trace("Learned %s has node id %s",
                  known_peer->uname, known_peer->uuid);
        if (attrd_election_won()) {
            write_attributes(FALSE, FALSE);
        }
    }
}
示例#15
0
int
main(int argc, char **argv)
{
    int flag;
    int rc = 0;
    int quiet = 0;
    int verbose = 0;
    int argerr = 0;
    int timeout = 120;
    int option_index = 0;
    int fence_level = 0;
    int no_connect = 0;
    int tolerance = 0;
    int as_nodeid = FALSE;

    char *name = NULL;
    char *value = NULL;
    char *target = NULL;
    char *lists = NULL;
    const char *agent = NULL;
    const char *device = NULL;
    const char *longname = NULL;

    char action = 0;
    stonith_t *st = NULL;
    stonith_key_value_t *params = NULL;
    stonith_key_value_t *devices = NULL;
    stonith_key_value_t *dIter = NULL;

    crm_log_cli_init("stonith_admin");
    crm_set_options(NULL, "mode [options]", long_options,
                    "Provides access to the stonith-ng API.\n"
                    "\nAllows the administrator to add/remove/list devices, check device and host status and fence hosts\n");

    async_fence_data.name = strdup(crm_system_name);

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

        switch (flag) {
            case 'V':
                verbose = 1;
                crm_bump_log_level(argc, argv);
                break;
            case '$':
            case '?':
                crm_help(flag, EX_OK);
                break;
            case 'I':
                no_connect = 1;
                /* fall through */
            case 'L':
                action = flag;
                break;
            case 'q':
                quiet = 1;
                break;
            case 'Q':
            case 'R':
            case 'D':
            case 's':
                action = flag;
                device = optarg;
                break;
            case 'T':
                free(async_fence_data.name);
                async_fence_data.name = crm_strdup_printf("%s.%s", crm_system_name, optarg);
                break;
            case 'a':
                agent = optarg;
                break;
            case 'l':
                target = optarg;
                action = 'L';
                break;
            case 'M':
                no_connect = 1;
                action = flag;
                break;
            case 't':
                timeout = crm_atoi(optarg, NULL);
                break;
            case 'B':
            case 'F':
            case 'U':
                /* using mainloop here */
                no_connect = 1;
                /* fall through */
            case 'C':
                /* Always log the input arguments */
                crm_log_args(argc, argv);
                target = optarg;
                action = flag;
                break;
            case 'n':
                as_nodeid = TRUE;
                break;
            case 'h':
            case 'H':
            case 'r':
            case 'd':
                target = optarg;
                action = flag;
                break;
            case 'i':
                fence_level = crm_atoi(optarg, NULL);
                break;
            case 'v':
                devices = stonith_key_value_add(devices, NULL, optarg);
                break;
            case 'o':
                crm_info("Scanning: -o %s", optarg);
                rc = sscanf(optarg, "%m[^=]=%m[^=]", &name, &value);
                if (rc != 2) {
                    crm_err("Invalid option: -o %s", optarg);
                    ++argerr;
                } else {
                    crm_info("Got: '%s'='%s'", name, value);
                    params = stonith_key_value_add(params, name, value);
                }
                free(value); value = NULL;
                free(name); name = NULL;
                break;
            case 'e':
                {
                    char *key = crm_concat("OCF_RESKEY", optarg, '_');
                    const char *env = getenv(key);

                    if (env == NULL) {
                        crm_err("Invalid option: -e %s", optarg);
                        ++argerr;
                    } else {
                        crm_info("Got: '%s'='%s'", optarg, env);
                        params = stonith_key_value_add(params, optarg, env);
                    }
                }
                break;
            case 0:
                if (safe_str_eq("tolerance", longname)) {
                    tolerance = crm_get_msec(optarg) / 1000;    /* Send in seconds */
                }
                break;
            default:
                ++argerr;
                break;
        }
    }

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

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

    crm_debug("Create");
    st = stonith_api_new();
    crm_debug("Created");

    if (!no_connect) {
        crm_debug("Connecting as %s", async_fence_data.name);
        rc = st->cmds->connect(st, async_fence_data.name, NULL);

        crm_debug("Connect: %d", rc);

        if (rc < 0) {
            goto done;
        }
    }

    switch (action) {
        case 'I':
            rc = st->cmds->list_agents(st, st_opt_sync_call, NULL, &devices, timeout);
            for (dIter = devices; dIter; dIter = dIter->next) {
                fprintf(stdout, " %s\n", dIter->value);
            }
            if (rc == 0) {
                fprintf(stderr, "No devices found\n");

            } else if (rc > 0) {
                fprintf(stderr, "%d devices found\n", rc);
                rc = 0;
            }
            stonith_key_value_freeall(devices, 1, 1);
            break;
        case 'L':
            rc = st->cmds->query(st, st_opts, target, &devices, timeout);
            for (dIter = devices; dIter; dIter = dIter->next) {
                fprintf(stdout, " %s\n", dIter->value);
            }
            if (rc == 0) {
                fprintf(stderr, "No devices found\n");
            } else if (rc > 0) {
                fprintf(stderr, "%d devices found\n", rc);
                rc = 0;
            }
            stonith_key_value_freeall(devices, 1, 1);
            break;
        case 'Q':
            rc = st->cmds->monitor(st, st_opts, device, timeout);
            if (rc < 0) {
                rc = st->cmds->list(st, st_opts, device, NULL, timeout);
            }
            break;
        case 's':
            rc = st->cmds->list(st, st_opts, device, &lists, timeout);
            if (rc == 0) {
                if (lists) {
                    char *source = lists, *dest = lists; 

                    while (*dest) {
                        if ((*dest == '\\') && (*(dest+1) == 'n')) {
                            *source = '\n';
                            dest++;
                            dest++;
                            source++;
                        } else if ((*dest == ',') || (*dest == ';')) {
                            dest++;
                        } else {
                            *source = *dest;
                            dest++;
                            source++;
                        }

                        if (!(*dest)) {
                            *source = 0;
                        }
                    }
                    fprintf(stdout, "%s", lists);
                    free(lists);
                }
            } else {
                fprintf(stderr, "List command returned error. rc : %d\n", rc);
            }
            break;
        case 'R':
            rc = st->cmds->register_device(st, st_opts, device, "stonith-ng", agent, params);
            break;
        case 'D':
            rc = st->cmds->remove_device(st, st_opts, device);
            break;
        case 'd':
        case 'r':
            rc = handle_level(st, target, fence_level, devices, action == 'r');
            break;
        case 'M':
            if (agent == NULL) {
                printf("Please specify an agent to query using -a,--agent [value]\n");
                return -1;
            } else {
                char *buffer = NULL;

                rc = st->cmds->metadata(st, st_opt_sync_call, agent, NULL, &buffer, timeout);
                if (rc == pcmk_ok) {
                    printf("%s\n", buffer);
                }
                free(buffer);
            }
            break;
        case 'C':
            rc = st->cmds->confirm(st, st_opts, target);
            break;
        case 'B':
            rc = mainloop_fencing(st, target, "reboot", timeout, tolerance);
            break;
        case 'F':
            rc = mainloop_fencing(st, target, "off", timeout, tolerance);
            break;
        case 'U':
            rc = mainloop_fencing(st, target, "on", timeout, tolerance);
            break;
        case 'h':
            {
                time_t when = 0;

                if(as_nodeid) {
                    uint32_t nodeid = atol(target);
                    when = stonith_api_time(nodeid, NULL, FALSE);
                } else {
                    when = stonith_api_time(0, target, FALSE);
                }
                if(when) {
                    printf("Node %s last kicked at: %s\n", target, ctime(&when));
                } else {
                    printf("Node %s has never been kicked\n", target);
                }
            }
            break;
        case 'H':
            rc = show_history(st, target, timeout, quiet, verbose);
            break;
    }

  done:
    free(async_fence_data.name);
    crm_info("Command returned: %s (%d)", pcmk_strerror(rc), rc);
    if (rc < 0) {
        printf("Command failed: %s\n", pcmk_strerror(rc));
    }

    stonith_key_value_freeall(params, 1, 1);
    st->cmds->disconnect(st);
    crm_debug("Disconnect: %d", rc);

    crm_debug("Destroy");
    stonith_api_delete(st);

    return rc;
}
示例#16
0
int
main(int argc, char **argv)
{
    int flag;
    int rc = 0;
    int quiet = 0;
    int verbose = 0;
    int argerr = 0;
    int timeout = 120;
    int option_index = 0;
    int fence_level = 0;
    int no_connect = 0;
    int tolerance = 0;

    char *name = NULL;
    char *value = NULL;
    const char *agent = NULL;
    const char *device = NULL;
    const char *target = NULL;
    const char *longname = NULL;

    char action = 0;
    stonith_t *st = NULL;
    stonith_key_value_t *params = NULL;
    stonith_key_value_t *devices = NULL;
    stonith_key_value_t *dIter = NULL;

    crm_log_cli_init("stonith_admin");
    crm_set_options(NULL, "mode [options]", long_options,
                    "Provides access to the stonith-ng API.\n"
                    "\nAllows the administrator to add/remove/list devices, check device and host status and fence hosts\n");

    async_fence_data.name = strdup(crm_system_name);

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

        switch (flag) {
            case 'V':
                verbose = 1;
                crm_bump_log_level(argc, argv);
                break;
            case '$':
            case '?':
                crm_help(flag, EX_OK);
                break;
            case 'I':
                no_connect = 1;
                /* fall through */
            case 'L':
                action = flag;
                break;
            case 'q':
                quiet = 1;
                break;
            case 'Q':
            case 'R':
            case 'D':
                action = flag;
                device = optarg;
                break;
            case 'T':
                free(async_fence_data.name);
                async_fence_data.name = g_strdup_printf("%s.%s", crm_system_name, optarg);
                break;
            case 'a':
                agent = optarg;
                break;
            case 'l':
                target = optarg;
                action = 'L';
                break;
            case 'M':
                no_connect = 1;
                action = flag;
                break;
            case 't':
                timeout = crm_atoi(optarg, NULL);
                break;
            case 'B':
            case 'F':
            case 'U':
                /* using mainloop here */
                no_connect = 1;
                /* fall through */
            case 'C':
                /* Always log the input arguments */
                crm_log_args(argc, argv);
                target = optarg;
                action = flag;
                break;
            case 'H':
            case 'r':
            case 'd':
                target = optarg;
                action = flag;
                break;
            case 'i':
                fence_level = crm_atoi(optarg, NULL);
                break;
            case 'v':
                devices = stonith_key_value_add(devices, NULL, optarg);
                break;
            case 'o':
                crm_info("Scanning: -o %s", optarg);
                rc = sscanf(optarg, "%m[^=]=%m[^=]", &name, &value);
                if (rc != 2) {
                    crm_err("Invalid option: -o %s", optarg);
                    ++argerr;
                } else {
                    crm_info("Got: '%s'='%s'", name, value);
                    params = stonith_key_value_add(params, name, value);
                }
                free(value); value = NULL;
                free(name); name = NULL;
                break;
            case 'e':
                {
                    char *key = crm_concat("OCF_RESKEY", optarg, '_');
                    const char *env = getenv(key);

                    if (env == NULL) {
                        crm_err("Invalid option: -e %s", optarg);
                        ++argerr;
                    } else {
                        crm_info("Got: '%s'='%s'", optarg, env);
                        params = stonith_key_value_add(params, optarg, env);
                    }
                }
                break;
            case 0:
                if (safe_str_eq("tolerance", longname)) {
                    tolerance = crm_get_msec(optarg) / 1000;    /* Send in seconds */
                }
                break;
            default:
                ++argerr;
                break;
        }
    }

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

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

    crm_debug("Create");
    st = stonith_api_new();
    crm_debug("Created");

    if (!no_connect) {
        crm_debug("Connecting as %s", async_fence_data.name);
        rc = st->cmds->connect(st, async_fence_data.name, NULL);

        crm_debug("Connect: %d", rc);

        if (rc < 0) {
            goto done;
        }
    }

    switch (action) {
        case 'I':
            rc = st->cmds->list_agents(st, st_opt_sync_call, NULL, &devices, timeout);
            for (dIter = devices; dIter; dIter = dIter->next) {
                fprintf(stdout, " %s\n", dIter->value);
            }
            if (rc == 0) {
                fprintf(stderr, "No devices found\n");

            } else if (rc > 0) {
                fprintf(stderr, "%d devices found\n", rc);
                rc = 0;
            }
            stonith_key_value_freeall(devices, 1, 1);
            break;
        case 'L':
            rc = st->cmds->query(st, st_opts, target, &devices, timeout);
            for (dIter = devices; dIter; dIter = dIter->next) {
                fprintf(stdout, " %s\n", dIter->value);
            }
            if (rc == 0) {
                fprintf(stderr, "No devices found\n");
            } else if (rc > 0) {
                fprintf(stderr, "%d devices found\n", rc);
                rc = 0;
            }
            stonith_key_value_freeall(devices, 1, 1);
            break;
        case 'Q':
            rc = st->cmds->monitor(st, st_opts, device, timeout);
            if (rc < 0) {
                rc = st->cmds->list(st, st_opts, device, NULL, timeout);
            }
            break;
        case 'R':
            rc = st->cmds->register_device(st, st_opts, device, "stonith-ng", agent, params);
            break;
        case 'D':
            rc = st->cmds->remove_device(st, st_opts, device);
            break;
        case 'r':
            rc = st->cmds->register_level(st, st_opts, target, fence_level, devices);
            break;
        case 'd':
            rc = st->cmds->remove_level(st, st_opts, target, fence_level);
            break;
        case 'M':
            if (agent == NULL) {
                printf("Please specify an agent to query using -a,--agent [value]\n");
                return -1;
            } else {
                char *buffer = NULL;

                rc = st->cmds->metadata(st, st_opt_sync_call, agent, NULL, &buffer, timeout);
                if (rc == pcmk_ok) {
                    printf("%s\n", buffer);
                }
                free(buffer);
            }
            break;
        case 'C':
            rc = st->cmds->confirm(st, st_opts, target);
            break;
        case 'B':
            rc = mainloop_fencing(st, target, "reboot", timeout, tolerance);
            break;
        case 'F':
            rc = mainloop_fencing(st, target, "off", timeout, tolerance);
            break;
        case 'U':
            rc = mainloop_fencing(st, target, "on", timeout, tolerance);
            break;
        case 'H':
            {
                stonith_history_t *history, *hp, *latest = NULL;

                rc = st->cmds->history(st, st_opts, target, &history, timeout);
                for (hp = history; hp; hp = hp->next) {
                    char *action_s = NULL;
                    time_t complete = hp->completed;

                    if (hp->state == st_done) {
                        latest = hp;
                    }

                    if (quiet || !verbose) {
                        continue;
                    } else if (hp->action == NULL) {
                        action_s = strdup("unknown");
                    } else if (hp->action[0] != 'r') {
                        action_s = crm_concat("turn", hp->action, ' ');
                    } else {
                        action_s = strdup(hp->action);
                    }

                    if (hp->state == st_failed) {
                        printf("%s failed to %s node %s on behalf of %s from %s at %s\n",
                               hp->delegate ? hp->delegate : "We", action_s, hp->target,
                               hp->client, hp->origin, ctime(&complete));

                    } else if (hp->state == st_done && hp->delegate) {
                        printf("%s was able to %s node %s on behalf of %s from %s at %s\n",
                               hp->delegate, action_s, hp->target,
                               hp->client, hp->origin, ctime(&complete));

                    } else if (hp->state == st_done) {
                        printf("We were able to %s node %s on behalf of %s from %s at %s\n",
                               action_s, hp->target, hp->client, hp->origin, ctime(&complete));
                    } else {
                        printf("%s at %s wishes to %s node %s - %d %d\n",
                               hp->client, hp->origin, action_s, hp->target, hp->state, hp->completed);
                    }

                    free(action_s);
                }

                if (latest) {
                    if (quiet) {
                        printf("%d\n", latest->completed);
                    } else {
                        char *action_s = NULL;
                        time_t complete = latest->completed;

                        if (latest->action == NULL) {
                            action_s = strdup("unknown");
                        } else if (latest->action[0] != 'r') {
                            action_s = crm_concat("turn", latest->action, ' ');
                        } else {
                            action_s = strdup(latest->action);
                        }

                        printf("%s was able to %s node %s on behalf of %s from %s at %s\n",
                               latest->delegate ? latest->delegate : "We", action_s, latest->target,
                               latest->client, latest->origin, ctime(&complete));

                        free(action_s);
                    }
                }
                break;
            }                   /* closing bracket for -H case */
    }                           /* closing bracket for switch case */

  done:
    free(async_fence_data.name);
    crm_info("Command returned: %s (%d)", pcmk_strerror(rc), rc);
    if (rc < 0) {
        printf("Command failed: %s\n", pcmk_strerror(rc));
    }

    stonith_key_value_freeall(params, 1, 1);
    st->cmds->disconnect(st);
    crm_debug("Disconnect: %d", rc);

    crm_debug("Destroy");
    stonith_api_delete(st);

    return rc;
}
示例#17
0
int
main(int argc, char **argv)
{
	int argerr = 0;
	int flag;

#ifdef HAVE_GETOPT_H
	int option_index = 0;
	static struct option long_options[] = {
		/* Top-level Options */
		{"verbose", 0, 0, 'V'},
		{"help", 0, 0, '?'},
		{"interval", 1, 0, 'i'},
		{"group-by-node", 0, 0, 'n'},
		{"inactive", 0, 0, 'r'},
		{"as-html", 1, 0, 'h'},		
		{"web-cgi", 0, 0, 'w'},
		{"simple-status", 0, 0, 's'},
		{"as-console", 0, 0, 'c'},		
		{"one-shot", 0, 0, '1'},		
		{"daemonize", 0, 0, 'd'},		
		{"pid-file", 0, 0, 'p'},		
		{"xml-file", 1, 0, 'X'},		

		{0, 0, 0, 0}
	};
#endif
	pid_file = crm_strdup("/tmp/ClusterMon.pid");
	crm_system_name = basename(argv[0]);
	crm_log_init(crm_system_name, LOG_ERR-1, FALSE, FALSE, 0, NULL);

	if (strcmp(crm_system_name, "crm_mon.cgi")==0) {
		web_cgi = TRUE;
		one_shot = TRUE;
	}
	
	while (1) {
#ifdef HAVE_GETOPT_H
		flag = getopt_long(argc, argv, OPTARGS,
				   long_options, &option_index);
#else
		flag = getopt(argc, argv, OPTARGS);
#endif
		if (flag == -1)
			break;

		switch(flag) {
			case 'V':
				cl_log_enable_stderr(TRUE);
				alter_debug(DEBUG_INC);
				break;
			case 'i':
				interval = crm_get_msec(optarg);
				break;
			case 'n':
				group_by_node = TRUE;
				break;
			case 'r':
				inactive_resources = TRUE;
				break;
			case 'd':
				daemonize = TRUE;
				break;
			case 'p':
				pid_file = crm_strdup(optarg);
				break;
			case 'X':
				xml_file = crm_strdup(optarg);
				one_shot = TRUE;
				break;
			case 'h':
				as_html_file = crm_strdup(optarg);
				break;
			case 'w':
			        web_cgi = TRUE;
				one_shot = TRUE;
				break;
			case 'c':
#if CURSES_ENABLED
				as_console = TRUE;
#else
				printf("You need to have curses available at compile time to enable console mode\n");
				argerr++;
#endif
				break;
			case 's':
			        simple_status = TRUE;
				one_shot = TRUE;
				break;
			case '1':
				one_shot = TRUE;
				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 (argerr) {
		usage(crm_system_name, LSB_EXIT_GENERIC);
	}

	if(as_html_file == NULL && !web_cgi && !simple_status) {
#if CURSES_ENABLED
		as_console = TRUE;
#else
		printf("Defaulting to one-shot mode\n");
		printf("You need to have curses available at compile time to enable console mode\n");
		one_shot = TRUE;
#endif
	}

	if(daemonize) {
		as_console = FALSE;
	}

	if(one_shot) {
		daemonize = FALSE;
		as_console = FALSE;
	}
	
	if(daemonize && as_html_file == NULL) {
		usage(crm_system_name, LSB_EXIT_GENERIC);
	}
	
	make_daemon(daemonize, pid_file);

#if CURSES_ENABLED
	if(as_console) {
		initscr();
		cbreak();
		noecho();
	}
#endif
	
	crm_info("Starting %s", crm_system_name);
	mainloop = g_main_new(FALSE);

	if(one_shot == FALSE) {
		timer_id = Gmain_timeout_add(
			interval, mon_timer_popped, NULL);

	} else if(xml_file != NULL) {
		FILE *xml_strm = fopen(xml_file, "r");
		crm_data_t *cib_object = NULL;			
		if(strstr(xml_file, ".bz2") != NULL) {
			cib_object = file2xml(xml_strm, TRUE);
		} else {
			cib_object = file2xml(xml_strm, FALSE);
		}
		if(xml_strm != NULL) {
			fclose(xml_strm);
		}
		one_shot = TRUE;
		mon_update(NULL, 0, cib_ok, cib_object, NULL);
	}

	mon_timer_popped(NULL);
	g_main_run(mainloop);
	return_to_orig_privs();
	
	crm_info("Exiting %s", crm_system_name);	
	
#if CURSES_ENABLED
	if(as_console) {
		echo();
		nocbreak();
		endwin();
	}
#endif
	return 0;
}