예제 #1
0
파일: ptest.c 프로젝트: brhellman/pacemaker
static char *
create_action_name(action_t * action)
{
    char *action_name = NULL;
    const char *action_host = NULL;

    if (action->node) {
        action_host = action->node->details->uname;
        action_name = crm_concat(action->uuid, action_host, ' ');

    } else if (is_set(action->flags, pe_action_pseudo)) {
        action_name = crm_strdup(action->uuid);

    } else {
        action_host = "<none>";
        action_name = crm_concat(action->uuid, action_host, ' ');
    }
    if (safe_str_eq(action->task, RSC_CANCEL)) {
        char *tmp_action_name = action_name;

        action_name = crm_concat("Cancel", tmp_action_name, ' ');
        crm_free(tmp_action_name);
    }

    return action_name;
}
예제 #2
0
static enum crmd_fsa_input
handle_failcount_op(xmlNode * stored_msg)
{
    const char *rsc = NULL;
    xmlNode *xml_rsc = get_xpath_object("//" XML_CIB_TAG_RESOURCE, stored_msg, LOG_ERR);

    if (xml_rsc) {
        rsc = ID(xml_rsc);
    }

    if (rsc) {
        char *attr = NULL;

        crm_info("Removing failcount for %s", rsc);

        attr = crm_concat("fail-count", rsc, '-');
        update_attrd(NULL, attr, NULL, NULL);
        free(attr);

        attr = crm_concat("last-failure", rsc, '-');
        update_attrd(NULL, attr, NULL, NULL);
        free(attr);

        lrm_clear_last_failure(rsc);
    } else {
        crm_log_xml_warn(stored_msg, "invalid failcount op");
    }

    return I_NULL;
}
예제 #3
0
char *
get_shadow_file(const char *suffix)
{
    char *cib_home = NULL;
    char *fullname = NULL;
    char *name = crm_concat("shadow", suffix, '.');
    const char *dir = getenv("CIB_shadow_dir");

    if (dir == NULL) {
        uid_t uid = geteuid();
        struct passwd *pwent = getpwuid(uid);
        const char *user = NULL;

        if (pwent) {
            user = pwent->pw_name;
        } else {
            user = getenv("USER");
            crm_perror(LOG_ERR,
                       "Assuming %s because cannot get user details for user ID %d",
                       (user? user : "******"), uid);
        }

        if (safe_str_eq(user, "root") || safe_str_eq(user, CRM_DAEMON_USER)) {
            dir = CRM_CONFIG_DIR;

        } else {
            const char *home = NULL;

            if ((home = getenv("HOME")) == NULL) {
                if (pwent) {
                    home = pwent->pw_dir;
                }
            }

            dir = crm_get_tmpdir();
            if (home && home[0] == '/') {
                int rc = 0;

                cib_home = crm_concat(home, ".cib", '/');

                rc = mkdir(cib_home, 0700);
                if (rc < 0 && errno != EEXIST) {
                    crm_perror(LOG_ERR, "Couldn't create user-specific shadow directory: %s",
                               cib_home);
                    errno = 0;

                } else {
                    dir = cib_home;
                }
            }
        }
    }

    fullname = crm_concat(dir, name, '/');
    free(cib_home);
    free(name);

    return fullname;
}
예제 #4
0
파일: io.c 프로젝트: ClusterLabs/pacemaker
/*!
 * \internal
 * \brief Check whether a directory or file is writable by the cluster daemon
 *
 * Return TRUE if either the cluster daemon user or cluster daemon group has
 * write permission on a specified file or directory.
 *
 * \param[in] dir      Directory to check (this argument must be specified, and
 *                     the directory must exist)
 * \param[in] file     File to check (only the directory will be checked if this
 *                     argument is not specified or the file does not exist)
 *
 * \return TRUE if target is writable by cluster daemon, FALSE otherwise
 */
