Esempio n. 1
0
static int
get_config_opt(cmap_handle_t object_handle, const char *key, char **value, const char *fallback)
{
    int rc = 0, retries = 0;

    cs_repeat(retries, 5, rc = cmap_get_string(object_handle, key, value));
    if(rc != CS_OK) {
        crm_trace("Search for %s failed %d, defaulting to %s", key, rc, fallback);
        if(fallback) {
            *value = crm_strdup(fallback);
        } else {
            *value = NULL;
        }
    }
    crm_trace("%s: %s", key, *value);
    return rc;
}
Esempio n. 2
0
static void
join_make_offer(gpointer key, gpointer value, gpointer user_data)
{
    const char *join_to = NULL;
    const crm_node_t *member = value;

    CRM_ASSERT(member != NULL);
    if (crm_is_peer_active(member) == FALSE) {
        crm_trace("Not making an offer to %s: not active", member->uname);
        return;
    }

    join_to = member->uname;
    if (join_to == NULL) {
        crm_err("No recipient for welcome message");
        return;
    }

    erase_node_from_join(join_to);

    if (saved_ccm_membership_id != crm_peer_seq) {
        saved_ccm_membership_id = crm_peer_seq;
        crm_info("Making join offers based on membership %llu", crm_peer_seq);
    }

    if (crm_is_peer_active(member)) {
        xmlNode *offer = create_request(CRM_OP_JOIN_OFFER, NULL, join_to,
                                        CRM_SYSTEM_CRMD, CRM_SYSTEM_DC, NULL);
        char *join_offered = crm_itoa(current_join_id);

        crm_xml_add_int(offer, F_CRM_JOIN_ID, current_join_id);
        /* send the welcome */
        crm_debug("join-%d: Sending offer to %s", current_join_id, join_to);

        send_cluster_message(join_to, crm_msg_crmd, offer, TRUE);
        free_xml(offer);

        g_hash_table_insert(welcomed_nodes, crm_strdup(join_to), join_offered);
    } else {
        crm_info("Peer process on %s is not active (yet?): %.8lx %d",
                 join_to, (long)member->processes, g_hash_table_size(crm_peer_cache));
    }

}
Esempio n. 3
0
char *
generate_hash_value(const char *src_node, const char *src_subsys)
{
	char *hash_value = NULL;
	
	if (src_node == NULL || src_subsys == NULL) {
		return NULL;
	}
    
	if (strcasecmp(CRM_SYSTEM_DC, src_subsys) == 0) {
		hash_value = crm_strdup(src_subsys);
		CRM_ASSERT(hash_value);
		return hash_value;
	}

	hash_value = crm_concat(src_node, src_subsys, '_');
	crm_info("created hash value: (%s)", hash_value);
	return hash_value;
}
Esempio n. 4
0
crm_node_t *crm_get_peer(unsigned int id, const char *uname)
{
    crm_node_t *node = NULL;
    if(uname != NULL) {
	node = g_hash_table_lookup(crm_peer_cache, uname);
    }
    
    if(node == NULL && id > 0) {
	node = g_hash_table_lookup(crm_peer_id_cache, GUINT_TO_POINTER(id));
	if(node && node->uname && uname) {
	    crm_crit("Node %s and %s share the same cluster node id '%u'!",
		     node->uname, uname, id);
	    
	    /* NOTE: Calling crm_new_peer() means the entry in 
	     * crm_peer_id_cache will point to the new entity
	     */

	    /* TODO: Replace the old uname instead? */
	    node = crm_new_peer(id, uname);
	    CRM_ASSERT(node->uname != NULL);
	}
    }

    if(node && uname && node->uname == NULL) {
	node->uname = crm_strdup(uname);
	crm_info("Node %u is now known as %s", id, uname);	
	g_hash_table_insert(crm_peer_cache, node->uname, node);
	if(crm_status_callback) {
	    crm_status_callback(crm_status_uname, node, NULL);
	}
	
    }

    if(node && id > 0 && id != node->id) {
	g_hash_table_remove(crm_peer_id_cache, GUINT_TO_POINTER(node->id));
	g_hash_table_insert(crm_peer_id_cache, GUINT_TO_POINTER(id), node);
	node->id = id;
	crm_info("Node %s now has id: %u", crm_str(uname), id);	
    }
    
    return node;
}
Esempio n. 5
0
static gboolean stonith_device_execute(stonith_device_t *device)
{
    int rc = 0;
    int exec_rc = 0;
    async_command_t *cmd = NULL;
    CRM_CHECK(device != NULL, return FALSE);

    if(device->active_pid) {	
	crm_trace("%s is still active with pid %u", device->id, device->active_pid);
	return TRUE;
    }
    
    if(device->pending_ops) {
	GList *first = device->pending_ops;
	device->pending_ops = g_list_remove_link(device->pending_ops, first);
	cmd = first->data;
	g_list_free_1(first);
    }

    if(cmd == NULL) {
	crm_trace("Nothing further to do for %s", device->id);
	return TRUE;
    }
    
    cmd->device = crm_strdup(device->id);
    exec_rc = run_stonith_agent(device->agent, cmd->action, cmd->victim,
				device->params, device->aliases, &rc, NULL, cmd);

    if(exec_rc > 0) {
	crm_debug("Operation %s%s%s on %s is active with pid: %d",
		  cmd->action, cmd->victim?" for node ":"", cmd->victim?cmd->victim:"",
		  device->id, exec_rc);
	device->active_pid = exec_rc;
	
    } else {
	crm_warn("Operation %s%s%s on %s failed (%d/%d)",
		 cmd->action, cmd->victim?" for node ":"", cmd->victim?cmd->victim:"",
		 device->id, exec_rc, rc);
	st_child_done(0, rc<0?rc:exec_rc, cmd);
    }
    return TRUE;
}
Esempio n. 6
0
xmlNode *
create_request_adv(const char *task, xmlNode *msg_data,
		   const char *host_to,  const char *sys_to,
		   const char *sys_from, const char *uuid_from,
		   const char *origin)
{
	char *true_from = NULL;
	xmlNode *request = NULL;
	char *reference = generateReference(task, sys_from);

	if (uuid_from != NULL) {
		true_from = generate_hash_key(sys_from, uuid_from);
	} else if(sys_from != NULL) {
		true_from = crm_strdup(sys_from);
	} else {
		crm_err("No sys from specified");
	}
	
	/* host_from will get set for us if necessary by CRMd when routed */
	request = create_xml_node(NULL, __FUNCTION__);
	crm_xml_add(request, F_CRM_ORIGIN,	origin);
	crm_xml_add(request, F_TYPE,		T_CRM);
	crm_xml_add(request, F_CRM_VERSION,	CRM_FEATURE_SET);
	crm_xml_add(request, F_CRM_MSG_TYPE,     XML_ATTR_REQUEST);
	crm_xml_add(request, XML_ATTR_REFERENCE, reference);
	crm_xml_add(request, F_CRM_TASK,		task);
	crm_xml_add(request, F_CRM_SYS_TO,       sys_to);
	crm_xml_add(request, F_CRM_SYS_FROM,     true_from);

	/* HOSTTO will be ignored if it is to the DC anyway. */
	if(host_to != NULL && strlen(host_to) > 0) {
		crm_xml_add(request, F_CRM_HOST_TO,  host_to);
	}

	if (msg_data != NULL) {
		add_message_xml(request, F_CRM_DATA, msg_data);
	}
	crm_free(reference);
	crm_free(true_from);
	
	return request;
}
Esempio n. 7
0
void
send_stonith_update(crm_action_t * action, const char *target, const char *uuid)
{
    enum cib_errors rc = cib_ok;

    /* zero out the node-status & remove all LRM status info */
    xmlNode *node_state = create_xml_node(NULL, XML_CIB_TAG_STATE);

    CRM_CHECK(target != NULL, return);
    CRM_CHECK(uuid != NULL, return);

    crm_xml_add(node_state, XML_ATTR_UUID, uuid);
    crm_xml_add(node_state, XML_ATTR_UNAME, target);
    crm_xml_add(node_state, XML_CIB_ATTR_HASTATE, DEADSTATUS);
    crm_xml_add(node_state, XML_CIB_ATTR_INCCM, XML_BOOLEAN_NO);
    crm_xml_add(node_state, XML_CIB_ATTR_CRMDSTATE, OFFLINESTATUS);
    crm_xml_add(node_state, XML_CIB_ATTR_JOINSTATE, CRMD_JOINSTATE_DOWN);
    crm_xml_add(node_state, XML_CIB_ATTR_EXPSTATE, CRMD_JOINSTATE_DOWN);
    crm_xml_add(node_state, XML_ATTR_ORIGIN, __FUNCTION__);

    rc = fsa_cib_conn->cmds->update(fsa_cib_conn, XML_CIB_TAG_STATUS, node_state,
                                    cib_quorum_override | cib_scope_local | cib_can_create);

    /* Delay processing the trigger until the update completes */
    crm_info("Sending fencing update %d for %s", rc, target);
    add_cib_op_callback(fsa_cib_conn, rc, FALSE, crm_strdup(target), cib_fencing_updated);

    /* Make sure it sticks */
    /* fsa_cib_conn->cmds->bump_epoch(fsa_cib_conn, cib_quorum_override|cib_scope_local);    */

    erase_status_tag(target, XML_CIB_TAG_LRM, cib_scope_local);
    erase_status_tag(target, XML_TAG_TRANSIENT_NODEATTRS, cib_scope_local);

    free_xml(node_state);

    /* Make sure the membership cache is accurate */
    crm_update_peer(0, 0, 0, -1, crm_proc_none, uuid, target, NULL, CRM_NODE_LOST);

    return;
}
Esempio n. 8
0
unsigned long long
crm_get_interval(const char * input)
{
    ha_time_t *interval = NULL;
    char *input_copy = crm_strdup(input);
    char *input_copy_mutable = input_copy;
    unsigned long long msec = 0;
    
    if(input == NULL) {
	return 0;

    } else if(input[0] != 'P') {
	crm_free(input_copy);
	return crm_get_msec(input);
    }
    
    interval = parse_time_duration(&input_copy_mutable);
    msec = date_in_seconds(interval);
    free_ha_date(interval);
    crm_free(input_copy);
    return msec * 1000;
}
Esempio n. 9
0
char *
generate_hash_value(const char *src_node, const char *src_subsys)
{
	char *hash_value = NULL;
	
	if (src_node == NULL || src_subsys == NULL) {
		return NULL;
	}
    
	if (strcasecmp(CRM_SYSTEM_DC, src_subsys) == 0) {
		hash_value = crm_strdup(src_subsys);
		if (!hash_value) {
			crm_err("memory allocation failed in "
			       "generate_hash_value()");
		}
		return hash_value;
	}

	hash_value = crm_concat(src_node, src_subsys, '_');
	crm_info("created hash value: (%s)", hash_value);
	return hash_value;
}
Esempio n. 10
0
gboolean
shutdown_constraints(node_t * node, action_t * shutdown_op, pe_working_set_t * data_set)
{
    /* add the stop to the before lists so it counts as a pre-req
     * for the shutdown
     */
    GListPtr lpc = NULL;

    for (lpc = data_set->actions; lpc != NULL; lpc = lpc->next) {
        action_t *action = (action_t *) lpc->data;

        if (action->rsc == NULL || action->node == NULL) {
            continue;
        } else if(action->node->details != node->details) {
            continue;
        } else if(is_set(data_set->flags, pe_flag_maintenance_mode)) {
            crm_trace("Skipping %s: maintainence mode", action->uuid);
            continue;
        } else if(safe_str_neq(action->task, RSC_STOP)) {
            continue;
        } else if(is_not_set(action->rsc->flags, pe_rsc_managed)
                  && is_not_set(action->rsc->flags, pe_rsc_block)) {
            /*
             * If another action depends on this one, we may still end up blocking
             */
            crm_trace("Skipping %s: unmanaged", action->uuid);
            continue;
        }

        crm_trace("Ordering %s before shutdown on %s", action->uuid, node->details->uname);
        clear_bit_inplace(action->flags, pe_action_optional);
        custom_action_order(action->rsc, NULL, action,
                            NULL, crm_strdup(CRM_OP_SHUTDOWN), shutdown_op,
                            pe_order_optional|pe_order_runnable_left, data_set);
    }

    return TRUE;
}
Esempio n. 11
0
const char *
cluster_option(GHashTable* options, gboolean(*validate)(const char*),
	       const char *name, const char *old_name, const char *def_value)
{
	const char *value = NULL;
	CRM_ASSERT(name != NULL);

	if(options != NULL) {
		value = g_hash_table_lookup(options, name);
	}

	if(value == NULL && old_name && options != NULL) {
		value = g_hash_table_lookup(options, old_name);
		if(value != NULL) {
			crm_config_warn("Using deprecated name '%s' for"
				       " cluster option '%s'", old_name, name);
			g_hash_table_insert(
				options, crm_strdup(name), crm_strdup(value));
			value = g_hash_table_lookup(options, old_name);
		}
	}

	if(value == NULL) {
		crm_debug("Using default value '%s' for cluster option '%s'",
			  def_value, name);

		if(options == NULL) {
			return def_value;
		}
		
		g_hash_table_insert(
			options, crm_strdup(name), crm_strdup(def_value));
		value = g_hash_table_lookup(options, name);
	}
	
	if(validate && validate(value) == FALSE) {
		crm_config_err("Value '%s' for cluster option '%s' is invalid."
			      "  Defaulting to %s", value, name, def_value);
		g_hash_table_replace(options, crm_strdup(name),
				     crm_strdup(def_value));
		value = g_hash_table_lookup(options, name);
	}
	
	return value;
}
Esempio n. 12
0
mainloop_io_t *
mainloop_add_fd(
    const char *name, int fd, void *userdata, struct mainloop_fd_callbacks *callbacks) 
{
    mainloop_io_t *client = NULL;
    if(fd > 0) {
        crm_malloc0(client, sizeof(mainloop_io_t));          
        client->name = crm_strdup(name);
        client->userdata = userdata;

        if(callbacks) {
            client->destroy_fn = callbacks->destroy;
            client->dispatch_fn_io = callbacks->dispatch;
        }

        client->channel = g_io_channel_unix_new(fd);
        client->source = g_io_add_watch_full(
            client->channel, G_PRIORITY_DEFAULT, (G_IO_IN|G_IO_HUP|G_IO_NVAL|G_IO_ERR),
            mainloop_gio_callback, client, mainloop_gio_destroy);
        crm_trace("Added connection %d for %s[%p].%d", client->source, client->name, client, fd);
    }

    return client;
}
Esempio n. 13
0
char *
get_corosync_uuid(uint32_t id, const char *uname) 
{
    if(!uname_is_uuid() && is_corosync_cluster()) {
        if(id <= 0) {
            /* Try the membership cache... */
            crm_node_t *node = g_hash_table_lookup(crm_peer_cache, uname);
            if(node != NULL) {
                id = node->id;
            }
        }

        if(id > 0) {
            return crm_itoa(id);
        } else {
            crm_warn("Node %s is not yet known by corosync", uname);
        }

    } else if(uname != NULL) {
        return crm_strdup(uname);
    }

    return NULL;
}
Esempio n. 14
0
static attr_hash_entry_t *
find_hash_entry(xmlNode * msg)
{
    const char *value = NULL;
    const char *attr = crm_element_value(msg, F_ATTRD_ATTRIBUTE);
    attr_hash_entry_t *hash_entry = NULL;

    if (attr == NULL) {
        crm_info("Ignoring message with no attribute name");
        return NULL;
    }

    hash_entry = g_hash_table_lookup(attr_hash, attr);

    if (hash_entry == NULL) {
        /* create one and add it */
        crm_info("Creating hash entry for %s", attr);
        crm_malloc0(hash_entry, sizeof(attr_hash_entry_t));
        hash_entry->id = crm_strdup(attr);

        g_hash_table_insert(attr_hash, hash_entry->id, hash_entry);
        hash_entry = g_hash_table_lookup(attr_hash, attr);
        CRM_CHECK(hash_entry != NULL, return NULL);
    }
Esempio n. 15
0
static gboolean
check_action_definition(resource_t *rsc, node_t *active_node, crm_data_t *xml_op,
			pe_working_set_t *data_set)
{
	char *key = NULL;
	int interval = 0;
	const char *interval_s = NULL;
	
	gboolean did_change = FALSE;
	gboolean start_op = FALSE;

	crm_data_t *params_all = NULL;
	crm_data_t *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);

	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) {
		crm_data_t *op_match = NULL;

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

		if(op_match == NULL && data_set->stop_action_orphans) {
			/* create a cancel action */
			action_t *cancel = NULL;
			char *cancel_key = NULL;
			const char *call_id = crm_element_value(xml_op, XML_LRM_ATTR_CALLID);
			
			crm_info("Orphan action will be stopped: %s on %s",
				 key, active_node->details->uname);

			cancel_key = generate_op_key(
				rsc->id, CRMD_ACTION_CANCEL, interval);

			cancel = custom_action(
				rsc, cancel_key, CRMD_ACTION_CANCEL,
				active_node, FALSE, TRUE, data_set);

			add_hash_param(cancel->meta, XML_LRM_ATTR_TASK,     task);
			add_hash_param(cancel->meta, XML_LRM_ATTR_CALLID,   call_id);
			add_hash_param(cancel->meta, XML_LRM_ATTR_INTERVAL, interval_s);

			custom_action_order(	
				rsc, stop_key(rsc), NULL,
				rsc, NULL, cancel,
				pe_order_optional, data_set);
			crm_free(key); key = NULL;
			return TRUE;

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

	action = custom_action(rsc, key, task, active_node, TRUE, FALSE, data_set);
	
	local_rsc_params = g_hash_table_new_full(
		g_str_hash, g_str_equal,
		g_hash_destroy_str, g_hash_destroy_str);
	
	unpack_instance_attributes(
		rsc->xml, XML_TAG_ATTR_SETS, active_node->details->attrs,
		local_rsc_params, NULL, data_set->now);
	
	params_all = create_xml_node(NULL, XML_TAG_PARAMS);
	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);
	g_hash_table_foreach(local_rsc_params, hash2field, 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(crm_str_eq(task, CRMD_ACTION_START, TRUE)) {
		start_op = TRUE;
	}
	
	if(start_op && digest_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;
			crm_log_xml_info(params_restart, "params:restart");
			crm_warn("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));
			
			key = generate_op_key(rsc->id, task, interval);
			custom_action(rsc, key, task, NULL, FALSE, TRUE, data_set);
			goto cleanup;
		}
	}

	if(safe_str_neq(digest_all_calc, digest_all)) {
		action_t *op = NULL;
		did_change = TRUE;
		crm_log_xml_info(params_all, "params:all");
 		crm_warn("Parameters to %s on %s changed: recorded %s vs. %s (all:%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));
		
		key = generate_op_key(rsc->id, task, interval);
		op = custom_action(rsc, key, task, NULL, FALSE, TRUE, data_set);
		if(start_op && digest_restart) {
			op->allow_reload_conversion = TRUE;

		} else if(interval > 0) {
			custom_action_order(rsc, start_key(rsc), NULL,
					    NULL, crm_strdup(op->task), op,
					    pe_order_runnable_left, 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;
}
/* 
	JOIN状態チェック処理
*/
gboolean
check_join_state(enum crmd_fsa_state cur_state, const char *source)
{
	crm_debug("Invoked by %s in state: %s",
		  source, fsa_state2string(cur_state));

	if(saved_ccm_membership_id != crm_peer_seq) {
		crm_info("%s: Membership changed since join started: %llu -> %llu",
			 source, saved_ccm_membership_id,
			 crm_peer_seq);
		register_fsa_input_before(C_FSA_INTERNAL, I_NODE_JOIN, NULL);
		
	} else if(cur_state == S_INTEGRATION) {
		/* 現在のstateがS_INTEGRATIONの時 */
		if(g_hash_table_size(welcomed_nodes) == 0) {
			/* welcomed_nodesハッシュテーブルのサイズが0(すべての認識済みのノードからCRM_OP_JOIN_REQUESTを受信した)の場合 */
			crm_debug("join-%d: Integration of %d peers complete: %s",
				  current_join_id,
				  g_hash_table_size(integrated_nodes), source);
			/* I_INTEGRATEDへ */
			register_fsa_input_before(
				C_FSA_INTERNAL, I_INTEGRATED, NULL);
			return TRUE;
		}

	} else if(cur_state == S_FINALIZE_JOIN) {
		/* 現在のstateがS_FINALIZE_JOINの時 */
		if(is_set(fsa_input_register, R_HAVE_CIB) == FALSE) {
			crm_debug("join-%d: Delaying I_FINALIZED until we have the CIB",
				  current_join_id);
			return TRUE;
			
		} else if(g_hash_table_size(integrated_nodes) == 0
			  && g_hash_table_size(finalized_nodes) == 0) {
			crm_debug("join-%d complete: %s",
				  current_join_id, source);
			/* I_FINALIZEDへ */
			register_fsa_input_later(C_FSA_INTERNAL, I_FINALIZED, NULL);
			
		} else if(g_hash_table_size(integrated_nodes) != 0
			  && g_hash_table_size(finalized_nodes) != 0) {
			char *msg = NULL;
			crm_err("join-%d: Waiting on %d integrated nodes"
				" AND %d finalized nodes",
				current_join_id,
				g_hash_table_size(integrated_nodes),
				g_hash_table_size(finalized_nodes));
			msg = crm_strdup("Integrated node");
			g_hash_table_foreach(integrated_nodes, ghash_print_node, msg);
			crm_free(msg);
			
			msg = crm_strdup("Finalized node");
			g_hash_table_foreach(finalized_nodes, ghash_print_node, msg);
			crm_free(msg);

		} else if(g_hash_table_size(integrated_nodes) != 0) {
			crm_debug("join-%d: Still waiting on %d integrated nodes",
				  current_join_id,
				  g_hash_table_size(integrated_nodes));
			
		} else if(g_hash_table_size(finalized_nodes) != 0) {
			crm_debug("join-%d: Still waiting on %d finalized nodes",
				  current_join_id,
				  g_hash_table_size(finalized_nodes));
		}
	}
	
	return FALSE;
}
/*
	ノードをCIBのnodeエントリに追加して、CRM_OP_JOIN_ACKNAKメッセージを送信する
	また、クラスタメンバーとして認識したノードは、finalized_nodesハッシュテーブルに追加する
*/
gboolean
finalize_join_for(gpointer key, gpointer value, gpointer user_data)
{
	const char *join_to = NULL;
	const char *join_state = NULL;
	xmlNode *acknak = NULL;
	crm_node_t *join_node = NULL;
	
	if(key == NULL || value == NULL) {
		return TRUE;
	}

	join_to    = (const char *)key;
	join_state = (const char *)value;

	/* make sure the node exists in the config section */
	/* CIBに対象ノードのnodeエントリを生成する */
	create_node_entry(join_to, join_to, NORMALNODE);

	join_node = crm_get_peer(0, join_to);
	if(crm_is_member_active(join_node) == FALSE) {
	    /*
	     * NACK'ing nodes that the membership layer doesn't know about yet
	     * simply creates more churn
	     *
	     * Better to leave them waiting and let the join restart when
	     * the new membership event comes in
	     *
	     * All other NACKs (due to versions etc) should still be processed
	     */
	    return TRUE;
	}
	
	/* send the ack/nack to the node */
	/* CRM_OP_JOIN_ACKNAKメッセージを生成する */
	acknak = create_request(
		CRM_OP_JOIN_ACKNAK, NULL, join_to,
		CRM_SYSTEM_CRMD, CRM_SYSTEM_DC, NULL);
	crm_xml_add_int(acknak, F_CRM_JOIN_ID, current_join_id);
	
	/* set the ack/nack */
	if(safe_str_eq(join_state, CRMD_JOINSTATE_MEMBER)) {
		/* 対象ノードの状態がCRMD_JOINSTATE_MEMBERの場合は、CRM_OP_JOIN_ACKNAKにXML_BOOLEAN_TRUEをセットする */
		crm_debug("join-%d: ACK'ing join request from %s, state %s",
			  current_join_id, join_to, join_state);
		crm_xml_add(acknak, CRM_OP_JOIN_ACKNAK, XML_BOOLEAN_TRUE);
		/* finalized_nodesハッシュテーブルにXML_BOOLEAN_TRUEを送信するノードをセットする */
		g_hash_table_insert(
			finalized_nodes,
			crm_strdup(join_to), crm_strdup(CRMD_JOINSTATE_MEMBER));
	} else {
		/* その他の状態の場合は、CRM_OP_JOIN_ACKNAKにXML_BOOLEAN_FALSEをセットする */
		crm_warn("join-%d: NACK'ing join request from %s, state %s",
			 current_join_id, join_to, join_state);
		
		crm_xml_add(acknak, CRM_OP_JOIN_ACKNAK, XML_BOOLEAN_FALSE);
	}
	/* セットしたCRM_OP_JOIN_ACKNAKメッセージを送信する */
	send_cluster_message(join_to, crm_msg_crmd, acknak, TRUE);
	/* 生成したメッセージを破棄する */
	free_xml(acknak);
	return TRUE;
}
/*
	CRM_OP_JOIN_ACKNACKを送信後、ノードからCRM_OP_JOIN_CONFIRMメッセージが送られて来たときの処理
*/
void
do_dc_join_ack(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 join_id = -1;
	int call_id = 0;
	ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg);

	const char *join_id_s  = NULL;
	const char *join_state = NULL;
	const char *op         = crm_element_value(join_ack->msg, F_CRM_TASK);
	const char *join_from  = crm_element_value(join_ack->msg, F_CRM_HOST_FROM);

	if(safe_str_neq(op, CRM_OP_JOIN_CONFIRM)) {
		/* CRM_OP_JOIN_CONFIRMメッセージ以外のメッセージは無視してログを出力 */
		crm_debug("Ignoring op=%s message from %s", op, join_from);
		return;
	} 

	crm_element_value_int(join_ack->msg, F_CRM_JOIN_ID, &join_id);
	join_id_s = crm_element_value(join_ack->msg, F_CRM_JOIN_ID);

	/* now update them to "member" */
	
	crm_debug_2("Processing ack from %s", join_from);

	/* CRM_OP_JOIN_CONFIRMを送ってきたノードがfinalized_nodesハッシュテーブルに含まれるかサーチする */
	join_state = (const char *)
		g_hash_table_lookup(finalized_nodes, join_from);
	
	if(join_state == NULL) {
		/* 含まれていない場合は、無視 */
		crm_err("Join not in progress: ignoring join-%d from %s",
			join_id, join_from);
		return;
		
	} else if(safe_str_neq(join_state, CRMD_JOINSTATE_MEMBER)) {
		crm_err("Node %s wasnt invited to join the cluster",join_from);
		/* 含まれていて、CRMD_JOINSTATE_MEMBER状態の場合は、finalized_nodesハッシュテーブルからCRM_OP_JOIN_CONFIRMを送ってきたノードを削除 */
		g_hash_table_remove(finalized_nodes, join_from);
		return;
		
	} else if(join_id != current_join_id) {
		crm_err("Invalid response from %s: join-%d vs. join-%d",
			join_from, join_id, current_join_id);
		/* JOIN_IDが異なる場合も、finalized_nodesハッシュテーブルからCRM_OP_JOIN_CONFIRMを送ってきたノードを削除 */
		g_hash_table_remove(finalized_nodes, join_from);
		return;
	}
	
	/* 上記以外の場合も、finalized_nodesハッシュテーブルからCRM_OP_JOIN_CONFIRMを送ってきたノードを削除 */
	g_hash_table_remove(finalized_nodes, join_from);
	
	/* confirmed_nodesハッシュテーブルにRM_OP_JOIN_CONFIRMを送ってきたノードでサーチ */
	if(g_hash_table_lookup(confirmed_nodes, join_from) != NULL) {
		/* 既に登録済みの場合は、エラーメッセージを表示 */
		crm_err("join-%d: hash already contains confirmation from %s",
			join_id, join_from);
	}

	/* confirmed_nodesハッシュテーブルにCRM_OP_JOIN_CONFIRMを送ってきたノードを追加 */
	g_hash_table_insert(
		confirmed_nodes, crm_strdup(join_from), crm_strdup(join_id_s));

	/* join完了ログを出す */
 	crm_info("join-%d: Updating node state to %s for %s",
 		 join_id, CRMD_JOINSTATE_MEMBER, join_from);

	/* update CIB with the current LRM status from the node
	 * We dont need to notify the TE of these updates, a transition will
	 *   be started in due time
	 */
	/* CIBからCRM_OP_JOIN_CONFIRMを送ってきたノードのXML_CIB_TAG_LRM情報を消去 */
	erase_status_tag(join_from, XML_CIB_TAG_LRM, cib_scope_local);
	/* CIBを更新 */
	/* CRM_OP_JOIN_CONFIRMを送ってきたノードのXML_CIB_TAG_LRM情報も追加される */
	/* クラスタ構成ノードのLRMD情報が最新で更新 */
	fsa_cib_update(XML_CIB_TAG_STATUS, join_ack->xml,
		       cib_scope_local|cib_quorum_override|cib_can_create, call_id);
	/* CIBの更新コールバックをセット */
	add_cib_op_callback(
		fsa_cib_conn, call_id, FALSE, NULL, join_update_complete_callback);
 	crm_debug("join-%d: Registered callback for LRM update %d",
		  join_id, call_id);
}
/*
	A_DC_JOIN_PROCESS_REQアクション処理(CRM_OP_JOIN_REQUESTをDCノードが受信した時の処理)
*/
void
do_dc_join_filter_offer(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)
{
	xmlNode *generation = NULL;

	int cmp = 0;
	int join_id = -1;
	gboolean ack_nack_bool = TRUE;
	const char *ack_nack = CRMD_JOINSTATE_MEMBER;
	ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg);

	const char *join_from = crm_element_value(join_ack->msg, F_CRM_HOST_FROM);
	const char *ref       = crm_element_value(join_ack->msg, XML_ATTR_REFERENCE);
	
	crm_node_t *join_node = crm_get_peer(0, join_from);

	crm_debug("Processing req from %s", join_from);
	
	generation = join_ack->xml;
	crm_element_value_int(join_ack->msg, F_CRM_JOIN_ID, &join_id);

	if(max_generation_xml != NULL && generation != NULL) {
	    int lpc = 0;
	    const char *attributes[] = {
		XML_ATTR_GENERATION_ADMIN,
		XML_ATTR_GENERATION,
		XML_ATTR_NUMUPDATES,
	    };
	    
	    for(lpc = 0; cmp == 0 && lpc < DIMOF(attributes); lpc++) {
			cmp = compare_int_fields(max_generation_xml, generation, attributes[lpc]);
	    }
	}
	
	if(join_id != current_join_id) {
		crm_debug("Invalid response from %s: join-%d vs. join-%d",
			  join_from, join_id, current_join_id);
		/* JOIN状態チェックを行う */
		check_join_state(cur_state, __FUNCTION__);
		return;
		
	} else if(join_node == NULL || crm_is_member_active(join_node) == FALSE) {
		crm_err("Node %s is not a member", join_from);
		ack_nack_bool = FALSE;
		
	} else if(generation == NULL) {
		crm_err("Generation was NULL");
		ack_nack_bool = FALSE;

	} else if(max_generation_xml == NULL) {
		max_generation_xml = copy_xml(generation);
		max_generation_from = crm_strdup(join_from);

	} else if(cmp < 0
		  || (cmp == 0 && safe_str_eq(join_from, fsa_our_uname))) {
		crm_debug("%s has a better generation number than"
			  " the current max %s",
			  join_from, max_generation_from);
		if(max_generation_xml) {
			crm_log_xml_debug(max_generation_xml, "Max generation");
		}
		crm_log_xml_debug(generation, "Their generation");
		
		crm_free(max_generation_from);
		free_xml(max_generation_xml);
		
		max_generation_from = crm_strdup(join_from);
		max_generation_xml = copy_xml(join_ack->xml);
	}
	
	if(ack_nack_bool == FALSE) {
		/* NACK this client */
		ack_nack = CRMD_JOINSTATE_NACK;
		crm_err("join-%d: NACK'ing node %s (ref %s)",
			join_id, join_from, ref);
	} else {
		crm_debug("join-%d: Welcoming node %s (ref %s)",
			  join_id, join_from, ref);
	}
	
	/* add them to our list of CRMD_STATE_ACTIVE nodes */
	/* integrated_nodesハッシュテーブルにCRM_OP_JOIN_REQUESTを送信して来たノードを追加する */
	g_hash_table_insert(
		integrated_nodes, crm_strdup(join_from), crm_strdup(ack_nack));

	/* integrated_nodesハッシュテーブルサイズと、CRM_OP_JOIN_REQUESTを送信して来たノードjoin_idをログ出力する */
	crm_debug("%u nodes have been integrated into join-%d",
		    g_hash_table_size(integrated_nodes), join_id);
	
	/* welcomed_nodesハッシュテーブルからCRM_OP_JOIN_REQUESTを送信して来たノードを削除する */
	g_hash_table_remove(welcomed_nodes, join_from);

	/* JOIN状態チェックを行う */
	if(check_join_state(cur_state, __FUNCTION__) == FALSE) {
		/* dont waste time by invoking the PE yet; */
		crm_debug("join-%d: Still waiting on %d outstanding offers",
			  join_id, g_hash_table_size(welcomed_nodes));
	}
}
Esempio n. 20
0
int
main(int argc, char **argv)
{
	int argerr = 0;
	int flag;
	const char *source = NULL;
	char *admin_input_xml = NULL;
	char *admin_input_file = NULL;
	gboolean dangerous_cmd = FALSE;
	gboolean admin_input_stdin = FALSE;
	xmlNode *output = NULL;
	xmlNode *input = NULL;
	
	int option_index = 0;
	crm_log_init("cibadmin", LOG_CRIT, FALSE, FALSE, argc, argv);
	crm_set_options("V?$o:QDUCEX:t:Srwlsh:MmBfbRx:pP5N:A:uncd", "command [options] [data]", long_options,
			"Provides direct access to the cluster configuration."
			"\n\n Allows the configuration, or sections of it, to be queried, modified, replaced and deleted."
			"\n\n Where necessary, XML data will be obtained using the -X, -x, or -p options\n");

	if(argc < 2) {
		crm_help('?',LSB_EXIT_EINVAL);
	}

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

		switch(flag) {
			case 't':
				message_timeout_ms = atoi(optarg);
				if(message_timeout_ms < 1) {
					message_timeout_ms = 30;
				}
				break;
			case 'A':
				obj_type = crm_strdup(optarg);
				command_options |= cib_xpath;
				break;
			case 'u':
				cib_action = CIB_OP_UPGRADE;
				dangerous_cmd = TRUE;
				break;
			case 'E':
				cib_action = CIB_OP_ERASE;
				dangerous_cmd = TRUE;
				break;
			case 'Q':
				cib_action = CIB_OP_QUERY;
				break;
			case 'P':
				cib_action = CIB_OP_APPLY_DIFF;
				break;
			case 'S':
				cib_action = CIB_OP_SYNC;
				break;
			case 'U':
			case 'M':
				cib_action = CIB_OP_MODIFY;
				break;
			case 'R':
				cib_action = CIB_OP_REPLACE;
				break;
			case 'C':
				cib_action = CIB_OP_CREATE;
				break;
			case 'D':
				cib_action = CIB_OP_DELETE;
				break;
			case '5':
				cib_action = "md5-sum";
				break;
			case 'c':
				command_options |= cib_can_create;
				break;
			case 'n':
				command_options |= cib_no_children;
				break;
			case 'm':
				cib_action = CIB_OP_ISMASTER;
				command_options |= cib_scope_local;
				break;
			case 'B':
				cib_action = CIB_OP_BUMP;
				break;
			case 'r':
				dangerous_cmd = TRUE;
				cib_action = CIB_OP_SLAVE;
				break;
			case 'w':
				dangerous_cmd = TRUE;
				cib_action = CIB_OP_MASTER;
				command_options |= cib_scope_local;
				break;
			case 'V':
				command_options = command_options | cib_verbose;
				cl_log_enable_stderr(TRUE);
				alter_debug(DEBUG_INC);
				break;
			case '?':
			case '$':
				crm_help(flag, LSB_EXIT_OK);
				break;
			case 'o':
				crm_debug_2("Option %c => %s", flag, optarg);
				obj_type = crm_strdup(optarg);
				break;
			case 'X':
				crm_debug_2("Option %c => %s", flag, optarg);
				admin_input_xml = crm_strdup(optarg);
				break;
			case 'x':
				crm_debug_2("Option %c => %s", flag, optarg);
				admin_input_file = crm_strdup(optarg);
				break;
			case 'p':
				admin_input_stdin = TRUE;
				break;
			case 'h':
				host = crm_strdup(optarg);
				break;
			case 'l':
				command_options |= cib_scope_local;
				break;
			case 'd':
				cib_action = CIB_OP_DELETE;
				command_options |= cib_multiple;
				dangerous_cmd = TRUE;
				break;
			case 'b':
				dangerous_cmd = TRUE;
				command_options |= cib_inhibit_bcast;
				command_options |= cib_scope_local;
				break;
			case 's':
				command_options |= cib_sync_call;
				break;
			case 'f':
				force_flag = TRUE;
				command_options |= cib_quorum_override;
				break;
			default:
				printf("Argument code 0%o (%c)"
				       " is not (?yet?) supported\n",
				       flag, flag);
				++argerr;
				break;
		}
	}

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

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

	if(dangerous_cmd && force_flag == FALSE) {
	    fprintf(stderr, "The supplied command is considered dangerous."
		    "  To prevent accidental destruction of the cluster,"
		    " the --force flag is required in order to proceed.\n");
	    fflush(stderr);
	    exit(LSB_EXIT_GENERIC);
	}
	
	if(admin_input_file != NULL) {
	    input = filename2xml(admin_input_file);
	    source = admin_input_file;
		
	} else if(admin_input_xml != NULL) {
	    source = "input string";
	    input = string2xml(admin_input_xml);

	} else if(admin_input_stdin) {
	    source = "STDIN";
	    input = stdin2xml();
	}
	
	if(input != NULL) {
	    crm_log_xml_debug(input, "[admin input]");

	} else if(source) {
	    fprintf(stderr, "Couldn't parse input from %s.\n", source);
	    return 1;
	}

	if(safe_str_eq(cib_action, "md5-sum")) {
	    char *digest = NULL;
	    if(input == NULL) {
		fprintf(stderr,
			"Please supply XML to process with -X, -x or -p\n");
		exit(1);
	    }
	    
	    digest = calculate_xml_digest(input, FALSE, FALSE);
	    fprintf(stderr, "Digest: ");
	    fprintf(stdout, "%s\n", crm_str(digest));
	    crm_free(digest);
	    exit(0);
	}
	
	exit_code = do_init();
	if(exit_code != cib_ok) {
		crm_err("Init failed, could not perform requested operations");
		fprintf(stderr, "Init failed, could not perform requested operations\n");
		return -exit_code;
	}	

	exit_code = do_work(input, command_options, &output);
	if (exit_code > 0) {
		/* wait for the reply by creating a mainloop and running it until
		 * the callbacks are invoked...
		 */
		request_id = exit_code;

		the_cib->cmds->register_callback(
		    the_cib, request_id, message_timeout_ms, FALSE, NULL,
		    "cibadmin_op_callback", cibadmin_op_callback);

		mainloop = g_main_new(FALSE);

		crm_debug_3("%s waiting for reply from the local CIB",
			 crm_system_name);
		
		crm_info("Starting mainloop");
		g_main_run(mainloop);
		
	} else if(exit_code < 0) {
		crm_err("Call failed: %s", cib_error2string(exit_code));
		fprintf(stderr, "Call failed: %s\n",
			cib_error2string(exit_code));
		operation_status = exit_code;

		if(exit_code == cib_dtd_validation) {
		    if(crm_str_eq(cib_action, CIB_OP_UPGRADE, TRUE)) {
			xmlNode *obj = NULL;
			int version = 0, rc = 0;
			rc = the_cib->cmds->query(the_cib, NULL, &obj, command_options);
			if(rc == cib_ok) {
			    update_validation(&obj, &version, TRUE, FALSE);
			}

		    } else if(output) {
			validate_xml_verbose(output);
		    }
		}
	}

	if(output != NULL) {
		char *buffer = dump_xml_formatted(output);
		fprintf(stdout, "%s\n", crm_str(buffer));
		crm_free(buffer);
	}

	the_cib->cmds->signoff(the_cib);
	
	crm_debug_3("%s exiting normally", crm_system_name);
	return -exit_code;
}
Esempio n. 21
0
gboolean
cib_remote_listen(int ssock, gpointer data)
{
    int lpc = 0;
    int csock = 0;
    unsigned laddr;
    time_t now = 0;
    time_t start = time(NULL);
    struct sockaddr_in addr;

#ifdef HAVE_GNUTLS_GNUTLS_H
    gnutls_session *session = NULL;
#endif
    cib_client_t *new_client = NULL;

    xmlNode *login = NULL;
    const char *user = NULL;
    const char *pass = NULL;
    const char *tmp = NULL;

    cl_uuid_t client_id;
    char uuid_str[UU_UNPARSE_SIZEOF];

#ifdef HAVE_DECL_NANOSLEEP
    const struct timespec sleepfast = { 0, 10000000 };  /* 10 millisec */
#endif

    /* accept the connection */
    laddr = sizeof(addr);
    csock = accept(ssock, (struct sockaddr *)&addr, &laddr);
    crm_debug("New %s connection from %s",
              ssock == remote_tls_fd ? "secure" : "clear-text", inet_ntoa(addr.sin_addr));

    if (csock == -1) {
        crm_err("accept socket failed");
        return TRUE;
    }

    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        /* create gnutls session for the server socket */
        session = create_tls_session(csock, GNUTLS_SERVER);
        if (session == NULL) {
            crm_err("TLS session creation failed");
            close(csock);
            return TRUE;
        }
#endif
    }

    do {
        crm_trace("Iter: %d", lpc++);
        if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
            login = cib_recv_remote_msg(session, TRUE);
#endif
        } else {
            login = cib_recv_remote_msg(GINT_TO_POINTER(csock), FALSE);
        }
        if (login != NULL) {
            break;
        }
#ifdef HAVE_DECL_NANOSLEEP
        nanosleep(&sleepfast, NULL);
#else
        sleep(1);
#endif
        now = time(NULL);

        /* Peers have 3s to connect */
    } while (login == NULL && (start - now) < 4);

    crm_log_xml_info(login, "Login: "******"cib_command")) {
        crm_err("Wrong tag: %s", tmp);
        goto bail;
    }

    tmp = crm_element_value(login, "op");
    if (safe_str_neq(tmp, "authenticate")) {
        crm_err("Wrong operation: %s", tmp);
        goto bail;
    }

    user = crm_element_value(login, "user");
    pass = crm_element_value(login, "password");

    /* Non-root daemons can only validate the password of the
     * user they're running as
     */
    if (check_group_membership(user, CRM_DAEMON_GROUP) == FALSE) {
        crm_err("User is not a member of the required group");
        goto bail;

    } else if (authenticate_user(user, pass) == FALSE) {
        crm_err("PAM auth failed");
        goto bail;
    }

    /* send ACK */
    crm_malloc0(new_client, sizeof(cib_client_t));
    num_clients++;
    new_client->channel_name = "remote";
    new_client->name = crm_element_value_copy(login, "name");

    cl_uuid_generate(&client_id);
    cl_uuid_unparse(&client_id, uuid_str);

    CRM_CHECK(new_client->id == NULL, crm_free(new_client->id));
    new_client->id = crm_strdup(uuid_str);

