db_updater: Put parentheses back
[merlin.git] / node.h
blob3b7d54487001de9b17ff81abfde39f0ff83d2542
1 #ifndef INCLUDE_node_h__
2 #define INCLUDE_node_h__
4 #include <sys/types.h>
5 #include <netinet/in.h>
6 #include <sys/time.h>
7 #include <nagios/lib/iocache.h>
8 #include <nagios/nebcallbacks.h>
9 #include "cfgfile.h"
10 #include "binlog.h"
11 #include "pgroup.h"
13 #if __BYTE_ORDER == __BIG_ENDIAN
14 # define MERLIN_SIGNATURE (uint64_t)0x4d524c4e45565400LL /* "MRLNEVT\0" */
15 #else
16 # define MERLIN_SIGNATURE (uint64_t)0x005456454e4c524dLL /* "MRLNEVT\0" */
17 #endif
19 #define MERLIN_PROTOCOL_VERSION 1
21 * how long we should wait before sending paths before trying
22 * to send them again in case something weird happens
24 #define MERLIN_SENDPATH_INTERVAL 15
27 * flags for node options. Must be powers of 2
29 #define MERLIN_NODE_TAKEOVER (1 << 0)
30 #define MERLIN_NODE_CONNECT (1 << 1)
31 #define MERLIN_NODE_FIXED_SRCPORT (1 << 2)
32 #define MERLIN_NODE_NOTIFIES (1 << 3)
34 #define MERLIN_NODE_DEFAULT_POLLER_FLAGS \
35 (MERLIN_NODE_TAKEOVER | MERLIN_NODE_CONNECT | MERLIN_NODE_NOTIFIES)
36 #define MERLIN_NODE_DEFAULT_PEER_FLAGS (MERLIN_NODE_CONNECT)
37 #define MERLIN_NODE_DEFAULT_MASTER_FLAGS (MERLIN_NODE_CONNECT)
38 #define MERLIN_NODE_DEFAULT_IPC_FLAGS (MERLIN_NODE_NOTIFIES)
40 /* various magic options for the "type" field */
41 #define CTRL_PACKET 0xffff /* control packet. "code" described below */
42 #define ACK_PACKET 0xfffe /* ACK ("I understood") (not used) */
43 #define NAK_PACKET 0xfffd /* NAK ("I don't understand") (not used) */
45 /* If "type" is CTRL_PACKET, then "code" is one of the following */
46 #define CTRL_GENERIC 0 /* generic control packet */
47 #define CTRL_PULSE 1 /* keep-alive signal */
48 #define CTRL_INACTIVE 2 /* signals that a slave went offline */
49 #define CTRL_ACTIVE 3 /* signals that a slave went online */
50 #define CTRL_PATHS 4 /* body contains paths to import */
51 #define CTRL_STALL 5 /* signal that we can't accept events for a while */
52 #define CTRL_RESUME 6 /* now we can accept events again */
53 #define CTRL_STOP 7 /* exit() immediately (only accepted via ipc) */
54 /* the following magic entries can be used for the "code" entry */
55 #define MAGIC_NONET 0xffff /* don't forward to the network */
58 * Mark "selection" with this to generate broadcast-ish
59 * events for various classes of merlin-nodes
61 #define DEST_BROADCAST 0xffff /* all nodes */
62 #define DEST_MAGIC (0xfff0)
63 #define DEST_POLLERS (DEST_MAGIC + (1 << 1)) /* all pollers */
64 #define DEST_PEERS (DEST_MAGIC + (1 << 2)) /* all peers */
65 #define DEST_MASTERS (DEST_MAGIC + (1 << 3)) /* all masters */
66 #define DEST_PEERS_POLLERS (DEST_POLLERS | DEST_PEERS)
67 #define DEST_PEERS_MASTERS (DEST_PEERS | DEST_MASTERS)
68 #define DEST_POLLERS_MASTERS (DEST_POLLERS | DEST_MASTERS)
69 #define magic_destination(pkt) ((pkt->hdr.selection & 0xfff0) == 0xfff0)
72 #define HDR_SIZE (sizeof(merlin_header))
73 #define PKT_SIZE (sizeof(merlin_event))
74 #define MAX_PKT_SIZE (PKT_SIZE)
75 #define packet_size(pkt) ((int)((pkt)->hdr.len + HDR_SIZE))
77 struct merlin_header {
78 union merlin_signature {
79 uint64_t id; /* used for assignment and comparison */
80 char ascii[8]; /* "MRLNEVT\0" for debugging, mostly */
81 } sig;
82 uint16_t protocol; /* protocol version */
83 uint16_t type; /* event type */
84 uint16_t code; /* event code (used for control packets) */
85 uint16_t selection; /* used when noc Nagios communicates with mrd */
86 uint32_t len; /* size of body */
87 struct timeval sent; /* when this message was sent */
89 /* pad to 64 bytes for future extensions */
90 char padding[64 - sizeof(struct timeval) - (2 * 6) - 8];
91 } __attribute__((packed));
92 typedef struct merlin_header merlin_header;
94 struct merlin_event {
95 merlin_header hdr;
96 char body[128 << 10];
97 } __attribute__((packed));
98 typedef struct merlin_event merlin_event;
101 * New entries in this struct *must* be appended LAST for the change
102 * to not break backwards compatibility. When the receiving code
103 * expects a new entry from this struct to exist, it should take care
104 * to mark the size of the received packet and never access anything
105 * beyond it.
106 * Since it gets copied into pre-allocated memory, we needn't bother
107 * about the fields we never set. Newly added fields just shouldn't
108 * ever have an expected value of 0 when it exists, since that's what
109 * they will be if the sending end doesn't have the field we want to
110 * know about.
111 * Thus, we must make sure to always use fixed-size entries in this
112 * struct.
114 /* change this macro when nodeinfo is rearranged */
115 #define MERLIN_NODEINFO_VERSION 1
116 /* change this macro when the struct grows incompatibly */
117 #define MERLIN_NODEINFO_MINSIZE sizeof(struct merlin_nodeinfo)
118 struct merlin_nodeinfo {
119 uint32_t version; /* version of this structure */
120 uint32_t word_size; /* bits per register (sizeof(void *) * 8) */
121 uint32_t byte_order; /* 1234 = little, 4321 = big, ... */
122 uint32_t object_structure_version;
123 struct timeval start; /* module (or daemon) start time */
124 time_t last_cfg_change; /* when config was last changed */
125 unsigned char config_hash[20]; /* SHA1 hash of object config hash */
126 uint32_t peer_id; /* self-assigned peer-id */
127 uint32_t active_peers;
128 uint32_t configured_peers;
129 uint32_t active_pollers;
130 uint32_t configured_pollers;
131 uint32_t active_masters;
132 uint32_t configured_masters;
133 uint32_t host_checks_handled;
134 uint32_t service_checks_handled;
135 uint32_t monitored_object_state_size;
136 /* new entries have to come LAST */
137 } __attribute__((packed));
138 typedef struct merlin_nodeinfo merlin_nodeinfo;
140 struct merlin_child {
141 char *cmd;
142 int pid;
144 typedef struct merlin_child merlin_child;
146 struct merlin_confsync {
147 int configured;
148 merlin_child push;
149 merlin_child fetch;
151 typedef struct merlin_confsync merlin_confsync;
153 /* 1MB receive buffer should work nicely */
154 #define MERLIN_IOC_BUFSIZE (1 * 1024 * 1024)
156 struct statistics_vars {
157 unsigned long long sent, read, logged, dropped;
159 struct callback_count {
160 unsigned int in, out;
162 struct merlin_node_stats {
163 struct statistics_vars events, bytes;
164 time_t last_logged; /* when we logged the event-count last */
165 struct callback_count cb_count[NEBCALLBACK_NUMITEMS + 1];
167 typedef struct merlin_node_stats merlin_node_stats;
169 /* used for various objects which we build linked lists for */
170 typedef struct linked_item {
171 void *item;
172 struct linked_item *next_item;
173 } linked_item;
175 struct node_selection {
176 int id;
177 char *name;
178 linked_item *nodes;
180 typedef struct node_selection node_selection;
182 /* for node->type */
183 #define MODE_LOCAL 0
184 #define MODE_NOC 1
185 #define MODE_MASTER MODE_NOC /* alias for MODE_NOC */
186 #define MODE_PEER (1 << 1)
187 #define MODE_POLLER (1 << 2)
188 #define MODE_INTERNAL (1 << 3)
190 /* for node->state */
191 #define STATE_NONE 0
192 #define STATE_PENDING 1
193 #define STATE_NEGOTIATING 2
194 #define STATE_CONNECTED 3
196 #define NODE_WARN_CLOCK 1 /* clock skew warning */
198 struct merlin_node {
199 char *name; /* name of this node */
200 char *source_name; /* check source name for this node */
201 char *hostgroups; /* only used for pollers */
202 uint id; /* internal index lookup number */
203 int latency; /* module to module latency of this node */
204 int sock; /* the socket */
205 int type; /* server type (master, slave, peer) */
206 int state; /* state of this node (down, pending, active) */
207 uint32_t peer_id; /* peer id, used to distribute checks */
208 int flags; /* flags for this node */
209 struct sockaddr *sa; /* should always point to sain */
210 struct sockaddr_in sain;
211 unsigned int data_timeout; /* send gracetime before we disconnect */
212 unsigned int host_checks; /* actually executed host checks */
213 unsigned int service_checks; /* actually executed service checks */
214 unsigned int warn_flags; /* warnings caught from this node */
215 time_t last_recv; /* last time node sent something to us */
216 time_t last_sent; /* when we sent something last */
217 time_t last_conn_attempt_logged; /* when we last logged a connect attempt */
218 time_t last_conn_attempt; /* when we last tried initiating a connection */
219 time_t connect_time; /* when we established a connection to this node */
220 merlin_peer_group *pgroup; /* this node's peer-group (if a poller) */
221 struct {
222 struct merlin_assigned_objects passive; /* passive check modifiers */
223 struct merlin_assigned_objects extra; /* taken over from a poller */
224 struct merlin_assigned_objects current; /* base assigned right now */
225 struct merlin_assigned_objects expired; /* expired checks */
226 } assigned;
227 merlin_nodeinfo info; /* node info */
228 int last_action; /* LA_CONNECT | LA_DISCONNECT | LA_HANDLED */
229 binlog *binlog; /* binary backlog for this node */
230 merlin_node_stats stats; /* event/data statistics */
231 iocache *ioc; /* I/O cache for bulk reads */
232 merlin_confsync csync; /* config synchronization configuration */
233 unsigned int csync_num_attempts;
234 unsigned int csync_max_attempts;
235 time_t csync_last_attempt;
236 int (*action)(struct merlin_node *, int); /* (daemon) action handler */
238 typedef struct merlin_node merlin_node;
240 #define node_table noc_table
241 extern merlin_node **noc_table, **peer_table, **poller_table;
243 extern node_selection *node_selection_by_name(const char *name);
244 extern char *get_sel_name(int index);
245 extern int get_sel_id(const char *name);
246 extern int get_num_selections(void);
247 extern linked_item *nodes_by_sel_id(int sel);
248 extern linked_item *nodes_by_sel_name(const char *name);
249 extern void node_grok_config(struct cfg_comp *config);
250 extern void node_log_event_count(merlin_node *node, int force);
251 extern void node_disconnect(merlin_node *node, const char *fmt, ...);
252 extern int node_send(merlin_node *node, void *data, unsigned int len, int flags);
253 extern int node_send_event(merlin_node *node, merlin_event *pkt, int msec);
254 extern int node_recv(merlin_node *node);
255 extern merlin_event *node_get_event(merlin_node *node);
256 extern int node_send_binlog(merlin_node *node, merlin_event *pkt);
257 extern const char *node_state(merlin_node *node);
258 extern const char *node_type(merlin_node *node);
259 extern void node_set_state(merlin_node *node, int state, const char *reason);
260 extern int node_ctrl(merlin_node *node, int code, uint selection, void *data, uint32_t len, int msec);
261 extern merlin_node *node_by_id(uint id);
262 int handle_ctrl_active(merlin_node *node, merlin_event *pkt);
265 * we make these inlined rather than macros so the compiler
266 * does type-checking in the arguments
268 static inline int node_send_ctrl_inactive(merlin_node *node, uint id, int msec)
270 return node_ctrl(node, CTRL_INACTIVE, id, NULL, 0, msec);
273 static inline int node_send_ctrl_active(merlin_node *node, uint id, merlin_nodeinfo *info, int msec)
275 return node_ctrl(node, CTRL_ACTIVE, id, (void *)info, sizeof(*info), msec);
277 #endif