Esempio n. 1
0
/* node connect/disconnect handlers */
static int node_action_handler(merlin_node *node, int prev_state)
{
	switch (node->state) {
	case STATE_CONNECTED:
		/*
		 * If we've received the timestamp marker from our module,
		 * We  need to send our own timestamp to the other end so
		 * they know how to sort us in case we're a peer to them.
		 */
		if (ipc.info.start.tv_sec && ipc_is_connected(0)) {
			node_send_ctrl_active(node, CTRL_GENERIC, &ipc.info, 100);
		}
		break;

	case STATE_PENDING:
	case STATE_NEGOTIATING:
	case STATE_NONE:
		/* only send INACTIVE if we haven't already */
		if (prev_state == STATE_CONNECTED) {
			db_mark_node_inactive(node);
			ldebug("Sending IPC control INACTIVE for '%s'", node->name);
			return ipc_send_ctrl(CTRL_INACTIVE, node->id);
		}
	}

	return 1;
}
Esempio n. 2
0
File: hooks.c Progetto: op5/merlin
neb_cb_result * merlin_mod_hook(int cb, void *data)
{
	merlin_event pkt;
	int result = 0;
	neb_cb_result *neb_result = NULL;
	static time_t last_pulse = 0, last_flood_warning = 0;
	time_t now;

	if (!data) {
		lerr("eventbroker module called with NULL data");
		return neb_cb_result_create(-1);
	} else if (cb < 0 || cb > NEBCALLBACK_NUMITEMS) {
		lerr("merlin_mod_hook() called with invalid callback id");
		return neb_cb_result_create(-1);
	}

	/*
	 * must reset this here so events we don't check for
	 * dupes are always sent properly
	 */
	check_dupes = 0;

	/* self-heal nodes that have missed out on the fact that we're up */
	now = time(NULL);
	if(!last_pulse || now - last_pulse > 15)
		node_send_ctrl_active(&ipc, CTRL_GENERIC, &ipc.info);
	last_pulse = now;

	memset(&pkt, 0, sizeof(pkt));
	pkt.hdr.type = cb;
	pkt.hdr.selection = DEST_BROADCAST;
	switch (cb) {
	case NEBCALLBACK_NOTIFICATION_DATA:
		neb_result = hook_notification(&pkt, data);
		break;

	case NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA:
		result = hook_contact_notification_method(&pkt, data);
		break;

	case NEBCALLBACK_HOST_CHECK_DATA:
		result = hook_host_result(&pkt, data);
		break;

	case NEBCALLBACK_SERVICE_CHECK_DATA:
		result = hook_service_result(&pkt, data);
		break;

	case NEBCALLBACK_COMMENT_DATA:
		result = hook_comment(&pkt, data);
		break;

	case NEBCALLBACK_DOWNTIME_DATA:
		result = hook_downtime(&pkt, data);
		break;

	case NEBCALLBACK_EXTERNAL_COMMAND_DATA:
		result = hook_external_command(&pkt, data);
		break;

	case NEBCALLBACK_FLAPPING_DATA:
		/*
		 * flapping doesn't go to the network. check processing
		 * will generate flapping alerts on all nodes anyway,
		 */
	case NEBCALLBACK_PROGRAM_STATUS_DATA:
	case NEBCALLBACK_PROCESS_DATA:
		/* these make no sense to ship across the wire */
		pkt.hdr.code = MAGIC_NONET;
		result = send_generic(&pkt, data);
		break;

	case NEBCALLBACK_HOST_STATUS_DATA:
	case NEBCALLBACK_SERVICE_STATUS_DATA:
		/*
		 * Don't handle status updates coming from Naemon.
		 * If we need to send status updates for any reason it is done through
		 * Merlin directly. For normal state updates, we let each node handle
		 * check results so they keep their own state.
		 */
		break;
	case NEBCALLBACK_EVENT_HANDLER_DATA:
		result = hook_event_handler(&pkt, data);
		break;
	default:
		lerr("Unhandled callback '%s' in merlin_hook()", callback_name(cb));
	}

	if (neb_result != NULL) {
		/*
		 * We have a rich callback result, propagate return code
		 * to preserve flood warnings
		 */
		result = neb_cb_result_returncode(neb_result);
	}
	else {
		/*
		 * No rich callback result, create one
		 */
		neb_result = neb_cb_result_create_full(result, "No callback result description available");
	}

	if (result < 0 && now - last_flood_warning > 30) {
		/* log a warning every 30 seconds */
		last_flood_warning = now;
		lwarn("Daemon is flooded and backlogging failed");
	}


	return neb_result;
}