#if ENABLE_ACL
    new_client->user = crm_strdup(user);
#endif

    new_client->callback_id = NULL;
    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        new_client->encrypted = TRUE;
        new_client->channel = (void *)session;
#endif
    } else {
        new_client->channel = GINT_TO_POINTER(csock);
    }

    free_xml(login);
    login = create_xml_node(NULL, "cib_result");
    crm_xml_add(login, F_CIB_OPERATION, CRM_OP_REGISTER);
    crm_xml_add(login, F_CIB_CLIENTID, new_client->id);
    cib_send_remote_msg(new_client->channel, login, new_client->encrypted);
    free_xml(login);

    new_client->source =
        (void *)G_main_add_fd(G_PRIORITY_DEFAULT, csock, FALSE, cib_remote_msg, new_client,
                              cib_remote_connection_destroy);

    g_hash_table_insert(client_list, new_client->id, new_client);

    return TRUE;

  bail:
    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        gnutls_bye(*session, GNUTLS_SHUT_RDWR);
        gnutls_deinit(*session);
        gnutls_free(session);
#endif
    }
    close(csock);
    free_xml(login);
    return TRUE;
}
Esempio n. 22
0
/*
 * version1 < version2 : -1
 * version1 = version2 :  0
 * version1 > version2 :  1
 */
