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; }
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; }
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); } }
bool can_unobstrusively_enable_extension(const wiimote& mote) { return !is_set(mote.enabled_capabilities, wiimote_capabilities::MotionPlus); }
void erase() { if (is_set()) { // IS IT NEEDED ?? neighbour()->erase_simple(this); this->erase_simple(); } }
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"); } }
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; }
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; }
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); } }
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; }
/* 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; }
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; }
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); } }
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; }
/* 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; } } }
//将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(); }
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; }
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; } } }
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; }
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; }
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 ); }
bool passthrough_mode(wiimote &mote) { return is_set(mote.enabled_capabilities, wiimote_capabilities::Extension | wiimote_capabilities::MotionPlus); }
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 ); }
/* 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); } }
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; }
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; }
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; }
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); }
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); } } }