|
1 /* |
|
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
|
3 * |
|
4 * U.S. Government Rights - Commercial software. Government users are subject to |
|
5 * the Sun Microsystems, Inc. standard license agreement and applicable |
|
6 * provisions of the FAR and its supplements. |
|
7 * |
|
8 * |
|
9 * This distribution may include materials developed by third parties. Sun, Sun |
|
10 * Microsystems, the Sun logo and Solaris are trademarks or registered |
|
11 * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. |
|
12 * |
|
13 */ |
|
14 |
|
15 |
|
16 /* |
|
17 * demo_module_4: |
|
18 * |
|
19 * This module is based on the SDK-DEMO4-MIB.txt MIB. It implements the |
|
20 * me4LoadGroup objects. |
|
21 * |
|
22 * This example module demonstrates following features: - Automatic Refresh of |
|
23 * data in regular intervals - Check for alarm condition in regular intervals |
|
24 * and generate trap if necessary. - Read threshold values from an external |
|
25 * configuration file called demo_module_4.conf |
|
26 */ |
|
27 |
|
28 |
|
29 #include <net-snmp/net-snmp-config.h> |
|
30 #include <net-snmp/net-snmp-includes.h> |
|
31 #include <net-snmp/agent/net-snmp-agent-includes.h> |
|
32 #include "me4LoadGroup.h" |
|
33 #include <sys/loadavg.h> |
|
34 #include <netdb.h> |
|
35 |
|
36 |
|
37 /* |
|
38 * Data for demo_module_4: loadavg1 stores data for me4SystemLoadAvg1min |
|
39 * loadavg5 stores data for me4SystemLoadAvg5min loadavg15 stores data for |
|
40 * me4SystemLoadAvg15min |
|
41 */ |
|
42 |
|
43 char *loadavg1, *loadavg5, *loadavg15; |
|
44 |
|
45 /* Alarm thresholds for demo_module_4 */ |
|
46 |
|
47 float threshold_loadavg1 = 1.0, threshold_loadavg5 = 2.0, threshold_loadavg15 = 3.0; |
|
48 |
|
49 /* Maintain previous alarm states for comparison */ |
|
50 |
|
51 int prev_loadavg1_state = OK; |
|
52 int prev_loadavg5_state = OK; |
|
53 int prev_loadavg15_state = OK; |
|
54 |
|
55 /* Common variables for information to be included in traps */ |
|
56 |
|
57 u_char hostName[MAXHOSTNAMELEN], moduleName[15]; |
|
58 |
|
59 |
|
60 /** Initializes the demo_module_4 module |
|
61 * This is the Init function which is called when the module is loaded by the agent. |
|
62 * |
|
63 * Note: The name of this function has been changed from "init_me4LoadGroup" to |
|
64 * "init_demo_module_4" to give unique names to example modules across the SMA |
|
65 * SDK. |
|
66 */ |
|
67 |
|
68 |
|
69 void |
|
70 init_demo_module_4(void) |
|
71 { |
|
72 |
|
73 int retCode; |
|
74 |
|
75 static oid me4SystemLoadAvg15min_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 3, 0}; |
|
76 static oid me4SystemLoadAvg1min_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 1, 0}; |
|
77 static oid me4SystemLoadAvg5min_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 2, 0}; |
|
78 |
|
79 DEBUGMSGTL(("me4LoadGroup", "Initializing\n")); |
|
80 |
|
81 netsnmp_register_read_only_instance(netsnmp_create_handler_registration |
|
82 ("me4SystemLoadAvg15min", |
|
83 get_me4SystemLoadAvg15min, |
|
84 me4SystemLoadAvg15min_oid, |
|
85 OID_LENGTH(me4SystemLoadAvg15min_oid), |
|
86 HANDLER_CAN_RONLY)); |
|
87 netsnmp_register_read_only_instance(netsnmp_create_handler_registration |
|
88 ("me4SystemLoadAvg1min", |
|
89 get_me4SystemLoadAvg1min, |
|
90 me4SystemLoadAvg1min_oid, |
|
91 OID_LENGTH(me4SystemLoadAvg1min_oid), |
|
92 HANDLER_CAN_RONLY)); |
|
93 netsnmp_register_read_only_instance(netsnmp_create_handler_registration |
|
94 ("me4SystemLoadAvg5min", |
|
95 get_me4SystemLoadAvg5min, |
|
96 me4SystemLoadAvg5min_oid, |
|
97 OID_LENGTH(me4SystemLoadAvg5min_oid), |
|
98 HANDLER_CAN_RONLY)); |
|
99 |
|
100 /* Initialize some common data */ |
|
101 |
|
102 retCode = gethostname((char *) hostName, MAXHOSTNAMELEN); |
|
103 if (retCode != 0) |
|
104 strcpy((char *) hostName, "null\0"); |
|
105 |
|
106 strcpy((char *) moduleName, "demo_module_4\0"); |
|
107 |
|
108 |
|
109 /* Allocate memory once. These variables will hold load data */ |
|
110 |
|
111 loadavg1 = malloc(10 * sizeof(char)); |
|
112 loadavg5 = malloc(10 * sizeof(char)); |
|
113 loadavg15 = malloc(10 * sizeof(char)); |
|
114 |
|
115 /* |
|
116 * Register for thresholds. When a token (say threshold_loadavg1) is |
|
117 * found in demo_module_4.conf file, the read_load_thresholds function is |
|
118 * called by the agent |
|
119 */ |
|
120 |
|
121 register_config_handler("demo_module_4", "threshold_loadavg1", |
|
122 read_load_thresholds, NULL, NULL); |
|
123 |
|
124 register_config_handler("demo_module_4", "threshold_loadavg5", |
|
125 read_load_thresholds, NULL, NULL); |
|
126 |
|
127 register_config_handler("demo_module_4", "threshold_loadavg15", |
|
128 read_load_thresholds, NULL, NULL); |
|
129 |
|
130 |
|
131 snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG, |
|
132 demo_4_post_read_config, NULL); |
|
133 |
|
134 |
|
135 } |
|
136 |
|
137 /** |
|
138 * The callback function that is called after the configuration files are |
|
139 * read by the agent ( the thresholds are loaded into the module ) |
|
140 */ |
|
141 |
|
142 int |
|
143 demo_4_post_read_config(int a, int b, void *c, void *d) |
|
144 { |
|
145 |
|
146 /* Refresh the load data every 60 seconds */ |
|
147 snmp_alarm_register(60, SA_REPEAT, refreshLoadAvg, NULL); |
|
148 |
|
149 /* Acquire the data first time */ |
|
150 refreshLoadAvg(0, NULL); |
|
151 |
|
152 return 1; |
|
153 |
|
154 } |
|
155 |
|
156 |
|
157 /* |
|
158 * This function is generated by mib2c. It is called when an SNMP "get" |
|
159 * request arrives for the node me4SystemLoadAvg15min |
|
160 * |
|
161 */ |
|
162 |
|
163 int |
|
164 get_me4SystemLoadAvg15min(netsnmp_mib_handler * handler, |
|
165 netsnmp_handler_registration * reginfo, |
|
166 netsnmp_agent_request_info * reqinfo, |
|
167 netsnmp_request_info * requests) |
|
168 { |
|
169 /* |
|
170 * We are never called for a GETNEXT if it's registered as a "instance", |
|
171 * as it's "magically" handled for us. |
|
172 */ |
|
173 |
|
174 /* |
|
175 * a instance handler also only hands us one request at a time, so we |
|
176 * don't need to loop over a list of requests; we'll only get one. |
|
177 */ |
|
178 |
|
179 /* Refresh the load data by calling the refresh function */ |
|
180 refreshLoadAvg(0, NULL); |
|
181 |
|
182 switch (reqinfo->mode) { |
|
183 |
|
184 case MODE_GET: |
|
185 |
|
186 refreshLoadAvg(0, NULL); |
|
187 |
|
188 snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) loadavg15, strlen(loadavg15)); |
|
189 break; |
|
190 |
|
191 |
|
192 default: |
|
193 /* we should never get here, so this is a really bad error */ |
|
194 return SNMP_ERR_GENERR; |
|
195 } |
|
196 |
|
197 return SNMP_ERR_NOERROR; |
|
198 } |
|
199 |
|
200 /* |
|
201 * This function is generated by mib2c. It is called when an SNMP "get" |
|
202 * request arrives for the node me4SystemLoadAvg1min |
|
203 * |
|
204 */ |
|
205 |
|
206 |
|
207 int |
|
208 get_me4SystemLoadAvg1min(netsnmp_mib_handler * handler, |
|
209 netsnmp_handler_registration * reginfo, |
|
210 netsnmp_agent_request_info * reqinfo, |
|
211 netsnmp_request_info * requests) |
|
212 { |
|
213 /* |
|
214 * We are never called for a GETNEXT if it's registered as a "instance", |
|
215 * as it's "magically" handled for us. |
|
216 */ |
|
217 |
|
218 /* |
|
219 * a instance handler also only hands us one request at a time, so we |
|
220 * don't need to loop over a list of requests; we'll only get one. |
|
221 */ |
|
222 |
|
223 switch (reqinfo->mode) { |
|
224 |
|
225 case MODE_GET: |
|
226 |
|
227 refreshLoadAvg(0, NULL); |
|
228 snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) loadavg1, strlen(loadavg1)); |
|
229 break; |
|
230 |
|
231 |
|
232 default: |
|
233 /* we should never get here, so this is a really bad error */ |
|
234 return SNMP_ERR_GENERR; |
|
235 } |
|
236 |
|
237 return SNMP_ERR_NOERROR; |
|
238 } |
|
239 |
|
240 /* |
|
241 * This function is generated by mib2c. It is called when an SNMP "get" |
|
242 * request arrives for the node me4SystemLoadAvg5min |
|
243 * |
|
244 */ |
|
245 |
|
246 |
|
247 int |
|
248 get_me4SystemLoadAvg5min(netsnmp_mib_handler * handler, |
|
249 netsnmp_handler_registration * reginfo, |
|
250 netsnmp_agent_request_info * reqinfo, |
|
251 netsnmp_request_info * requests) |
|
252 { |
|
253 /* |
|
254 * We are never called for a GETNEXT if it's registered as a "instance", |
|
255 * as it's "magically" handled for us. |
|
256 */ |
|
257 |
|
258 /* |
|
259 * a instance handler also only hands us one request at a time, so we |
|
260 * don't need to loop over a list of requests; we'll only get one. |
|
261 */ |
|
262 |
|
263 refreshLoadAvg(0, NULL); |
|
264 |
|
265 switch (reqinfo->mode) { |
|
266 |
|
267 case MODE_GET: |
|
268 |
|
269 refreshLoadAvg(0, NULL); |
|
270 |
|
271 snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) loadavg5, strlen(loadavg5)); |
|
272 break; |
|
273 |
|
274 default: |
|
275 /* we should never get here, so this is a really bad error */ |
|
276 return SNMP_ERR_GENERR; |
|
277 } |
|
278 |
|
279 return SNMP_ERR_NOERROR; |
|
280 } |
|
281 |
|
282 |
|
283 /* |
|
284 * refreshLoadAvg: This is the function which "refreshes" the load data using |
|
285 * the system call "getloadavg". The data is stored in the 3 variables |
|
286 * loadavg1, loadavg5, loadavg15. Once the data is refreshed, the "check" |
|
287 * functions are called to check for alarm conditions |
|
288 */ |
|
289 |
|
290 void |
|
291 refreshLoadAvg(unsigned int clientreg, void *clientarg) |
|
292 { |
|
293 |
|
294 double loadavg[3]; |
|
295 int numOfSamples = getloadavg(loadavg, 3); |
|
296 sprintf(loadavg1, "%.3f\0", loadavg[LOADAVG_1MIN]); |
|
297 sprintf(loadavg5, "%.3f\0", loadavg[LOADAVG_5MIN]); |
|
298 sprintf(loadavg15, "%.3f\0", loadavg[LOADAVG_15MIN]); |
|
299 |
|
300 check_loadavg1_state(); |
|
301 check_loadavg5_state(); |
|
302 check_loadavg15_state(); |
|
303 |
|
304 } |
|
305 |
|
306 |
|
307 /* |
|
308 * Function: conv_alarm_state : This function returns appropriate charecter |
|
309 * string for each integer alarm type |
|
310 */ |
|
311 |
|
312 char * |
|
313 conv_alarm_state(int state) |
|
314 { |
|
315 switch (state) { |
|
316 case 0: |
|
317 return "OK\0"; |
|
318 case 1: |
|
319 return "ERROR\0"; |
|
320 default: |
|
321 return "NULL\0"; |
|
322 } |
|
323 } |
|
324 |
|
325 |
|
326 |
|
327 /* |
|
328 * read_load_thresholds: This function is called when a registered token (see |
|
329 * Init_demo_module_4 function) is found in the appropriate configuration |
|
330 * file. The token's values (thresholds) are then stored in some variables. |
|
331 */ |
|
332 |
|
333 void |
|
334 read_load_thresholds(const char *token, char *cptr) |
|
335 { |
|
336 |
|
337 if (strcmp(token, "threshold_loadavg1") == 0) { |
|
338 threshold_loadavg1 = atof(cptr); |
|
339 } else if (strcmp(token, "threshold_loadavg5") == 0) { |
|
340 threshold_loadavg5 = atof(cptr); |
|
341 } else if (strcmp(token, "threshold_loadavg15") == 0) { |
|
342 threshold_loadavg15 = atof(cptr); |
|
343 } else { |
|
344 /* Do nothing */ |
|
345 } |
|
346 |
|
347 return; |
|
348 |
|
349 } |
|
350 |
|
351 |
|
352 |
|
353 /* send_trap: This function generates an snmpv2 trap */ |
|
354 |
|
355 void |
|
356 send_trap(u_char * hostname, u_char * modulename, oid * trapoid, int size, u_char * status, u_char * description) |
|
357 { |
|
358 |
|
359 /* This is the notification type itself. This is statusChange trap */ |
|
360 |
|
361 oid notification_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 2, 1}; |
|
362 |
|
363 size_t notification_oid_len = OID_LENGTH(notification_oid); |
|
364 |
|
365 /* |
|
366 * In the notification, we have to assign our notification OID to the |
|
367 * snmpTrapOID.0 object. Here is it's definition. |
|
368 */ |
|
369 |
|
370 oid objid_snmptrap[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0}; |
|
371 size_t objid_snmptrap_len = OID_LENGTH(objid_snmptrap); |
|
372 |
|
373 /* |
|
374 * here is where we store the variables to be sent in the trap |
|
375 */ |
|
376 |
|
377 netsnmp_variable_list *notification_vars = NULL; |
|
378 |
|
379 oid hostname_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 1, 0}; |
|
380 |
|
381 size_t hostname_oid_len = OID_LENGTH(hostname_oid); |
|
382 |
|
383 |
|
384 oid modulename_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 2, 0}; |
|
385 |
|
386 size_t modulename_oid_len = OID_LENGTH(modulename_oid); |
|
387 |
|
388 |
|
389 oid nodeoid_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 3, 0}; |
|
390 |
|
391 size_t nodeoid_oid_len = OID_LENGTH(nodeoid_oid); |
|
392 |
|
393 |
|
394 oid status_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 4, 0}; |
|
395 |
|
396 size_t status_oid_len = OID_LENGTH(status_oid); |
|
397 |
|
398 |
|
399 oid description_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 3, 5, 0}; |
|
400 |
|
401 size_t description_oid_len = OID_LENGTH(description_oid); |
|
402 |
|
403 |
|
404 /* |
|
405 * add in the trap definition object |
|
406 */ |
|
407 |
|
408 snmp_varlist_add_variable(¬ification_vars, |
|
409 /* |
|
410 * the snmpTrapOID.0 variable |
|
411 */ |
|
412 objid_snmptrap, objid_snmptrap_len, |
|
413 /* |
|
414 * value type is an OID |
|
415 */ |
|
416 ASN_OBJECT_ID, |
|
417 /* |
|
418 * value contents is our notification OID |
|
419 */ |
|
420 (u_char *) notification_oid, |
|
421 /* |
|
422 * size in bytes = oid length * sizeof(oid) |
|
423 */ |
|
424 notification_oid_len * sizeof(oid)); |
|
425 |
|
426 |
|
427 /* |
|
428 * if we wanted to insert additional objects, we'd do it here |
|
429 */ |
|
430 |
|
431 |
|
432 snmp_varlist_add_variable(¬ification_vars, |
|
433 hostname_oid, hostname_oid_len, |
|
434 /* |
|
435 * value type is an OID |
|
436 */ |
|
437 ASN_OCTET_STR, |
|
438 /* |
|
439 * value contents is our notification OID |
|
440 */ |
|
441 (u_char *) hostname, |
|
442 /* |
|
443 * size in bytes = oid length * sizeof(oid) |
|
444 */ |
|
445 strlen((char *) hostname)); |
|
446 |
|
447 |
|
448 snmp_varlist_add_variable(¬ification_vars, |
|
449 modulename_oid, modulename_oid_len, |
|
450 /* |
|
451 * value type is an OID |
|
452 */ |
|
453 ASN_OCTET_STR, |
|
454 /* |
|
455 * value contents is our notification OID |
|
456 */ |
|
457 (u_char *) modulename, |
|
458 /* |
|
459 * size in bytes = oid length * sizeof(oid) |
|
460 */ |
|
461 strlen((char *) modulename)); |
|
462 |
|
463 |
|
464 snmp_varlist_add_variable(¬ification_vars, |
|
465 nodeoid_oid, nodeoid_oid_len, |
|
466 /* |
|
467 * value type is an OID |
|
468 */ |
|
469 ASN_OBJECT_ID, |
|
470 /* |
|
471 * value contents is our notification OID |
|
472 */ |
|
473 (u_char *) trapoid, |
|
474 /* |
|
475 * size in bytes = oid length * sizeof(oid) |
|
476 */ |
|
477 size * sizeof(oid)); |
|
478 |
|
479 |
|
480 snmp_varlist_add_variable(¬ification_vars, |
|
481 status_oid, status_oid_len, |
|
482 /* |
|
483 * value type is an OID |
|
484 */ |
|
485 ASN_OCTET_STR, |
|
486 /* |
|
487 * value contents is our notification OID |
|
488 */ |
|
489 (u_char *) status, |
|
490 /* |
|
491 * size in bytes = oid length * sizeof(oid) |
|
492 */ |
|
493 strlen((char *) status)); |
|
494 |
|
495 |
|
496 snmp_varlist_add_variable(¬ification_vars, |
|
497 description_oid, description_oid_len, |
|
498 /* |
|
499 * value type is an OID |
|
500 */ |
|
501 ASN_OCTET_STR, |
|
502 /* |
|
503 * value contents is our notification OID |
|
504 */ |
|
505 (u_char *) description, |
|
506 /* |
|
507 * size in bytes = oid length * sizeof(oid) |
|
508 */ |
|
509 strlen((char *) description)); |
|
510 |
|
511 |
|
512 /* SEND THE TRAP !!!! */ |
|
513 |
|
514 send_v2trap(notification_vars); |
|
515 |
|
516 /* |
|
517 * free the created notification variable list |
|
518 */ |
|
519 |
|
520 DEBUGMSGTL(("example_notification", "cleaning up\n")); |
|
521 snmp_free_varbind(notification_vars); |
|
522 |
|
523 return; |
|
524 |
|
525 } |
|
526 |
|
527 |
|
528 |
|
529 /* |
|
530 * check_loadavg1_state: This function does 2 things: step-1) Determine the |
|
531 * current alarm state of the node by comparing it's value with threshold. |
|
532 * step-2) Depending on the new state of the node, generate a trap |
|
533 */ |
|
534 |
|
535 void |
|
536 check_loadavg1_state() |
|
537 { |
|
538 |
|
539 /* Trap stuff */ |
|
540 |
|
541 oid trapoid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 1, 0}; |
|
542 u_char status[8]; |
|
543 u_char description[] = "Load Average over last 1 minute crossed the threshold \0"; |
|
544 int size; |
|
545 int new_loadavg1_state = OK; |
|
546 float currentLoad = atof(loadavg1); |
|
547 |
|
548 /* Step-1 */ |
|
549 |
|
550 /* If threshold is crossed, set state to ERROR */ |
|
551 if (currentLoad > threshold_loadavg1) { |
|
552 new_loadavg1_state = ERROR; |
|
553 } |
|
554 /* Step-2 */ |
|
555 |
|
556 /* Depending on the new state, send trap if necessary */ |
|
557 |
|
558 size = sizeof(trapoid) / sizeof(oid); |
|
559 strcpy((char *) status, conv_alarm_state(new_loadavg1_state)); |
|
560 |
|
561 if (new_loadavg1_state > prev_loadavg1_state) { |
|
562 /* Send trap */ |
|
563 send_trap(hostName, moduleName, trapoid, size, status, description); |
|
564 prev_loadavg1_state = new_loadavg1_state; |
|
565 } else if (new_loadavg1_state == prev_loadavg1_state) { |
|
566 /* No Change in state .. Do nothing */ |
|
567 } else if (new_loadavg1_state < prev_loadavg1_state) { |
|
568 if (new_loadavg1_state == OK) { |
|
569 /* Send OK trap */ |
|
570 prev_loadavg1_state = OK; |
|
571 send_trap(hostName, moduleName, trapoid, size, status, description); |
|
572 } |
|
573 } |
|
574 } |
|
575 |
|
576 /* |
|
577 * check_loadavg5_state: This function does 2 things: step-1) Determine the |
|
578 * current alarm state of the node by comparing it's value with threshold. |
|
579 * step-2) Depending on the new state of the node, generate a trap |
|
580 */ |
|
581 |
|
582 |
|
583 void |
|
584 check_loadavg5_state() |
|
585 { |
|
586 |
|
587 /* Trap stuff */ |
|
588 |
|
589 oid trapoid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 2, 0}; |
|
590 u_char status[8]; |
|
591 u_char description[] = "Load Average over last 5 minute crossed the threshold \0"; |
|
592 int size; |
|
593 |
|
594 int new_loadavg5_state = OK; |
|
595 double currentLoad = atof(loadavg5); |
|
596 |
|
597 /* If threshold is crossed, set state to ERROR */ |
|
598 if (currentLoad > threshold_loadavg5) |
|
599 new_loadavg5_state = ERROR; |
|
600 |
|
601 /* Depending on the new state, send trap if necessary */ |
|
602 |
|
603 size = sizeof(trapoid) / sizeof(oid); |
|
604 strcpy((char *) status, conv_alarm_state(new_loadavg5_state)); |
|
605 |
|
606 if (new_loadavg5_state > prev_loadavg5_state) { |
|
607 /* Send trap */ |
|
608 send_trap(hostName, moduleName, trapoid, size, status, description); |
|
609 prev_loadavg5_state = new_loadavg5_state; |
|
610 } else if (new_loadavg5_state == prev_loadavg5_state) { |
|
611 /* No Change in state .. Do nothing */ |
|
612 } else if (new_loadavg5_state < prev_loadavg5_state) { |
|
613 if (new_loadavg5_state == OK) { |
|
614 /* Send OK trap */ |
|
615 prev_loadavg5_state = OK; |
|
616 send_trap(hostName, moduleName, trapoid, size, status, description); |
|
617 } |
|
618 } |
|
619 } |
|
620 |
|
621 /* |
|
622 * check_loadavg15_state: This function does 2 things: step-1) Determine the |
|
623 * current alarm state of the node by comparing it's value with threshold. |
|
624 * step-2) Depending on the new state of the node, generate a trap |
|
625 */ |
|
626 |
|
627 |
|
628 void |
|
629 check_loadavg15_state() |
|
630 { |
|
631 |
|
632 /* Trap stuff */ |
|
633 |
|
634 oid trapoid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 4, 1, 3, 0}; |
|
635 u_char status[8]; |
|
636 u_char description[] = "Load Average over last 15 minute crossed the threshold \0"; |
|
637 int size; |
|
638 |
|
639 int new_loadavg15_state = OK; |
|
640 double currentLoad = atof(loadavg15); |
|
641 |
|
642 /* If threshold is crossed, set state to ERROR */ |
|
643 if (currentLoad > threshold_loadavg15) |
|
644 new_loadavg15_state = ERROR; |
|
645 |
|
646 /* Depending on the new state, send trap if necessary */ |
|
647 |
|
648 size = sizeof(trapoid) / sizeof(oid); |
|
649 strcpy((char *) status, conv_alarm_state(new_loadavg15_state)); |
|
650 |
|
651 if (new_loadavg15_state > prev_loadavg15_state) { |
|
652 /* Send trap */ |
|
653 prev_loadavg15_state = new_loadavg15_state; |
|
654 send_trap(hostName, moduleName, trapoid, size, status, description); |
|
655 } else if (new_loadavg15_state == prev_loadavg15_state) { |
|
656 /* No Change in state .. Do nothing */ |
|
657 } else if (new_loadavg15_state < prev_loadavg15_state) { |
|
658 if (new_loadavg15_state == OK) { |
|
659 /* Send OK trap */ |
|
660 prev_loadavg15_state = OK; |
|
661 send_trap(hostName, moduleName, trapoid, size, status, description); |
|
662 } |
|
663 } |
|
664 } |