Esempio n. 1
0
int get_corosync_id(int id, const char *uuid) 
{
    if(id == 0 && !uname_is_uuid() && is_corosync_cluster()) {
        id = crm_atoi(uuid, "0");
    }
    
    return id;
}
Esempio n. 2
0
int
stonith_fence_history(xmlNode * msg, xmlNode ** output)
{
    int rc = 0;
    const char *target = NULL;
    xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, msg, LOG_TRACE);

    if (dev) {
        int options = 0;

        target = crm_element_value(dev, F_STONITH_TARGET);
        crm_element_value_int(msg, F_STONITH_CALLOPTS, &options);
        if (target && (options & st_opt_cs_nodeid)) {
            int nodeid = crm_atoi(target, NULL);
            crm_node_t *node = crm_get_peer(nodeid, NULL);

            if (node) {
                target = node->uname;
            }
        }
    }

    crm_trace("Looking for operations on %s in %p", target, remote_op_list);

    *output = create_xml_node(NULL, F_STONITH_HISTORY_LIST);
    if (remote_op_list) {
        GHashTableIter iter;
        remote_fencing_op_t *op = NULL;

        g_hash_table_iter_init(&iter, remote_op_list);
        while (g_hash_table_iter_next(&iter, NULL, (void **)&op)) {
            xmlNode *entry = NULL;

            if (target && strcmp(op->target, target) != 0) {
                continue;
            }

            rc = 0;
            crm_trace("Attaching op %s", op->id);
            entry = create_xml_node(*output, STONITH_OP_EXEC);
            crm_xml_add(entry, F_STONITH_TARGET, op->target);
            crm_xml_add(entry, F_STONITH_ACTION, op->action);
            crm_xml_add(entry, F_STONITH_ORIGIN, op->originator);
            crm_xml_add(entry, F_STONITH_DELEGATE, op->delegate);
            crm_xml_add(entry, F_STONITH_CLIENTNAME, op->client_name);
            crm_xml_add_int(entry, F_STONITH_DATE, op->completed);
            crm_xml_add_int(entry, F_STONITH_STATE, op->state);
        }
    }

    return rc;
}
Esempio n. 3
0
int
main(int argc, char **argv)
{
    int rc = 0;
    int lpc = 0;
    int flag = 0;
    int option_index = 0;

    crm_log_cli_init("crm_error");
    crm_set_options(NULL, "[options] -- rc", long_options,
                    "Tool for displaying the textual description of a reported error code");
    
    while (flag >= 0) {
        flag = crm_get_option(argc, argv, &option_index);
        switch (flag) {
            case -1:
                break;
            case 'V':
                crm_bump_log_level(argc, argv);
                break;
            case '$':
            case '?':
                crm_help(flag, EX_OK);
                break;
            default:
                crm_help(flag, EX_OK);
                break;
        }
    }

    for(lpc = optind; lpc < argc; lpc++) {
        rc = crm_atoi(argv[lpc], NULL);
        printf("%s\n", pcmk_strerror(rc));
    }
    return 0;
}
Esempio n. 4
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;
}
Esempio n. 5
0
/*!
 * \internal
 * \brief Create a new remote stonith op
 * \param client, he local stonith client id that initaited the operation
 * \param request, The request from the client that started the operation
 * \param peer, Is this operation owned by another stonith peer? Operations
 *        owned by other peers are stored on all the stonith nodes, but only the
 *        owner executes the operation.  All the nodes get the results to the operation
 *        once the owner finishes executing it.
 */