bool
pcmk__daemon_can_write(const char *dir, const char *file)
{
    int s_res = 0;
    struct stat buf;
    char *full_file = NULL;
    const char *target = NULL;

    // Caller must supply directory
    CRM_ASSERT(dir != NULL);

    // If file is given, check whether it exists as a regular file
    if (file != NULL) {
        full_file = crm_concat(dir, file, '/');
        target = full_file;

        s_res = stat(full_file, &buf);
        if (s_res < 0) {
            crm_notice("%s not found: %s", target, pcmk_strerror(errno));
            free(full_file);
            full_file = NULL;
            target = NULL;

        } else if (S_ISREG(buf.st_mode) == FALSE) {
            crm_err("%s must be a regular file " CRM_XS " st_mode=0%lo",
                    target, (unsigned long) buf.st_mode);
            free(full_file);
            return FALSE;
        }
    }

    // If file is not given, ensure dir exists as directory
    if (target == NULL) {
        target = dir;
        s_res = stat(dir, &buf);
        if (s_res < 0) {
            crm_err("%s not found: %s", dir, pcmk_strerror(errno));
            return FALSE;

        } else if (S_ISDIR(buf.st_mode) == FALSE) {
            crm_err("%s must be a directory " CRM_XS " st_mode=0%lo",
                    dir, (unsigned long) buf.st_mode);
            return FALSE;
        }
    }

    if (!pcmk__daemon_user_can_write(target, &buf)
        && !pcmk__daemon_group_can_write(target, &buf)) {

        crm_err("%s must be owned and writable by either user %s or group %s "
                CRM_XS " st_mode=0%lo",
                target, CRM_DAEMON_USER, CRM_DAEMON_GROUP,
                (unsigned long) buf.st_mode);
        free(full_file);
        return FALSE;
    }

    free(full_file);
    return TRUE;
}
예제 #5
0
char *
generate_hash_key(const char *crm_msg_reference, const char *sys)
{
	char *hash_key = crm_concat(sys?sys:"none", crm_msg_reference, '_');
	crm_debug_3("created hash key: (%s)", hash_key);
	return hash_key;
}
예제 #6
0
파일: clone.c 프로젝트: credativ/pacemaker
static void
clone_print_xml(resource_t * rsc, const char *pre_text, long options, void *print_data)
{
    int is_master_slave = rsc->variant == pe_master ? 1 : 0;
    char *child_text = crm_concat(pre_text, "   ", ' ');
    GListPtr gIter = rsc->children;

    status_print("%s<clone ", pre_text);
    status_print("id=\"%s\" ", rsc->id);
    status_print("multi_state=\"%s\" ", is_master_slave ? "true" : "false");
    status_print("unique=\"%s\" ", is_set(rsc->flags, pe_rsc_unique) ? "true" : "false");
    status_print("managed=\"%s\" ", is_set(rsc->flags, pe_rsc_managed) ? "true" : "false");
    status_print("failed=\"%s\" ", is_set(rsc->flags, pe_rsc_failed) ? "true" : "false");
    status_print("failure_ignored=\"%s\" ",
                 is_set(rsc->flags, pe_rsc_failure_ignored) ? "true" : "false");
    status_print(">\n");

    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child_rsc = (resource_t *) gIter->data;

        child_rsc->fns->print(child_rsc, child_text, options, print_data);
    }

    status_print("%s</clone>\n", pre_text);
    free(child_text);
}
예제 #7
0
static enum crmd_fsa_input
handle_failcount_op(xmlNode * stored_msg)
{
    const char *rsc = NULL;
    const char *uname = NULL;
    gboolean is_remote_node = FALSE;
    xmlNode *xml_rsc = get_xpath_object("//" XML_CIB_TAG_RESOURCE, stored_msg, LOG_ERR);

    if (xml_rsc) {
        rsc = ID(xml_rsc);
    }

    uname = crm_element_value(stored_msg, XML_LRM_ATTR_TARGET);
    if (crm_element_value(stored_msg, XML_LRM_ATTR_ROUTER_NODE)) {
        is_remote_node = TRUE;
    }

    if (rsc) {
        char *attr = NULL;

        crm_info("Removing failcount for %s", rsc);

        attr = crm_concat("fail-count", rsc, '-');
        update_attrd(uname, attr, NULL, NULL, is_remote_node);
        free(attr);

        attr = crm_concat("last-failure", rsc, '-');
        update_attrd(uname, attr, NULL, NULL, is_remote_node);
        free(attr);

        lrm_clear_last_failure(rsc, uname);
    } else {
        crm_log_xml_warn(stored_msg, "invalid failcount op");
    }

    return I_NULL;
}
예제 #8
0
static char *
template_op_key(xmlNode * op)
{
    const char *name = crm_element_value(op, "name");
    const char *role = crm_element_value(op, "role");
    char *key = NULL;

    if (role == NULL || crm_str_eq(role, RSC_ROLE_STARTED_S, TRUE)
        || crm_str_eq(role, RSC_ROLE_SLAVE_S, TRUE)) {
        role = RSC_ROLE_UNKNOWN_S;
    }

    key = crm_concat(name, role, '-');
    return key;
}
예제 #9
0
파일: group.c 프로젝트: MEShrek/pacemaker
void
group_print(resource_t * rsc, const char *pre_text, long options, void *print_data)
{
    char *child_text = NULL;
    GListPtr gIter = rsc->children;

    if (pre_text == NULL) {
        pre_text = " ";
    }

    if (options & pe_print_xml) {
        group_print_xml(rsc, pre_text, options, print_data);
        return;
    }

    child_text = crm_concat(pre_text, "   ", ' ');

    status_print("%sResource Group: %s", pre_text ? pre_text : "", rsc->id);

    if (options & pe_print_html) {
        status_print("\n<ul>\n");

    } else if ((options & pe_print_log) == 0) {
        status_print("\n");
    }

    if (options & pe_print_brief) {
        print_rscs_brief(rsc->children, child_text, options, print_data, TRUE);

    } else {
        for (; gIter != NULL; gIter = gIter->next) {
            resource_t *child_rsc = (resource_t *) gIter->data;

            if (options & pe_print_html) {
                status_print("<li>\n");
            }
            child_rsc->fns->print(child_rsc, child_text, options, print_data);
            if (options & pe_print_html) {
                status_print("</li>\n");
            }
        }
    }

    if (options & pe_print_html) {
        status_print("</ul>\n");
    }
    free(child_text);
}
예제 #10
0
파일: clone.c 프로젝트: credativ/pacemaker
resource_t *
find_clone_instance(resource_t * rsc, const char *sub_id, pe_working_set_t * data_set)
{
    char *child_id = NULL;
    resource_t *child = NULL;
    const char *child_base = NULL;
    clone_variant_data_t *clone_data = NULL;

    get_clone_variant_data(clone_data, rsc);

    child_base = ID(clone_data->xml_obj_child);
    child_id = crm_concat(child_base, sub_id, ':');
    child = pe_find_resource(rsc->children, child_id);

    free(child_id);
    return child;
}
예제 #11
0
static int
get_config_opt(confdb_handle_t config,
               hdb_handle_t object_handle, const char *key, char **value, const char *fallback)
{
    size_t len = 0;
    char *env_key = NULL;
    const char *env_value = NULL;
    char buffer[256];

    if (*value) {
        free(*value);
        *value = NULL;
    }

    if (object_handle > 0) {
        if (CS_OK == confdb_key_get(config, object_handle, key, strlen(key), &buffer, &len)) {
            *value = strdup(buffer);
        }
    }

    if (*value) {
        crm_info("Found '%s' for option: %s", *value, key);
        return 0;
    }

    env_key = crm_concat("HA", key, '_');
    env_value = getenv(env_key);
    free(env_key);

    if (*value) {
        crm_info("Found '%s' in ENV for option: %s", *value, key);
        *value = strdup(env_value);
        return 0;
    }

    if (fallback) {
        crm_info("Defaulting to '%s' for option: %s", fallback, key);
        *value = strdup(fallback);

    } else {
        crm_info("No default for option: %s", key);
    }

    return -1;
}
예제 #12
0
파일: group.c 프로젝트: MEShrek/pacemaker
static void
group_print_xml(resource_t * rsc, const char *pre_text, long options, void *print_data)
{
    GListPtr gIter = rsc->children;
    char *child_text = crm_concat(pre_text, "    ", ' ');

    status_print("%s<group id=\"%s\" ", pre_text, rsc->id);
    status_print("number_resources=\"%d\" ", g_list_length(rsc->children));
    status_print(">\n");

    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child_rsc = (resource_t *) gIter->data;

        child_rsc->fns->print(child_rsc, child_text, options, print_data);
    }

    status_print("%s</group>\n", pre_text);
    free(child_text);
}
예제 #13
0
char *
generate_hash_value(const char *src_node, const char *src_subsys)
{
	char *hash_value = NULL;
	
	if (src_node == NULL || src_subsys == NULL) {
		return NULL;
	}
    
	if (strcasecmp(CRM_SYSTEM_DC, src_subsys) == 0) {
		hash_value = crm_strdup(src_subsys);
		CRM_ASSERT(hash_value);
		return hash_value;
	}

	hash_value = crm_concat(src_node, src_subsys, '_');
	crm_info("created hash value: (%s)", hash_value);
	return hash_value;
}
예제 #14
0
파일: utils.c 프로젝트: beekhof/pacemaker
char *
crm_meta_name(const char *field)
{
    int lpc = 0;
    int max = 0;
    char *crm_name = NULL;

    CRM_CHECK(field != NULL, return NULL);
    crm_name = crm_concat(CRM_META, field, '_');

    /* Massage the names so they can be used as shell variables */
    max = strlen(crm_name);
    for (; lpc < max; lpc++) {
        switch (crm_name[lpc]) {
            case '-':
                crm_name[lpc] = '_';
                break;
        }
    }
    return crm_name;
}
예제 #15
0
파일: utils.c 프로젝트: sipwise/heartbeat
char *
generate_hash_value(const char *src_node, const char *src_subsys)
{
	char *hash_value = NULL;
	
	if (src_node == NULL || src_subsys == NULL) {
		return NULL;
	}
    
	if (strcasecmp(CRM_SYSTEM_DC, src_subsys) == 0) {
		hash_value = crm_strdup(src_subsys);
		if (!hash_value) {
			crm_err("memory allocation failed in "
			       "generate_hash_value()");
		}
		return hash_value;
	}

	hash_value = crm_concat(src_node, src_subsys, '_');
	crm_info("created hash value: (%s)", hash_value);
	return hash_value;
}
예제 #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
update_attr_delegate(cib_t * the_cib, int call_options,
                     const char *section, const char *node_uuid, const char *set_type,
                     const char *set_name, const char *attr_id, const char *attr_name,
                     const char *attr_value, gboolean to_console, const char *user_name)
{
    const char *tag = NULL;
    int rc = pcmk_ok;
    xmlNode *xml_top = NULL;
    xmlNode *xml_obj = NULL;

    char *local_attr_id = NULL;
    char *local_set_name = NULL;
    gboolean use_attributes_tag = FALSE;

    CRM_CHECK(section != NULL, return -EINVAL);
    CRM_CHECK(attr_value != NULL, return -EINVAL);
    CRM_CHECK(attr_name != NULL || attr_id != NULL, return -EINVAL);

    rc = find_nvpair_attr_delegate(the_cib, XML_ATTR_ID, section, node_uuid, set_type, set_name,
                                   attr_id, attr_name, FALSE, &local_attr_id, user_name);
    if (rc == pcmk_ok) {
        attr_id = local_attr_id;
        goto do_modify;

    } else if (rc != -ENXIO) {
        return rc;

        /* } else if(attr_id == NULL) { */
        /*     return -EINVAL; */

    } else {
        const char *value = NULL;
        const char *node_type = NULL;
        xmlNode *cib_top = NULL;

        rc = cib_internal_op(the_cib, CIB_OP_QUERY, NULL, "/cib", NULL, &cib_top,
                             cib_sync_call | cib_scope_local | cib_xpath | cib_no_children, user_name);

        value = crm_element_value(cib_top, "ignore_dtd");
        if (value != NULL) {
            use_attributes_tag = TRUE;

        } else {
            value = crm_element_value(cib_top, XML_ATTR_VALIDATION);
            if (value && strstr(value, "-0.6")) {
                use_attributes_tag = TRUE;
            }
        }
        free_xml(cib_top);

        if (safe_str_eq(section, XML_CIB_TAG_TICKETS)) {
            node_uuid = NULL;
            section = XML_CIB_TAG_STATUS;
            node_type = XML_CIB_TAG_TICKETS;

            xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_STATUS);
            if (xml_top == NULL) {
                xml_top = xml_obj;
            }

            xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_TICKETS);

        } else if (safe_str_eq(section, XML_CIB_TAG_NODES)) {
            tag = XML_CIB_TAG_NODE;
            if (node_uuid == NULL) {
                return -EINVAL;
            }

        } else if (safe_str_eq(section, XML_CIB_TAG_STATUS)) {
            tag = XML_TAG_TRANSIENT_NODEATTRS;
            if (node_uuid == NULL) {
                return -EINVAL;
            }

            xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_STATE);
            crm_xml_add(xml_obj, XML_ATTR_ID, node_uuid);
            if (xml_top == NULL) {
                xml_top = xml_obj;
            }

        } else {
            tag = section;
            node_uuid = NULL;
        }

        if (set_name == NULL) {
            if (safe_str_eq(section, XML_CIB_TAG_CRMCONFIG)) {
                local_set_name = strdup(CIB_OPTIONS_FIRST);

            } else if (safe_str_eq(node_type, XML_CIB_TAG_TICKETS)) {
                local_set_name = crm_concat(section, XML_CIB_TAG_TICKETS, '-');

            } else if (node_uuid) {
                local_set_name = crm_concat(section, node_uuid, '-');

                if (set_type) {
                    char *tmp_set_name = local_set_name;

                    local_set_name = crm_concat(tmp_set_name, set_type, '-');
                    free(tmp_set_name);
                }
            } else {
                local_set_name = crm_concat(section, "options", '-');
            }
            set_name = local_set_name;
        }

        if (attr_id == NULL) {
            int lpc = 0;

            local_attr_id = crm_concat(set_name, attr_name, '-');
            attr_id = local_attr_id;

            /* Minimal attempt at sanitizing automatic IDs */
            for (lpc = 0; local_attr_id[lpc] != 0; lpc++) {
                switch (local_attr_id[lpc]) {
                    case ':':
                        local_attr_id[lpc] = '.';
                }
            }

        } else if (attr_name == NULL) {
            attr_name = attr_id;
        }

        crm_trace("Creating %s/%s", section, tag);
        if (tag != NULL) {
            xml_obj = create_xml_node(xml_obj, tag);
            crm_xml_add(xml_obj, XML_ATTR_ID, node_uuid);
            if (xml_top == NULL) {
                xml_top = xml_obj;
            }
        }

        if (node_uuid == NULL && safe_str_neq(node_type, XML_CIB_TAG_TICKETS)) {
            if (safe_str_eq(section, XML_CIB_TAG_CRMCONFIG)) {
                xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_PROPSET);
            } else {
                xml_obj = create_xml_node(xml_obj, XML_TAG_META_SETS);
            }

        } else if (set_type) {
            xml_obj = create_xml_node(xml_obj, set_type);

        } else {
            xml_obj = create_xml_node(xml_obj, XML_TAG_ATTR_SETS);
        }
        crm_xml_add(xml_obj, XML_ATTR_ID, set_name);

        if (xml_top == NULL) {
            xml_top = xml_obj;
        }

        if (use_attributes_tag) {
            xml_obj = create_xml_node(xml_obj, XML_TAG_ATTRS);
        }
    }

  do_modify:
    xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_NVPAIR);
    if (xml_top == NULL) {
        xml_top = xml_obj;
    }

    crm_xml_add(xml_obj, XML_ATTR_ID, attr_id);
    crm_xml_add(xml_obj, XML_NVPAIR_ATTR_NAME, attr_name);
    crm_xml_add(xml_obj, XML_NVPAIR_ATTR_VALUE, attr_value);

    crm_log_xml_trace(xml_top, "update_attr");
    rc = cib_internal_op(the_cib, CIB_OP_MODIFY, NULL, section, xml_top, NULL,
                         call_options | cib_quorum_override, user_name);

    if (rc < pcmk_ok) {
        attr_msg(LOG_ERR, "Error setting %s=%s (section=%s, set=%s): %s",
                 attr_name, attr_value, section, crm_str(set_name), pcmk_strerror(rc));
        crm_log_xml_info(xml_top, "Update");
    }

    free(local_set_name);
    free(local_attr_id);
    free_xml(xml_top);

    return rc;
}
예제 #18
0
/**
 * This is the main function to update resource table v2.
 * Return the number of resources.
 */
