Ejemplo n.º 1
0
action_t *
custom_action(resource_t * rsc, char *key, const char *task,
              node_t * on_node, gboolean optional, gboolean save_action,
              pe_working_set_t * data_set)
{
    action_t *action = NULL;
    GListPtr possible_matches = NULL;

    CRM_CHECK(key != NULL, return NULL);
    CRM_CHECK(task != NULL, return NULL);

    if (save_action && rsc != NULL) {
        possible_matches = find_actions(rsc->actions, key, on_node);
    }

    if (possible_matches != NULL) {
        if (g_list_length(possible_matches) > 1) {
            pe_warn("Action %s for %s on %s exists %d times",
                    task, rsc ? rsc->id : "<NULL>",
                    on_node ? on_node->details->uname : "<NULL>", g_list_length(possible_matches));
        }

        action = g_list_nth_data(possible_matches, 0);
        crm_trace("Found existing action (%d) %s for %s on %s",
                  action->id, task, rsc ? rsc->id : "<NULL>",
                  on_node ? on_node->details->uname : "<NULL>");
        g_list_free(possible_matches);
    }

    if (action == NULL) {
        if (save_action) {
            crm_trace("Creating%s action %d: %s for %s on %s",
                      optional ? "" : " manditory", data_set->action_id, key,
                      rsc ? rsc->id : "<NULL>", on_node ? on_node->details->uname : "<NULL>");
        }

        action = calloc(1, sizeof(action_t));
        if (save_action) {
            action->id = data_set->action_id++;
        } else {
            action->id = 0;
        }
        action->rsc = rsc;
        CRM_ASSERT(task != NULL);
        action->task = strdup(task);
        if (on_node) {
            action->node = node_copy(on_node);
        }
        action->uuid = strdup(key);

        pe_set_action_bit(action, pe_action_failure_is_fatal);
        pe_set_action_bit(action, pe_action_runnable);
        if (optional) {
            pe_set_action_bit(action, pe_action_optional);
        } else {
            pe_clear_action_bit(action, pe_action_optional);
        }

/*
  Implied by calloc()...
  action->actions_before   = NULL;
  action->actions_after    = NULL;
		
  action->pseudo     = FALSE;
  action->dumped     = FALSE;
  action->processed  = FALSE;
  action->seen_count = 0;
*/

        action->extra = g_hash_table_new_full(crm_str_hash, g_str_equal, free, free);

        action->meta = g_hash_table_new_full(crm_str_hash, g_str_equal, free, free);

        if (save_action) {
            data_set->actions = g_list_prepend(data_set->actions, action);
        }

        if (rsc != NULL) {
            action->op_entry = find_rsc_op_entry_helper(rsc, key, TRUE);

            unpack_operation(action, action->op_entry, data_set);

            if (save_action) {
                rsc->actions = g_list_prepend(rsc->actions, action);
            }
        }

        if (save_action) {
            crm_trace("Action %d created", action->id);
        }
    }

    if (optional == FALSE) {
        crm_trace("Action %d (%s) marked manditory", action->id, action->uuid);
        pe_clear_action_bit(action, pe_action_optional);
    }

    if (rsc != NULL) {
        enum action_tasks a_task = text2task(action->task);
        int warn_level = LOG_DEBUG_3;

        if (save_action) {
            warn_level = LOG_WARNING;
        }

        if (is_set(action->flags, pe_action_have_node_attrs) == FALSE
            && action->node != NULL && action->op_entry != NULL) {
            pe_set_action_bit(action, pe_action_have_node_attrs);
            unpack_instance_attributes(data_set->input, action->op_entry, XML_TAG_ATTR_SETS,
                                       action->node->details->attrs,
                                       action->extra, NULL, FALSE, data_set->now);
        }

        if (is_set(action->flags, pe_action_pseudo)) {
            /* leave untouched */

        } else if (action->node == NULL) {
            pe_clear_action_bit(action, pe_action_runnable);

        } else if (is_not_set(rsc->flags, pe_rsc_managed)
                   && g_hash_table_lookup(action->meta, XML_LRM_ATTR_INTERVAL) == NULL) {
            crm_debug("Action %s (unmanaged)", action->uuid);
            pe_set_action_bit(action, pe_action_optional);
/*   			action->runnable = FALSE; */

        } else if (action->node->details->online == FALSE) {
            pe_clear_action_bit(action, pe_action_runnable);
            do_crm_log(warn_level, "Action %s on %s is unrunnable (offline)",
                       action->uuid, action->node->details->uname);
            if (is_set(action->rsc->flags, pe_rsc_managed)
                && save_action && a_task == stop_rsc) {
                do_crm_log(warn_level, "Marking node %s unclean", action->node->details->uname);
                action->node->details->unclean = TRUE;
            }

        } else if (action->node->details->pending) {
            pe_clear_action_bit(action, pe_action_runnable);
            do_crm_log(warn_level, "Action %s on %s is unrunnable (pending)",
                       action->uuid, action->node->details->uname);

        } else if (action->needs == rsc_req_nothing) {
            crm_trace("Action %s doesnt require anything", action->uuid);
            pe_set_action_bit(action, pe_action_runnable);
#if 0
            /*
             * No point checking this
             * - if we dont have quorum we cant stonith anyway
             */
        } else if (action->needs == rsc_req_stonith) {
            crm_trace("Action %s requires only stonith", action->uuid);
            action->runnable = TRUE;
#endif
        } else if (is_set(data_set->flags, pe_flag_have_quorum) == FALSE
                   && data_set->no_quorum_policy == no_quorum_stop) {
            pe_clear_action_bit(action, pe_action_runnable);
            crm_debug("%s\t%s (cancelled : quorum)", action->node->details->uname, action->uuid);

        } else if (is_set(data_set->flags, pe_flag_have_quorum) == FALSE
                   && data_set->no_quorum_policy == no_quorum_freeze) {
            crm_trace("Check resource is already active");
            if (rsc->fns->active(rsc, TRUE) == FALSE) {
                pe_clear_action_bit(action, pe_action_runnable);
                crm_debug("%s\t%s (cancelled : quorum freeze)",
                          action->node->details->uname, action->uuid);
            }

        } else {
            crm_trace("Action %s is runnable", action->uuid);
            pe_set_action_bit(action, pe_action_runnable);
        }

        if (save_action) {
            switch (a_task) {
                case stop_rsc:
                    set_bit(rsc->flags, pe_rsc_stopping);
                    break;
                case start_rsc:
                    clear_bit(rsc->flags, pe_rsc_starting);
                    if (is_set(action->flags, pe_action_runnable)) {
                        set_bit(rsc->flags, pe_rsc_starting);
                    }
                    break;
                default:
                    break;
            }
        }
    }

    free(key);
    return action;
}
Ejemplo n.º 2
0
int
process_remote_stonith_query(xmlNode * msg)
{
    int devices = 0;
    gboolean host_is_target = FALSE;
    const char *id = NULL;
    const char *host = NULL;
    remote_fencing_op_t *op = NULL;
    st_query_result_t *result = NULL;
    uint32_t active = fencing_active_peers();
    xmlNode *dev = get_xpath_object("//@" F_STONITH_REMOTE_OP_ID, msg, LOG_ERR);
    xmlNode *child = NULL;

    CRM_CHECK(dev != NULL, return -EPROTO);

    id = crm_element_value(dev, F_STONITH_REMOTE_OP_ID);
    CRM_CHECK(id != NULL, return -EPROTO);

    dev = get_xpath_object("//@st-available-devices", msg, LOG_ERR);
    CRM_CHECK(dev != NULL, return -EPROTO);
    crm_element_value_int(dev, "st-available-devices", &devices);

    op = g_hash_table_lookup(remote_op_list, id);
    if (op == NULL) {
        crm_debug("Unknown or expired remote op: %s", id);
        return -EOPNOTSUPP;
    }

    op->replies++;
    host = crm_element_value(msg, F_ORIG);
    host_is_target = safe_str_eq(host, op->target);

    if (devices <= 0) {
        /* If we're doing 'known' then we might need to fire anyway */
        crm_trace("Query result from %s (%d devices)", host, devices);
        if(op->state == st_query && (op->replies >= op->replies_expected || op->replies >= active)) {
            crm_info("All queries have arrived, continuing (%d, %d, %d) ", op->replies_expected, active, op->replies);
            call_remote_stonith(op, NULL);
        }
        return pcmk_ok;

    } else if (host_is_target) {
        if (op->call_options & st_opt_allow_suicide) {
            crm_trace("Allowing %s to potentialy fence itself", op->target);
        } else {
            crm_info("Ignoring reply from %s, hosts are not permitted to commit suicide",
                     op->target);
            return pcmk_ok;
        }
    }

    crm_info("Query result %d of %d from %s (%d devices)", op->replies, op->replies_expected, host, devices);
    result = calloc(1, sizeof(st_query_result_t));
    result->host = strdup(host);
    result->devices = devices;
    result->custom_action_timeouts = g_hash_table_new_full(crm_str_hash, g_str_equal, free, NULL);
    result->verified_devices = g_hash_table_new_full(crm_str_hash, g_str_equal, free, NULL);

    for (child = __xml_first_child(dev); child != NULL; child = __xml_next(child)) {
        const char *device = ID(child);
        int action_timeout = 0;
        int verified = 0;

        if (device) {
            result->device_list = g_list_prepend(result->device_list, strdup(device));
            crm_element_value_int(child, F_STONITH_ACTION_TIMEOUT, &action_timeout);
            crm_element_value_int(child, F_STONITH_DEVICE_VERIFIED, &verified);
            if (action_timeout) {
                crm_trace("Peer %s with device %s returned action timeout %d",
                          result->host, device, action_timeout);
                g_hash_table_insert(result->custom_action_timeouts,
                                    strdup(device), GINT_TO_POINTER(action_timeout));
            }
            if (verified) {
                crm_trace("Peer %s has confirmed a verified device %s", result->host, device);
                g_hash_table_insert(result->verified_devices,
                                    strdup(device), GINT_TO_POINTER(verified));
            }
        }
    }

    CRM_CHECK(devices == g_list_length(result->device_list),
              crm_err("Mis-match: Query claimed to have %d devices but %d found", devices,
                      g_list_length(result->device_list)));

    op->query_results = g_list_insert_sorted(op->query_results, result, sort_peers);

    if (is_set(op->call_options, st_opt_topology)) {
        /* If we start the fencing before all the topology results are in,
         * it is possible fencing levels will be skipped because of the missing
         * query results. */
        if (op->state == st_query && all_topology_devices_found(op)) {
            /* All the query results are in for the topology, start the fencing ops. */
            crm_trace("All topology devices found");
            call_remote_stonith(op, result);

        } else if(op->state == st_query && (op->replies >= op->replies_expected || op->replies >= active)) {
            crm_info("All topology queries have arrived, continuing (%d, %d, %d) ", op->replies_expected, active, op->replies);
            call_remote_stonith(op, NULL);
        }

    } else if (op->state == st_query) {
        /* We have a result for a non-topology fencing op that looks promising,
         * go ahead and start fencing before query timeout */
        if (host_is_target == FALSE && g_hash_table_size(result->verified_devices)) {
            /* we have a verified device living on a peer that is not the target */
            crm_trace("Found %d verified devices", g_hash_table_size(result->verified_devices));
            call_remote_stonith(op, result);

        } else if (safe_str_eq(op->action, "on")) {
            crm_trace("Unfencing %s", op->target);
            call_remote_stonith(op, result);

        } else if(op->replies >= op->replies_expected || op->replies >= active) {
            crm_info("All queries have arrived, continuing (%d, %d, %d) ", op->replies_expected, active, op->replies);
            call_remote_stonith(op, NULL);

        } else {
            crm_trace("Waiting for more peer results before launching fencing operation");
        }

    } else if (op->state == st_done) {
        crm_info("Discarding query result from %s (%d devices): Operation is in state %d",
                 result->host, result->devices, op->state);
    }

    return pcmk_ok;
}
Ejemplo n.º 3
0
void
call_remote_stonith(remote_fencing_op_t * op, st_query_result_t * peer)
{
    const char *device = NULL;
    int timeout = op->base_timeout;

    crm_trace("State for %s.%.8s: %s %d", op->target, op->client_name, op->id, op->state);
    if (peer == NULL && !is_set(op->call_options, st_opt_topology)) {
        peer = stonith_choose_peer(op);
    }

    if (!op->op_timer_total) {
        int total_timeout = get_op_total_timeout(op, peer, op->base_timeout);

        op->total_timeout = TIMEOUT_MULTIPLY_FACTOR * total_timeout;
        op->op_timer_total = g_timeout_add(1000 * op->total_timeout, remote_op_timeout, op);
        report_timeout_period(op, op->total_timeout);
        crm_info("Total remote op timeout set to %d for fencing of node %s for %s.%.8s",
                 total_timeout, op->target, op->client_name, op->id);
    }

    if (is_set(op->call_options, st_opt_topology) && op->devices) {
        /* Ignore any preference, they might not have the device we need */
        /* When using topology, the stonith_choose_peer function pops off
         * the peer from the op's query results.  Make sure to calculate
         * the op_timeout before calling this function when topology is in use */
        peer = stonith_choose_peer(op);
        device = op->devices->data;
        timeout = get_device_timeout(peer, device, op->base_timeout);
    }

    if (peer) {
        int timeout_one = 0;
        xmlNode *query = stonith_create_op(op->client_callid, op->id, STONITH_OP_FENCE, NULL, 0);

        crm_xml_add(query, F_STONITH_REMOTE_OP_ID, op->id);
        crm_xml_add(query, F_STONITH_TARGET, op->target);
        crm_xml_add(query, F_STONITH_ACTION, op->action);
        crm_xml_add(query, F_STONITH_ORIGIN, op->originator);
        crm_xml_add(query, F_STONITH_CLIENTID, op->client_id);
        crm_xml_add(query, F_STONITH_CLIENTNAME, op->client_name);
        crm_xml_add_int(query, F_STONITH_TIMEOUT, timeout);

        if (device) {
            timeout_one =
                TIMEOUT_MULTIPLY_FACTOR * get_device_timeout(peer, device, op->base_timeout);
            crm_info("Requesting that %s perform op %s %s with %s for %s (%ds)", peer->host,
                     op->action, op->target, device, op->client_name, timeout_one);
            crm_xml_add(query, F_STONITH_DEVICE, device);
            crm_xml_add(query, F_STONITH_MODE, "slave");

        } else {
            timeout_one = TIMEOUT_MULTIPLY_FACTOR * get_peer_timeout(peer, op->base_timeout);
            crm_info("Requesting that %s perform op %s %s for %s (%ds)",
                     peer->host, op->action, op->target, op->client_name, timeout_one);
            crm_xml_add(query, F_STONITH_MODE, "smart");
        }

        op->state = st_exec;
        if (op->op_timer_one) {
            g_source_remove(op->op_timer_one);
        }
        op->op_timer_one = g_timeout_add((1000 * timeout_one), remote_op_timeout_one, op);

        send_cluster_message(crm_get_peer(0, peer->host), crm_msg_stonith_ng, query, FALSE);
        peer->tried = TRUE;
        free_xml(query);
        return;

    } else if (op->owner == FALSE) {
        crm_err("The termination of %s for %s is not ours to control", op->target, op->client_name);

    } else if (op->query_timer == 0) {
        /* We've exhausted all available peers */
        crm_info("No remaining peers capable of terminating %s for %s (%d)", op->target,
                 op->client_name, op->state);
        CRM_LOG_ASSERT(op->state < st_done);
        remote_op_timeout(op);

    } else if(op->replies >= op->replies_expected || op->replies >= fencing_active_peers()) {
        int rc = -EHOSTUNREACH;

        /* if the operation never left the query state,
         * but we have all the expected replies, then no devices
         * are available to execute the fencing operation. */
        if (op->state == st_query) {
           crm_info("None of the %d peers have devices capable of terminating %s for %s (%d)",
                   op->replies, op->target, op->client_name, op->state);

            rc = -ENODEV;
        } else {
           crm_info("None of the %d peers are capable of terminating %s for %s (%d)",
                   op->replies, op->target, op->client_name, op->state);
        }

        op->state = st_failed;
        remote_op_done(op, NULL, rc, FALSE);

    } else if (device) {
        crm_info("Waiting for additional peers capable of terminating %s with %s for %s.%.8s",
                 op->target, device, op->client_name, op->id);
    } else {
        crm_info("Waiting for additional peers capable of terminating %s for %s%.8s",
                 op->target, op->client_name, op->id);
    }
}
Ejemplo n.º 4
0
 bool can_unobstrusively_enable_extension(const wiimote& mote)
 {
   return !is_set(mote.enabled_capabilities, wiimote_capabilities::MotionPlus);
 }