void *
create_remote_stonith_op(const char *client, xmlNode * request, gboolean peer)
{
    remote_fencing_op_t *op = NULL;
    xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, request, LOG_TRACE);
    int call_options = 0;

    if (remote_op_list == NULL) {
        remote_op_list = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, free_remote_op);
    }

    /* If this operation is owned by another node, check to make
     * sure we haven't already created this operation. */
    if (peer && dev) {
        const char *op_id = crm_element_value(dev, F_STONITH_REMOTE_OP_ID);

        CRM_CHECK(op_id != NULL, return NULL);

        op = g_hash_table_lookup(remote_op_list, op_id);
        if (op) {
            crm_debug("%s already exists", op_id);
            return op;
        }
    }

    op = calloc(1, sizeof(remote_fencing_op_t));

    crm_element_value_int(request, F_STONITH_TIMEOUT, (int *)&(op->base_timeout));

    if (peer && dev) {
        op->id = crm_element_value_copy(dev, F_STONITH_REMOTE_OP_ID);
    } else {
        op->id = crm_generate_uuid();
    }

    g_hash_table_replace(remote_op_list, op->id, op);
    CRM_LOG_ASSERT(g_hash_table_lookup(remote_op_list, op->id) != NULL);
    crm_trace("Created %s", op->id);

    op->state = st_query;
    op->replies_expected = fencing_active_peers();
    op->action = crm_element_value_copy(dev, F_STONITH_ACTION);
    op->originator = crm_element_value_copy(dev, F_STONITH_ORIGIN);
    op->delegate = crm_element_value_copy(dev, F_STONITH_DELEGATE); /* May not be set */
    op->created = time(NULL);

    if (op->originator == NULL) {
        /* Local or relayed request */
        op->originator = strdup(stonith_our_uname);
    }

    CRM_LOG_ASSERT(client != NULL);
    if (client) {
        op->client_id = strdup(client);
    }

    op->client_name = crm_element_value_copy(request, F_STONITH_CLIENTNAME);

    op->target = crm_element_value_copy(dev, F_STONITH_TARGET);
    op->request = copy_xml(request);    /* TODO: Figure out how to avoid this */
    crm_element_value_int(request, F_STONITH_CALLOPTS, &call_options);
    op->call_options = call_options;
    
    crm_element_value_int(request, F_STONITH_CALLID, (int *)&(op->client_callid));

    crm_trace("%s new stonith op: %s - %s of %s for %s",
              (peer
               && dev) ? "Recorded" : "Generated", op->id, op->action, op->target, op->client_name);

    if (op->call_options & st_opt_cs_nodeid) {
        int nodeid = crm_atoi(op->target, NULL);
        crm_node_t *node = crm_get_peer(nodeid, NULL);

        /* Ensure the conversion only happens once */
        op->call_options &= ~st_opt_cs_nodeid;

        if (node && node->uname) {
            free(op->target);
            op->target = strdup(node->uname);
        } else {
            crm_warn("Could not expand nodeid '%s' into a host name (%p)", op->target, node);
        }
    }

    /* check to see if this is a duplicate operation of another in-flight operation */
    merge_duplicates(op);

    return op;
}
Esempio n. 6
0
/*!
 * \internal
 * \brief Handle fence-history messages (either from API or coming in as
 *        broadcasts
 *
 * \param[in] msg       Request message
 * \param[in] output    In case of a request from the API used to craft
 *                      a reply from
 * \param[in] remote_peer
 * \param[in] options   call-options from the request
 *
 * \return always success as there is actully nothing that can go really wrong
 */