static int
update_resources_recursively(GListPtr reslist, GListPtr nodelist, int index)
{
    GListPtr gIter1 = NULL;

    if (reslist == NULL) {
        return index;
    }
    /*
     * Set resource info to resource table v2 from data_set,
     * and add it to Glib's array.
     */
    for(gIter1 = reslist; gIter1 != NULL; gIter1 = gIter1->next) {
        resource_t *rsc = gIter1->data;
        GListPtr gIter2 = NULL;

        cl_log(LOG_DEBUG, "resource %s processing.", rsc->id);

        for(gIter2 = nodelist; gIter2 != NULL; gIter2 = gIter2->next) {
            node_t *node = gIter2->data;
            struct hb_rsinfov2 *rsinfo;
            enum rsc_role_e rsstate;

            rsinfo = (struct hb_rsinfov2 *) malloc(sizeof(struct hb_rsinfov2));
            if (!rsinfo) {
                cl_log(LOG_CRIT, "malloc resource info v2 failed.");
                return HA_FAIL;
            }

            rsinfo->resourceid = strdup(rsc->id);
            rsinfo->type = PE_OBJ_TYPES2AGENTTYPE(rsc->variant);

            /* using a temp var to suppress casting warning of the compiler */
            rsstate = rsc->fns->state(rsc, TRUE);
            {
                GListPtr running_on_nodes = NULL;

                rsc->fns->location(rsc, &running_on_nodes, TRUE);
                if (pe_find_node_id(
                    running_on_nodes, node->details->id) == NULL) {
                    /*
                     * if the resource is not running on current node,
                     * its status is "stopped(1)".
                     */
                    rsstate = RSC_ROLE_STOPPED;
                }
               g_list_free(running_on_nodes);
            }
            rsinfo->status = RSC_ROLE_E2AGENTSTATUS(rsstate);
            rsinfo->node = strdup(node->details->uname);

            if (is_not_set(rsc->flags, pe_rsc_managed)) {
                rsinfo->is_managed = LHARESOURCEISMANAGED_UNMANAGED;
            } else {
                rsinfo->is_managed = LHARESOURCEISMANAGED_MANAGED;
            }

            /* get fail-count from <status> */
            {
                char *attr_name = NULL;
                char *attr_value = NULL;
                crm_data_t *tmp_xml = NULL;

                attr_name = crm_concat("fail-count", rsinfo->resourceid, '-');
                attr_value = g_hash_table_lookup(node->details->attrs,
                    attr_name); 
                rsinfo->failcount = crm_parse_int(attr_value, "0");
                free(attr_name);
                free_xml(tmp_xml);
             }

            if (rsc->parent != NULL) {
                rsinfo->parent = strdup(rsc->parent->id);
            } else {
                rsinfo->parent = strdup("");
            }

            /*
             * if the resource stops, and its fail-count is 0,
             * don't list it up.
             */ 
            if (rsinfo->status != LHARESOURCESTATUS_STOPPED || 
                   rsinfo->failcount > 0) {
                rsinfo->index = index++;
                g_ptr_array_add(gResourceTableV2, (gpointer *)rsinfo);
            } else {
                free(rsinfo->resourceid);
                free(rsinfo->node);
                free(rsinfo->parent);
                free(rsinfo);
            }

        } /* end slist_iter(node) */

        /* add resources recursively for group/clone/master */
        index = update_resources_recursively(rsc->children,
            nodelist, index);

    } /* end slist_iter(rsc) */

    return index;
}
예제 #19
0
파일: admin.c 프로젝트: brhellman/pacemaker
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;
}
예제 #20
0
파일: io.c 프로젝트: KevenChang/pacemaker
/*!
 * \internal
 * \brief Return whether a directory or file is writable by a user/group
 *
 * \param[in] dir Directory to check or that contains file
 * \param[in] file File name to check (or NULL to check directory)
 * \param[in] user Name of user that should have write permission
 * \param[in] group Name of group that should have write permission
 * \param[in] need_both Whether both user and group must be able to write
 *
 * \return TRUE if permissions match, FALSE if they don't or on error
 */
