[op5-users] [PATCH] Fix poller node automatic (de)activate ipc message sending.
Sean Millichamp
sean at bruenor.org
Tue Nov 3 22:42:16 CET 2009
There is support for the daemon to send IPC control messages to
the module to dynamically enable/disable checks on the NOC for
hostgroups based on whether the poller associated with that
hostgroup is connected or not.
Currently, the code doesn't trigger the transition at key
critical connection events with the poller. Also, if Nagios
was restarted without restarting the daemon there is no
facility to remember the last state sent and to trigger a
re-notification of the module to (de)activate the checks
properly.
This patch refactors the support a bit to add tracking of
the last state sent, trigger the previously unused node
action function to set the state at all connection events,
and re-notifies the module via IPC of the last state for
the hostgroups after each IPC re-connection.
Signed-off-by: Sean Millichamp <sean at bruenor.org>
---
daemon.c | 14 ++++++++++++--
net.c | 26 ++++++++++++++++++++++----
net.h | 1 +
types.h | 1 +
4 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/daemon.c b/daemon.c
index 9a96b89..93a11cc 100644
--- a/daemon.c
+++ b/daemon.c
@@ -46,12 +46,20 @@ static int node_action_handler(merlin_node *node, int action)
if (node->type != MODE_POLLER)
return 0;
- ldebug("Handling action %d for node '%s'", action, node->name);
-
switch (action) {
case STATE_CONNECTED:
+ if (node->poller_active)
+ break;
+ node->poller_active = 1;
+ ldebug("Sending IPC control ACTIVE for '%s'", node->name);
return ipc_send_ctrl(CTRL_ACTIVE, node->id);
+ case STATE_PENDING:
+ case STATE_NEGOTIATING:
case STATE_NONE:
+ if (!node->poller_active)
+ break;
+ node->poller_active = 0;
+ ldebug("Sending IPC control INACTIVE for '%s'", node->name);
return ipc_send_ctrl(CTRL_INACTIVE, node->id);
}
@@ -90,6 +98,7 @@ static void grok_node(struct cfg_comp *c, merlin_node *node)
}
node->action = node_action_handler;
node->last_action = -1;
+ node->poller_active = 0;
}
static void grok_daemon_compound(struct cfg_comp *comp)
@@ -389,6 +398,7 @@ static int io_poll_sockets(void)
if (ipc_listen_sock > 0 && FD_ISSET(ipc_listen_sock, &rd)) {
linfo("Accepting inbound connection on ipc socket");
ipc_accept();
+ force_node_ipc_update();
} else if (ipc_sock > 0 && FD_ISSET(ipc_sock, &rd)) {
sockets++;
ipc_reap_events(ipc_sock);
diff --git a/net.c b/net.c
index aa236a9..5c8940a 100644
--- a/net.c
+++ b/net.c
@@ -162,6 +162,7 @@ static int net_complete_connection(merlin_node *node)
linfo("Successfully completed connection to %s node '%s' (%s:%d)",
node_type(node), node->name, inet_ntoa(node->sain.sin_addr),
ntohs(node->sain.sin_port));
+ node->action(node, node->status);
}
return !fail;
@@ -173,6 +174,8 @@ static void net_disconnect(merlin_node *node)
{
close(node->sock);
node->status = STATE_NONE;
+ node->action(node, node->status);
+ node->last_recv = 0;
node->sock = -1;
node->zread = 0;
}
@@ -327,6 +330,7 @@ static int node_is_connected(merlin_node *node)
if (result)
node->status = STATE_CONNECTED;
+ node->action(node, node->status);
return result;
}
@@ -368,6 +372,7 @@ static int net_negotiate_socket(merlin_node *node, int lis)
close(lis);
close(con);
node->status = STATE_NONE;
+ node->action(node, node->status);
return -1;
}
@@ -402,6 +407,7 @@ static int net_negotiate_socket(merlin_node *node, int lis)
net_disconnect(node);
node->status = STATE_CONNECTED;
node->sock = lis;
+ node->action(node, node->status);
return lis;
}
@@ -462,6 +468,7 @@ int net_accept_one(void)
}
node->status = STATE_CONNECTED;
+ node->action(node, node->status);
node->last_sent = node->last_recv = time(NULL);
return sock;
@@ -566,7 +573,7 @@ static void check_node_activity(merlin_node *node)
return;
if (node->last_recv && node->last_recv < now - (pulse_interval * 2))
- set_inactive(node);
+ node->action(node, STATE_NONE);
}
@@ -638,9 +645,6 @@ static void net_input(merlin_node *node)
len, inet_ntoa(node->sain.sin_addr),
pkt.hdr.protocol, pkt.hdr.type, pkt.hdr.len);
- if (!node->last_recv)
- set_active(node);
-
node->last_recv = time(NULL);
if (pkt.hdr.type == CTRL_PACKET && pkt.hdr.code == CTRL_PULSE) {
@@ -779,6 +783,20 @@ void check_all_node_activity(void)
check_node_activity(node_table[i]);
}
+/* Force sending control packets to ensure proper state in Nagios after
+ * reconnection of an ipc socket */
+void force_node_ipc_update(void)
+{
+ int i;
+ merlin_node *node;
+
+ for (i = 0; i < num_nodes; i++) {
+ node = node_table[i];
+ if(node->type == MODE_POLLER)
+ node->poller_active ? set_active(node) : set_inactive(node);
+ }
+}
+
/* poll for INBOUND socket events and completion of pending connections */
int net_poll(void)
{
diff --git a/net.h b/net.h
index 1661616..ecefba2 100644
--- a/net.h
+++ b/net.h
@@ -19,6 +19,7 @@ extern int net_send_ipc_data(merlin_event *pkt);
extern int net_sock_desc();
extern int net_polling_helper(fd_set *rd, fd_set *wr, int sel_val);
extern void check_all_node_activity(void);
+extern void force_node_ipc_update(void);
extern int net_accept_one(void);
extern int net_handle_polling_results(fd_set *rd, fd_set *wr);
#endif /* INCLUDE_net_h__ */
diff --git a/types.h b/types.h
index 60e288e..325320c 100644
--- a/types.h
+++ b/types.h
@@ -24,6 +24,7 @@ struct merlin_node {
time_t last_recv; /* last time node sent something to us */
time_t last_sent; /* when we sent something last */
int last_action; /* LA_CONNECT | LA_DISCONNECT | LA_HANDLED */
+ int poller_active; /* Is the poller active? */
int (*action)(struct merlin_node *, int); /* (daemon) action handler */
struct merlin_node *next; /* linked list (and tabulated) */
};
--
1.6.2.5
More information about the op5-users
mailing list