Ejemplo n.º 5
0
 void erase() {
     if (is_set()) { // IS IT NEEDED ??
         neighbour()->erase_simple(this);
         this->erase_simple();
     }
 }
Ejemplo n.º 6
0
DLLIMPORT void cfg_opt_print_indent(cfg_opt_t *opt, FILE *fp, int indent)
{
    assert(opt && fp);

    if(opt->type == CFGT_SEC)
    {
        cfg_t *sec;
        unsigned int i;

        for(i = 0; i < cfg_opt_size(opt); i++)
        {
            sec = cfg_opt_getnsec(opt, i);
            cfg_indent(fp, indent);
            if(is_set(CFGF_TITLE, opt->flags))
                fprintf(fp, "%s \"%s\" {\n", opt->name, cfg_title(sec));
            else
                fprintf(fp, "%s {\n", opt->name);
            cfg_print_indent(sec, fp, indent + 1);
            cfg_indent(fp, indent);
            fprintf(fp, "}\n");
        }
    }
    else if(opt->type != CFGT_FUNC && opt->type != CFGT_NONE)
    {
        if(is_set(CFGF_LIST, opt->flags))
        {
            unsigned int i;

            cfg_indent(fp, indent);
            fprintf(fp, "%s = {", opt->name);

            if(opt->nvalues)
            {
                if(opt->pf)
                    opt->pf(opt, 0, fp);
                else
                    cfg_opt_nprint_var(opt, 0, fp);
                for(i = 1; i < opt->nvalues; i++)
                {
                    fprintf(fp, ", ");
                    if(opt->pf)
                        opt->pf(opt, i, fp);
                    else
                        cfg_opt_nprint_var(opt, i, fp);
                }
            }

            fprintf(fp, "}");
        }
        else
        {
            cfg_indent(fp, indent);
            /* comment out the option if is not set */
            if(opt->simple_value)
            {
                if(opt->type == CFGT_STR && *((char **)opt->simple_value) == 0)
                    fprintf(fp, "# ");
            }
            else
            {
                if(cfg_opt_size(opt) == 0 || (
                       opt->type == CFGT_STR && (opt->values[0]->string == 0 ||
                                             opt->values[0]->string[0] == 0)))
                    fprintf(fp, "# ");
            }
            fprintf(fp, "%s = ", opt->name);
            if(opt->pf)
                opt->pf(opt, 0, fp);
            else
                cfg_opt_nprint_var(opt, 0, fp);
        }
    
        fprintf(fp, "\n");
    }
    else if(opt->pf)
    {
        cfg_indent(fp, indent);
        opt->pf(opt, 0, fp);
        fprintf(fp, "\n");
    }
}
Ejemplo n.º 7
0
static cfg_value_t *cfg_setopt(cfg_t *cfg, cfg_opt_t *opt, char *value)
{
    cfg_value_t *val = 0;
    int b;
    char *s;
    double f;
    long int i;
    void *p;
    char *endptr;

    assert(cfg && opt);

    if(opt->simple_value)
    {
        assert(opt->type != CFGT_SEC);
        val = (cfg_value_t *)opt->simple_value;
    }
    else
    {
        if(is_set(CFGF_RESET, opt->flags))
        {
            cfg_free_value(opt);
            opt->flags &= ~CFGF_RESET;
        }

        if(opt->nvalues == 0 || is_set(CFGF_MULTI, opt->flags) ||
           is_set(CFGF_LIST, opt->flags))
        {
            val = 0;
            if(opt->type == CFGT_SEC && is_set(CFGF_TITLE, opt->flags))
            {
                unsigned int i;

                /* check if there already is a section with the same title
                 */
                assert(value);
                for(i = 0; i < opt->nvalues; i++)
                {
                    cfg_t *sec = opt->values[i]->section;
                    if(is_set(CFGF_NOCASE, cfg->flags))
                    {
                        if(strcasecmp(value, sec->title) == 0)
                            val = opt->values[i];
                    }
                    else
                    {
                        if(strcmp(value, sec->title) == 0)
                            val = opt->values[i];
                    }
                }
            }
            if(val == 0)
                val = cfg_addval(opt);
        }
        else
            val = opt->values[0];
    }

    switch(opt->type)
    {
        case CFGT_INT:
            if(opt->parsecb)
            {
                if((*opt->parsecb)(cfg, opt, value, &i) != 0)
                    return 0;
                val->number = i;
            }
            else
            {
                val->number = strtol(value, &endptr, 0);
                if(*endptr != '\0')
                {
                    cfg_error(cfg, _("invalid integer value for option '%s'"),
                              opt->name);
                    return 0;
                }
                if(errno == ERANGE)
                {
                    cfg_error(cfg,
                          _("integer value for option '%s' is out of range"),
                              opt->name);
                    return 0;
                }
            }
            break;

        case CFGT_FLOAT:
            if(opt->parsecb)
            {
                if((*opt->parsecb)(cfg, opt, value, &f) != 0)
                    return 0;
                val->fpnumber = f;
            }
            else
            {
                val->fpnumber = strtod(value, &endptr);
                if(*endptr != '\0')
                {
                    cfg_error(cfg,
                          _("invalid floating point value for option '%s'"),
                              opt->name);
                    return 0;
                }
                if(errno == ERANGE)
                {
                    cfg_error(cfg,
                  _("floating point value for option '%s' is out of range"),
                              opt->name);
                    return 0;
                }
            }
            break;

        case CFGT_STR:
            free(val->string);
            if(opt->parsecb)
            {
                s = 0;
                if((*opt->parsecb)(cfg, opt, value, &s) != 0)
                    return 0;
                val->string = strdup(s);
            }
            else
                val->string = strdup(value);
            break;

        case CFGT_SEC:
            if(is_set(CFGF_MULTI, opt->flags) || val->section == 0)
            {
                cfg_free(val->section);
                val->section = (cfg_t *)malloc(sizeof(cfg_t));
                assert(val->section);
                memset(val->section, 0, sizeof(cfg_t));
                val->section->name = strdup(opt->name);
                val->section->opts = cfg_dupopt_array(opt->subopts);
                val->section->flags = cfg->flags;
                val->section->filename = cfg->filename ? strdup(cfg->filename) : 0;
                val->section->line = cfg->line;
                val->section->errfunc = cfg->errfunc;
                val->section->title = value;
            }
            if(!is_set(CFGF_DEFINIT, opt->flags))
                cfg_init_defaults(val->section);
            break;

        case CFGT_BOOL:
            if(opt->parsecb)
            {
                if((*opt->parsecb)(cfg, opt, value, &b) != 0)
                    return 0;
            }
            else
            {
                b = cfg_parse_boolean(value);
                if(b == -1)
                {
                    cfg_error(cfg, _("invalid boolean value for option '%s'"),
                              opt->name);
                    return 0;
                }
            }
            val->boolean = (cfg_bool_t)b;
            break;

        case CFGT_PTR:
            assert(opt->parsecb);
            if((*opt->parsecb)(cfg, opt, value, &p) != 0)
                return 0;
            val->ptr = p;
            break;

        default:
            cfg_error(cfg, "internal error in cfg_setopt(%s, %s)",
                      opt->name, value);
            assert(0);
            break;
    }
    return val;
}
Ejemplo n.º 8
0
int32_t cluster_include_and_reindex(uintptr_t unfiltered_indiv_ct, uintptr_t* indiv_include, uint32_t remove_size1, uintptr_t* pheno_c, uintptr_t indiv_ct, uint32_t cluster_ct, uint32_t* cluster_map, uint32_t* cluster_starts, uint32_t* new_cluster_ct_ptr, uint32_t** new_cluster_map_ptr, uint32_t** new_cluster_starts_ptr, uint32_t** cluster_case_cts_ptr, uintptr_t** cluster_cc_perm_preimage_ptr) {
  // If any individuals are excluded, this converts a unfiltered-index cluster
  // map to a collapsed-index cluster map (suitable for passing to the
  // per-cluster permutation function), allocating space for the latter.
  // Otherwise, this just sets the new cluster map to point to the old one.
  //
  // remove_size1 should be 0 or 1.  If it's 1, all size-1 clusters are
  // removed.
  //
  // If pheno_c is set, this also allocates and populates an array of
  // per-cluster case counts, and a permutation preimage.
  unsigned char* wkspace_mark = wkspace_base;
  uint32_t old_assigned_ct = cluster_starts[cluster_ct];
  uint32_t new_cluster_ct = 0;
  uint32_t indiv_uidx = 0;
  uint32_t case_ct = 0;
  uint32_t assigned_ct = 0;
  uintptr_t* cluster_cc_perm_preimage = NULL;
  uint32_t* new_cluster_map;
  uint32_t* new_cluster_starts;
  uint32_t* cluster_case_cts;
  uint32_t* uidx_to_idx;
  uint32_t cluster_assigned_ct;
  uint32_t cluster_idx;
  uint32_t cluster_end;
  uint32_t cluster_read_idx;
  uint32_t map_idx;
  uint32_t map_read_idx;
  uint32_t last_case_ct_incr;
  uint32_t shrink_map;
  if (pheno_c) {
    if (wkspace_alloc_ul_checked(cluster_cc_perm_preimage_ptr, 2 * ((indiv_ct + (BITCT - 1)) / BITCT) * sizeof(intptr_t))) {
      goto cluster_include_and_reindex_ret_NOMEM;
    }
    cluster_cc_perm_preimage = *cluster_cc_perm_preimage_ptr;
    collapse_copy_bitarr_to_vec_incl(unfiltered_indiv_ct, pheno_c, indiv_include, indiv_ct, cluster_cc_perm_preimage);
  }
  if ((indiv_ct == unfiltered_indiv_ct) && ((!remove_size1) || no_size1(cluster_ct, cluster_starts))) {
    *new_cluster_map_ptr = cluster_map;
    *new_cluster_ct_ptr = cluster_ct;
    *new_cluster_starts_ptr = cluster_starts;
    if (pheno_c) {
      if (wkspace_alloc_ui_checked(cluster_case_cts_ptr, cluster_ct * sizeof(int32_t))) {
	goto cluster_include_and_reindex_ret_NOMEM;
      }
      populate_cluster_case_cts(pheno_c, cluster_ct, cluster_map, cluster_starts, *cluster_case_cts_ptr);
      adjust_cc_perm_preimage(cluster_ct, cluster_map, cluster_starts, *cluster_case_cts_ptr, cluster_cc_perm_preimage);
    }
    return 0;
  }
  // scan to determine new memory allocation sizes
  for (cluster_idx = 0; cluster_idx < cluster_ct; cluster_idx++) {
    cluster_assigned_ct = 0;
    cluster_end = cluster_starts[cluster_idx + 1];
    for (map_idx = cluster_starts[cluster_idx]; map_idx < cluster_end; map_idx++) {
      cluster_assigned_ct += is_set(indiv_include, cluster_map[map_idx]);
    }
    if (cluster_assigned_ct > remove_size1) {
      new_cluster_ct++;
      assigned_ct += cluster_assigned_ct;
    }
  }
  // possibly +1 to simplify remove_size1 logic
  if (wkspace_alloc_ui_checked(new_cluster_map_ptr, (assigned_ct + remove_size1) * sizeof(int32_t))) {
    goto cluster_include_and_reindex_ret_NOMEM;
  }
  new_cluster_map = *new_cluster_map_ptr;
  shrink_map = (assigned_ct < old_assigned_ct)? 1 : 0;
  if (shrink_map) {
    if (wkspace_alloc_ui_checked(new_cluster_starts_ptr, (new_cluster_ct + 1) * sizeof(int32_t))) {
      goto cluster_include_and_reindex_ret_NOMEM;
    }
    new_cluster_starts = *new_cluster_starts_ptr;
    new_cluster_starts[0] = 0;
  } else {
    new_cluster_starts = cluster_starts;
    *new_cluster_starts_ptr = cluster_starts;
  }
  if (pheno_c) {
    if (wkspace_alloc_ui_checked(cluster_case_cts_ptr, new_cluster_ct * sizeof(int32_t))) {
      goto cluster_include_and_reindex_ret_NOMEM;
    }
  }
  if (wkspace_alloc_ui_checked(&uidx_to_idx, unfiltered_indiv_ct * sizeof(int32_t))) {
    goto cluster_include_and_reindex_ret_NOMEM;
  }
  cluster_case_cts = *cluster_case_cts_ptr;
  fill_uidx_to_idx_incl(indiv_include, indiv_ct, uidx_to_idx);
  *new_cluster_ct_ptr = new_cluster_ct;
  cluster_read_idx = 1;
  map_idx = 0;
  cluster_idx = 0;
  cluster_end = 0;
  last_case_ct_incr = 0;
  for (map_read_idx = 0; map_read_idx < old_assigned_ct; map_read_idx++) {
    indiv_uidx = cluster_map[map_read_idx];
    if (!is_set(indiv_include, indiv_uidx)) {
      continue;
    }
    if (map_read_idx >= cluster_end) {
      if (cluster_idx) {
        if ((!remove_size1) || (map_idx - new_cluster_starts[cluster_idx] > 1)) {
	  if (pheno_c) {
	    cluster_case_cts[cluster_idx - 1] = case_ct + last_case_ct_incr;
	  }
	  if (shrink_map) {
	    new_cluster_starts[cluster_idx] = map_idx;
	  }
	  case_ct = 0;
	  cluster_idx++;
        } else {
          map_idx--;
        }
	last_case_ct_incr = 0;
      } else {
        cluster_idx = 1;
      }
      do {
	cluster_end = cluster_starts[cluster_read_idx++];
      } while (cluster_end <= map_read_idx);
    }
    if (pheno_c) {
      case_ct += last_case_ct_incr;
      last_case_ct_incr = is_set(pheno_c, indiv_uidx);
    }
    new_cluster_map[map_idx++] = uidx_to_idx[indiv_uidx];
  }
  if (new_cluster_ct && ((!remove_size1) || (map_idx - new_cluster_starts[cluster_idx] > 1))) {
    if (pheno_c) {
      cluster_case_cts[new_cluster_ct - 1] = case_ct + last_case_ct_incr;
    }
    if (shrink_map) {
      new_cluster_starts[new_cluster_ct] = map_idx;
    }
  }
  if (pheno_c && new_cluster_ct) {
    adjust_cc_perm_preimage(new_cluster_ct, new_cluster_map, new_cluster_starts, cluster_case_cts, cluster_cc_perm_preimage);
  }
  wkspace_reset((unsigned char*)uidx_to_idx);
  return 0;
 cluster_include_and_reindex_ret_NOMEM:
  wkspace_reset(wkspace_mark);
  return RET_NOMEM;
}
Ejemplo n.º 9
0
void find_familiar( char_data* ch, obj_data* obj, int level,
  int species_list, int obj_list )
{
  char_data*      familiar;
  player_data*      pc;
  species_data*    species;
  int                    i;

  if( obj == NULL ) {
    bug( "Find_Familiar: Null Object as reagent!?" );
    return;
    }

  if( ( pc = player( ch ) ) == NULL )
    return;

  if( ch->shdata->level < LEVEL_APPRENTICE
    && is_set( ch->pcdata->pfile->flags, PLR_FAMILIAR ) ) {
    send( ch, "Nothing happens.\n\r" );
    send( ch, "You can only summon one familiar per level.\n\r" );
    return;
    }

  if( pc->familiar != NULL ) {
    send( ch, "Nothing happens.\n\r" );
    send( ch, "You can only have one familiar at a time.\n\r" );
    return;
    }

  for( i = 0; i < 10; i++ )
    if( obj->pIndexData->vnum
      == list_value[ obj_list ][ 10*(ch->shdata->alignment%3)+i ] )
      break;

  if( i == 10 ) {
    send( ch, "Nothing happens.\n\r" );
    return;
    }

  send( *ch->array, "%s disintegrates in a burst of blue flame.\n\r", obj );
  obj->Extract( 1 );

  if( number_range( 0,100 ) < 50-7*level+10*i ) {
    send( ch, "You feel the summoning fail.\n\r" );
    return;
    }

  i = list_value[ species_list ][ 10*(ch->shdata->alignment%3)+i ];

  if( ( species = get_species( i ) ) == NULL ) {
    bug( "Find_familiar: unknown species." );
    return;
    }

  familiar         = create_mobile( species );
  familiar->reset  = NULL;
  pc->familiar = familiar;

  set_bit( &familiar->status, STAT_PET );
  set_bit( &familiar->status, STAT_FAMILIAR );
  set_bit( ch->pcdata->pfile->flags, PLR_FAMILIAR );

  remove_bit( &familiar->status, STAT_AGGR_ALL );
  remove_bit( &familiar->status, STAT_AGGR_GOOD );
  remove_bit( &familiar->status, STAT_AGGR_EVIL );

  familiar->To( ch->array );

  send( ch,
    "%s comes to your summons, stepping from the shadows.\n\r",
    familiar );

  add_follower( familiar, ch );

  return;
}
void
notify_crmd(crm_graph_t *graph)
{
	int log_level = LOG_DEBUG;
	const char *type = "unknown";
	enum crmd_fsa_input event = I_NULL;
	
	crm_debug("Processing transition completion in state %s", fsa_state2string(fsa_state));
	
	CRM_CHECK(graph->complete, graph->complete = TRUE);

	switch(graph->completion_action) {
		case tg_stop:
		    type = "stop";
		    /* fall through */
		case tg_done:
		    type = "done";
		    log_level = LOG_INFO;
		    if(fsa_state == S_TRANSITION_ENGINE) {
			event = I_TE_SUCCESS;
		    }
		    break;
		    
		case tg_restart:
		    type = "restart";
		    if(fsa_state == S_TRANSITION_ENGINE) {
			if(transition_timer->period_ms > 0) {
			    crm_timer_start(transition_timer);
			} else {
			    event = I_PE_CALC;
			}

		    } else if(fsa_state == S_POLICY_ENGINE) {
				/* fsa_actionにA_PE_INVOKEアクションを追加して、fsa_sourceトリガーを叩いてcrmdに通知する */
				register_fsa_action(A_PE_INVOKE);
		    }
		    break;

		case tg_shutdown:
		    type = "shutdown";
		    if(is_set(fsa_input_register, R_SHUTDOWN)) {
			event = I_STOP;			
			
		    } else {
			event = I_TERMINATE;
		    }
	}

	te_log_action(log_level, "Transition %d status: %s - %s",
		      graph->id, type, crm_str(graph->abort_reason));

	graph->abort_reason = NULL;
	graph->completion_action = tg_done;
	clear_bit_inplace(fsa_input_register, R_IN_TRANSITION);

	if(event != I_NULL) {
	    register_fsa_input(C_FSA_INTERNAL, event, NULL);

	} else if(fsa_source) {
	    mainloop_set_trigger(fsa_source);
	}
}
Ejemplo n.º 11
0
int32_t load_clusters(char* fname, uintptr_t unfiltered_indiv_ct, uintptr_t* indiv_exclude, uintptr_t indiv_ct, char* person_ids, uintptr_t max_person_id_len, uint32_t mwithin_col, uint32_t keep_na, uintptr_t* cluster_ct_ptr, uint32_t** cluster_map_ptr, uint32_t** cluster_starts_ptr, char** cluster_ids_ptr, uintptr_t* max_cluster_id_len_ptr) {
  unsigned char* wkspace_mark = wkspace_base;
  FILE* infile = NULL;
  uintptr_t indiv_ctl = (indiv_ct + (BITCT - 1)) / BITCT;
  uintptr_t topsize = 0;
  int32_t retval = 0;
  char* idbuf = &(tbuf[MAXLINELEN]);
  uintptr_t max_cluster_id_len = 0;
  uintptr_t assigned_ct = 0;
  uintptr_t cluster_ct = 0;
  Ll_str* cluster_names = NULL;
  uintptr_t* already_seen;
  char* cluster_ids;
  uint32_t* cluster_map;
  uint32_t* cluster_starts;
  uint32_t* tmp_cluster_starts;
  uintptr_t topsize_bak;
  Ll_str* llptr;
  char* sorted_ids;
  uint32_t* id_map;
  char* fam_id;
  char* indiv_id;
  char* cluster_name_ptr;
  uintptr_t ulii;
  int32_t sorted_idx;
  uint32_t indiv_uidx;
  uint32_t slen;
  uint32_t uii;

  sorted_ids = (char*)top_alloc(&topsize, indiv_ct * max_person_id_len);
  if (!sorted_ids) {
    goto load_clusters_ret_NOMEM;
  }
  id_map = (uint32_t*)top_alloc(&topsize, indiv_ct * sizeof(int32_t));
  if (!id_map) {
    goto load_clusters_ret_NOMEM;
  }
  topsize_bak = topsize;
  already_seen = (uintptr_t*)top_alloc(&topsize, indiv_ctl * sizeof(intptr_t));
  if (!already_seen) {
    goto load_clusters_ret_NOMEM;
  }
  fill_ulong_zero(already_seen, indiv_ctl);
  memcpy(sorted_ids, person_ids, indiv_ct * max_person_id_len);
  wkspace_left -= topsize;
  retval = sort_item_ids_noalloc(sorted_ids, id_map, unfiltered_indiv_ct, indiv_exclude, indiv_ct, person_ids, max_person_id_len, 0, 0, strcmp_deref);
  wkspace_left += topsize;
  if (retval) {
    goto load_clusters_ret_1;
  }

  // two-pass load
  // 1. load cluster names, track longest length, validate format, verify no
  //    individual ID appears multiple times
  // intermission. sort cluster names, purge duplicates, allocate memory for
  //               return values
  // 2. populate return name arrays
  if (fopen_checked(&infile, fname, "r")) {
    goto load_clusters_ret_OPEN_FAIL;
  }
  tbuf[MAXLINELEN - 1] = ' ';
  if (!mwithin_col) {
    mwithin_col = 1;
  }
  while (fgets(tbuf, MAXLINELEN, infile)) {
    if (!tbuf[MAXLINELEN - 1]) {
      logprint("Error: Pathologically long line in --within file.\n");
      goto load_clusters_ret_INVALID_FORMAT;
    }
    fam_id = skip_initial_spaces(tbuf);
    if (is_eoln_kns(*fam_id)) {
      continue;
    }
    indiv_id = next_item(fam_id);
    cluster_name_ptr = next_item_mult(indiv_id, mwithin_col);
    if (no_more_items_kns(cluster_name_ptr)) {
      logprint("Error: Fewer entries than expected in --within file line.\n");
      goto load_clusters_ret_INVALID_FORMAT;
    }
    sorted_idx = bsearch_fam_indiv(idbuf, sorted_ids, max_person_id_len, indiv_ct, fam_id, indiv_id);
    if (sorted_idx == -1) {
      continue;
    }
    if (is_set(already_seen, sorted_idx)) {
      idbuf[strlen_se(fam_id)] = ' ';
      sprintf(logbuf, "Error: Duplicate individual %s in --within file.\n", idbuf);
      logprintb();
      goto load_clusters_ret_INVALID_FORMAT;
    }
    set_bit_noct(already_seen, sorted_idx);
    slen = strlen_se(cluster_name_ptr);
    if ((!keep_na) && (slen == 2) && (!memcmp(cluster_name_ptr, "NA", 2))) {
      // postponed to here because, even without 'keep-NA', we do not want to
      // ignore cluster=NA lines for the purpose of detecting duplicate indivs
      continue;
    }
    if (slen >= max_cluster_id_len) {
      max_cluster_id_len = slen + 1;
    }
    llptr = top_alloc_llstr(&topsize, slen + 1);
    llptr->next = cluster_names;
    memcpyx(llptr->ss, cluster_name_ptr, slen, '\0');
    cluster_names = llptr;
    assigned_ct++;
  }
  if (!feof(infile)) {
    goto load_clusters_ret_READ_FAIL;
  }
  if (cluster_names) {
    *max_cluster_id_len_ptr = max_cluster_id_len;
    wkspace_left -= topsize;
    if (wkspace_alloc_c_checked(cluster_ids_ptr, assigned_ct * max_cluster_id_len)) {
      goto load_clusters_ret_NOMEM2;
    }
    cluster_ids = *cluster_ids_ptr;
    for (ulii = 0; ulii < assigned_ct; ulii++) {
      strcpy(&(cluster_ids[ulii * max_cluster_id_len]), cluster_names->ss);
      cluster_names = cluster_names->next;
    }
    // deallocate cluster ID linked list and duplicate indiv ID detector from
    // top of stack, allocate cluster size tracker
    wkspace_left += topsize;
    topsize = topsize_bak;
    tmp_cluster_starts = (uint32_t*)top_alloc(&topsize, assigned_ct * sizeof(int32_t));
    if (!tmp_cluster_starts) {
      goto load_clusters_ret_NOMEM;
    }
    wkspace_left -= topsize;
    // may as well use natural sort of cluster names
    qsort(cluster_ids, assigned_ct, max_cluster_id_len, strcmp_natural);
    cluster_ct = collapse_duplicate_ids(cluster_ids, assigned_ct, max_cluster_id_len, tmp_cluster_starts);
    *cluster_ct_ptr = cluster_ct;
    // shrink
    wkspace_reset(cluster_ids);
    wkspace_alloc_c_checked(cluster_ids_ptr, cluster_ct * max_cluster_id_len);
    if (wkspace_alloc_ui_checked(cluster_map_ptr, assigned_ct * sizeof(int32_t)) ||
        wkspace_alloc_ui_checked(cluster_starts_ptr, (cluster_ct + 1) * sizeof(int32_t))) {
      goto load_clusters_ret_NOMEM2;
    }
    wkspace_left += topsize;
    cluster_map = *cluster_map_ptr;
    cluster_starts = *cluster_starts_ptr;
    memcpy(cluster_starts, tmp_cluster_starts, cluster_ct * sizeof(int32_t));
    cluster_starts[cluster_ct] = assigned_ct;
    rewind(infile);
    // second pass
    while (fgets(tbuf, MAXLINELEN, infile)) {
      fam_id = skip_initial_spaces(tbuf);
      if (is_eoln_kns(*fam_id)) {
	continue;
      }
      indiv_id = next_item(fam_id);
      cluster_name_ptr = next_item_mult(indiv_id, mwithin_col);
      slen = strlen_se(cluster_name_ptr);
      if ((!keep_na) && (slen == 2) && (!memcmp(cluster_name_ptr, "NA", 2))) {
	continue;
      }
      sorted_idx = bsearch_fam_indiv(idbuf, sorted_ids, max_person_id_len, indiv_ct, fam_id, indiv_id);
      if (sorted_idx == -1) {
	continue;
      }
      indiv_uidx = id_map[(uint32_t)sorted_idx];
      cluster_name_ptr[slen] = '\0';
      sorted_idx = bsearch_str_natural(cluster_name_ptr, cluster_ids, max_cluster_id_len, 0, cluster_ct - 1);
      uii = tmp_cluster_starts[(uint32_t)sorted_idx];
      tmp_cluster_starts[(uint32_t)sorted_idx] += 1;
      cluster_map[uii] = indiv_uidx;
    }
    if (!feof(infile)) {
      goto load_clusters_ret_READ_FAIL;
    }
    for (ulii = 0; ulii < cluster_ct; ulii++) {
      if (cluster_starts[ulii + 1] - cluster_starts[ulii] > 1) {
#ifdef __cplusplus
	std::sort(&(cluster_map[cluster_starts[ulii]]), &(cluster_map[cluster_starts[ulii + 1]]));
#else
	qsort(&(cluster_map[cluster_starts[ulii]]), cluster_starts[ulii + 1] - cluster_starts[ulii], sizeof(int32_t), intcmp);
#endif
      }
    }
    sprintf(logbuf, "--within: %" PRIuPTR " cluster%s loaded, covering a total of %" PRIuPTR " %s.\n", cluster_ct, (cluster_ct == 1)? "" : "s", assigned_ct, species_str(assigned_ct));
    logprintb();
  } else {
    logprint("Warning: No individuals named in --within file remain in the current analysis.\n");
  }

  while (0) {
  load_clusters_ret_NOMEM2:
    wkspace_left += topsize;
  load_clusters_ret_NOMEM:
    retval = RET_NOMEM;
    break;
  load_clusters_ret_OPEN_FAIL:
    retval = RET_OPEN_FAIL;
    break;
  load_clusters_ret_READ_FAIL:
    retval = RET_READ_FAIL;
    break;
  load_clusters_ret_INVALID_FORMAT:
    retval = RET_INVALID_FORMAT;
    break;
  }
 load_clusters_ret_1:
  if (retval) {
    wkspace_reset(wkspace_mark);
  }
  fclose_cond(infile);
  return retval;
}
Ejemplo n.º 12
0
/*	A_ELECTION_VOTE	*/
void
do_election_vote(long long action,
                 enum crmd_fsa_cause cause,
                 enum crmd_fsa_state cur_state,
                 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
{
    struct timeval age;
    xmlNode *vote = NULL;
    gboolean not_voting = FALSE;

    /* don't vote if we're in one of these states or wanting to shut down */
    switch (cur_state) {
        case S_STARTING:
        case S_RECOVERY:
        case S_STOPPING:
        case S_TERMINATE:
            crm_warn("Not voting in election, we're in state %s", fsa_state2string(cur_state));
            not_voting = TRUE;
            break;
        default:
            break;
    }

    if (not_voting == FALSE) {
        if (is_set(fsa_input_register, R_STARTING)) {
            not_voting = TRUE;
        }
    }

    if (not_voting) {
        if (AM_I_DC) {
            register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL);

        } else {
            register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL);
        }
        return;
    }

    vote = create_request(CRM_OP_VOTE, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL);

    current_election_id++;
    crm_xml_add(vote, F_CRM_ELECTION_OWNER, fsa_our_uuid);
    crm_xml_add_int(vote, F_CRM_ELECTION_ID, current_election_id);

    crm_uptime(&age);
    crm_xml_add_int(vote, F_CRM_ELECTION_AGE_S, age.tv_sec);
    crm_xml_add_int(vote, F_CRM_ELECTION_AGE_US, age.tv_usec);

    send_cluster_message(NULL, crm_msg_crmd, vote, TRUE);
    free_xml(vote);

    crm_debug("Started election %d", current_election_id);
    if (voted) {
        g_hash_table_destroy(voted);
    }
    voted = NULL;

    if (cur_state == S_ELECTION || cur_state == S_RELEASE_DC) {
        crm_timer_start(election_timeout);

    } else if (cur_state != S_INTEGRATION) {
        crm_err("Broken? Voting in state %s", fsa_state2string(cur_state));
    }

    return;
}
Ejemplo n.º 13
0
enum crmd_fsa_state
s_crmd_fsa(enum crmd_fsa_cause cause)
{
    fsa_data_t *fsa_data = NULL;
    long long register_copy = fsa_input_register;
    long long new_actions = A_NOTHING;
    enum crmd_fsa_state last_state;

    crm_trace("FSA invoked with Cause: %s\tState: %s",
              fsa_cause2string(cause), fsa_state2string(fsa_state));

    fsa_dump_actions(fsa_actions, "Initial");

    do_fsa_stall = FALSE;
    if (is_message() == FALSE && fsa_actions != A_NOTHING) {
        /* fake the first message so we can get into the loop */
        fsa_data = calloc(1, sizeof(fsa_data_t));
        fsa_data->fsa_input = I_NULL;
        fsa_data->fsa_cause = C_FSA_INTERNAL;
        fsa_data->origin = __FUNCTION__;
        fsa_data->data_type = fsa_dt_none;
        fsa_message_queue = g_list_append(fsa_message_queue, fsa_data);
        fsa_data = NULL;
    }
    while (is_message() && do_fsa_stall == FALSE) {
        crm_trace("Checking messages (%d remaining)", g_list_length(fsa_message_queue));

        fsa_data = get_message();
        if(fsa_data == NULL) {
            continue;
        }

        log_fsa_input(fsa_data);

        /* add any actions back to the queue */
        fsa_actions |= fsa_data->actions;
        fsa_dump_actions(fsa_data->actions, "Restored actions");

        /* get the next batch of actions */
        new_actions = crmd_fsa_actions[fsa_data->fsa_input][fsa_state];
        fsa_actions |= new_actions;
        fsa_dump_actions(new_actions, "New actions");

        if (fsa_data->fsa_input != I_NULL && fsa_data->fsa_input != I_ROUTER) {
            crm_debug("Processing %s: [ state=%s cause=%s origin=%s ]",
                      fsa_input2string(fsa_data->fsa_input),
                      fsa_state2string(fsa_state),
                      fsa_cause2string(fsa_data->fsa_cause), fsa_data->origin);
        }

        /* logging : *before* the state is changed */
        if (is_set(fsa_actions, A_ERROR)) {
            do_fsa_action(fsa_data, A_ERROR, do_log);
        }
        if (is_set(fsa_actions, A_WARN)) {
            do_fsa_action(fsa_data, A_WARN, do_log);
        }
        if (is_set(fsa_actions, A_LOG)) {
            do_fsa_action(fsa_data, A_LOG, do_log);
        }

        /* update state variables */
        last_state = fsa_state;
        fsa_state = crmd_fsa_state[fsa_data->fsa_input][fsa_state];

        /*
         * Remove certain actions during shutdown
         */
        if (fsa_state == S_STOPPING || ((fsa_input_register & R_SHUTDOWN) == R_SHUTDOWN)) {
            clear_bit(fsa_actions, startup_actions);
        }

        /*
         * Hook for change of state.
         * Allows actions to be added or removed when entering a state
         */
        if (last_state != fsa_state) {
            fsa_actions = do_state_transition(fsa_actions, last_state, fsa_state, fsa_data);
        } else {
            do_dot_log(DOT_PREFIX "\t// FSA input: State=%s \tCause=%s"
                       " \tInput=%s \tOrigin=%s() \tid=%d",
                       fsa_state2string(fsa_state),
                       fsa_cause2string(fsa_data->fsa_cause),
                       fsa_input2string(fsa_data->fsa_input), fsa_data->origin, fsa_data->id);
        }

        /* start doing things... */
        s_crmd_fsa_actions(fsa_data);
        delete_fsa_input(fsa_data);
        fsa_data = NULL;
    }

    if (g_list_length(fsa_message_queue) > 0 || fsa_actions != A_NOTHING || do_fsa_stall) {
        crm_debug("Exiting the FSA: queue=%d, fsa_actions=0x%llx, stalled=%s",
                  g_list_length(fsa_message_queue), fsa_actions, do_fsa_stall ? "true" : "false");
    } else {
        crm_trace("Exiting the FSA");
    }

    /* cleanup inputs? */
    if (register_copy != fsa_input_register) {
        long long same = register_copy & fsa_input_register;

        fsa_dump_inputs(LOG_DEBUG, "Added", fsa_input_register ^ same);
        fsa_dump_inputs(LOG_DEBUG, "Removed", register_copy ^ same);
    }

    fsa_dump_actions(fsa_actions, "Remaining");
    fsa_dump_queue(LOG_DEBUG);

    return fsa_state;
}
Ejemplo n.º 14
0
static void
tengine_stonith_notify(stonith_t * st, stonith_event_t * st_event)
{
    if(te_client_id == NULL) {
        te_client_id = crm_strdup_printf("%s.%d", crm_system_name, getpid());
    }

    if (st_event == NULL) {
        crm_err("Notify data not found");
        return;
    }

    crmd_notify_fencing_op(st_event);

    if (st_event->result == pcmk_ok && safe_str_eq("on", st_event->action)) {
        crm_notice("%s was successfully unfenced by %s (at the request of %s)",
                   st_event->target, st_event->executioner ? st_event->executioner : "<anyone>", st_event->origin);
                /* TODO: Hook up st_event->device */
        return;

    } else if (safe_str_eq("on", st_event->action)) {
        crm_err("Unfencing of %s by %s failed: %s (%d)",
                st_event->target, st_event->executioner ? st_event->executioner : "<anyone>",
                pcmk_strerror(st_event->result), st_event->result);
        return;

    } else if (st_event->result == pcmk_ok && crm_str_eq(st_event->target, fsa_our_uname, TRUE)) {
        crm_crit("We were allegedly just fenced by %s for %s!",
                 st_event->executioner ? st_event->executioner : "<anyone>", st_event->origin); /* Dumps blackbox if enabled */

        qb_log_fini(); /* Try to get the above log message to disk - somehow */

        /* Get out ASAP and do not come back up.
         *
         * Triggering a reboot is also not the worst idea either since
         * the rest of the cluster thinks we're safely down
         */

#ifdef RB_HALT_SYSTEM
        reboot(RB_HALT_SYSTEM);
#endif

        /*
         * If reboot() fails or is not supported, coming back up will
         * probably lead to a situation where the other nodes set our
         * status to 'lost' because of the fencing callback and will
         * discard subsequent election votes with:
         *
         * Election 87 (current: 5171, owner: 103): Processed vote from east-03 (Peer is not part of our cluster)
         *
         * So just stay dead, something is seriously messed up anyway.
         *
         */
        exit(100); /* None of our wrappers since we already called qb_log_fini() */
        return;
    }

    if (st_event->result == pcmk_ok &&
        safe_str_eq(st_event->operation, T_STONITH_NOTIFY_FENCE)) {
        st_fail_count_reset(st_event->target);
    }

    crm_notice("Peer %s was%s terminated (%s) by %s for %s: %s (ref=%s) by client %s",
               st_event->target, st_event->result == pcmk_ok ? "" : " not",
               st_event->action,
               st_event->executioner ? st_event->executioner : "<anyone>",
               st_event->origin, pcmk_strerror(st_event->result), st_event->id,
               st_event->client_origin ? st_event->client_origin : "<unknown>");

#if SUPPORT_CMAN
    if (st_event->result == pcmk_ok && is_cman_cluster()) {
        int local_rc = 0;
        int confirm = 0;
        char *target_copy = strdup(st_event->target);

        /* In case fenced hasn't noticed yet
         *
         * Any fencing that has been inititated will be completed by way of the fence_pcmk redirect
         */
        local_rc = fenced_external(target_copy);
        if (local_rc != 0) {
            crm_err("Could not notify CMAN that '%s' is now fenced: %d", st_event->target,
                    local_rc);
        } else {
            crm_notice("Notified CMAN that '%s' is now fenced", st_event->target);
        }

        /* In case fenced is already trying to shoot it */
        confirm = open("/var/run/cluster/fenced_override", O_NONBLOCK|O_WRONLY);
        if (confirm >= 0) {
            int ignore = 0;
            int len = strlen(target_copy);

            errno = 0;
            local_rc = write(confirm, target_copy, len);
            ignore = write(confirm, "\n", 1);

            if(ignore < 0 && errno == EBADF) {
                crm_trace("CMAN not expecting %s to be fenced (yet)", st_event->target);

            } else if (local_rc < len) {
                crm_perror(LOG_ERR, "Confirmation of CMAN fencing event for '%s' failed: %d", st_event->target, local_rc);

            } else {
                fsync(confirm);
                crm_notice("Confirmed CMAN fencing event for '%s'", st_event->target);
            }
            close(confirm);
        }
        free(target_copy);
    }
#endif

    if (st_event->result == pcmk_ok) {
        crm_node_t *peer = crm_find_peer_full(0, st_event->target, CRM_GET_PEER_ANY);
        const char *uuid = NULL;
        gboolean we_are_executioner = safe_str_eq(st_event->executioner, fsa_our_uname);

        if (peer == NULL) {
            return;
        }

        uuid = crm_peer_uuid(peer);

        crm_trace("target=%s dc=%s", st_event->target, fsa_our_dc);
        if(AM_I_DC) {
            /* The DC always sends updates */
            send_stonith_update(NULL, st_event->target, uuid);

            if (st_event->client_origin && safe_str_neq(st_event->client_origin, te_client_id)) {

                /* Abort the current transition graph if it wasn't us
                 * that invoked stonith to fence someone
                 */
                crm_info("External fencing operation from %s fenced %s", st_event->client_origin, st_event->target);
                abort_transition(INFINITY, tg_restart, "External Fencing Operation", NULL);
            }

            /* Assume it was our leader if we dont currently have one */
        } else if (((fsa_our_dc == NULL) || safe_str_eq(fsa_our_dc, st_event->target))
            && !is_set(peer->flags, crm_remote_node)) {

            crm_notice("Target %s our leader %s (recorded: %s)",
                       fsa_our_dc ? "was" : "may have been", st_event->target,
                       fsa_our_dc ? fsa_our_dc : "<unset>");

            /* Given the CIB resyncing that occurs around elections,
             * have one node update the CIB now and, if the new DC is different,
             * have them do so too after the election
             */
            if (we_are_executioner) {
                send_stonith_update(NULL, st_event->target, uuid);
            }
            add_stonith_cleanup(st_event->target);
        }

        /* If the target is a remote node, and we host its connection,
         * immediately fail all monitors so it can be recovered quickly.
         * The connection won't necessarily drop when a remote node is fenced,
         * so the failure might not otherwise be detected until the next poke.
         */
        if (is_set(peer->flags, crm_remote_node)) {
            remote_ra_fail(st_event->target);
        }

        crmd_peer_down(peer, TRUE);
     }
}
Ejemplo n.º 15
0
void
master_rsc_colocation_rh(resource_t * rsc_lh, resource_t * rsc_rh, rsc_colocation_t * constraint)
{
    GListPtr gIter = NULL;
    clone_variant_data_t *clone_data = NULL;

    get_clone_variant_data(clone_data, rsc_rh);

    CRM_CHECK(rsc_rh != NULL, return);
    if (is_set(rsc_rh->flags, pe_rsc_provisional)) {
        return;

    } else if (constraint->role_rh == RSC_ROLE_UNKNOWN) {
        crm_trace("Handling %s as a clone colocation", constraint->id);
        clone_rsc_colocation_rh(rsc_lh, rsc_rh, constraint);
        return;
    }

    CRM_CHECK(rsc_lh != NULL, return);
    CRM_CHECK(rsc_lh->variant == pe_native, return);
    crm_trace("Processing constraint %s: %d", constraint->id, constraint->score);

    if (constraint->role_rh == RSC_ROLE_UNKNOWN) {

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

            child_rsc->cmds->rsc_colocation_rh(rsc_lh, child_rsc, constraint);
        }

    } else if (is_set(rsc_lh->flags, pe_rsc_provisional)) {
        GListPtr rhs = NULL;

        gIter = rsc_rh->children;
        for (; gIter != NULL; gIter = gIter->next) {
            resource_t *child_rsc = (resource_t *) gIter->data;
            node_t *chosen = child_rsc->fns->location(child_rsc, NULL, FALSE);
            enum rsc_role_e next_role = child_rsc->fns->state(child_rsc, FALSE);

            crm_trace("Processing: %s", child_rsc->id);
            if (chosen != NULL && next_role == constraint->role_rh) {
                crm_trace("Applying: %s %s %s %d", child_rsc->id,
                            role2text(next_role), chosen->details->uname, constraint->score);
                if (constraint->score < INFINITY) {
                    node_hash_update_one(rsc_lh->allowed_nodes, chosen,
                                         constraint->node_attribute, constraint->score);
                }
                rhs = g_list_prepend(rhs, chosen);
            }
        }

        /* Only do this if its not a master-master colocation
         * Doing this unconditionally would prevent the slaves from being started
         */
        if (constraint->role_lh != RSC_ROLE_MASTER || constraint->role_rh != RSC_ROLE_MASTER) {
            if (constraint->score >= INFINITY) {
                node_list_exclude(rsc_lh->allowed_nodes, rhs, TRUE);
            }
        }
        g_list_free(rhs);

    } else if (constraint->role_lh == RSC_ROLE_MASTER) {
        resource_t *rh_child = find_compatible_child(rsc_lh, rsc_rh, constraint->role_rh, FALSE);

        if (rh_child == NULL && constraint->score >= INFINITY) {
            crm_trace("%s can't be promoted %s", rsc_lh->id, constraint->id);
            rsc_lh->priority = -INFINITY;

        } else if (rh_child != NULL) {
            int new_priority = merge_weights(rsc_lh->priority, constraint->score);

            crm_debug("Applying %s to %s", constraint->id, rsc_lh->id);
            crm_debug("\t%s: %d->%d", rsc_lh->id, rsc_lh->priority, new_priority);
            rsc_lh->priority = new_priority;
        }
    }

    return;
}
Ejemplo n.º 16
0
/*	 A_CIB_STOP, A_CIB_START, A_CIB_RESTART,	*/
void
do_cib_control(long long action,
	       enum crmd_fsa_cause cause,
	       enum crmd_fsa_state cur_state,
	       enum crmd_fsa_input current_input,
	       fsa_data_t *msg_data)
{
	struct crm_subsystem_s *this_subsys = cib_subsystem;
	
	long long stop_actions = A_CIB_STOP;
	long long start_actions = A_CIB_START;

	if(action & stop_actions) {

		if (fsa_cib_conn->state != cib_disconnected && last_resource_update != 0) {
		    crm_info("Waiting for resource update %d to complete", last_resource_update);
		    crmd_fsa_stall(NULL);
		    return;
		}

		crm_info("Disconnecting CIB");
		clear_bit_inplace(fsa_input_register, R_CIB_CONNECTED);
		CRM_ASSERT(fsa_cib_conn != NULL);

		fsa_cib_conn->cmds->del_notify_callback(
		    fsa_cib_conn, T_CIB_DIFF_NOTIFY, do_cib_updated);

		if(fsa_cib_conn->state != cib_disconnected) {
			fsa_cib_conn->cmds->set_slave(
				fsa_cib_conn, cib_scope_local);
			fsa_cib_conn->cmds->signoff(fsa_cib_conn);
		}
	}

	if(action & start_actions) {
		int rc = cib_ok;
		
		CRM_ASSERT(fsa_cib_conn != NULL);
		
		if(cur_state == S_STOPPING) {
			crm_err("Ignoring request to start %s after shutdown",
				this_subsys->name);
			return;
		}

		rc = fsa_cib_conn->cmds->signon(
			fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command);

		if(rc != cib_ok) {
			/* a short wait that usually avoids stalling the FSA */
			sleep(1); 
			rc = fsa_cib_conn->cmds->signon(
				fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command);
		}
		
		if(rc != cib_ok){
			crm_info("Could not connect to the CIB service: %s", cib_error2string(rc));

		} else if(cib_ok != fsa_cib_conn->cmds->set_connection_dnotify(
				  fsa_cib_conn, crmd_cib_connection_destroy)) {
			crm_err("Could not set dnotify callback");
			
		} else if(cib_ok != fsa_cib_conn->cmds->add_notify_callback(
				  fsa_cib_conn, T_CIB_REPLACE_NOTIFY,
				  do_cib_replaced)) {
			crm_err("Could not set CIB notification callback");

		} else if(cib_ok != fsa_cib_conn->cmds->add_notify_callback(
			      fsa_cib_conn, T_CIB_DIFF_NOTIFY, do_cib_updated)) {
		    crm_err("Could not set CIB notification callback");
			
		} else {
			set_bit_inplace(
				fsa_input_register, R_CIB_CONNECTED);
		}
		
		if(is_set(fsa_input_register, R_CIB_CONNECTED) == FALSE) {
			
			cib_retries++;
			crm_warn("Couldn't complete CIB registration %d"
				 " times... pause and retry",
				 cib_retries);
			
			if(cib_retries < 30) {
				crm_timer_start(wait_timer);
				crmd_fsa_stall(NULL);
				
			} else {
				crm_err("Could not complete CIB"
					" registration  %d times..."
					" hard error", cib_retries);
				register_fsa_error(
					C_FSA_INTERNAL, I_ERROR, NULL);
			}
		} else {
			int call_id = 0;
			
			crm_info("CIB connection established");
			
			call_id = fsa_cib_conn->cmds->query(
				fsa_cib_conn, NULL, NULL, cib_scope_local);
			
			add_cib_op_callback(fsa_cib_conn, call_id, FALSE, NULL,
					    revision_check_callback);
			cib_retries = 0;
		}
	}
}
Ejemplo n.º 17
0
//将o移动到new_pos,并计算视野变化
void move_to(struct map *m,struct aoi_object *o,struct point2D *new_pos)
{
	struct point2D old_pos = o->current_pos;
	o->current_pos = *new_pos;
	struct map_block *old_block = get_block_by_point(m,&old_pos);
	struct map_block *new_block = get_block_by_point(m,new_pos);
	if(old_block != new_block)
		double_link_remove(&o->block_node);
		
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
		radius = o->view_radius;		
	//计算新旧管理区域
	uint32_t n_x1,n_y1,n_x2,n_y2;
	uint32_t o_x1,o_y1,o_x2,o_y2;
	cal_blocks(m,&old_pos,radius,&o_x1,&o_y1,&o_x2,&o_y2);
	cal_blocks(m,new_pos,radius,&n_x1,&n_y1,&n_x2,&n_y2);
	
	uint32_t y = n_y1;
	uint32_t x;
	for( ; y <= n_y2; ++y)
	{
		for( x = n_x1; x <= n_x2; ++x)
		{
			if(x >= o_x1 && x <= o_x2 && y >= o_y1 && y <= o_y2)
			{
				//无变化区域
				struct map_block *bl = get_block(m,y,x);
				struct aoi_object *cur = (struct aoi_object*)bl->aoi_objs.head.next;
				while(cur != (struct aoi_object*)&bl->aoi_objs.tail)
				{
					uint64_t distance = cal_distance_2D(new_pos,&cur->current_pos);
					if(o != cur)
					{
						if(o->view_radius >= distance && !is_set(&o->self_view_objs,cur->aoi_object_id))
							enter_me(m,o,cur);
						if(o->view_radius < distance && is_set(&o->self_view_objs,cur->aoi_object_id))
							leave_me(m,o,cur);
						if(cur->view_radius >= distance && !is_set(&cur->self_view_objs,o->aoi_object_id))
							enter_me(m,cur,o);
						if(cur->view_radius < distance && is_set(&cur->self_view_objs,o->aoi_object_id))
							leave_me(m,cur,o);
					}
					cur = (struct aoi_object *)cur->block_node.next;			
				}				
			}
			else
			{
				//新进入的区域
				block_process_enter(m,get_block(m,y,x),o);
			}
		}
	}
	if(old_block != new_block)
		double_link_push(&new_block->aoi_objs,&o->block_node);
	y = o_y1;
	for( ; y <= o_y2; ++y)
	{
		for(x = o_x1; x <= o_x2; ++x)
		{
			if(x >= n_x1 && x <= n_x2 && y >= n_y1 && y <= n_y2)
				continue;//这里不处理无变化区域
			block_process_leave(m,get_block(m,y,x),o,0);
		}		
	}
	o->last_update_tick = GetCurrentMs();
}
Ejemplo n.º 18
0
void do_buy( char_data *ch, char *argument )
{
  char             buf  [ MAX_INPUT_LENGTH ];
  char_data*    keeper;
  char_data*       pet;
  obj_data*        obj;
  room_data*      room;
  thing_array*   array;

  if( ( keeper = find_keeper( ch ) ) == NULL )
    return;

  /* PET SHOP */

  if( is_set( &ch->in_room->room_flags, RFLAG_PET_SHOP ) ) {
    if( ch->species != NULL  ) {
      send( ch, "Monsters can't buy pets." );
      return;
      }

    if( ( room = get_room_index( ch->in_room->vnum+1 ) ) == NULL ) {
      send( ch, "The pet shop is still under construction.\r\n" );
      return;
      }

    thing_array list;

    for( int i = 0; i < room->contents; i++ ) 
      if( ( pet = character( room->contents[i] ) ) != NULL
        && buyable_pet( pet ) )
        list += pet;

    if( ( pet = one_character( ch, argument, "buy", &list ) ) == NULL )
      return;

    if( pet->shdata->level > ch->shdata->level ) {
      send( ch, "%s is too high a level for you.\r\n", pet );
      return;
      }

    if( pet->species->price == 0 ) {
      send( ch,
        "That pet is not for sale until a god sets a price for it.\r\n" );
      return;
      }

    if( is_set( &pet->species->act_flags, ACT_MOUNT ) ) {
      if( has_mount( ch ) )
        return;
      }
    else {
      if( number_of_pets( ch ) >= 2 ) {
        send( ch, "You already have two pets.\r\n" );
        return;
        }
      }

    sprintf( buf, "You hand %s", keeper->descr->name ); 
    if( !remove_coins( ch, pet->species->price, buf ) ) {
      if( ch->shdata->level < LEVEL_APPRENTICE ) {
        send( ch, "You can't afford it.\r\n" );
        return;
        }
      send( ch, "You don't have enough gold, but it doesn't seem to\
 matter.\r\n" );
      }

    pet->From( );
    pet->To( ch->array );

    set_bit( &pet->status, STAT_PET );
    add_follower( pet, ch );

    send( ch, "Enjoy your pet.\r\n" );
    fsend( ch, "%s bought %s as a pet.\r\n", ch, pet );

    if( pet->reset != NULL ) {
      pet->reset->count--;
      pet->reset = NULL;
      }
    return;
    }

  /* OBJECT SHOP */

  thing_array list;

  for( int i = 0; i < keeper->contents; i++ ) {
    obj = (obj_data*) keeper->contents[i];
    if( will_trade( keeper, obj ) )
      list += obj;
    }
    
  if( ( array = several_things( ch, argument, "buy", &list ) ) == NULL )
    return;

  thing_array   subset  [ 4 ];
  thing_func*     func  [ 4 ]  = { heavy, many, cantafford, buy };

  sort_objects( ch, *array, keeper, 4, subset, func );
  
  page_priv( ch, NULL, empty_string );
  page_priv( ch, &subset[0], "can't lift" );
  page_priv( ch, &subset[1], "can't handle" );
  page_priv( ch, &subset[2], "can't afford" );
  page_publ( ch, &subset[3], "buy", keeper, "from", "for" );

  delete array;
}
Ejemplo n.º 19
0
static void cfg_init_defaults(cfg_t *cfg)
{
    int i;

    for(i = 0; cfg->opts[i].name; i++)
    {
        /* libConfuse doesn't handle default values for "simple" options */
        if(cfg->opts[i].simple_value || is_set(CFGF_NODEFAULT, cfg->opts[i].flags))
            continue;

        if(cfg->opts[i].type != CFGT_SEC)
        {
            cfg->opts[i].flags |= CFGF_DEFINIT;

            if(is_set(CFGF_LIST, cfg->opts[i].flags) ||
               cfg->opts[i].def.parsed)
            {
                int xstate, ret;

                /* If it's a list, but no default value was given,
                 * keep the option uninitialized.
                 */
                if(cfg->opts[i].def.parsed == 0 ||
                   cfg->opts[i].def.parsed[0] == 0)
                    continue;

                /* setup scanning from the string specified for the
                 * "default" value, force the correct state and option
                 */

                if(is_set(CFGF_LIST, cfg->opts[i].flags))
                    /* lists must be surrounded by {braces} */
                    xstate = 3;
                else if(cfg->opts[i].type == CFGT_FUNC)
                    xstate = 0;
                else
                    xstate = 2;

                cfg_scan_string_begin(cfg->opts[i].def.parsed);
                do
                {
                    ret = cfg_parse_internal(cfg, 1, xstate, &cfg->opts[i]);
                    xstate = -1;
                } while(ret == STATE_CONTINUE);
                cfg_scan_string_end();
                if(ret == STATE_ERROR)
                {
                    /*
                     * If there was an error parsing the default string,
                     * the initialization of the default value could be
                     * inconsistent or empty. What to do? It's a
                     * programming error and not an end user input
                     * error. Lets print a message and abort...
                     */
                    fprintf(stderr, "Parse error in default value '%s'"
                            " for option '%s'\n",
                            cfg->opts[i].def.parsed, cfg->opts[i].name);
                    fprintf(stderr, "Check your initialization macros and the"
                            " libConfuse documentation\n");
                    abort();
                }
            }
            else
            {
                switch(cfg->opts[i].type)
                {
                    case CFGT_INT:
                        cfg_opt_setnint(&cfg->opts[i],
                                        cfg->opts[i].def.number, 0);
                        break;
                    case CFGT_FLOAT:
                        cfg_opt_setnfloat(&cfg->opts[i],
                                          cfg->opts[i].def.fpnumber, 0);
                        break;
                    case CFGT_BOOL:
                        cfg_opt_setnbool(&cfg->opts[i],
                                         cfg->opts[i].def.boolean, 0);
                        break;
                    case CFGT_STR:
                        cfg_opt_setnstr(&cfg->opts[i],
                                        cfg->opts[i].def.string, 0);
                        break;
                    case CFGT_FUNC:
                    case CFGT_PTR:
                        break;
                    default:
                        cfg_error(cfg,
                                  "internal error in cfg_init_defaults(%s)",
                                  cfg->opts[i].name);
                        break;
                }
            }

            /* The default value should only be returned if no value
             * is given in the configuration file, so we set the RESET
             * flag here. When/If cfg_setopt() is called, the value(s)
             * will be freed and the flag unset.
             */
            cfg->opts[i].flags |= CFGF_RESET;
        } /* end if cfg->opts[i].type != CFGT_SEC */
        else if(!is_set(CFGF_MULTI, cfg->opts[i].flags))
        {
            cfg_setopt(cfg, &cfg->opts[i], 0);
            cfg->opts[i].flags |= CFGF_DEFINIT;
        }
    }
}
Ejemplo n.º 20
0
void do_list( char_data* ch, char* argument )
{
  char_data*   keeper;
  char_data*      pet;
  thing_array*  array;
  obj_data*       obj;
  room_data*     room;
  int i;

  if( ( keeper = find_keeper( ch ) ) == NULL )
    return;

  if( *argument == '\0' )
    argument = "all";

  /* PET SHOP */

  if( is_set( &ch->in_room->room_flags, RFLAG_PET_SHOP ) ) {
    if( ( room = get_room_index( ch->in_room->vnum+1 ) ) == NULL ) {
      send( ch, "The pet shop is still under construction.\r\n" );
      return;
      }

    thing_array list;

    for( i = 0; i < room->contents; i++ ) 
      if( ( pet = character( room->contents[i] ) ) != NULL
        && buyable_pet( pet ) )
        list += pet;

    if( is_empty( list ) ) {
      process_tell( keeper, ch, "Sorry, I'm out of pets right now.\r\n" );
      return;
      }

    if( ( array = several_things( ch, argument, "list", &list ) ) == NULL )
      return;

    send( ch, "Copper Pieces: %d\r\n\r\n", get_money( ch ) );
    send_underlined( ch,
      "Pet                          Cost    Level\r\n" );

    for( i = 0; i < *array; i++ ) {
      pet = (char_data*) array->list[i];
      send( ch, "%-25s%8d%8d\r\n", pet->Seen_Name( ch, 1, TRUE ),
        pet->species->price, pet->shdata->level );
      }

    delete array;

    return;
    }

  /* OBJECT SHOP */

  thing_array list;

  for( i = 0; i < keeper->contents; i++ ) {
    obj = (obj_data*) keeper->contents[i];
    obj->selected = 1;
    if( ( obj->temp = get_cost( keeper, ch, obj, TRUE ) ) > 0 )
      list += obj;
    }

  if( is_empty( list ) ) {
    process_tell( keeper, ch,
      "Sorry, I have nothing to sell right now.\r\n" );
    return;
    }

  if( ( array = several_things( ch, argument, "list",  &list ) ) == NULL )
    return;

  page( ch, "Copper Pieces: %d\r\n\r\n", get_money( ch ) );
  page_underlined( ch, "Item                                     Cost\
    Level   Number   Condition\r\n" );

  char level [ 5 ];

  include_closed = FALSE;

  for( i = 0; i < *array; i++ ) {
    obj = (obj_data*) array->list[i];

    if( !can_use( ch, obj->pIndexData, obj ) )
      sprintf( level, "***" );
    else
      sprintf( level, "%d", obj->pIndexData->level );

    page( ch, "%-37s%8d%8s%8d%5s%-s\r\n",
      truncate( (char *) obj->Seen_Name( ch, 1, TRUE ), 37 ), obj->temp, level,
      obj->number, "", obj->condition_name( ch, TRUE ) );
    }

  include_closed = TRUE;

  delete array;
}
Ejemplo n.º 21
0
static int cfg_parse_internal(cfg_t *cfg, int level,
                              int force_state, cfg_opt_t *force_opt)
{
    int state = 0;
    char *opttitle = 0;
    cfg_opt_t *opt = 0;
    cfg_value_t *val = 0;
    cfg_opt_t funcopt = CFG_STR(0, 0, 0);
    int num_values = 0; /* number of values found for a list option */
    int rc;

    if(force_state != -1)
        state = force_state;
    if(force_opt)
        opt = force_opt;

    while(1)
    {
        int tok = cfg_yylex(cfg);

        if(tok == 0)
        {
            /* lexer.l should have called cfg_error */
            return STATE_ERROR;
        }

        if(tok == EOF)
        {
            if(state != 0)
            {
                cfg_error(cfg, _("premature end of file"));
                return STATE_ERROR;
            }
            return STATE_EOF;
        }

        switch(state)
        {
            case 0: /* expecting an option name */
                if(tok == '}')
                {
                    if(level == 0)
                    {
                        cfg_error(cfg, _("unexpected closing brace"));
                        return STATE_ERROR;
                    }
                    return STATE_EOF;
                }
                if(tok != CFGT_STR)
                {
                    cfg_error(cfg, _("unexpected token '%s'"), cfg_yylval);
                    return STATE_ERROR;
                }
                opt = cfg_getopt(cfg, cfg_yylval);
                if(opt == 0)
                    return STATE_ERROR;
                if(opt->type == CFGT_SEC)
                {
                    if(is_set(CFGF_TITLE, opt->flags))
                        state = 6;
                    else
                        state = 5;
                }
                else if(opt->type == CFGT_FUNC)
                {
                    state = 7;
                }
                else
                    state = 1;
                break;

            case 1: /* expecting an equal sign or plus-equal sign */
                if(tok == '+')
                {
                    if(!is_set(CFGF_LIST, opt->flags))
                    {
                        cfg_error(cfg,
                                  _("attempt to append to non-list option '%s'"),
                                  opt->name);
                        return STATE_ERROR;
                    }
                    /* Even if the reset flag was set by
                     * cfg_init_defaults, appending to the defaults
                     * should be ok.
                     */
                    opt->flags &= ~CFGF_RESET;
                }
                else if(tok == '=')
                {
                    /* set the (temporary) reset flag to clear the old
                     * values, since we obviously didn't want to append */
                    opt->flags |= CFGF_RESET;
                }
                else
                {
                    cfg_error(cfg, _("missing equal sign after option '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                if(is_set(CFGF_LIST, opt->flags))
                {
                    state = 3;
                    num_values = 0;
                } else
                    state = 2;
                break;

            case 2: /* expecting an option value */
                if(tok == '}' && is_set(CFGF_LIST, opt->flags))
                {
                    state = 0;
                    if(num_values == 0 && is_set(CFGF_RESET, opt->flags))
                        /* Reset flags was set, and the empty list was
                         * specified. Free all old values. */
                        cfg_free_value(opt);
                    break;
                }

                if(tok != CFGT_STR)
                {
                    cfg_error(cfg, _("unexpected token '%s'"), cfg_yylval);
                    return STATE_ERROR;
                }

                if(cfg_setopt(cfg, opt, cfg_yylval) == 0)
                    return STATE_ERROR;
                if(opt->validcb && (*opt->validcb)(cfg, opt) != 0)
                    return STATE_ERROR;
                if(is_set(CFGF_LIST, opt->flags))
                {
                    state = 4;
                    ++num_values;
                }
                else
                    state = 0;
                break;

            case 3: /* expecting an opening brace for a list option */
                if(tok != '{')
                {
                    cfg_error(cfg, _("missing opening brace for option '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                state = 2;
                break;

            case 4: /* expecting a separator for a list option, or
                     * closing (list) brace */
                if(tok == ',')
                    state = 2;
                else if(tok == '}')
                {
                    state = 0;
                    if(opt->validcb && (*opt->validcb)(cfg, opt) != 0)
                        return STATE_ERROR;
                }
                else
                {
                    cfg_error(cfg, _("unexpected token '%s'"), cfg_yylval);
                    return STATE_ERROR;
                }
                break;

            case 5: /* expecting an opening brace for a section */
                if(tok != '{')
                {
                    cfg_error(cfg, _("missing opening brace for section '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }

                val = cfg_setopt(cfg, opt, opttitle);
                opttitle = 0;
                if(!val)
                    return STATE_ERROR;

                val->section->line = cfg->line;
                rc = cfg_parse_internal(val->section, level+1,-1,0);
                cfg->line = val->section->line;
                if(rc != STATE_EOF)
                    return STATE_ERROR;
                if(opt->validcb && (*opt->validcb)(cfg, opt) != 0)
                    return STATE_ERROR;
                state = 0;
                break;

            case 6: /* expecting a title for a section */
                if(tok != CFGT_STR)
                {
                    cfg_error(cfg, _("missing title for section '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                else
                    opttitle = strdup(cfg_yylval);
                state = 5;
                break;

            case 7: /* expecting an opening parenthesis for a function */
                if(tok != '(')
                {
                    cfg_error(cfg, _("missing parenthesis for function '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                state = 8;
                break;

            case 8: /* expecting a function parameter or a closing paren */
                if(tok == ')')
                {
                    int ret = call_function(cfg, opt, &funcopt);
                    if(ret != 0)
                        return STATE_ERROR;
                    state = 0;
                }
                else if(tok == CFGT_STR)
                {
                    val = cfg_addval(&funcopt);
                    val->string = strdup(cfg_yylval);
                    state = 9;
                }
                else
                {
                    cfg_error(cfg, _("syntax error in call of function '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                break;

            case 9: /* expecting a comma in a function or a closing paren */
                if(tok == ')')
                {
                    int ret = call_function(cfg, opt, &funcopt);
                    if(ret != 0)
                        return STATE_ERROR;
                    state = 0;
                }
                else if(tok == ',')
                    state = 8;
                else
                {
                    cfg_error(cfg, _("syntax error in call of function '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                break;

            default:
                /* missing state, internal error, abort */
                assert(0);
        }
    }

    return STATE_EOF;
}
Ejemplo n.º 22
0
void do_value( char_data* ch, char* argument )
{
  char           buf  [ MAX_STRING_LENGTH ];
  char_data*  keeper;
  obj_data*      obj;
  int           cost;
  int          rcost;
  int         blocks;

  if( ( keeper = find_keeper( ch ) ) == NULL )
    return;

  if( is_set( &ch->in_room->room_flags, RFLAG_PET_SHOP ) ) {
    process_tell( keeper, ch, "We don't buy pets" );
    return;
    }

  if( ( obj = one_object( ch, argument, "value",
    &ch->contents ) ) == NULL ) 
    return;

  if( !obj->droppable( ) ) {
    send( ch, "You can't let go of %s.\r\n", obj );
    return;
    }
  
  if( !obj->Belongs( ch ) ) {
    sprintf( buf, "%s is stolen so I would never buy it.",
      obj->Seen_Name( ch ) );
    process_tell( keeper, ch, buf );
    return;
    } 

  cost  = get_cost( keeper, ch, obj, FALSE );
  rcost = repair_cost( keeper, obj );
 
  if( obj->Damaged( ) ) {
    if( rcost > 0 ) 
      sprintf( buf, "I see %s is damaged.  I can repair it for %d cp %s ",
        obj->Seen_Name( ch ), rcost, cost > 0 ? "or" : "but" ); 
    else 
      sprintf( buf, "I see %s is damaged.  I am unable to repair it %s ",
        obj->Seen_Name( ch ), cost > 0 ? "but" : "and" );
    if( cost > 0 ) 
      sprintf( buf+strlen( buf ), "would give you %d cp for it.", cost );
    else
      strcat( buf, "am uninterested in buying it." );
    }
  else {
    if( cost > 0 )
      sprintf( buf, "I would pay you %d cp for %s.",
        cost, obj->Seen_Name( ch ) ); 
    else
      sprintf( buf, "I am uninterested in buying %s.",
        obj->Seen_Name( ch ) );
    }

  blocks = obj->pIndexData->blocks;
  if( ( cost = melt_cost( keeper, obj ) ) != 0 ) 
    sprintf( buf+strlen( buf ),
      "  I would melt it down to produce %d block%s for %d cp.",
      blocks, blocks == 1 ? "" : "s", cost );
      
  process_tell( keeper, ch, buf );
}
Ejemplo n.º 23
0
 bool passthrough_mode(wiimote &mote)
 {
   return is_set(mote.enabled_capabilities, wiimote_capabilities::Extension | wiimote_capabilities::MotionPlus);
 }
Ejemplo n.º 24
0
void do_melt( char_data *ch, char *argument )
{
  char           buf  [ MAX_INPUT_LENGTH ];
  char_data*  keeper;
  obj_data*      obj;
  int           cost;
  int         blocks;
  int          metal;
  int         length;

  if( ( keeper = find_keeper( ch ) ) == NULL )
    return;

  if( ( obj = one_object( ch, argument, "melt", &ch->contents ) ) == NULL ) 
    return;

  for( metal = MAT_BRONZE; metal <= MAT_GOLD; metal++ )
    if( is_set( &obj->materials, metal ) )
      break;

  if( metal > MAT_GOLD ) {
    fsend( ch, "%s is not made out of metal.", obj );
    return;
    }

  if( ( blocks = obj->pIndexData->blocks ) == 0 ) {
    fsend( ch, "%s does not contain enough metal to be worth melting.",
      obj );
    return;
    }

  if( !obj->droppable( ) ) {
    send( ch, "You can't let go of %s.\r\n", obj );
    return;
    }

  if( (keeper->pShop->materials & ( 1 << metal )) == 0 ) {
    process_tell( keeper, ch,
      "Sorry that is not made out of a metal I deal with." );
    return;
    }

  cost = 100;

  sprintf( buf, "You hand %s to %s along with",
    obj->Seen_Name( ch ), keeper->Seen_Name( ch ) );
  if( !remove_coins( ch, cost, buf ) ) { 
    sprintf( buf, "You can't afford my fee of %d cp to melt %s.",
      cost, obj->Seen_Name( ch ) );
    process_tell( keeper, ch, buf );
    return;
    }
    
  fsend( ch, "%s has %s melted down.", ch, obj );
  sprintf( buf, "%s takes %s and places it in the furnace.  ",
    keeper->Seen_Name( ch ), obj->Seen_Name( ch ) );
  buf[0] = toupper( buf[0] );

  obj->Extract( 1 );

  if( ( obj = create( get_obj_index(
    ingot_vnum[metal-MAT_BRONZE] ) ) ) == NULL ) {
    bug( "Repair: Ingot for %s does not exist.", 
      material_table[metal].name );
    return;
    }

  obj->number = blocks;
  obj->shown  = blocks;
  set_bit( &obj->materials, metal );

  length = strlen( buf );
  sprintf( &buf[length],
  "%s then pulls it out and after much hammering and reheating hands you %s.",
    keeper->He_She( ), obj->Seen_Name( ch, blocks ) );
  buf[length] = toupper( buf[length] );
  fsend( ch, buf );

  obj->To( &ch->contents );
}
Ejemplo n.º 25
0
/*	 A_TE_START, A_TE_STOP, A_TE_RESTART	*/
void
do_te_control(long long action,
	      enum crmd_fsa_cause cause,
	      enum crmd_fsa_state cur_state,
	      enum crmd_fsa_input current_input,
	      fsa_data_t *msg_data)
{
    int dummy;
    gboolean init_ok = TRUE;
	
    cl_uuid_t new_uuid;
    char uuid_str[UU_UNPARSE_SIZEOF];
	
    if(action & A_TE_STOP) {
	if(transition_graph) {
	    destroy_graph(transition_graph);
	    transition_graph = NULL;
	}

	if(fsa_cib_conn && cib_ok != fsa_cib_conn->cmds->del_notify_callback(
	       fsa_cib_conn, T_CIB_DIFF_NOTIFY, te_update_diff)) {
	    crm_err("Could not unset CIB notification callback");
	}

	clear_bit_inplace(fsa_input_register, te_subsystem->flag_connected);
	crm_info("Transitioner is now inactive");
	
	if(stonith_src) {
	    GCHSource *source = stonith_src;
	    crm_info("Disconnecting STONITH...");
	    stonith_src = NULL; /* so that we don't try to reconnect */
	    G_main_del_IPC_Channel(source);
	    stonithd_signoff();	    
	}
    }

    if((action & A_TE_START) == 0) {
	return;

    } else if(is_set(fsa_input_register, te_subsystem->flag_connected)) {
	crm_debug("The transitioner is already active");
	return;

    } else if((action & A_TE_START) && cur_state == S_STOPPING) {
	crm_info("Ignoring request to start %s while shutting down",
		 te_subsystem->name);
	return;
    }	

    cl_uuid_generate(&new_uuid);
    cl_uuid_unparse(&new_uuid, uuid_str);
    te_uuid = crm_strdup(uuid_str);
    crm_info("Registering TE UUID: %s", te_uuid);
	
    if(transition_trigger == NULL) {
	transition_trigger = mainloop_add_trigger(
	    G_PRIORITY_LOW, te_graph_trigger, NULL);
    }

    if(stonith_reconnect == NULL) {
	stonith_reconnect = mainloop_add_trigger(
	    G_PRIORITY_LOW, te_connect_stonith, &dummy);
    }
		    
    if(cib_ok != fsa_cib_conn->cmds->add_notify_callback(
	   fsa_cib_conn, T_CIB_DIFF_NOTIFY, te_update_diff)) {
	crm_err("Could not set CIB notification callback");
	init_ok = FALSE;
    }

    if(cib_ok != fsa_cib_conn->cmds->set_op_callback(fsa_cib_conn, global_cib_callback)) {
	crm_err("Could not set CIB global callback");
	init_ok = FALSE;
    }
    
    if(init_ok) {
	mainloop_set_trigger(stonith_reconnect);

	set_graph_functions(&te_graph_fns);

	if(transition_graph) {
	    destroy_graph(transition_graph);			    
	}
			
	/* create a blank one */
	crm_debug("Transitioner is now active");
	transition_graph = create_blank_graph();
	set_bit_inplace(fsa_input_register, te_subsystem->flag_connected);
    }
}
Ejemplo n.º 26
0
static gboolean
check_action_definition(resource_t *rsc, node_t *active_node, xmlNode *xml_op,
			pe_working_set_t *data_set)
{
	char *key = NULL;
	int interval = 0;
	const char *interval_s = NULL;
	
	gboolean did_change = FALSE;

	xmlNode *params_all = NULL;
	xmlNode *params_restart = NULL;
	GHashTable *local_rsc_params = NULL;
	
	char *digest_all_calc = NULL;
	const char *digest_all = NULL;

	const char *restart_list = NULL;
	const char *digest_restart = NULL;
	char *digest_restart_calc = NULL;

	action_t *action = NULL;
	const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
	const char *op_version = crm_element_value(xml_op, XML_ATTR_CRM_VERSION);

	CRM_CHECK(active_node != NULL, return FALSE);
    if(safe_str_eq(task, RSC_STOP)) {
	return FALSE;
    }
    
	interval_s = crm_element_value(xml_op, XML_LRM_ATTR_INTERVAL);
	interval = crm_parse_int(interval_s, "0");
	/* we need to reconstruct the key because of the way we used to construct resource IDs */
	key = generate_op_key(rsc->id, task, interval);

	if(interval > 0) {
		xmlNode *op_match = NULL;

		crm_debug_2("Checking parameters for %s", key);
		op_match = find_rsc_op_entry(rsc, key);

		if(op_match == NULL && is_set(data_set->flags, pe_flag_stop_action_orphans)) {
			CancelXmlOp(rsc, xml_op, active_node, "orphan", data_set);
			crm_free(key);
			return TRUE;

		} else if(op_match == NULL) {
			crm_debug("Orphan action detected: %s on %s",
				  key, active_node->details->uname);
			crm_free(key);
			return TRUE;
		}
	}

	action = custom_action(rsc, key, task, active_node, TRUE, FALSE, data_set);
	/* key is free'd by custom_action() */
	
	local_rsc_params = g_hash_table_new_full(
		g_str_hash, g_str_equal,
		g_hash_destroy_str, g_hash_destroy_str);
	
	get_rsc_attributes(local_rsc_params, rsc, active_node, data_set);
	
	params_all = create_xml_node(NULL, XML_TAG_PARAMS);
	g_hash_table_foreach(local_rsc_params, hash2field, params_all);
	g_hash_table_foreach(action->extra, hash2field, params_all);
	g_hash_table_foreach(rsc->parameters, hash2field, params_all);
	g_hash_table_foreach(action->meta, hash2metafield, params_all);

	filter_action_parameters(params_all, op_version);
	digest_all_calc = calculate_xml_digest(params_all, TRUE, FALSE);
	digest_all = crm_element_value(xml_op, XML_LRM_ATTR_OP_DIGEST);
	digest_restart = crm_element_value(xml_op, XML_LRM_ATTR_RESTART_DIGEST);
	restart_list = crm_element_value(xml_op, XML_LRM_ATTR_OP_RESTART);

    if(interval == 0 && safe_str_eq(task, RSC_STATUS)) {
	/* Reload based on the start action not a probe */
	task = RSC_START;
	}
    
    if(digest_restart) {
	/* Changes that force a restart */
		params_restart = copy_xml(params_all);
		if(restart_list) {
			filter_reload_parameters(params_restart, restart_list);
		}

		digest_restart_calc = calculate_xml_digest(params_restart, TRUE, FALSE);
		if(safe_str_neq(digest_restart_calc, digest_restart)) {
			did_change = TRUE;
			key = generate_op_key(rsc->id, task, interval);
			crm_log_xml_info(params_restart, "params:restart");
	    crm_info("Parameters to %s on %s changed: recorded %s vs. %s (restart:%s) %s",
				 key, active_node->details->uname,
				 crm_str(digest_restart), digest_restart_calc,
				 op_version, crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC));
			
			custom_action(rsc, key, task, NULL, FALSE, TRUE, data_set);
			goto cleanup;
		}
	}

	if(safe_str_neq(digest_all_calc, digest_all)) {
	/* Changes that can potentially be handled by a reload */
		did_change = TRUE;
		crm_log_xml_info(params_all, "params:reload");
		key = generate_op_key(rsc->id, task, interval);
		crm_info("Parameters to %s on %s changed: recorded %s vs. %s (reload:%s) %s",
			 key, active_node->details->uname,
			 crm_str(digest_all), digest_all_calc, op_version,
			 crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC));

	if(interval > 0) {
            action_t *op = NULL;
#if 0
	    /* Always reload/restart the entire resource */
	    op = custom_action(rsc, start_key(rsc), RSC_START, NULL, FALSE, TRUE, data_set);
	    update_action_flags(op, pe_action_allow_reload_conversion);
#else
	    /* Re-sending the recurring op is sufficient - the old one will be cancelled automatically */
	    op = custom_action(rsc, key, task, NULL, FALSE, TRUE, data_set);
	    custom_action_order(rsc, start_key(rsc), NULL,
				NULL, NULL, op, pe_order_runnable_left, data_set);
#endif
	    
	} else if(digest_restart) {
	    crm_debug_2("Reloading '%s' action for resource %s", task, rsc->id);

            /* Allow this resource to reload - unless something else causes a full restart */
            set_bit(rsc->flags, pe_rsc_try_reload);

            /* Create these for now, it keeps the action IDs the same in the regression outputs */
            custom_action(rsc, key, task, NULL, TRUE, TRUE, data_set);

	} else {
	    crm_debug_2("Resource %s doesn't know how to reload", rsc->id);

	    /* Re-send the start/demote/promote op
	     * Recurring ops will be detected independantly
	     */
	    custom_action(rsc, key, task, NULL, FALSE, TRUE, data_set);
		}
	}

  cleanup:
	free_xml(params_all);
	free_xml(params_restart);
	crm_free(digest_all_calc);
	crm_free(digest_restart_calc);
	g_hash_table_destroy(local_rsc_params);

	pe_free_action(action);
	
	return did_change;
}
Ejemplo n.º 27
0
int
process_remote_stonith_exec(xmlNode * msg)
{
    int rc = 0;
    const char *id = NULL;
    const char *device = NULL;
    remote_fencing_op_t *op = NULL;
    xmlNode *dev = get_xpath_object("//@" F_STONITH_REMOTE_OP_ID, msg, LOG_ERR);

    CRM_CHECK(dev != NULL, return -EPROTO);

    id = crm_element_value(dev, F_STONITH_REMOTE_OP_ID);
    CRM_CHECK(id != NULL, return -EPROTO);

    dev = get_xpath_object("//@" F_STONITH_RC, msg, LOG_ERR);
    CRM_CHECK(dev != NULL, return -EPROTO);

    crm_element_value_int(dev, F_STONITH_RC, &rc);

    device = crm_element_value(dev, F_STONITH_DEVICE);

    if (remote_op_list) {
        op = g_hash_table_lookup(remote_op_list, id);
    }

    if (op == NULL && rc == pcmk_ok) {
        /* Record successful fencing operations */
        const char *client_id = crm_element_value(dev, F_STONITH_CLIENTID);

        op = create_remote_stonith_op(client_id, dev, TRUE);
    }

    if (op == NULL) {
        /* Could be for an event that began before we started */
        /* TODO: Record the op for later querying */
        crm_info("Unknown or expired remote op: %s", id);
        return -EOPNOTSUPP;
    }

    if (op->devices && device && safe_str_neq(op->devices->data, device)) {
        crm_err
            ("Received outdated reply for device %s (instead of %s) to %s node %s. Operation already timed out at remote level.",
             device, op->devices->data, op->action, op->target);
        return rc;
    }

    if (safe_str_eq(crm_element_value(msg, F_SUBTYPE), "broadcast")) {
        crm_debug("Marking call to %s for %s on behalf of %s@%s.%.8s: %s (%d)",
                  op->action, op->target, op->client_name, op->id, op->originator,
                  pcmk_strerror(rc), rc);
        if (rc == pcmk_ok) {
            op->state = st_done;
        } else {
            op->state = st_failed;
        }
        remote_op_done(op, msg, rc, FALSE);
        return pcmk_ok;
    } else if (safe_str_neq(op->originator, stonith_our_uname)) {
        /* If this isn't a remote level broadcast, and we are not the
         * originator of the operation, we should not be receiving this msg. */
        crm_err
            ("%s received non-broadcast fencing result for operation it does not own (device %s targeting %s)",
             stonith_our_uname, device, op->target);
        return rc;
    }

    if (is_set(op->call_options, st_opt_topology)) {
        const char *device = crm_element_value(msg, F_STONITH_DEVICE);

        crm_notice("Call to %s for %s on behalf of %s@%s: %s (%d)",
                   device, op->target, op->client_name, op->originator,
                   pcmk_strerror(rc), rc);

        /* We own the op, and it is complete. broadcast the result to all nodes
         * and notify our local clients. */
        if (op->state == st_done) {
            remote_op_done(op, msg, rc, FALSE);
            return rc;
        }

        /* An operation completed succesfully but has not yet been marked as done.
         * Continue the topology if more devices exist at the current level, otherwise
         * mark as done. */
        if (rc == pcmk_ok) {
            if (op->devices) {
                /* Success, are there any more? */
                op->devices = op->devices->next;
            }
            /* if no more devices at this fencing level, we are done,
             * else we need to contine with executing the next device in the list */
            if (op->devices == NULL) {
                crm_trace("Marking complex fencing op for %s as complete", op->target);
                op->state = st_done;
                remote_op_done(op, msg, rc, FALSE);
                return rc;
            }
        } else {
            /* This device failed, time to try another topology level. If no other
             * levels are available, mark this operation as failed and report results. */
            if (stonith_topology_next(op) != pcmk_ok) {
                op->state = st_failed;
                remote_op_done(op, msg, rc, FALSE);
                return rc;
            }
        }
    } else if (rc == pcmk_ok && op->devices == NULL) {
        crm_trace("All done for %s", op->target);

        op->state = st_done;
        remote_op_done(op, msg, rc, FALSE);
        return rc;
    }

    /* Retry on failure or execute the rest of the topology */
    crm_trace("Next for %s on behalf of %s@%s (rc was %d)", op->target, op->originator,
              op->client_name, rc);
    call_remote_stonith(op, NULL);
    return rc;
}
Ejemplo n.º 28
0
node_t *
master_color(resource_t * rsc, node_t * prefer, pe_working_set_t * data_set)
{
    int promoted = 0;
    GListPtr gIter = NULL;
    GListPtr gIter2 = NULL;

    GHashTableIter iter;
    node_t *node = NULL;
    node_t *chosen = NULL;
    node_t *cons_node = NULL;
    enum rsc_role_e next_role = RSC_ROLE_UNKNOWN;

    clone_variant_data_t *clone_data = NULL;

    get_clone_variant_data(clone_data, rsc);

    if (is_not_set(rsc->flags, pe_rsc_provisional)) {
        return NULL;

    } else if (is_set(rsc->flags, pe_rsc_allocating)) {
        crm_debug("Dependency loop detected involving %s", rsc->id);
        return NULL;
    }

    apply_master_prefs(rsc);

    clone_color(rsc, prefer, data_set);

    set_bit(rsc->flags, pe_rsc_allocating);

    /* count now tracks the number of masters allocated */
    g_hash_table_iter_init(&iter, rsc->allowed_nodes);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
        node->count = 0;
    }

    /*
     * assign priority
     */
    gIter = rsc->children;
    for (; gIter != NULL; gIter = gIter->next) {
        GListPtr list = NULL;
        resource_t *child_rsc = (resource_t *) gIter->data;

        crm_trace("Assigning priority for %s: %s", child_rsc->id,
                    role2text(child_rsc->next_role));

        if (child_rsc->fns->state(child_rsc, TRUE) == RSC_ROLE_STARTED) {
            set_role_slave(child_rsc, TRUE);
        }

        chosen = child_rsc->fns->location(child_rsc, &list, FALSE);
        if (g_list_length(list) > 1) {
            crm_config_err("Cannot promote non-colocated child %s", child_rsc->id);
        }

        g_list_free(list);
        if (chosen == NULL) {
            continue;
        }

        next_role = child_rsc->fns->state(child_rsc, FALSE);
        switch (next_role) {
            case RSC_ROLE_STARTED:
            case RSC_ROLE_UNKNOWN:
                CRM_CHECK(chosen != NULL, break);
                /*
                 * Default to -1 if no value is set
                 *
                 * This allows master locations to be specified
                 * based solely on rsc_location constraints,
                 * but prevents anyone from being promoted if
                 * neither a constraint nor a master-score is present
                 */
                child_rsc->priority = master_score(child_rsc, chosen, -1);
                break;

            case RSC_ROLE_SLAVE:
            case RSC_ROLE_STOPPED:
                child_rsc->priority = -INFINITY;
                break;
            case RSC_ROLE_MASTER:
                /* We will arrive here if we're re-creating actions after a stonith
                 */
                break;
            default:
                CRM_CHECK(FALSE /* unhandled */ ,
                          crm_err("Unknown resource role: %d for %s", next_role, child_rsc->id));
        }

        apply_master_location(child_rsc->rsc_location);
        apply_master_location(rsc->rsc_location);

        gIter2 = child_rsc->rsc_cons;
        for (; gIter2 != NULL; gIter2 = gIter2->next) {
            rsc_colocation_t *cons = (rsc_colocation_t *) gIter2->data;

            child_rsc->cmds->rsc_colocation_lh(child_rsc, cons->rsc_rh, cons);
        }

        child_rsc->sort_index = child_rsc->priority;
        crm_trace("Assigning priority for %s: %d", child_rsc->id, child_rsc->priority);

        if (next_role == RSC_ROLE_MASTER) {
            child_rsc->sort_index = INFINITY;
        }
    }

    dump_node_scores(LOG_DEBUG_3, rsc, "Pre merge", rsc->allowed_nodes);
    master_promotion_order(rsc, data_set);

    /* mark the first N as masters */

    gIter = rsc->children;
    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child_rsc = (resource_t *) gIter->data;
        char *score = score2char(child_rsc->sort_index);

        chosen = child_rsc->fns->location(child_rsc, NULL, FALSE);
        if (show_scores) {
            fprintf(stdout, "%s promotion score on %s: %s\n",
                    child_rsc->id, chosen ? chosen->details->uname : "none", score);

        } else {
            do_crm_log(scores_log_level, "%s promotion score on %s: %s",
                                child_rsc->id, chosen ? chosen->details->uname : "none", score);
        }
        crm_free(score);

        chosen = NULL;          /* nuke 'chosen' so that we don't promote more than the
                                 * required number of instances
                                 */

        if (child_rsc->sort_index < 0) {
            crm_trace("Not supposed to promote child: %s", child_rsc->id);

        } else if (promoted < clone_data->master_max || is_not_set(rsc->flags, pe_rsc_managed)) {
            chosen = can_be_master(child_rsc);
        }

        crm_debug("%s master score: %d", child_rsc->id, child_rsc->priority);

        if (chosen == NULL) {
            set_role_slave(child_rsc, FALSE);
            continue;
        }

        chosen->count++;
        crm_info("Promoting %s (%s %s)",
                 child_rsc->id, role2text(child_rsc->role), chosen->details->uname);
        set_role_master(child_rsc);
        promoted++;
    }

    clone_data->masters_allocated = promoted;
    crm_info("%s: Promoted %d instances of a possible %d to master",
             rsc->id, promoted, clone_data->master_max);

    clear_bit(rsc->flags, pe_rsc_provisional);
    clear_bit(rsc->flags, pe_rsc_allocating);

    return NULL;
}
Ejemplo n.º 29
0
int
main(int argc, char **argv)
{
    GListPtr lpc = NULL;
    gboolean process = TRUE;
    gboolean all_good = TRUE;
    enum transition_status graph_rc = -1;
    crm_graph_t *transition = NULL;
    ha_time_t *a_date = NULL;
    cib_t *cib_conn = NULL;

    xmlNode *cib_object = NULL;
    int argerr = 0;
    int flag;

    char *msg_buffer = NULL;
    gboolean optional = FALSE;
    pe_working_set_t data_set;

    const char *source = NULL;
    const char *xml_file = NULL;
    const char *dot_file = NULL;
    const char *graph_file = NULL;
    const char *input_file = NULL;
    const char *input_xml = NULL;

    /* disable glib's fancy allocators that can't be free'd */
    GMemVTable vtable;

    vtable.malloc = malloc;
    vtable.realloc = realloc;
    vtable.free = free;
    vtable.calloc = calloc;
    vtable.try_malloc = malloc;
    vtable.try_realloc = realloc;

    g_mem_set_vtable(&vtable);

    crm_log_init_quiet(NULL, LOG_CRIT, FALSE, FALSE, argc, argv);
    crm_set_options(NULL, "[-?Vv] -[Xxp] {other options}", long_options,
                    "Calculate the cluster's response to the supplied cluster state\n"
                    "\nSuperceeded by crm_simulate and likely to be removed in a future release\n\n");

    while (1) {
        int option_index = 0;

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

        switch (flag) {
            case 'S':
                do_simulation = TRUE;
                break;
            case 'a':
                all_actions = TRUE;
                break;
            case 'w':
                inhibit_exit = TRUE;
                break;
            case 'X':
                /*use_stdin = TRUE;*/
                input_xml = optarg;
                break;
            case 's':
                show_scores = TRUE;
                break;
            case 'U':
                show_utilization = TRUE;
                break;
            case 'x':
                xml_file = optarg;
                break;
            case 'd':
                use_date = optarg;
                break;
            case 'D':
                dot_file = optarg;
                break;
            case 'G':
                graph_file = optarg;
                break;
            case 'I':
                input_file = optarg;
                break;
            case 'V':
                crm_bump_log_level();
                break;
            case 'L':
                USE_LIVE_CIB = TRUE;
                break;
            case '$':
            case '?':
                crm_help(flag, 0);
                break;
            default:
                fprintf(stderr, "Option -%c is not yet supported\n", flag);
                ++argerr;
                break;
        }
    }

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

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

    if (argerr) {
        crm_err("%d errors in option parsing", argerr);
        crm_help('?', 1);
    }

    update_all_trace_data();    /* again, so we see which trace points got updated */

    if (USE_LIVE_CIB) {
        int rc = cib_ok;

        source = "live cib";
        cib_conn = cib_new();
        rc = cib_conn->cmds->signon(cib_conn, "ptest", cib_command);

        if (rc == cib_ok) {
            crm_info("Reading XML from: live cluster");
            cib_object = get_cib_copy(cib_conn);

        } else {
            fprintf(stderr, "Live CIB query failed: %s\n", cib_error2string(rc));
            return 3;
        }
        if (cib_object == NULL) {
            fprintf(stderr, "Live CIB query failed: empty result\n");
            return 3;
        }

    } else if (xml_file != NULL) {
        source = xml_file;
        cib_object = filename2xml(xml_file);

    } else if (use_stdin) {
        source = "stdin";
        cib_object = filename2xml(NULL);
    } else if (input_xml) {
        source = "input string";
        cib_object = string2xml(input_xml);
    }

    if (cib_object == NULL && source) {
        fprintf(stderr, "Could not parse configuration input from: %s\n", source);
        return 4;

    } else if (cib_object == NULL) {
        fprintf(stderr, "No configuration specified\n");
        crm_help('?', 1);
    }

    if (get_object_root(XML_CIB_TAG_STATUS, cib_object) == NULL) {
        create_xml_node(cib_object, XML_CIB_TAG_STATUS);
    }

    if (cli_config_update(&cib_object, NULL, FALSE) == FALSE) {
        free_xml(cib_object);
        return cib_STALE;
    }

    if (validate_xml(cib_object, NULL, FALSE) != TRUE) {
        free_xml(cib_object);
        return cib_dtd_validation;
    }

    if (input_file != NULL) {
        FILE *input_strm = fopen(input_file, "w");

        if (input_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", input_file);
        } else {
            msg_buffer = dump_xml_formatted(cib_object);
            if (fprintf(input_strm, "%s\n", msg_buffer) < 0) {
                crm_perror(LOG_ERR, "Write to %s failed", input_file);
            }
            fflush(input_strm);
            fclose(input_strm);
            crm_free(msg_buffer);
        }
    }

    if (use_date != NULL) {
        a_date = parse_date(&use_date);
        log_date(LOG_WARNING, "Set fake 'now' to", a_date, ha_log_date | ha_log_time);
        log_date(LOG_WARNING, "Set fake 'now' to (localtime)",
                 a_date, ha_log_date | ha_log_time | ha_log_local);
    }

    set_working_set_defaults(&data_set);
    if (process) {
        if (show_scores && show_utilization) {
            fprintf(stdout, "Allocation scores and utilization information:\n");
        } else if (show_scores) {
            fprintf(stdout, "Allocation scores:\n");
        } else if (show_utilization) {
            fprintf(stdout, "Utilization information:\n");
        }
        do_calculations(&data_set, cib_object, a_date);
    }

    msg_buffer = dump_xml_formatted(data_set.graph);
    if (safe_str_eq(graph_file, "-")) {
        fprintf(stdout, "%s\n", msg_buffer);
        fflush(stdout);
    } else if (graph_file != NULL) {
        FILE *graph_strm = fopen(graph_file, "w");

        if (graph_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", graph_file);
        } else {
            if (fprintf(graph_strm, "%s\n\n", msg_buffer) < 0) {
                crm_perror(LOG_ERR, "Write to %s failed", graph_file);
            }
            fflush(graph_strm);
            fclose(graph_strm);
        }
    }
    crm_free(msg_buffer);

    if (dot_file != NULL) {
        dot_strm = fopen(dot_file, "w");
        if (dot_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", dot_file);
        }
    }

    if (dot_strm == NULL) {
        goto simulate;
    }

    init_dotfile();
    for (lpc = data_set.actions; lpc != NULL; lpc = lpc->next) {
        action_t *action = (action_t *) lpc->data;
        const char *style = "filled";
        const char *font = "black";
        const char *color = "black";
        const char *fill = NULL;
        char *action_name = create_action_name(action);

        crm_trace("Action %d: %p", action->id, action);

        if (is_set(action->flags, pe_action_pseudo)) {
            font = "orange";
        }

        style = "dashed";
        if (is_set(action->flags, pe_action_dumped)) {
            style = "bold";
            color = "green";

        } else if (action->rsc != NULL && is_not_set(action->rsc->flags, pe_rsc_managed)) {
            color = "purple";
            if (all_actions == FALSE) {
                goto dont_write;
            }

        } else if (is_set(action->flags, pe_action_optional)) {
            color = "blue";
            if (all_actions == FALSE) {
                goto dont_write;
            }

        } else {
            color = "red";
            CRM_CHECK(is_set(action->flags, pe_action_runnable) == FALSE,;
                );
        }

        set_bit_inplace(action->flags, pe_action_dumped);
        dot_write("\"%s\" [ style=%s color=\"%s\" fontcolor=\"%s\"  %s%s]",
                  action_name, style, color, font, fill ? "fillcolor=" : "", fill ? fill : "");
  dont_write:
        crm_free(action_name);
    }
Ejemplo n.º 30
0
void
dump_node_scores_worker(int level, const char *file, const char *function, int line,
                        resource_t * rsc, const char *comment, GHashTable * nodes)
{
    GHashTable *hash = nodes;
    GHashTableIter iter;
    node_t *node = NULL;

    if (rsc) {
        hash = rsc->allowed_nodes;
    }

    if (rsc && is_set(rsc->flags, pe_rsc_orphan)) {
        /* Don't show the allocation scores for orphans */
        return;
    }

    if (level == 0) {
        /* For now we want this in sorted order to keep the regression tests happy */
        GListPtr gIter = NULL;
        GListPtr list = g_hash_table_get_values(hash);

        list = g_list_sort(list, sort_node_uname);

        gIter = list;
        for (; gIter != NULL; gIter = gIter->next) {
            node_t *node = (node_t *) gIter->data;
            char *score = score2char(node->weight);

            if (rsc) {
                printf("%s: %s allocation score on %s: %s\n",
                       comment, rsc->id, node->details->uname, score);
            } else {
                printf("%s: %s = %s\n", comment, node->details->uname, score);
            }
            free(score);
        }

        g_list_free(list);

    } else if (hash) {
        g_hash_table_iter_init(&iter, hash);
        while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
            char *score = score2char(node->weight);

            if (rsc) {
                do_crm_log_alias(LOG_TRACE, file, function, line,
                                 "%s: %s allocation score on %s: %s", comment, rsc->id,
                                 node->details->uname, score);
            } else {
                do_crm_log_alias(LOG_TRACE, file, function, line + 1, "%s: %s = %s", comment,
                                 node->details->uname, score);
            }
            free(score);
        }
    }

    if (rsc && rsc->children) {
        GListPtr gIter = NULL;

        gIter = rsc->children;
        for (; gIter != NULL; gIter = gIter->next) {
            resource_t *child = (resource_t *) gIter->data;

            dump_node_scores_worker(level, file, function, line, child, comment, nodes);
        }
    }
}