Example #1
0
File: hooks.c Project: op5/merlin
static int is_dupe(merlin_event *pkt)
{
	if (!check_dupes) {
		return 0;
	}

	if (last_pkt.hdr.type != pkt->hdr.type) {
		return 0;
	}

	if (packet_size(&last_pkt) != packet_size(pkt)) {
		return 0;
	}

	/* if this is truly a dupe, return 1 and log every 100'th */
	if (!memcmp(&last_pkt, pkt, packet_size(pkt))) {
		dupe_bytes += packet_size(pkt);
		if (!(++dupes % 100)) {
			ldebug("%s in %llu duplicate packets dropped",
				   human_bytes(dupe_bytes), dupes);
		}
		return 1;
	}

	return 0;
}
Example #2
0
File: net.c Project: op5/merlin
/*
 * Reads input from a particular node and ships it off to
 * the "handle_event()"
 */
int net_input(int sd, int io_evt, void *node_)
{
	merlin_event *pkt;
	merlin_node *node = (merlin_node *)node_;
	int len, events = 0;

	errno = 0;
	ldebug("NETINPUT from %p (%s)", node, node ? node->name : "oops");
	len = node_recv(node);
	if (len < 0) {
		return 0;
	}
	node->stats.bytes.read += len;
	node->last_recv = time(NULL);

	while ((pkt = node_get_event(node))) {
		events++;
		handle_event(node, pkt);
		free(pkt);
	}
	ldebug("Read %d events in %s from %s node %s",
		   events, human_bytes(len), node_type(node), node->name);

	return events;
}
Example #3
0
static int ipc_reap_events(void)
{
	int len, events = 0;
	merlin_event *pkt;

	node_log_event_count(&ipc, 0);

	len = node_recv(&ipc);
	if (len < 0)
		return len;

	while ((pkt = node_get_event(&ipc))) {
		events++;
		handle_ipc_event(pkt);
	}
	ldebug("Read %d events in %s from %s", events, human_bytes(len), ipc.name);

	return 0;
}
Example #4
0
File: net.c Project: ageric/merlin
/*
 * Reads input from a particular node and ships it off to
 * the "handle_network_event()" routine up above
 */
static int net_input(merlin_node *node)
{
	merlin_event *pkt;
	int len, events = 0;

	errno = 0;
	len = node_recv(node);
	if (len < 0) {
		return 0;
	}
	node->stats.bytes.read += len;
	node->last_recv = time(NULL);

	while ((pkt = node_get_event(node))) {
		events++;
		handle_network_event(node, pkt);
	}
	ldebug("Read %d events in %s from %s node %s",
		   events, human_bytes(len), node_type(node), node->name);

	return events;
}
Example #5
0
File: node.c Project: ageric/merlin
void node_log_event_count(merlin_node *node, int force)
{
	struct timeval now;
	merlin_node_stats *s = &node->stats;
	unsigned long long b_in, b_out, e_in, e_out;
	const char *dura;

	/*
	 * This works like a 'mark' that syslogd produces. We log once
	 * every 60 seconds
	 */
	gettimeofday(&now, NULL);
	if (!force && s->last_logged && s->last_logged + 60 > now.tv_sec)
		return;

	s->last_logged = now.tv_sec;
	dura = tv_delta(&self.start, &now);

	b_in = s->bytes.read;
	b_out = s->bytes.sent + s->bytes.logged + s->bytes.dropped;
	e_in = s->events.read;
	e_out = s->events.sent + s->events.logged + s->events.dropped;
	linfo("Handled %llu events from/to %s in %s. in: %llu, out: %llu",
		  e_in + e_out, node->name, dura, e_in, e_out);
	linfo("Handled %s from/to %s in %s. in: %s, out: %s",
		  human_bytes(b_in + b_out), node->name, dura,
		  human_bytes(b_in), human_bytes(b_out));
	if (!e_out)
		return;
	linfo("%s events/bytes: read %llu/%s, sent %llu/%s, dropped %llu/%s, logged %llu/%s, logsize %u/%s",
	      node->name, e_in, human_bytes(b_in),
		  s->events.sent, human_bytes(s->bytes.sent),
		  s->events.dropped, human_bytes(s->bytes.dropped),
		  s->events.logged, human_bytes(s->bytes.logged),
		  binlog_entries(node->binlog), human_bytes(binlog_size(node->binlog)));
}
Example #6
0
File: node.c Project: ageric/merlin
void node_set_state(merlin_node *node, int state, const char *reason)
{
	int prev_state, add;

	if (!node)
		return;

	if (node->state == state)
		return;

	if (reason) {
		linfo("NODESTATE: %s: %s -> %s: %s", node->name,
		      node_state_name(node->state), node_state_name(state), reason);
	}

	/*
	 * Keep track of active nodes. Setting 'add' to the proper
	 * value means we needn't bother with an insane chain of
	 * if()'s later.
	 * add = +1 if state changes TO 'STATE_CONNECTED'.
	 * add = -1 if state changes FROM 'STATE_CONNECTED'
	 * add remains zero for all other cases
	 */
	if (state == STATE_CONNECTED) {
		add = 1;
		node->connect_time = time(NULL);
	} else if (node->state == STATE_CONNECTED) {
		add = -1;
	} else {
		add = 0;
	}
	if (node->type == MODE_POLLER)
		self.active_pollers += add;
	else if (node->type == MODE_PEER)
		self.active_peers += add;
	else if (node->type == MODE_MASTER)
		self.active_masters += add;

	prev_state = node->state;
	node->state = state;

	if (node->state != STATE_CONNECTED && prev_state != STATE_CONNECTED)
		return;

	if (node->action)
		node->action(node, prev_state);

	if (node->state == STATE_CONNECTED && node->sock >= 0) {
		int snd, rcv;
		socklen_t size = sizeof(int);

		/* mark this so we can disconnect nodes that never send data */
		node->last_recv = time(NULL);

		merlin_set_socket_options(node->sock, 224 * 1024);
		getsockopt(node->sock, SOL_SOCKET, SO_SNDBUF, &snd, &size);
		getsockopt(node->sock, SOL_SOCKET, SO_SNDBUF, &rcv, &size);
		ldebug("send / receive buffers are %s / %s for node %s",
			   human_bytes(snd), human_bytes(rcv), node->name);
	}
}