gboolean
crm_is_writable(const char *dir, const char *file,
                const char *user, const char *group, gboolean need_both)
{
    int s_res = -1;
    struct stat buf;
    char *full_file = NULL;
    const char *target = NULL;

    gboolean pass = TRUE;
    gboolean readwritable = FALSE;

    CRM_ASSERT(dir != NULL);
    if (file != NULL) {
        full_file = crm_concat(dir, file, '/');
        target = full_file;
        s_res = stat(full_file, &buf);
        if (s_res == 0 && S_ISREG(buf.st_mode) == FALSE) {
            crm_err("%s must be a regular file", target);
            pass = FALSE;
            goto out;
        }
    }

    if (s_res != 0) {
        target = dir;
        s_res = stat(dir, &buf);
        if (s_res != 0) {
            crm_err("%s must exist and be a directory", dir);
            pass = FALSE;
            goto out;

        } else if (S_ISDIR(buf.st_mode) == FALSE) {
            crm_err("%s must be a directory", dir);
            pass = FALSE;
        }
    }

    if (user) {
        struct passwd *sys_user = NULL;

        sys_user = getpwnam(user);
        readwritable = (sys_user != NULL
                        && buf.st_uid == sys_user->pw_uid && (buf.st_mode & (S_IRUSR | S_IWUSR)));
        if (readwritable == FALSE) {
            crm_err("%s must be owned and r/w by user %s", target, user);
            if (need_both) {
                pass = FALSE;
            }
        }
    }

    if (group) {
        struct group *sys_grp = getgrnam(group);

        readwritable = (sys_grp != NULL
                        && buf.st_gid == sys_grp->gr_gid && (buf.st_mode & (S_IRGRP | S_IWGRP)));
        if (readwritable == FALSE) {
            if (need_both || user == NULL) {
                pass = FALSE;
                crm_err("%s must be owned and r/w by group %s", target, group);
            } else {
                crm_warn("%s should be owned and r/w by group %s", target, group);
            }
        }
    }

  out:
    free(full_file);
    return pass;
}
예제 #21
0
static gboolean
update_failcount(xmlNode * event, const char *event_node_uuid, int rc, int target_rc, gboolean do_update)
{
    int interval = 0;

    char *task = NULL;
    char *rsc_id = NULL;
    char *attr_name = NULL;

    const char *value = NULL;
    const char *id = crm_element_value(event, XML_LRM_ATTR_TASK_KEY);
    const char *on_uname = get_uname_from_event(event);
    const char *origin = crm_element_value(event, XML_ATTR_ORIGIN);

    if (rc == 99) {
        /* this is an internal code for "we're busy, try again" */
        return FALSE;

    } else if (rc == target_rc) {
        return FALSE;
    }

    if (safe_str_eq(origin, "build_active_RAs")) {
        crm_debug("No update for %s (rc=%d) on %s: Old failure from lrm status refresh",
                  id, rc, on_uname);
        return FALSE;
    }

    CRM_LOG_ASSERT(on_uname != NULL);
    if (on_uname == NULL) {
        return TRUE;
    }

    if (failed_stop_offset == NULL) {
        failed_stop_offset = strdup(INFINITY_S);
    }

    if (failed_start_offset == NULL) {
        failed_start_offset = strdup(INFINITY_S);
    }

    CRM_CHECK(parse_op_key(id, &rsc_id, &task, &interval), crm_err("Couldn't parse: %s", ID(event));
              goto bail);
    CRM_CHECK(task != NULL, goto bail);
    CRM_CHECK(rsc_id != NULL, goto bail);

    if (do_update || interval > 0) {
        do_update = TRUE;

    } else if (safe_str_eq(task, CRMD_ACTION_START)) {
        do_update = TRUE;
        value = failed_start_offset;

    } else if (safe_str_eq(task, CRMD_ACTION_STOP)) {
        do_update = TRUE;
        value = failed_stop_offset;

    } else if (safe_str_eq(task, CRMD_ACTION_STOP)) {
        do_update = TRUE;
        value = failed_stop_offset;

    } else if (safe_str_eq(task, CRMD_ACTION_PROMOTE)) {
        do_update = TRUE;

    } else if (safe_str_eq(task, CRMD_ACTION_DEMOTE)) {
        do_update = TRUE;
    }

    if (value == NULL || safe_str_neq(value, INFINITY_S)) {
        value = XML_NVPAIR_ATTR_VALUE "++";
    }

    if (do_update) {
        char *now = crm_itoa(time(NULL));
        gboolean is_remote_node = get_is_remote_from_event(event);

        crm_warn("Updating failcount for %s on %s after failed %s:"
                 " rc=%d (update=%s, time=%s)", rsc_id, on_uname, task, rc, value, now);

        attr_name = crm_concat("fail-count", rsc_id, '-');
        update_attrd(on_uname, attr_name, value, NULL, is_remote_node);
        free(attr_name);

        attr_name = crm_concat("last-failure", rsc_id, '-');
        update_attrd(on_uname, attr_name, now, NULL, is_remote_node);
        free(attr_name);

        free(now);
    }

  bail:
    free(rsc_id);
    free(task);
    return TRUE;
}
예제 #22
0
파일: clone.c 프로젝트: credativ/pacemaker
void
clone_print(resource_t * rsc, const char *pre_text, long options, void *print_data)
{
    char *list_text = NULL;
    char *child_text = NULL;
    char *stopped_list = NULL;
    const char *type = "Clone";

    GListPtr master_list = NULL;
    GListPtr started_list = NULL;
    GListPtr gIter = rsc->children;

    clone_variant_data_t *clone_data = NULL;
    int active_instances = 0;

    if (pre_text == NULL) {
        pre_text = " ";
    }

    if (options & pe_print_xml) {
        clone_print_xml(rsc, pre_text, options, print_data);
        return;
    }

    get_clone_variant_data(clone_data, rsc);

    child_text = crm_concat(pre_text, "   ", ' ');

    if (rsc->variant == pe_master) {
        type = "Master/Slave";
    }

    status_print("%s%s Set: %s [%s]%s%s",
                 pre_text ? pre_text : "", type, rsc->id, ID(clone_data->xml_obj_child),
                 is_set(rsc->flags, pe_rsc_unique) ? " (unique)" : "",
                 is_set(rsc->flags, pe_rsc_managed) ? "" : " (unmanaged)");

    if (options & pe_print_html) {
        status_print("\n<ul>\n");

    } else if ((options & pe_print_log) == 0) {
        status_print("\n");
    }

    for (; gIter != NULL; gIter = gIter->next) {
        gboolean print_full = FALSE;
        resource_t *child_rsc = (resource_t *) gIter->data;

        if (options & pe_print_clone_details) {
            print_full = TRUE;
        }

        if (child_rsc->fns->active(child_rsc, FALSE) == FALSE) {
            /* Inactive clone */
            if (is_set(child_rsc->flags, pe_rsc_orphan)) {
                continue;

            } else if (is_set(rsc->flags, pe_rsc_unique)) {
                print_full = TRUE;

            } else if (is_not_set(options, pe_print_clone_active)) {
                stopped_list = add_list_element(stopped_list, child_rsc->id);
            }

        } else if (is_set_recursive(child_rsc, pe_rsc_unique, TRUE)
                   || is_set_recursive(child_rsc, pe_rsc_orphan, TRUE)
                   || is_set_recursive(child_rsc, pe_rsc_managed, FALSE) == FALSE
                   || is_set_recursive(child_rsc, pe_rsc_failed, TRUE)) {

            /* Unique, unmanaged or failed clone */
            print_full = TRUE;

        } else if (is_set(options, pe_print_pending) && child_rsc->pending_task != NULL) {
            /* In a pending state */
            print_full = TRUE;

        } else if (child_rsc->fns->active(child_rsc, TRUE)) {
            /* Fully active anonymous clone */
            node_t *location = child_rsc->fns->location(child_rsc, NULL, TRUE);

            if (location) {
                enum rsc_role_e a_role = child_rsc->fns->state(child_rsc, TRUE);

                if (location->details->online == FALSE && location->details->unclean) {
                    print_full = TRUE;

                } else if (a_role > RSC_ROLE_SLAVE) {
                    /* And active on a single node as master */
                    master_list = g_list_append(master_list, location);

                } else {
                    /* And active on a single node as started/slave */
                    started_list = g_list_append(started_list, location);
                }

            } else {
                /* uncolocated group - bleh */
                print_full = TRUE;
            }

        } else {
            /* Partially active anonymous clone */
            print_full = TRUE;
        }

        if (print_full) {
            if (options & pe_print_html) {
                status_print("<li>\n");
            }
            child_rsc->fns->print(child_rsc, child_text, options, print_data);
            if (options & pe_print_html) {
                status_print("</li>\n");
            }
        }
    }

    /* Masters */
    master_list = g_list_sort(master_list, sort_node_uname);
    for (gIter = master_list; gIter; gIter = gIter->next) {
        node_t *host = gIter->data;

        list_text = add_list_element(list_text, host->details->uname);
	active_instances++;
    }

    short_print(list_text, child_text, "Masters", NULL, options, print_data);
    g_list_free(master_list);
    free(list_text);
    list_text = NULL;

    /* Started/Slaves */
    started_list = g_list_sort(started_list, sort_node_uname);
    for (gIter = started_list; gIter; gIter = gIter->next) {
        node_t *host = gIter->data;

        list_text = add_list_element(list_text, host->details->uname);
	active_instances++;
    }

    if(rsc->variant == pe_master) {
        enum rsc_role_e role = configured_role(rsc);

        if(role > RSC_ROLE_STOPPED && role < RSC_ROLE_MASTER) {
            short_print(list_text, child_text, "Slaves (target-role)", NULL, options, print_data);
        } else {
            short_print(list_text, child_text, "Slaves", NULL, options, print_data);
        }

    } else {
        short_print(list_text, child_text, "Started", NULL, options, print_data);
    }

    g_list_free(started_list);
    free(list_text);
    list_text = NULL;

    if (is_not_set(options, pe_print_clone_active)) {
        const char *state = "Stopped";
        enum rsc_role_e role = configured_role(rsc);

        if (role == RSC_ROLE_STOPPED) {
            state = "Stopped (disabled)";
        }

        if (is_not_set(rsc->flags, pe_rsc_unique)
            && (clone_data->clone_max > active_instances)) {

            GListPtr nIter;
            GListPtr list = g_hash_table_get_values(rsc->allowed_nodes);

            /* Custom stopped list for non-unique clones */
            free(stopped_list); stopped_list = NULL;

            if (g_list_length(list) == 0) {
                /* Clusters with symmetrical=false haven't calculated allowed_nodes yet
                 * If we've not probed for them yet, the Stopped list will be empty
                 */
                list = g_hash_table_get_values(rsc->known_on);
            }

            list = g_list_sort(list, sort_node_uname);
            for (nIter = list; nIter != NULL; nIter = nIter->next) {
                node_t *node = (node_t *)nIter->data;

                if (pe_find_node(rsc->running_on, node->details->uname) == NULL) {
                    stopped_list = add_list_element(stopped_list, node->details->uname);
                }
            }
            g_list_free(list);
        }

        short_print(stopped_list, child_text, state, NULL, options, print_data);
        free(stopped_list);
    }

    if (options & pe_print_html) {
        status_print("</ul>\n");
    }

    free(child_text);
}
예제 #23
0
파일: admin.c 프로젝트: bubble75/pacemaker
static int
show_history(stonith_t *st, const char *target, int timeout, int quiet,
             int verbose)
{
    stonith_history_t *history, *hp, *latest = NULL;
    int rc = 0;

    rc = st->cmds->history(st, st_opts,
                           (safe_str_eq(target, "*")? NULL : 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 {
            /* ocf:pacemaker:controld depends on "wishes to" being
             * in this output, when used with older versions of DLM
             * that don't report stateful_merge_wait
             */
            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);
        }
    }
    return rc;
}
예제 #24
0
파일: admin.c 프로젝트: bubble75/pacemaker
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;
}
예제 #25
0
void
process_utilization(resource_t * rsc, node_t ** prefer, pe_working_set_t * data_set)
{
    int alloc_details = scores_log_level + 1;

    if (safe_str_neq(data_set->placement_strategy, "default")) {
        GListPtr gIter = NULL;
        GListPtr colocated_rscs = NULL;
        gboolean any_capable = FALSE;

        colocated_rscs = find_colocated_rscs(colocated_rscs, rsc, rsc);
        if (colocated_rscs) {
            GHashTable *unallocated_utilization = NULL;
            char *rscs_id = crm_concat(rsc->id, "and its colocated resources", ' ');
            node_t *most_capable_node = NULL;

            unallocated_utilization = sum_unallocated_utilization(rsc, colocated_rscs);

            for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
                node_t *node = (node_t *) gIter->data;

                if (have_enough_capacity(node, rscs_id, unallocated_utilization)) {
                    any_capable = TRUE;
                }

                if (most_capable_node == NULL ||
                    compare_capacity(node, most_capable_node) < 0) {
                    /* < 0 means 'node' is more capable */
                    most_capable_node = node;
                }
            }

            if (any_capable) {
                for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
                    node_t *node = (node_t *) gIter->data;

                    if (have_enough_capacity(node, rscs_id, unallocated_utilization) == FALSE) {
                        pe_rsc_debug(rsc, "Resource %s and its colocated resources cannot be allocated to node %s: no enough capacity",
                                     rsc->id, node->details->uname);
                        resource_location(rsc, node, -INFINITY, "__limit_utilization__", data_set);
                    }
                }

            } else if (*prefer == NULL) {
                *prefer = most_capable_node;
            }

            if (unallocated_utilization) {
                g_hash_table_destroy(unallocated_utilization);
            }

            g_list_free(colocated_rscs);
            free(rscs_id);
        }

        if (any_capable == FALSE) {
            for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
                node_t *node = (node_t *) gIter->data;

                if (have_enough_capacity(node, rsc->id, rsc->utilization) == FALSE) {
                    pe_rsc_debug(rsc, "Resource %s cannot be allocated to node %s: no enough capacity",
                                 rsc->id, node->details->uname);
                    resource_location(rsc, node, -INFINITY, "__limit_utilization__", data_set);
                }
            }
        }
        dump_node_scores(alloc_details, rsc, "Post-utilization", rsc->allowed_nodes);
    }
}
예제 #26
0
/*!
 * \internal
 * \brief Update failure-related node attributes if warranted
 *
 * \param[in] event            XML describing operation that (maybe) failed
 * \param[in] event_node_uuid  Node that event occurred on
 * \param[in] rc               Actual operation return code
 * \param[in] target_rc        Expected operation return code
 * \param[in] do_update        If TRUE, do update regardless of operation type
 * \param[in] ignore_failures  If TRUE, update last failure but not fail count
 *
 * \return TRUE if this was not a direct nack, success or lrm status refresh
 */
