Ejemplo n.º 1
0
void
send_hello_message(IPC_Channel *ipc_client,
		   const char *uuid,
		   const char *client_name,
		   const char *major_version,
		   const char *minor_version)
{
	xmlNode *hello_node = NULL;
	xmlNode *hello = NULL;
	if (uuid == NULL || strlen(uuid) == 0
	    || client_name == NULL || strlen(client_name) == 0
	    || major_version == NULL || strlen(major_version) == 0
	    || minor_version == NULL || strlen(minor_version) == 0) {
		crm_err("Missing fields, Hello message will not be valid.");
		return;
	}

	hello_node = create_xml_node(NULL, XML_TAG_OPTIONS);
	crm_xml_add(hello_node, "major_version", major_version);
	crm_xml_add(hello_node, "minor_version", minor_version);
	crm_xml_add(hello_node, "client_name",   client_name);
	crm_xml_add(hello_node, "client_uuid",   uuid);

	crm_debug_4("creating hello message");
	hello = create_request(
		CRM_OP_HELLO, hello_node, NULL, NULL, client_name, uuid);

	send_ipc_message(ipc_client, hello);
	crm_debug_4("hello message sent");
	
	free_xml(hello_node);
	free_xml(hello);
}
Ejemplo n.º 2
0
void
notify_crmd(crm_graph_t *graph)
{	
	HA_Message *cmd = NULL;
	int log_level = LOG_DEBUG;
	const char *op = CRM_OP_TEABORT;
	int pending_callbacks = num_cib_op_callbacks();
	

	stop_te_timer(transition_timer);
	
	if(pending_callbacks != 0) {
		crm_warn("Delaying completion until all CIB updates complete");
		return;
	}

	CRM_CHECK(graph->complete, graph->complete = TRUE);

	switch(graph->completion_action) {
		case tg_stop:
			op = CRM_OP_TECOMPLETE;
			log_level = LOG_INFO;
			break;

		case tg_abort:
		case tg_restart:
			op = CRM_OP_TEABORT;
			break;

		case tg_shutdown:
			crm_info("Exiting after transition");
			if (mainloop != NULL && g_main_is_running(mainloop)) {
				g_main_quit(mainloop);
				return;
			}
			exit(LSB_EXIT_OK);
	}

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

	print_graph(LOG_DEBUG_3, graph);
	
	cmd = create_request(
		op, NULL, NULL, CRM_SYSTEM_DC, CRM_SYSTEM_TENGINE, NULL);

	if(graph->abort_reason != NULL) {
		ha_msg_add(cmd, "message", graph->abort_reason);
	}

	send_ipc_message(crm_ch, cmd);
	crm_msg_del(cmd);

	graph->abort_reason = NULL;
	graph->completion_action = tg_restart;	

}
Ejemplo n.º 3
0
static gboolean
te_crm_command(crm_graph_t *graph, crm_action_t *action)
{
	char *value = NULL;
	char *counter = NULL;
	HA_Message *cmd = NULL;		

	const char *id = NULL;
	const char *task = NULL;
	const char *on_node = NULL;

	gboolean ret = TRUE;

	id      = ID(action->xml);
	task    = crm_element_value(action->xml, XML_LRM_ATTR_TASK);
	on_node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET);

	CRM_CHECK(on_node != NULL && strlen(on_node) != 0,
		  te_log_action(LOG_ERR, "Corrupted command (id=%s) %s: no node",
				crm_str(id), crm_str(task));
		  return FALSE);
	
	te_log_action(LOG_INFO, "Executing crm-event (%s): %s on %s",
		      crm_str(id), crm_str(task), on_node);
	
	cmd = create_request(task, NULL, on_node, CRM_SYSTEM_CRMD,
			     CRM_SYSTEM_TENGINE, NULL);
	
	counter = generate_transition_key(
		transition_graph->id, action->id, te_uuid);
	crm_xml_add(cmd, XML_ATTR_TRANSITION_KEY, counter);
	ret = send_ipc_message(crm_ch, cmd);
	crm_free(counter);
	crm_msg_del(cmd);
	
	value = g_hash_table_lookup(action->params, crm_meta_name(XML_ATTR_TE_NOWAIT));
	if(ret == FALSE) {
		crm_err("Action %d failed: send", action->id);
		return FALSE;
		
	} else if(crm_is_true(value)) {
		crm_info("Skipping wait for %d", action->id);
		action->confirmed = TRUE;
		update_graph(graph, action);
		trigger_graph();
		
	} else if(ret && action->timeout > 0) {
		crm_debug("Setting timer for action %d",action->id);
		action->timer->reason = timeout_action_warn;
		te_start_action_timer(action);
	}
	
	return TRUE;
}
Ejemplo n.º 4
0
static int
send_via_callback_channel(xmlNode *msg, const char *token) 
{
    stonith_client_t *hash_client = NULL;
    enum stonith_errors rc = stonith_ok;
	
    crm_trace("Delivering msg %p to client %s", msg, token);

    if(token == NULL) {
	crm_err("No client id token, cant send message");
	if(rc == stonith_ok) {
	    rc = -1;
	}

    } else if(msg == NULL) {
	crm_err("No message to send");
	rc = -1;
	    
    } else {
	/* A client that left before we could reply is not really
	 * _our_ error.  Warn instead.
	 */
	hash_client = g_hash_table_lookup(client_list, token);
	if(hash_client == NULL) {
	    crm_warn("Cannot find client for token %s", token);
	    rc = -1;
			
	} else if (crm_str_eq(hash_client->channel_name, "remote", FALSE)) {
	    /* just hope it's alive */
		    
	} else if(hash_client->channel == NULL) {
	    crm_err("Cannot find channel for client %s", token);
	    rc = -1;
	}
    }

    if(rc == stonith_ok) {
	crm_trace("Delivering reply to client %s (%s)",
		    token, hash_client->channel_name);
	if(send_ipc_message(hash_client->channel, msg) == FALSE) {
	    crm_warn("Delivery of reply to client %s/%s failed",
		     hash_client->name, token);
	    rc = -1;
	}
    }
	
    return rc;
}
Ejemplo n.º 5
0
gboolean
send_msg_via_ipc(xmlNode * msg, const char *sys)
{
    gboolean send_ok = TRUE;
    IPC_Channel *client_channel;

    client_channel = (IPC_Channel *) g_hash_table_lookup(ipc_clients, sys);

    if (crm_element_value(msg, F_CRM_HOST_FROM) == NULL) {
        crm_xml_add(msg, F_CRM_HOST_FROM, fsa_our_uname);
    }

    if (client_channel != NULL) {
        crm_debug_3("Sending message via channel %s.", sys);
        send_ok = send_ipc_message(client_channel, msg);

    } else if (sys != NULL && strcmp(sys, CRM_SYSTEM_TENGINE) == 0) {
        xmlNode *data = get_message_xml(msg, F_CRM_DATA);

        process_te_message(msg, data);

    } else if (sys != NULL && strcmp(sys, CRM_SYSTEM_LRMD) == 0) {
        fsa_data_t fsa_data;
        ha_msg_input_t fsa_input;

        fsa_input.msg = msg;
        fsa_input.xml = get_message_xml(msg, F_CRM_DATA);

        fsa_data.id = 0;
        fsa_data.actions = 0;
        fsa_data.data = &fsa_input;
        fsa_data.fsa_input = I_MESSAGE;
        fsa_data.fsa_cause = C_IPC_MESSAGE;
        fsa_data.origin = __FUNCTION__;
        fsa_data.data_type = fsa_dt_ha_msg;

#ifdef FSA_TRACE
        crm_debug_2("Invoking action A_LRM_INVOKE (%.16llx)", A_LRM_INVOKE);
#endif
        do_lrm_invoke(A_LRM_INVOKE, C_IPC_MESSAGE, fsa_state, I_MESSAGE, &fsa_data);

    } else {
        crm_err("Unknown Sub-system (%s)... discarding message.", crm_str(sys));
        send_ok = FALSE;
    }

    return send_ok;
}
Ejemplo n.º 6
0
static void
stonith_notify_client(gpointer key, gpointer value, gpointer user_data)
{

    IPC_Channel *ipc_client = NULL;
    xmlNode *update_msg = user_data;
    stonith_client_t *client = value;
    const char *type = NULL;

    CRM_CHECK(client != NULL, return);
    CRM_CHECK(update_msg != NULL, return);

    type = crm_element_value(update_msg, F_SUBTYPE);
    CRM_CHECK(type != NULL, crm_log_xml_err(update_msg, "notify"); return);

    if(client == NULL) {
	crm_trace("Skipping NULL client");
	return;

    } else if(client->channel == NULL) {
	crm_trace("Skipping client with NULL channel");
	return;

    } else if(client->name == NULL) {
	crm_trace("Skipping unnammed client / comamnd channel");
	return;
    }

    ipc_client = client->channel;
    if(client->flags & get_stonith_flag(type)) {
	crm_trace("Sending %s-notification to client %s/%s", type, client->name, client->id);
	if(ipc_client->send_queue->current_qlen >= ipc_client->send_queue->max_qlen) {
	    /* We never want the STONITH to exit because our client is slow */
	    crm_debug("%s-notification of client %s/%s failed - queue saturated",
		     type, client->name, client->id);
			
	} else if(send_ipc_message(ipc_client, update_msg) == FALSE) {
	    crm_warn("%s-Notification of client %s/%s failed",
		     type, client->name, client->id);
	}
    }
}
Ejemplo n.º 7
0
int ipc_cld_join_send (IDTYPE dest)
{
    BEGIN_PROFILE_INTERVAL();
    struct shim_ipc_port * port = dest ?
                                  lookup_ipc_port(dest, IPC_PORT_DIRPRT) :
                                  get_parent_port(&dest);
    if (!port)
        return -ESRCH;

    struct shim_ipc_msg * msg =
                create_ipc_msg_on_stack(IPC_CLD_JOIN, 0, dest);

    debug("ipc send to %u: IPC_CLD_JOIN\n", dest);

    int ret = send_ipc_message(msg, port);

    add_ipc_port(port, dest, IPC_PORT_DIRPRT, NULL);
    put_ipc_port(port);
    SAVE_PROFILE_INTERVAL(ipc_cld_join_send);
    return ret;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
int ipc_cld_profile_send (void)
{
    IDTYPE dest;
    struct shim_ipc_port * port = get_parent_port(&dest);
    if (!port)
        return -ESRCH;

    unsigned long time = GET_PROFILE_INTERVAL();
    int nsending = 0;
    for (int i = 0 ; i < N_PROFILE ; i++)
        switch (PROFILES[i].type) {
            case OCCURENCE:
                if (atomic_read(&PROFILES[i].val.occurence.count))
                    nsending++;
                break;
            case INTERVAL:
                if (atomic_read(&PROFILES[i].val.interval.count))
                    nsending++;
                break;
            case CATAGORY:
                break;
        }


    struct shim_ipc_msg * msg = create_ipc_msg_on_stack(
                                        IPC_CLD_PROFILE,
                                        sizeof(struct shim_ipc_cld_profile) +
                                        sizeof(struct profile_val) *
                                        nsending, dest);
    struct shim_ipc_cld_profile * msgin =
                (struct shim_ipc_cld_profile *) &msg->msg;

    int nsent = 0;
    for (int i = 0 ; i < N_PROFILE && nsent < nsending ; i++)
        switch (PROFILES[i].type) {
            case OCCURENCE: {
                unsigned long count =
                    atomic_read(&PROFILES[i].val.occurence.count);
                if (count) {
                    msgin->profile[nsent].idx = i + 1;
                    msgin->profile[nsent].val.occurence.count = count;
                    debug("send %s: %lu times\n", PROFILES[i].name, count);
                    nsent++;
                }
                break;
            }
            case INTERVAL: {
                unsigned long count =
                    atomic_read(&PROFILES[i].val.interval.count);
                if (count) {
                    msgin->profile[nsent].idx = i + 1;
                    msgin->profile[nsent].val.interval.count = count;
                    msgin->profile[nsent].val.interval.time =
                        atomic_read(&PROFILES[i].val.interval.time);
                    debug("send %s: %lu times, %lu msec\n", PROFILES[i].name,
                          count, msgin->profile[nsent].val.interval.time);
                    nsent++;
                }
                break;
            }
            case CATAGORY:
                break;
        }

    msgin->time = time;
    msgin->nprofile = nsent;

    debug("ipc send to %u: IPC_CLD_PROFILE\n", dest);

    int ret = send_ipc_message(msg, port);
    put_ipc_port(port);
    return ret;
}
Ejemplo n.º 10
0
void
cib_notify_client(gpointer key, gpointer value, gpointer user_data)
{

	IPC_Channel *ipc_client = NULL;
	HA_Message *update_msg = user_data;
	cib_client_t *client = value;
	const char *type = NULL;
	gboolean is_pre = FALSE;
	gboolean is_post = FALSE;	
	gboolean is_confirm = FALSE;
	gboolean is_replace = FALSE;
	gboolean is_diff = FALSE;
	gboolean do_send = FALSE;

	int qlen = 0;
	int max_qlen = 0;
	
	CRM_DEV_ASSERT(client != NULL);
	CRM_DEV_ASSERT(update_msg != NULL);

	type = cl_get_string(update_msg, F_SUBTYPE);
	CRM_DEV_ASSERT(type != NULL);

	if(client == NULL) {
		crm_warn("Skipping NULL client");
		return;

	} else if(client->channel == NULL) {
		crm_warn("Skipping client with NULL channel");
		return;

	} else if(client->name == NULL) {
		crm_debug_2("Skipping unnammed client / comamnd channel");
		return;
	}
	
	if(safe_str_eq(type, T_CIB_PRE_NOTIFY)) {
		is_pre = TRUE;
		
	} else if(safe_str_eq(type, T_CIB_POST_NOTIFY)) {
		is_post = TRUE;

	} else if(safe_str_eq(type, T_CIB_UPDATE_CONFIRM)) {
		is_confirm = TRUE;

	} else if(safe_str_eq(type, T_CIB_DIFF_NOTIFY)) {
		is_diff = TRUE;

	} else if(safe_str_eq(type, T_CIB_REPLACE_NOTIFY)) {
		is_replace = TRUE;
	}

	ipc_client = client->channel;
	qlen = ipc_client->send_queue->current_qlen;
	max_qlen = ipc_client->send_queue->max_qlen;

#if 1
	/* get_chan_status() causes memory to be allocated that isnt free'd
	 *   until the message is read (which messes up the memory stats) 
	 */
	if(ipc_client->ops->get_chan_status(ipc_client) != IPC_CONNECT) {
		crm_debug_2("Skipping notification to disconnected"
			    " client %s/%s", client->name, client->id);
		
	} else if(client->pre_notify && is_pre) {
		if(qlen < (int)(0.4 * max_qlen)) {
			do_send = TRUE;
		} else {
			crm_warn("Throttling pre-notifications due to"
				 " high load: queue=%d (max=%d)",
				 qlen, max_qlen);
		}
		 
	} else if(client->post_notify && is_post) {
		if(qlen < (int)(0.7 * max_qlen)) {
			do_send = TRUE;
		} else {
			crm_warn("Throttling post-notifications due to"
				 " extreme load: queue=%d (max=%d)",
				 qlen, max_qlen);
		}

		/* these are critical */
	} else
#endif
		if(client->diffs && is_diff) {
		do_send = TRUE;

	} else if(client->confirmations && is_confirm) {
		do_send = TRUE;

	} else if(client->replace && is_replace) {
		do_send = TRUE;
	}

	if(do_send) {
		crm_debug_2("Notifying client %s/%s of %s update (queue=%d)",
			    client->name, client->channel_name, type, qlen);

		if(ipc_client->send_queue->current_qlen >= ipc_client->send_queue->max_qlen) {
			/* We never want the CIB to exit because our client is slow */
			crm_crit("%s-notification of client %s/%s failed - queue saturated",
				 is_confirm?"Confirmation":is_post?"Post":"Pre",
				 client->name, client->id);
			
		} else if(send_ipc_message(ipc_client, update_msg) == FALSE) {
			crm_warn("Notification of client %s/%s failed",
				 client->name, client->id);
		}
		
	} else {
		crm_debug_3("Client %s/%s not interested in %s notifications",
			    client->name, client->channel_name, type);	
	}
}
Ejemplo n.º 11
0
void
send_rsc_command(crm_action_t *action) 
{
	HA_Message *cmd = NULL;
	crm_data_t *rsc_op  = NULL;
	char *counter = NULL;

	const char *task    = NULL;
	const char *value   = NULL;
	const char *on_node = NULL;
	const char *task_uuid = NULL;

	CRM_ASSERT(action != NULL);
	CRM_ASSERT(action->xml != NULL);

	rsc_op  = action->xml;
	task    = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
	task_uuid = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY);
	on_node = crm_element_value(rsc_op, XML_LRM_ATTR_TARGET);
	counter = generate_transition_key(
		transition_graph->id, action->id, te_uuid);
	crm_xml_add(rsc_op, XML_ATTR_TRANSITION_KEY, counter);

	crm_info("Initiating action %d: %s on %s",
		 action->id, task_uuid, on_node);

	crm_free(counter);
	
	if(rsc_op != NULL) {
		crm_log_xml_debug_2(rsc_op, "Performing");
	}
	cmd = create_request(CRM_OP_INVOKE_LRM, rsc_op, on_node,
			     CRM_SYSTEM_LRMD, CRM_SYSTEM_TENGINE, NULL);
	
#if 1
	send_ipc_message(crm_ch, cmd);
#else
	/* test the TE timer/recovery code */
	if((action->id % 11) == 0) {
		crm_err("Faking lost action %d: %s", action->id, task_uuid);
	} else {
		send_ipc_message(crm_ch, cmd);
	}
#endif
	crm_msg_del(cmd);
	
	action->executed = TRUE;
	value = g_hash_table_lookup(action->params, crm_meta_name(XML_ATTR_TE_NOWAIT));
	if(crm_is_true(value)) {
		crm_debug("Skipping wait for %d", action->id);
		action->confirmed = TRUE;
		update_graph(transition_graph, action);
		trigger_graph();

	} else if(action->timeout > 0) {
		int action_timeout = (2 * action->timeout) + transition_graph->network_delay;
		crm_debug_3("Setting timer for action %s", task_uuid);
		if(transition_graph->transition_timeout < action_timeout) {
			crm_debug("Action %d:"
				  " Increasing transition %d timeout to %d (2*%d + %d)",
				  action->id, transition_graph->id, action_timeout,
				  action->timeout, transition_graph->network_delay);
			transition_graph->transition_timeout = action_timeout;
		}
		te_start_action_timer(action);
	}
}
Ejemplo n.º 12
0
gboolean
cib_notify_client(gpointer key, gpointer value, gpointer user_data)
{
    int qlen = 0;
    int max_qlen = 500;
    const char *type = NULL;
    gboolean do_send = FALSE;
    gboolean do_remote = FALSE;
    IPC_Channel *ipc_client = NULL;

    cib_client_t *client = value;
    xmlNode *update_msg = user_data;

    CRM_CHECK(client != NULL, return TRUE);
    CRM_CHECK(update_msg != NULL, return TRUE);

    if (client == NULL) {
        crm_warn("Skipping NULL client");
        return TRUE;

    } else if (client->channel == NULL) {
        crm_warn("Skipping client with NULL channel");
        return FALSE;

    } else if (client->name == NULL) {
        crm_trace("Skipping unnammed client / comamnd channel");
        return FALSE;
    }

    type = crm_element_value(update_msg, F_SUBTYPE);

    ipc_client = client->channel;
    do_remote = crm_str_eq(client->channel_name, "remote", FALSE);

    if (do_remote == FALSE) {
        qlen = ipc_client->send_queue->current_qlen;
        max_qlen = ipc_client->send_queue->max_qlen;
    }

    CRM_LOG_ASSERT(type != NULL);
    if (client->diffs && safe_str_eq(type, T_CIB_DIFF_NOTIFY)) {
        do_send = TRUE;

    } else if (client->replace && safe_str_eq(type, T_CIB_REPLACE_NOTIFY)) {
        do_send = TRUE;

    } else if (client->confirmations && safe_str_eq(type, T_CIB_UPDATE_CONFIRM)) {
        do_send = TRUE;

    } else if (client->pre_notify && safe_str_eq(type, T_CIB_PRE_NOTIFY)) {
        if (qlen < (int)(0.4 * max_qlen)) {
            do_send = TRUE;
        } else {
            crm_warn("Throttling pre-notifications due to"
                     " high load: queue=%d (max=%d)", qlen, max_qlen);
        }

    } else if (client->post_notify && safe_str_eq(type, T_CIB_POST_NOTIFY)) {
        if (qlen < (int)(0.7 * max_qlen)) {
            do_send = TRUE;
        } else {
            crm_warn("Throttling post-notifications due to"
                     " extreme load: queue=%d (max=%d)", qlen, max_qlen);
        }
    }

    if (do_send) {
        if (do_remote) {
            crm_debug("Sent %s notification to client %s/%s", type, client->name, client->id);
            cib_send_remote_msg(client->channel, update_msg, client->encrypted);

        } else if (ipc_client->send_queue->current_qlen >= ipc_client->send_queue->max_qlen) {
            /* We never want the CIB to exit because our client is slow */
            crm_crit("%s-notification of client %s/%s failed - queue saturated",
                     type, client->name, client->id);

        } else if (send_ipc_message(ipc_client, update_msg) == FALSE) {
            crm_warn("Notification of client %s/%s failed", client->name, client->id);
            return FALSE;
        }
    }
    return FALSE;
}
Ejemplo n.º 13
0
gboolean
process_pe_message(xmlNode *msg, xmlNode *xml_data, IPC_Channel *sender)
{
    gboolean send_via_disk = FALSE;
    const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
    const char *op = crm_element_value(msg, F_CRM_TASK);
    const char *ref = crm_element_value(msg, XML_ATTR_REFERENCE);

    crm_debug_3("Processing %s op (ref=%s)...", op, ref);

    if(op == NULL) {
        /* error */

    } else if(strcasecmp(op, CRM_OP_HELLO) == 0) {
        /* ignore */

    } else if(safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE),
                          XML_ATTR_RESPONSE)) {
        /* ignore */

    } else if(sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) {
        crm_debug_3("Bad sys-to %s", crm_str(sys_to));
        return FALSE;

    } else if(strcasecmp(op, CRM_OP_PECALC) == 0) {
        int seq = -1;
        int series_id = 0;
        int series_wrap = 0;
        char *filename = NULL;
        char *graph_file = NULL;
        const char *value = NULL;
        pe_working_set_t data_set;
        xmlNode *converted = NULL;
        xmlNode *reply = NULL;
        gboolean process = TRUE;
#if HAVE_BZLIB_H
        gboolean compress = TRUE;
#else
        gboolean compress = FALSE;
#endif

        crm_config_error = FALSE;
        crm_config_warning = FALSE;

        was_processing_error = FALSE;
        was_processing_warning = FALSE;

        graph_file = crm_strdup(CRM_STATE_DIR"/graph.XXXXXX");
        graph_file = mktemp(graph_file);

        converted = copy_xml(xml_data);
        if(cli_config_update(&converted, NULL, TRUE) == FALSE) {
            set_working_set_defaults(&data_set);
            data_set.graph = create_xml_node(NULL, XML_TAG_GRAPH);
            crm_xml_add_int(data_set.graph, "transition_id", 0);
            crm_xml_add_int(data_set.graph, "cluster-delay", 0);
            process = FALSE;
        }

        if(process) {
            do_calculations(&data_set, converted, NULL);
        }

        series_id = get_series();
        series_wrap = series[series_id].wrap;
        value = pe_pref(data_set.config_hash, series[series_id].param);

        if(value != NULL) {
            series_wrap = crm_int_helper(value, NULL);
            if(errno != 0) {
                series_wrap = series[series_id].wrap;
            }

        } else {
            crm_config_warn("No value specified for cluster"
                            " preference: %s",
                            series[series_id].param);
        }

        seq = get_last_sequence(PE_STATE_DIR, series[series_id].name);

        data_set.input = NULL;
        reply = create_reply(msg, data_set.graph);
        CRM_ASSERT(reply != NULL);

        filename = generate_series_filename(
                       PE_STATE_DIR, series[series_id].name, seq, compress);
        crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
        crm_xml_add_int(reply, "graph-errors", was_processing_error);
        crm_xml_add_int(reply, "graph-warnings", was_processing_warning);
        crm_xml_add_int(reply, "config-errors", crm_config_error);
        crm_xml_add_int(reply, "config-warnings", crm_config_warning);

        if(send_ipc_message(sender, reply) == FALSE) {
            if(sender && sender->ops->get_chan_status(sender) == IPC_CONNECT) {
                send_via_disk = TRUE;
                crm_err("Answer could not be sent via IPC, send via the disk instead");
                crm_info("Writing the TE graph to %s", graph_file);
                if(write_xml_file(data_set.graph, graph_file, FALSE) < 0) {
                    crm_err("TE graph could not be written to disk");
                }
            } else {
                crm_info("Peer disconnected, discarding transition graph");
            }
        }

        free_xml(reply);
        cleanup_alloc_calculations(&data_set);

        if(series_wrap != 0) {
            write_xml_file(xml_data, filename, compress);
            write_last_sequence(PE_STATE_DIR, series[series_id].name,
                                seq+1, series_wrap);
        }

        if(was_processing_error) {
            crm_err("Transition %d:"
                    " ERRORs found during PE processing."
                    " PEngine Input stored in: %s",
                    transition_id, filename);

        } else if(was_processing_warning) {
            crm_warn("Transition %d:"
                     " WARNINGs found during PE processing."
                     " PEngine Input stored in: %s",
                     transition_id, filename);

        } else {
            crm_info("Transition %d: PEngine Input stored in: %s",
                     transition_id, filename);
        }

        if(crm_config_error) {
            crm_info("Configuration ERRORs found during PE processing."
                     "  Please run \"crm_verify -L\" to identify issues.");

        } else if(crm_config_warning) {
            crm_info("Configuration WARNINGs found during PE processing."
                     "  Please run \"crm_verify -L\" to identify issues.");
        }

        if(send_via_disk) {
            reply = create_reply(msg, NULL);
            crm_xml_add(reply, F_CRM_TGRAPH, graph_file);
            crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
            CRM_ASSERT(reply != NULL);
            if(send_ipc_message(sender, reply) == FALSE) {
                crm_err("Answer could not be sent");
            }
            free_xml(reply);
        }

        free_xml(converted);
        crm_free(graph_file);
        crm_free(filename);

    } else if(strcasecmp(op, CRM_OP_QUIT) == 0) {
        crm_warn("Received quit message, terminating");
        exit(0);
    }

    return TRUE;
}
Ejemplo n.º 14
0
int
main(int argc, char **argv)
{
    int flag;
    int argerr = 0;
    gboolean allow_cores = TRUE;
    IPC_Channel *old_instance = NULL;

    crm_system_name = CRM_SYSTEM_PENGINE;
    mainloop_add_signal(SIGTERM, pengine_shutdown);

    while ((flag = getopt(argc, argv, OPTARGS)) != EOF) {
        switch (flag) {
            case 'V':
                alter_debug(DEBUG_INC);
                break;
            case 'h':          /* Help message */
                usage(crm_system_name, LSB_EXIT_OK);
                break;
            case 'c':
                allow_cores = TRUE;
                break;
            default:
                ++argerr;
                break;
        }
    }

    if (argc - optind == 1 && safe_str_eq("metadata", argv[optind])) {
        pe_metadata();
        return 0;
    }

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

    if (argerr) {
        usage(crm_system_name, LSB_EXIT_GENERIC);
    }

    crm_log_init(NULL, LOG_NOTICE, TRUE, FALSE, argc, argv);

    if (crm_is_writable(PE_STATE_DIR, NULL, CRM_DAEMON_USER, CRM_DAEMON_GROUP, FALSE) == FALSE) {
        crm_err("Bad permissions on " PE_STATE_DIR ". Terminating");
        fprintf(stderr, "ERROR: Bad permissions on " PE_STATE_DIR ". See logs for details\n");
        fflush(stderr);
        return 100;
    }

    ipc_server = crm_strdup(CRM_SYSTEM_PENGINE);

    /* find any previous instances and shut them down */
    crm_debug("Checking for old instances of %s", crm_system_name);
    old_instance = init_client_ipc_comms_nodispatch(CRM_SYSTEM_PENGINE);
    while (old_instance != NULL) {
        xmlNode *cmd =
            create_request(CRM_OP_QUIT, NULL, NULL, CRM_SYSTEM_PENGINE, CRM_SYSTEM_PENGINE, NULL);

        crm_warn("Terminating previous PE instance");
        send_ipc_message(old_instance, cmd);
        free_xml(cmd);

        sleep(2);

        old_instance->ops->destroy(old_instance);
        old_instance = init_client_ipc_comms_nodispatch(CRM_SYSTEM_PENGINE);
    }

    crm_debug("Init server comms");
    if (init_server_ipc_comms(ipc_server, pe_client_connect, default_ipc_connection_destroy)) {
        crm_err("Couldn't start IPC server");
        return 1;
    }

    /* Create the mainloop and run it... */
    crm_info("Starting %s", crm_system_name);

    mainloop = g_main_new(FALSE);
    g_main_run(mainloop);

#if HAVE_LIBXML2
    crm_xml_cleanup();
#endif

    crm_info("Exiting %s", crm_system_name);
    return 0;
}
Ejemplo n.º 15
0
int
do_work(void)
{
    int ret = 1;

    /* construct the request */
    xmlNode *msg_data = NULL;
    gboolean all_is_good = TRUE;

    msg_options = create_xml_node(NULL, XML_TAG_OPTIONS);
    crm_xml_add(msg_options, XML_ATTR_VERBOSE, admin_verbose);
    crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0");

    if (DO_HEALTH == TRUE) {
        crm_debug_2("Querying the system");

        sys_to = CRM_SYSTEM_DC;

        if (dest_node != NULL) {
            sys_to = CRM_SYSTEM_CRMD;
            crmd_operation = CRM_OP_PING;

            if (BE_VERBOSE) {
                expected_responses = 1;
            }

            crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0");

        } else {
            crm_info("Cluster-wide health not available yet");
            all_is_good = FALSE;
        }

    } else if (DO_ELECT_DC) {
        /* tell the local node to initiate an election */

        sys_to = CRM_SYSTEM_CRMD;
        crmd_operation = CRM_OP_VOTE;

        crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0");

        dest_node = NULL;

        ret = 0;                /* no return message */

    } else if (DO_WHOIS_DC) {
        sys_to = CRM_SYSTEM_DC;
        crmd_operation = CRM_OP_PING;

        crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0");

        dest_node = NULL;

    } else if (DO_NODE_LIST) {

        cib_t *the_cib = cib_new();
        xmlNode *output = NULL;

        enum cib_errors rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command);

        if (rc != cib_ok) {
            return -1;
        }

        output = get_cib_copy(the_cib);
        do_find_node_list(output);

        free_xml(output);
        the_cib->cmds->signoff(the_cib);
        exit(rc);

    } else if (DO_RESET) {
        /* tell dest_node to initiate the shutdown proceedure
         *
         * if dest_node is NULL, the request will be sent to the
         *   local node
         */
        sys_to = CRM_SYSTEM_CRMD;
        crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0");

        ret = 0;                /* no return message */

    } else if (DO_DEBUG == debug_inc) {
        /* tell dest_node to increase its debug level
         *
         * if dest_node is NULL, the request will be sent to the
         *   local node
         */
        sys_to = CRM_SYSTEM_CRMD;
        crmd_operation = CRM_OP_DEBUG_UP;

        ret = 0;                /* no return message */

    } else if (DO_DEBUG == debug_dec) {
        /* tell dest_node to increase its debug level
         *
         * if dest_node is NULL, the request will be sent to the
         *   local node
         */
        sys_to = CRM_SYSTEM_CRMD;
        crmd_operation = CRM_OP_DEBUG_DOWN;

        ret = 0;                /* no return message */

    } else {
        crm_err("Unknown options");
        all_is_good = FALSE;
    }

    if (all_is_good == FALSE) {
        crm_err("Creation of request failed.  No message to send");
        return -1;
    }

/* send it */
    if (crmd_channel == NULL) {
        crm_err("The IPC connection is not valid, cannot send anything");
        return -1;
    }

    if (sys_to == NULL) {
        if (dest_node != NULL) {
            sys_to = CRM_SYSTEM_CRMD;
        } else {
            sys_to = CRM_SYSTEM_DC;
        }
    }

    {
        xmlNode *cmd = create_request(crmd_operation, msg_data, dest_node, sys_to,
                                      crm_system_name, admin_uuid);

        send_ipc_message(crmd_channel, cmd);
        free_xml(cmd);
    }

    return ret;
}