int
compare_version(const char *version1, const char *version2)
{
	int rc = 0;
	int lpc = 0;
	char *ver1_copy = NULL, *ver2_copy = NULL;
	char *rest1 = NULL, *rest2 = NULL;

	if(version1 == NULL && version2 == NULL) {
		return 0;
	} else if(version1 == NULL) {
		return -1;
	} else if(version2 == NULL) {
		return 1;
	}
	
	ver1_copy = crm_strdup(version1);
	ver2_copy = crm_strdup(version2);
	rest1 = ver1_copy;
	rest2 = ver2_copy;

	while(1) {
		int digit1 = 0;
		int digit2 = 0;

		lpc++;

		if(rest1 == rest2) {
		    break;
		}
		
		if(rest1 != NULL) {
		    digit1 = crm_version_helper(rest1, &rest1);
		}

		if(rest2 != NULL) {
		    digit2 = crm_version_helper(rest2, &rest2);
		}

		if(digit1 < digit2){
			rc = -1;
			crm_debug_5("%d < %d", digit1, digit2);
			break;
			
		} else if (digit1 > digit2){
			rc = 1;
			crm_debug_5("%d > %d", digit1, digit2);
			break;
		}

		if(rest1 != NULL && rest1[0] == '.') {
		    rest1++;
		}
		if(rest1 != NULL && rest1[0] == 0) {
		    rest1 = NULL;
		}

		if(rest2 != NULL && rest2[0] == '.') {
		    rest2++;
		}
		if(rest2 != NULL && rest2[0] == 0) {
		    rest2 = NULL;
		}
	}
	
	crm_free(ver1_copy);
	crm_free(ver2_copy);

	if(rc == 0) {
	    crm_debug_3("%s == %s (%d)", version1, version2, lpc);
	} else if(rc < 0) {
	    crm_debug_3("%s < %s (%d)", version1, version2, lpc);
	} else if(rc > 0) {
	    crm_debug_3("%s > %s (%d)", version1, version2, lpc);
	}

	return rc;
}
Esempio n. 23
0
int
main(int argc, char **argv)
{
	int flag;
	int argerr = 0;
	const char *xml_file = NULL;
	crm_data_t *xml_graph = NULL;
  
	set_crm_log_level(0);
/* 	crm_log_init("ttest"); */
	g_log_set_handler(NULL,
			  G_LOG_LEVEL_ERROR      | G_LOG_LEVEL_CRITICAL
			  | G_LOG_LEVEL_WARNING  | G_LOG_LEVEL_MESSAGE
			  | G_LOG_LEVEL_INFO     | G_LOG_LEVEL_DEBUG
			  | G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL,
			  cl_glib_msg_handler, NULL);

	/* and for good measure... - this enum is a bit field (!) */
	g_log_set_always_fatal((GLogLevelFlags)0); /*value out of range*/
	set_crm_log_level(LOG_WARNING);

	transition_trigger = G_main_add_TriggerHandler(
		G_PRIORITY_LOW, te_graph_trigger, NULL, NULL);

	set_graph_functions(&ttest_graph_fns);

	while (1) {
		flag = getopt(argc, argv, OPTARGS);
		if (flag == -1)
			break;
    
		switch(flag) {
			case 'X':
				xml_file = crm_strdup(optarg);
				break;

			case 'V':
				cl_log_enable_stderr(TRUE);
				alter_debug(DEBUG_INC);
				break;
			default:
				printf("?? getopt returned character code 0%o ??\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_debug("=#=#=#=#= Getting XML =#=#=#=#=");
	if(xml_file != NULL) {
		FILE *xml_strm = fopen(xml_file, "r");
		if(xml_strm) {
			xml_graph = file2xml(xml_strm, FALSE);
			fclose(xml_strm);
			
		} else {
			cl_perror("Could not open %s for reading", xml_file);
			xml_file = NULL;
		}
		
	}
	if(xml_file == NULL) {
		xml_graph = stdin2xml();
	}

#ifdef MTRACE  
	mtrace();
#endif

	transition_graph = unpack_graph(xml_graph);
	trigger_graph();
	print_graph(LOG_DEBUG, transition_graph);
	transition_graph->completion_action = tg_shutdown;

	mainloop = g_main_new(FALSE);
	
	g_main_run(mainloop);
	
	crm_info("Exiting ttest");
	
#ifdef MTRACE  
	muntrace();
#endif
	crm_debug_4("Transition complete...");

	return 0;
}
Esempio n. 24
0
gboolean
cib_remote_msg(int csock, gpointer data)
{
    const char *value = NULL;
    xmlNode *command = NULL;
    cib_client_t *client = data;

    crm_trace("%s callback", client->encrypted ? "secure" : "clear-text");

    command = cib_recv_remote_msg(client->channel, client->encrypted);
    if (command == NULL) {
        return FALSE;
    }

    value = crm_element_name(command);
    if (safe_str_neq(value, "cib_command")) {
        crm_log_xml(LOG_MSG, "Bad command: ", command);
        goto bail;
    }

    if (client->name == NULL) {
        value = crm_element_value(command, F_CLIENTNAME);
        if (value == NULL) {
            client->name = crm_strdup(client->id);
        } else {
            client->name = crm_strdup(value);
        }
    }

    if (client->callback_id == NULL) {
        value = crm_element_value(command, F_CIB_CALLBACK_TOKEN);
        if (value != NULL) {
            client->callback_id = crm_strdup(value);
            crm_debug_2("Callback channel for %s is %s", client->id, client->callback_id);

        } else {
            client->callback_id = crm_strdup(client->id);
        }
    }

    /* unset dangerous options */
    xml_remove_prop(command, F_ORIG);
    xml_remove_prop(command, F_CIB_HOST);
    xml_remove_prop(command, F_CIB_GLOBAL_UPDATE);

    crm_xml_add(command, F_TYPE, T_CIB);
    crm_xml_add(command, F_CIB_CLIENTID, client->id);
    crm_xml_add(command, F_CIB_CLIENTNAME, client->name);
#if ENABLE_ACL
    crm_xml_add(command, F_CIB_USER, client->user);
#endif

    if (crm_element_value(command, F_CIB_CALLID) == NULL) {
        cl_uuid_t call_id;
        char call_uuid[UU_UNPARSE_SIZEOF];

        /* fix the command */
        cl_uuid_generate(&call_id);
        cl_uuid_unparse(&call_id, call_uuid);
        crm_xml_add(command, F_CIB_CALLID, call_uuid);
    }

    if (crm_element_value(command, F_CIB_CALLOPTS) == NULL) {
        crm_xml_add_int(command, F_CIB_CALLOPTS, 0);
    }

    crm_log_xml(LOG_MSG, "Remote command: ", command);
    cib_common_callback_worker(command, client, FALSE, TRUE);
  bail:
    free_xml(command);
    command = NULL;
    return TRUE;
}
Esempio n. 25
0
static gboolean
stonith_client_connect(IPC_Channel *channel, gpointer user_data)
{
    cl_uuid_t client_id;
    xmlNode *reg_msg = NULL;
    stonith_client_t *new_client = NULL;
    char uuid_str[UU_UNPARSE_SIZEOF];
    const char *channel_name = user_data;

    crm_trace("Connecting channel");
    CRM_CHECK(channel_name != NULL, return FALSE);
	
    if (channel == NULL) {
	crm_err("Channel was NULL");
	return FALSE;

    } else if (channel->ch_status != IPC_CONNECT) {
	crm_err("Channel was disconnected");
	return FALSE;
		
    } else if(stonith_shutdown_flag) {
	crm_info("Ignoring new client [%d] during shutdown",
		 channel->farside_pid);
	return FALSE;		
    }

    crm_malloc0(new_client, sizeof(stonith_client_t));
    new_client->channel = channel;
    new_client->channel_name = channel_name;
	
    crm_trace("Created channel %p for channel %s",
		new_client, new_client->channel_name);
	
    channel->ops->set_recv_qlen(channel, 1024);
    channel->ops->set_send_qlen(channel, 1024);
	
    new_client->source = G_main_add_IPC_Channel(
	G_PRIORITY_DEFAULT, channel, FALSE, stonith_client_callback,
	new_client, stonith_client_destroy);
	
    crm_trace("Channel %s connected for client %s",
		new_client->channel_name, new_client->id);
	
    cl_uuid_generate(&client_id);
    cl_uuid_unparse(&client_id, uuid_str);

    CRM_CHECK(new_client->id == NULL, crm_free(new_client->id));
    new_client->id = crm_strdup(uuid_str);
	
    /* make sure we can find ourselves later for sync calls
     * redirected to the master instance
     */
    g_hash_table_insert(client_list, new_client->id, new_client);
	
    reg_msg = create_xml_node(NULL, "callback");
    crm_xml_add(reg_msg, F_STONITH_OPERATION, CRM_OP_REGISTER);
    crm_xml_add(reg_msg, F_STONITH_CLIENTID,  new_client->id);
	
    send_ipc_message(channel, reg_msg);		
    free_xml(reg_msg);
	
    return TRUE;
}
Esempio n. 26
0
int
main(int argc, char **argv)
{
	msgtype type = -1;
	char *request = NULL;
	gboolean request_only = FALSE;
	char *reqid = NULL;
	int loglevel = LOG_INFO;
	gboolean verbose = FALSE;
	gboolean quiet = FALSE;
	int argerr = 0, flag;
#ifdef HAVE_GETOPT_H
	int opt_idx = 0;
	static struct option long_opts[] = {
		{"type",		1, 0, 't'},
		{"request",		1, 0, 'r'},
		{"request-only",	1, 0, 'R'},
		{"reqid",		1, 0, 'i'},
		{"verbose",		0, 0, 'V'},
		{"quiet",		0, 0, 'q'},
		{"help",		0, 0, '?'},
		{0, 0, 0, 0}
	};
#endif
	int sockfd, rc, ret = 0;
	vm_message msg;

	while (1) {
#ifdef HAVE_GETOPT_H
		flag = getopt_long(argc, argv, OPTARGS, long_opts, &opt_idx);
#else
		flag = getopt(argc, argv, OPTARGS);
#endif
		if (flag == -1)
			break;
		switch (flag) {
		case 't':
			if (safe_str_eq(optarg, "monitor"))
				type = T_MOD_MONITOR;
			else if (safe_str_eq(optarg, "stonith"))
				type = T_MOD_STONITH;
			break;
		case 'r':
			request = crm_strdup(optarg);
			break;
		case 'R':
			request_only = TRUE;
			request = crm_strdup(optarg);
			break;
		case 'i':
			reqid = crm_strdup(optarg);
			break;
		case 'V':
			loglevel++;
			verbose = TRUE;
			break;
		case 'q':
			quiet = TRUE;
			break;
		case '?':
			usage(basename(argv[0]), LSB_EXIT_GENERIC);
			break;
		default:
			fprintf(stderr, "Argument code 0%o (%c) is not (?yet?) supported",
				flag, flag);
			argerr++;
			break;
		}
	}

	if (!quiet)
		crm_log_init(basename(argv[0]), loglevel, TRUE, verbose, argc, argv);
	else
		crm_log_init(basename(argv[0]), loglevel, TRUE, verbose, 0, NULL);

	if (optind < argc) {
		fprintf(stderr, "non-option ARGV-elements: ");
		while (optind < argc)
			fprintf(stderr, "%s", argv[optind++]);
		fprintf(stderr, "\n");
		argerr++;
	}
	if (argerr || type == -1 || !request)
		usage(crm_system_name, LSB_EXIT_GENERIC);

	on_host = FALSE;
	if ((sockfd = connect_to(SOCK_PATH, 0)) < 0)
		return 1;
	if (send_message(sockfd, type, reqid, request) < 0) {
		ret = 1;
		goto end;
	}
	if (request_only == TRUE)
		goto end;

	while (1) {
		rc = receive_msg(sockfd, &msg);
		if (rc == 0) {
			if (reqid && safe_str_neq(reqid, msg.info.id)) {
				crm_info("request ID (%s) is unmatch : %s", reqid, msg.info.id);
				continue;
			}
			else {
				fprintf(stdout, "%s\n", msg.data);
				goto end;
			}
		}
		else if (rc == 2) {
			/* migration occurred.. */
			ret = 2;
			goto end;
		}
		ret = 1;
		goto end;
	}
end:
	close(sockfd);
	return ret;
}
Esempio n. 27
0
int
main(int argc, char ** argv)
{
    int lpc;
    int flag;
    int rc = 0;
    int argerr = 0;
    int max_msg_types = DIMOF(cib_pipe_ops);

    int command_options = 0;
    gboolean changed = FALSE;
    gboolean force_flag = FALSE;
    gboolean dangerous_cmd = FALSE;
	
    char *buffer = NULL;
    const char *section = NULL;
    const char *input_xml = NULL;
    const char *input_file = NULL;
    const char *cib_action = NULL;
	
    xmlNode *input = NULL;
    xmlNode *output = NULL;
    xmlNode *result_cib = NULL;
    xmlNode *current_cib = NULL;

    gboolean query = FALSE;
    cib_op_t *fn = NULL;
    
#ifdef HAVE_GETOPT_H
    int option_index = 0;
    static struct option long_options[] = {
	{CIB_OP_ERASE,   0, 0, 'E'},
	{CIB_OP_QUERY,   0, 0, 'Q'},
	{CIB_OP_CREATE,  0, 0, 'C'},
	{CIB_OP_REPLACE, 0, 0, 'R'},
	{CIB_OP_UPDATE,  0, 0, 'U'},
	{CIB_OP_MODIFY,  0, 0, 'M'},
	{"patch",	 0, 0, 'P'},
	{CIB_OP_DELETE,  0, 0, 'D'},
	{CIB_OP_BUMP,    0, 0, 'B'},
	{"md5-sum",	 0, 0, '5'},

	{"force",	0, 0, 'f'},
	{"xml-file",    1, 0, 'x'},
	{"xml-text",    1, 0, 'X'},
	{"xml-save",    1, 0, 'S'},
	{"obj_type",    1, 0, 'o'},

	{"verbose",     0, 0, 'V'},
	{"help",        0, 0, '?'},

	{0, 0, 0, 0}
    };
#endif
	
    crm_log_init("cibpipe", LOG_ERR, FALSE, FALSE, 0, NULL);

    while (1) {
#ifdef HAVE_GETOPT_H
	flag = getopt_long(argc, argv, OPTARGS,
			   long_options, &option_index);
#else
	flag = getopt(argc, argv, OPTARGS);
#endif
	if (flag == -1)
	    break;
		
	switch(flag) {
	    case 'E':
		cib_action = CIB_OP_ERASE;
		dangerous_cmd = TRUE;
		break;
	    case 'Q':
		cib_action = CIB_OP_QUERY;
		break;
	    case 'P':
		cib_action = CIB_OP_APPLY_DIFF;
		break;
	    case 'S':
		cib_action = CIB_OP_SYNC;
		break;
	    case 'U':
	    case 'M':
		cib_action = CIB_OP_MODIFY;
		break;
	    case 'R':
		cib_action = CIB_OP_REPLACE;
		break;
	    case 'C':
		cib_action = CIB_OP_CREATE;
		break;
	    case 'D':
		cib_action = CIB_OP_DELETE;
		break;
	    case '5':
		cib_action = "md5-sum";
		break;
	    case 'd':
		cib_action = CIB_OP_DELETE_ALT;
		break;
	    case 'm':
		cib_action = CIB_OP_ISMASTER;
		command_options |= cib_scope_local;
		break;
	    case 'B':
		cib_action = CIB_OP_BUMP;
		break;
	    case 'o':
		crm_debug_2("Option %c => %s", flag, optarg);
		section = crm_strdup(optarg);
		break;
	    case 'x':
		crm_debug_2("Option %c => %s", flag, optarg);
		input_file = crm_strdup(optarg);
		break;
	    case 'X':
		crm_debug_2("Option %c => %s", flag, optarg);
		input_xml = crm_strdup(optarg);
		break;
	    case 'f':
		force_flag = TRUE;
		command_options |= cib_quorum_override;
		break;		    
	    case 'V':
		alter_debug(DEBUG_INC);
		cl_log_enable_stderr(1);
		break;
	    case '?':		/* Help message */
		usage(crm_system_name, LSB_EXIT_OK);
		break;
	    default:
		++argerr;
		break;
	}
    }

    if (cib_action == NULL) {
	++argerr;
    }
    
    if (optind > argc) {
	++argerr;
    }
    
    if (argerr) {
	usage(crm_system_name, LSB_EXIT_GENERIC);
    }
	
    if(dangerous_cmd && force_flag == FALSE) {
	fprintf(stderr, "The supplied command is considered dangerous."
		"  To prevent accidental destruction of the cluster,"
		" the --force flag is required in order to proceed.\n");
	fflush(stderr);
	usage(crm_system_name, LSB_EXIT_GENERIC);	    
    }

    if(input_file != NULL) {
	input = filename2xml(input_file);
	if(input == NULL) {
	    fprintf(stderr, "Couldn't parse input file: %s\n", input_file);
	    return 1;
	}
	    
    } else if(input_xml != NULL) {
	input = string2xml(input_xml);
	if(input == NULL) {
	    fprintf(stderr, "Couldn't parse input string: %s\n", input_xml);
	    return 1;
	}
    }

    if(input && safe_str_eq(cib_action, CIB_OP_QUERY)) {
	current_cib = copy_xml(input);

    } else {
	current_cib = stdin2xml();
	if(current_cib == NULL && safe_str_neq(cib_action, CIB_OP_ERASE)) {
	    fprintf(stderr, "Couldn't parse existing CIB from STDIN.\n");
	    return 1;
	}
    }
	
	
    if(current_cib == NULL) {
	current_cib = createEmptyCib();
    }
    result_cib = copy_xml(current_cib);

    if(safe_str_eq(cib_action, "md5-sum")) {
	char *digest = NULL;
	digest = calculate_xml_digest(current_cib, FALSE, FALSE);
	fprintf(stdout, "%s\n", crm_str(digest));
	crm_free(digest);
	return 0;
    }

    
    /* read local config file */
    if(cib_action == NULL) {
	crm_err("No operation specified");
	return cib_operation;
    }

    for (lpc = 0; lpc < max_msg_types; lpc++) {
	if (safe_str_eq(cib_action, cib_pipe_ops[lpc].op)) {
	    fn = &(cib_pipe_ops[lpc].fn);
	    query = cib_pipe_ops[lpc].read_only;
	    break;
	}
    }
    
    if(fn == NULL) {
	rc = cib_NOTSUPPORTED;
    } else {
	rc = cib_perform_op(cib_action, command_options, fn, query,
			    section, NULL, input, TRUE, &changed,
			    current_cib, &result_cib, NULL, &output);
    }

    if(rc != cib_ok) {
	fprintf(stderr, "Call failed: %s\n", cib_error2string(rc));
	fprintf(stdout, "%c", 0);
	return -rc;    
    }

    cl_log_args(argc, argv);
    
    if(output) {
	buffer = dump_xml_formatted(output);
    } else {
	buffer = dump_xml_formatted(result_cib);
    }

    fprintf(stdout, "%s\n", buffer);
    fflush(stdout);
    
    crm_info("Done");
    return 0;
}
Esempio n. 28
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);
    }
}
Esempio n. 29
0
int
main(int argc, char **argv)
{
    int option_index = 0;
    int argerr = 0;
    int flag;

    crm_log_cli_init("crmadmin");
    crm_set_options(NULL, "command [options]", long_options,
                    "Development tool for performing some crmd-specific commands."
                    "\n  Likely to be replaced by crm_node in the future");
    if (argc < 2) {
        crm_help('?', LSB_EXIT_EINVAL);
    }

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

        switch (flag) {
            case 'V':
                BE_VERBOSE = TRUE;
                admin_verbose = XML_BOOLEAN_TRUE;
                crm_bump_log_level();
                break;
            case 't':
                message_timeout_ms = atoi(optarg);
                if (message_timeout_ms < 1) {
                    message_timeout_ms = 30 * 1000;
                }
                break;

            case '$':
            case '?':
                crm_help(flag, LSB_EXIT_OK);
                break;
            case 'D':
                DO_WHOIS_DC = TRUE;
                break;
            case 'B':
                BASH_EXPORT = TRUE;
                break;
            case 'K':
                DO_RESET = TRUE;
                crm_trace("Option %c => %s", flag, optarg);
                dest_node = crm_strdup(optarg);
                crmd_operation = CRM_OP_LOCAL_SHUTDOWN;
                break;
            case 'q':
                BE_SILENT = TRUE;
                break;
            case 'i':
                DO_DEBUG = debug_inc;
                crm_trace("Option %c => %s", flag, optarg);
                dest_node = crm_strdup(optarg);
                break;
            case 'd':
                DO_DEBUG = debug_dec;
                crm_trace("Option %c => %s", flag, optarg);
                dest_node = crm_strdup(optarg);
                break;
            case 'S':
                DO_HEALTH = TRUE;
                crm_trace("Option %c => %s", flag, optarg);
                dest_node = crm_strdup(optarg);
                break;
            case 'E':
                DO_ELECT_DC = TRUE;
                break;
            case 'N':
                DO_NODE_LIST = TRUE;
                break;
            case 'H':
                DO_HEALTH = TRUE;
                break;
            default:
                printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
                ++argerr;
                break;
        }
    }

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

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

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

    if (do_init()) {
        int res = 0;

        res = do_work();
        if (res > 0) {
            /* wait for the reply by creating a mainloop and running it until
             * the callbacks are invoked...
             */
            mainloop = g_main_new(FALSE);
            crm_trace("Waiting for %d replies from the local CRM", expected_responses);

            message_timer_id = g_timeout_add(message_timeout_ms, admin_message_timeout, NULL);

            g_main_run(mainloop);

        } else if (res < 0) {
            crm_err("No message to send");
            operation_status = -1;
        }
    } else {
        crm_warn("Init failed, could not perform requested operations");
        operation_status = -2;
    }

    crm_trace("%s exiting normally", crm_system_name);
    return operation_status;
}
Esempio n. 30
0
gboolean
parse_op_key(const char *key, char **rsc_id, char **op_type, int *interval)
{
	char *notify = NULL;
	char *mutable_key = NULL;
	char *mutable_key_ptr = NULL;
	int len = 0, offset = 0, ch = 0;

	CRM_CHECK(key != NULL, return FALSE);
	
	*interval = 0;
	len = strlen(key);
	offset = len-1;

	crm_debug_3("Source: %s", key);
	
	while(offset > 0 && isdigit(key[offset])) {
		int digits = len-offset;
		ch = key[offset] - '0';
		CRM_CHECK(ch < 10, return FALSE);
		CRM_CHECK(ch >= 0, return FALSE);
		while(digits > 1) {
			digits--;
			ch = ch * 10;
		}
		*interval +=  ch;
		offset--;
	}

	crm_debug_3("  Interval: %d", *interval);
	CRM_CHECK(key[offset] == '_', return FALSE);

	mutable_key = crm_strdup(key);
	mutable_key_ptr = mutable_key_ptr;
	mutable_key[offset] = 0;
	offset--;

	while(offset > 0 && key[offset] != '_') {
		offset--;
	}

	CRM_CHECK(key[offset] == '_',
		  crm_free(mutable_key); return FALSE);

	mutable_key_ptr = mutable_key+offset+1;

	crm_debug_3("  Action: %s", mutable_key_ptr);
	
	*op_type = crm_strdup(mutable_key_ptr);

	mutable_key[offset] = 0;
	offset--;

	CRM_CHECK(mutable_key != mutable_key_ptr,
		  crm_free(mutable_key); return FALSE);

	notify = strstr(mutable_key, "_post_notify");
	if(safe_str_eq(notify, "_post_notify")) {
	    notify[0] = 0;
	}

	notify = strstr(mutable_key, "_pre_notify");
	if(safe_str_eq(notify, "_pre_notify")) {
	    notify[0] = 0;
	}

	crm_debug_3("  Resource: %s", mutable_key);
	*rsc_id = mutable_key;

	return TRUE;
}