static gboolean
update_failcount(xmlNode * event, const char *event_node_uuid, int rc,
                 int target_rc, gboolean do_update, gboolean ignore_failures)
{
    int interval = 0;

    char *task = NULL;
    char *rsc_id = NULL;

    const char *value = NULL;
    const char *id = crm_element_value(event, XML_LRM_ATTR_TASK_KEY);
    const char *on_uname = crm_peer_uname(event_node_uuid);
    const char *origin = crm_element_value(event, XML_ATTR_ORIGIN);

    /* Nothing needs to be done for success, lrm status refresh,
     * or direct nack (internal code for "busy, try again")
     */
    if ((rc == CRM_DIRECT_NACK_RC) || (rc == target_rc)) {
        return FALSE;
    } else if (safe_str_eq(origin, "build_active_RAs")) {
        crm_debug("No update for %s (rc=%d) on %s: Old failure from lrm status refresh",
                  id, rc, on_uname);
        return FALSE;
    }

    /* Sanity check */
    CRM_CHECK(on_uname != NULL, return TRUE);
    CRM_CHECK(parse_op_key(id, &rsc_id, &task, &interval),
              crm_err("Couldn't parse: %s", ID(event)); goto bail);
    CRM_CHECK(task != NULL, goto bail);
    CRM_CHECK(rsc_id != NULL, goto bail);

    /* Decide whether update is necessary and what value to use */
    if ((interval > 0) || safe_str_eq(task, CRMD_ACTION_PROMOTE)
        || safe_str_eq(task, CRMD_ACTION_DEMOTE)) {
        do_update = TRUE;

    } else if (safe_str_eq(task, CRMD_ACTION_START)) {
        do_update = TRUE;
        if (failed_start_offset == NULL) {
            failed_start_offset = strdup(INFINITY_S);
        }
        value = failed_start_offset;

    } else if (safe_str_eq(task, CRMD_ACTION_STOP)) {
        do_update = TRUE;
        if (failed_stop_offset == NULL) {
            failed_stop_offset = strdup(INFINITY_S);
        }
        value = failed_stop_offset;
    }

    /* Fail count will be either incremented or set to infinity */
    if (value == NULL || safe_str_neq(value, INFINITY_S)) {
        value = XML_NVPAIR_ATTR_VALUE "++";
    }

    if (do_update) {
        char *now = crm_itoa(time(NULL));
        char *attr_name = NULL;
        gboolean is_remote_node = FALSE;

        if (g_hash_table_lookup(crm_remote_peer_cache, event_node_uuid)) {
            is_remote_node = TRUE;
        }

        crm_info("Updating %s for %s on %s after failed %s: rc=%d (update=%s, time=%s)",
                 (ignore_failures? "last failure" : "failcount"),
                 rsc_id, on_uname, task, rc, value, now);

        /* Update the fail count, if we're not ignoring failures */
        if (!ignore_failures) {
            attr_name = crm_concat("fail-count", rsc_id, '-');
            update_attrd(on_uname, attr_name, value, NULL, is_remote_node);
            free(attr_name);
        }

        /* Update the last failure time (even if we're ignoring failures,
         * so that failure can still be detected and shown, e.g. by crm_mon)
         */
        attr_name = crm_concat("last-failure", rsc_id, '-');
        update_attrd(on_uname, attr_name, now, NULL, is_remote_node);
        free(attr_name);

        free(now);
    }

  bail:
    free(rsc_id);
    free(task);
    return TRUE;
}