int
stonith_fence_history(xmlNode *msg, xmlNode **output,
                      const char *remote_peer, int options)
{
    int rc = 0;
    const char *target = NULL;
    xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, msg, LOG_TRACE);
    xmlNode *out_history = NULL;

    if (dev) {
        target = crm_element_value(dev, F_STONITH_TARGET);
        if (target && (options & st_opt_cs_nodeid)) {
            int nodeid = crm_atoi(target, NULL);
            crm_node_t *node = crm_find_known_peer_full(nodeid, NULL, CRM_GET_PEER_ANY);

            if (node) {
                target = node->uname;
            }
        }
    }

    if (options & st_opt_cleanup) {
        crm_trace("Cleaning up operations on %s in %p", target,
                  stonith_remote_op_list);

        stonith_fence_history_cleanup(target,
            crm_element_value(msg, F_STONITH_CALLID) != NULL);
    } else if (options & st_opt_broadcast) {
        if (crm_element_value(msg, F_STONITH_CALLID)) {
            /* this is coming from the stonith-API
            *
            * craft a broadcast with node's history
            * so that every node can merge and broadcast
            * what it has on top
            */
            out_history = stonith_local_history_diff(NULL, TRUE, NULL);
            crm_trace("Broadcasting history to peers");
            stonith_send_broadcast_history(out_history,
                                        st_opt_broadcast | st_opt_discard_reply,
                                        NULL);
        } else if (remote_peer &&
                   !safe_str_eq(remote_peer, stonith_our_uname)) {
            xmlNode *history =
                get_xpath_object("//" F_STONITH_HISTORY_LIST, msg, LOG_TRACE);
            GHashTable *received_history =
                history?stonith_xml_history_to_list(history):NULL;

            /* either a broadcast created directly upon stonith-API request
            * or a diff as response to such a thing
            *
            * in both cases it may have a history or not
            * if we have differential data
            * merge in what we've received and stop
            * otherwise broadcast what we have on top
            * marking as differential and merge in afterwards
            */
            if (!history ||
                !crm_is_true(crm_element_value(history,
                                               F_STONITH_DIFFERENTIAL))) {
                out_history =
                    stonith_local_history_diff(received_history, TRUE, NULL);
                if (out_history) {
                    crm_trace("Broadcasting history-diff to peers");
                    crm_xml_add(out_history, F_STONITH_DIFFERENTIAL,
                                XML_BOOLEAN_TRUE);
                    stonith_send_broadcast_history(out_history,
                        st_opt_broadcast | st_opt_discard_reply,
                        NULL);
                } else {
                    crm_trace("History-diff is empty - skip broadcast");
                }
            }
            stonith_merge_in_history_list(received_history);
        } else {
            crm_trace("Skipping history-query-broadcast (%s%s)"
                      " we sent ourselves",
                      remote_peer?"remote-peer=":"local-ipc",
                      remote_peer?remote_peer:"");
        }
    } else {
        /* plain history request */
        crm_trace("Looking for operations on %s in %p", target,
                  stonith_remote_op_list);
        *output = stonith_local_history_diff(NULL, FALSE, target);
    }
    free_xml(out_history);
    return rc;
}
Esempio n. 7
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;
}
Esempio n. 8
0
void *create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer)
{
    remote_fencing_op_t *op = NULL;
    xmlNode *dev = get_xpath_object("//@"F_STONITH_TARGET, request, LOG_TRACE);

    if(remote_op_list == NULL) {
        remote_op_list = g_hash_table_new_full(
        crm_str_hash, g_str_equal, NULL, free_remote_op);
    }

    if(peer && dev) {
        const char *peer_id = crm_element_value(dev, F_STONITH_REMOTE);
        CRM_CHECK(peer_id != NULL, return NULL);

        op = g_hash_table_lookup(remote_op_list, peer_id);
        if(op) {
            crm_debug("%s already exists", peer_id);
            return op;
        }
    }

    op = calloc(1, sizeof(remote_fencing_op_t));
    crm_element_value_int(request, F_STONITH_TIMEOUT, (int*)&(op->base_timeout));

    if(peer && dev) {
        op->id = crm_element_value_copy(dev, F_STONITH_REMOTE);
        crm_trace("Recorded new stonith op: %s", op->id);
    } else {
        op->id = crm_generate_uuid();
        crm_trace("Generated new stonith op: %s", op->id);
    }

    g_hash_table_replace(remote_op_list, op->id, op);
    CRM_LOG_ASSERT(g_hash_table_lookup(remote_op_list, op->id) != NULL);

    op->state = st_query;
    op->action = crm_element_value_copy(dev, F_STONITH_ACTION);
    op->originator = crm_element_value_copy(dev, F_STONITH_OWNER);

    if(op->originator == NULL) {
        /* Local request */
        op->originator = strdup(stonith_our_uname);
    }

    if(client) {
        op->client_id = strdup(client);
    }

    op->client_name = crm_element_value_copy(request, F_STONITH_CLIENTNAME);

    op->target = crm_element_value_copy(dev, F_STONITH_TARGET);
    op->request = copy_xml(request); /* TODO: Figure out how to avoid this */
    crm_element_value_int(request, F_STONITH_CALLOPTS, (int*)&(op->call_options));

    if(op->call_options & st_opt_cs_nodeid) {
        int nodeid = crm_atoi(op->target, NULL);
        crm_node_t *node = crm_get_peer(nodeid, NULL);

        /* Ensure the conversion only happens once */
        op->call_options &= ~st_opt_cs_nodeid;

        if(node) {
            free(op->target);
            op->target = strdup(node->uname);
        }
    }

    if(stonith_topology_next(op) != pcmk_ok) {
        op->state = st_failed;
    }
    return op;
}
Esempio n. 9
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;

    char name[512];
    char value[512];
    const char *agent = NULL;
    const char *device = NULL;
    const char *target = 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_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv);
    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");

    while (1) {
	flag = crm_get_option(argc, argv, &option_index);
	if (flag == -1)
	    break;
		
	switch(flag) {
	    case 'V':
		verbose = 1;
		crm_bump_log_level();
		break;
	    case '$':
	    case '?':
		crm_help(flag, LSB_EXIT_OK);
		break;
	    case 'L':
	    case 'I':
		action = flag;
		break;
	    case 'q':
		quiet = 1;
		break;
	    case 'Q':
	    case 'R':
	    case 'D':
		action = flag;
		device = optarg;
		break;
	    case 'a':
		agent = optarg;
		break;
	    case 'l':
		target = optarg;
		action = 'L';
		break;
	    case 'M':
		action = flag;
		break;
            case 't':
                timeout = crm_atoi(optarg, NULL);
                break;
	    case 'B':
	    case 'F':
	    case 'U':
	    case 'C':
	    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, "%[^=]=%[^=]", name, value);
		if(rc != 2) {
		    crm_err("Invalid option: -o %s", optarg);
		    ++argerr;
		} else {
		    crm_info("Got: '%s'='%s'", name, value);
		    stonith_key_value_add(params, name, value);
		}
		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);
                        stonith_key_value_add( params, optarg, env);
		    }
		}
		break;
	    default:
		++argerr;
		break;
	}
    }

    if (optind > argc) {
	++argerr;
    }
    
    if (argerr) {
	crm_help('?', LSB_EXIT_GENERIC);
    }

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

    if(action != 'M' && action != 'I') {
	rc = st->cmds->connect(st, crm_system_name, NULL);
	crm_debug("Connect: %d", rc);

	if(rc < 0) {
	    goto done;
	}
    }
    
    switch(action)
    {
	case 'I':
	    rc = st->cmds->list(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->call(st, st_opts, device, "monitor", NULL, timeout);
	    if(rc < 0) {
		rc = st->cmds->call(st, st_opts, device, "list", 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;
		st->cmds->metadata(st, st_opt_sync_call, agent, NULL, &buffer, timeout);
		printf("%s\n", buffer);
		crm_free(buffer);
	    }
	    break;
	    
	case 'C':
	    rc = st->cmds->confirm(st, st_opts, target);
	    break;
	case 'B':
	    rc = st->cmds->fence(st, st_opts, target, "reboot", timeout);
	    break;
	case 'F':
	    rc = st->cmds->fence(st, st_opts, target, "off", timeout);
	    break;
	case 'U':
	    rc = st->cmds->fence(st, st_opts, target, "on", timeout);
	    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 = crm_strdup("unknown");
		    } else if(hp->action[0] != 'r') {
			action_s = crm_concat("turn", hp->action, ' ');
		    } else {
			action_s = crm_strdup(hp->action);
		    }
			
		    if(hp->state == st_failed) {
			printf("%s failed to %s node %s on behalf of %s at %s\n",
			       hp->delegate?hp->delegate:"We", action_s, hp->target, hp->origin,
			       ctime(&complete));

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

		    } else if(hp->state == st_done) {
			printf("We were able to %s node %s on behalf of %s at %s\n",
			       action_s, hp->target, hp->origin, ctime(&complete));
		    } else {
			printf("%s wishes to %s node %s - %d %d\n",
			       hp->origin, action_s, hp->target, hp->state, hp->completed);
		    }
		    
		    crm_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 = crm_strdup("unknown");
			} else if(latest->action[0] != 'r') {
			    action_s = crm_concat("turn", latest->action, ' ');
			} else {
			    action_s = crm_strdup(latest->action);
			}
			
			printf("%s was able to %s node %s on behalf of %s at %s\n",
			       latest->delegate?latest->delegate:"We", action_s, latest->target,
			       latest->origin, ctime(&complete));
			
			crm_free(action_s);
		    }
		}
	    }
	    break;
    }    

  done:
    if(rc < 0) {
	printf("Command failed: %s\n", stonith_error2string(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;
}