# | Line 1 | Line 1 | |
---|---|---|
1 | + | /* |
2 | + | * i-scream central monitoring system |
3 | + | * Copyright (C) 2000-2002 i-scream |
4 | + | * |
5 | + | * This program is free software; you can redistribute it and/or |
6 | + | * modify it under the terms of the GNU General Public License |
7 | + | * as published by the Free Software Foundation; either version 2 |
8 | + | * of the License, or (at your option) any later version. |
9 | + | * |
10 | + | * This program is distributed in the hope that it will be useful, |
11 | + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | + | * GNU General Public License for more details. |
14 | + | * |
15 | + | * You should have received a copy of the GNU General Public License |
16 | + | * along with this program; if not, write to the Free Software |
17 | + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 | + | */ |
19 | + | |
20 | #include <stdio.h> | |
2 | – | #include <sys/socket.h> |
21 | #include <stdlib.h> | |
22 | #include <unistd.h> | |
23 | #include <syslog.h> | |
24 | #include <netinet/in.h> | |
25 | < | #include <ukcprog.h> |
25 | > | #include "ukcprog.h" |
26 | #include <netdb.h> | |
27 | < | #include <strings.h> |
27 | > | #include <string.h> |
28 | > | #include "statgrab.h" |
29 | > | #include <time.h> |
30 | > | #include <sys/socket.h> |
31 | > | #include <netinet/in.h> |
32 | > | #include <arpa/inet.h> |
33 | ||
34 | #define RECONFIGURE_RETURN_CODE 2 | |
35 | + | #define UDP_MAX_PACKET_SIZE 8192 |
36 | ||
37 | typedef struct{ | |
38 | int fm_port; | |
39 | char *fm_host; | |
40 | < | |
40 | > | |
41 | > | char *my_ip; |
42 | char *my_fqdn; | |
43 | char *server_fqdn; | |
44 | int server_udp_port; | |
# | Line 38 | Line 63 | char* sock_comm(FILE *f_r, FILE *f_w, char *sendString | |
63 | int ihost_configure(ihost_state_t *ihost_state){ | |
64 | struct sockaddr_in addr; | |
65 | struct in_addr haddr; | |
66 | + | struct sockaddr ip; |
67 | + | int ip_len; |
68 | int sd; | |
69 | FILE *fm_fd_r, *fm_fd_w; | |
70 | char *reply; | |
# | Line 59 | Line 86 | int ihost_configure(ihost_state_t *ihost_state){ | |
86 | return -1; | |
87 | } | |
88 | ||
89 | < | memset((char *)&addr, 0, sizeof addr); |
89 | > | memset(&addr, 0, sizeof addr); |
90 | addr.sin_family = AF_INET; | |
91 | < | memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr); |
91 | > | memcpy(&addr.sin_addr, &haddr, sizeof haddr); |
92 | addr.sin_port = htons(ihost_state->fm_port); | |
93 | ||
94 | if (connect(sd, (struct sockaddr *)&addr, sizeof addr) != 0) { | |
# | Line 71 | Line 98 | int ihost_configure(ihost_state_t *ihost_state){ | |
98 | ||
99 | /* Need to open 2 files, one for reading one for writing, as it gets confused if we only use 1 :) */ | |
100 | if ((fm_fd_r=fdopen(sd,"r")) == NULL){ | |
101 | < | errf("Failed to open stream (%m)"); |
101 | > | errf("Failed to open read stream (%m)"); |
102 | return -1; | |
103 | } | |
104 | ||
105 | if ((fm_fd_w=fdopen(dup(sd),"w")) == NULL){ | |
106 | < | errf("Failed to open stream (%m)"); |
106 | > | errf("Failed to open write stream (%m)"); |
107 | return -1; | |
108 | } | |
109 | + | ip_len=sizeof ip; |
110 | + | memset(&ip, 0, ip_len); |
111 | + | if((getsockname(sd, &ip, &ip_len)) != 0){ |
112 | + | errf("Failed to get IP address (%m)"); |
113 | + | return -1; |
114 | + | } |
115 | + | if (ip.sa_family!=AF_INET){ |
116 | + | errf("sa family is wrong type"); |
117 | + | return -1; |
118 | + | } |
119 | + | |
120 | + | if((ihost_state->my_ip=inet_ntoa(((struct sockaddr_in *)&ip)->sin_addr))==NULL){ |
121 | + | errf("Failed to get IP (%m)"); |
122 | + | return -1; |
123 | + | } |
124 | ||
125 | reply=sock_comm(fm_fd_r, fm_fd_w, "STARTCONFIG"); | |
126 | if ((reply==NULL) || (strncasecmp(reply, "OK", 2) != 0) ) { | |
# | Line 142 | Line 184 | int ihost_configure(ihost_state_t *ihost_state){ | |
184 | ||
185 | reply=sock_comm(fm_fd_r, fm_fd_w, "FILTER"); | |
186 | if((reply== NULL) || (strncasecmp(reply, "ERROR", 5)==0)){ | |
187 | < | errf("Server error (%m)"); |
187 | > | errf("Server error FILTER failed (%m)"); |
188 | return -1; | |
189 | } | |
190 | reply_ptr=strchr(reply,';'); | |
# | Line 155 | Line 197 | int ihost_configure(ihost_state_t *ihost_state){ | |
197 | errf("strdup failed (%m)"); | |
198 | return -1; | |
199 | } | |
200 | < | reply=++reply_ptr; |
200 | > | reply=reply_ptr + 1; |
201 | reply_ptr=strchr(reply,';'); | |
202 | if (reply_ptr==NULL){ | |
203 | errf("Incorrect data returned 2"); | |
# | Line 163 | Line 205 | int ihost_configure(ihost_state_t *ihost_state){ | |
205 | } | |
206 | *reply_ptr='\0'; | |
207 | ihost_state->server_udp_port=atoi(reply); | |
208 | < | reply=++reply_ptr; |
208 | > | reply=reply_ptr+1; |
209 | ihost_state->server_tcp_port=atoi(reply); | |
210 | if ((ihost_state->server_tcp_port==0) || (ihost_state->server_udp_port==0)){ | |
211 | errf("Incorrect data returned 3 "); | |
# | Line 177 | Line 219 | int ihost_configure(ihost_state_t *ihost_state){ | |
219 | } | |
220 | ||
221 | if(fclose(fm_fd_r) !=0){ | |
222 | < | errf("Failed to close FD (%m)"); |
222 | > | errf("Failed to close read FD (%m)"); |
223 | return -1; | |
224 | } | |
225 | if(fclose(fm_fd_w) !=0){ | |
226 | < | errf("Failed to close FD (%m)"); |
226 | > | errf("Failed to close write FD (%m)"); |
227 | return -1; | |
228 | } | |
229 | ||
# | Line 206 | Line 248 | int heartbeat(ihost_state_t *ihost_state){ | |
248 | return -1; | |
249 | } | |
250 | ||
251 | < | memset((char *)&addr, 0, sizeof addr); |
251 | > | memset(&addr, 0, sizeof addr); |
252 | addr.sin_family = AF_INET; | |
253 | < | memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr); |
253 | > | memcpy(&addr.sin_addr, &haddr, sizeof haddr); |
254 | addr.sin_port = htons(ihost_state->server_tcp_port); | |
255 | ||
256 | if (connect(sd, (struct sockaddr *)&addr, sizeof addr) != 0) { | |
# | Line 232 | Line 274 | int heartbeat(ihost_state_t *ihost_state){ | |
274 | errf("Server error"); | |
275 | return -1; | |
276 | } | |
277 | < | if (ihost_state->fm_host!=NULL) free(ihost_state->fm_host); |
277 | > | |
278 | reply=sock_comm(fm_fd_r, fm_fd_w, "CONFIG"); | |
279 | if ((reply==NULL) || (strncasecmp(reply, "ERROR", 5) == 0) ) { | |
280 | errf("Server error"); | |
# | Line 272 | Line 314 | int heartbeat(ihost_state_t *ihost_state){ | |
314 | return -1; | |
315 | } | |
316 | ||
317 | + | fflush(fm_fd_r); |
318 | + | fflush(fm_fd_w); |
319 | + | |
320 | if(fclose(fm_fd_r) !=0){ | |
321 | < | errf("Failed to close FD (%m)"); |
321 | > | errf("Failed to close read FD (%m)"); |
322 | return -1; | |
323 | } | |
324 | if(fclose(fm_fd_w) !=0){ | |
325 | < | errf("Failed to close FD (%m)"); |
325 | > | errf("Failed to close write FD (%m)"); |
326 | return -1; | |
327 | } | |
328 | ||
329 | return exitcode; | |
330 | } | |
331 | ||
332 | + | char *stat_grab(ihost_state_t *ihost_state, int counter){ |
333 | + | #define NUM_STATS 9 |
334 | + | char *stats[NUM_STATS]; |
335 | + | char *xml_data=NULL; |
336 | + | char *xml_data_p; |
337 | + | int x=0; |
338 | + | |
339 | + | stats[0]=get_cpu_stats(); |
340 | + | stats[1]=get_disk_stats(); |
341 | + | stats[2]=get_load_stats(); |
342 | + | stats[3]=get_memory_stats(); |
343 | + | stats[4]=get_os_info(); |
344 | + | stats[5]=get_page_stats(); |
345 | + | stats[6]=get_process_stats(); |
346 | + | stats[7]=get_swap_stats(); |
347 | + | stats[8]=get_user_stats(); |
348 | ||
349 | + | for(;x<NUM_STATS;x++){ |
350 | + | if(stats[x]==NULL){ |
351 | + | return NULL; |
352 | + | } |
353 | + | if(xml_data==NULL){ |
354 | + | if((xml_data=strf("%s", stats[x])) == NULL){ |
355 | + | errf("str failed (%m)"); |
356 | + | return NULL; |
357 | + | } |
358 | + | }else{ |
359 | + | xml_data_p=xml_data; |
360 | + | if((xml_data=strf("%s%s", xml_data, stats[x])) == NULL){ |
361 | + | errf("str failed (%m)"); |
362 | + | return NULL; |
363 | + | } |
364 | + | free(xml_data_p); |
365 | + | } |
366 | + | free(stats[x]); |
367 | + | } |
368 | + | xml_data_p=xml_data; |
369 | + | xml_data=strf("<packet seq_no=\"%d\" machine_name=\"%s\" date=\"%ld\" type=\"data\" ip=\"%s\" key=\"%s\">%s</packet>", counter, ihost_state->my_fqdn, time(NULL), ihost_state->my_ip, ihost_state->key, xml_data); |
370 | + | free(xml_data_p); |
371 | + | |
372 | + | return xml_data; |
373 | + | } |
374 | + | |
375 | + | int send_stats(ihost_state_t *ihost_state, char *data_stream){ |
376 | + | struct sockaddr_in addr; |
377 | + | struct in_addr haddr; |
378 | + | |
379 | + | int sd; |
380 | + | size_t len; |
381 | + | |
382 | + | len=strlen(data_stream); |
383 | + | if(len>UDP_MAX_PACKET_SIZE){ |
384 | + | errf("Too big to send to server. Please reconfigure client and server and recompile"); |
385 | + | exit(1); |
386 | + | } |
387 | + | |
388 | + | if (get_host_addr(ihost_state->server_fqdn, &haddr) != 0){ |
389 | + | errf("Failed to resolve address %s (%m)", ihost_state->fm_host); |
390 | + | return -1; |
391 | + | } |
392 | + | |
393 | + | if((sd=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){ |
394 | + | errf("failed to create UDP socket (%m)"); |
395 | + | return -1; |
396 | + | } |
397 | + | |
398 | + | memset(&addr, 0, sizeof(addr)); |
399 | + | addr.sin_family=AF_INET; |
400 | + | memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr); |
401 | + | addr.sin_port = htons(ihost_state->server_udp_port); |
402 | + | |
403 | + | if((sendto(sd, data_stream, len, 0, (struct sockaddr *) &addr, sizeof(addr))) != len){ |
404 | + | errf("Send the wrong number of bytes (%m)"); |
405 | + | return -1; |
406 | + | } |
407 | + | |
408 | + | close(sd); |
409 | + | |
410 | + | return 0; |
411 | + | } |
412 | + | |
413 | int main(int argc, char **argv){ | |
414 | ihost_state_t ihost_state; | |
415 | int heartbeat_exit; | |
416 | int counter=0; | |
417 | + | long udp_time=0, tcp_time=0, stat_grab_time=0, cur_time=0; |
418 | + | int sleep_delay=0; |
419 | + | char *xml_stats; |
420 | ||
293 | – | |
421 | /* NULL'ify so i can tell if i need to free it or not */ | |
422 | ihost_state.fm_host=NULL; | |
423 | ihost_state.my_fqdn=NULL; | |
# | Line 315 | Line 442 | int main(int argc, char **argv){ | |
442 | exit(1); | |
443 | } | |
444 | ||
445 | < | while(TRUE){ |
445 | > | for(;;){ |
446 | > | cur_time=time(NULL); |
447 | > | if(cur_time>=tcp_time){ |
448 | > | /*printf("sending TCP\n");*/ |
449 | > | heartbeat_exit=heartbeat(&ihost_state); |
450 | > | if(heartbeat_exit==RECONFIGURE_RETURN_CODE){ |
451 | > | /*errf("heartbeat needs to be reconfigured");*/ |
452 | > | ihost_configure(&ihost_state); |
453 | > | /* So udp doesn't wait til next sending before updating */ |
454 | > | udp_time=0; |
455 | > | } |
456 | > | if(heartbeat_exit==-1){ |
457 | > | errf("ah crap"); |
458 | > | exit(1); |
459 | > | } |
460 | > | tcp_time=time(NULL)+ihost_state.tcp_update_time; |
461 | > | } |
462 | ||
463 | < | heartbeat_exit=heartbeat(&ihost_state); |
464 | < | if(heartbeat_exit==RECONFIGURE_RETURN_CODE){ |
465 | < | errf("heartbeat needs to be reconfigured"); |
466 | < | ihost_configure(&ihost_state); |
463 | > | if(cur_time>=udp_time){ |
464 | > | /*printf("sending UDP\n");*/ |
465 | > | stat_grab_time=time(NULL); |
466 | > | if((xml_stats=stat_grab(&ihost_state, counter++)) == NULL){ |
467 | > | errf("Failed to get stats (%m)"); |
468 | > | exit(1); |
469 | > | } |
470 | > | stat_grab_time=time(NULL)-stat_grab_time; |
471 | > | send_stats(&ihost_state, xml_stats); |
472 | > | free(xml_stats); |
473 | > | udp_time=time(NULL)+ihost_state.udp_update_time-stat_grab_time; |
474 | } | |
475 | < | if(heartbeat_exit==-1){ |
476 | < | errf("ah crap"); |
477 | < | exit(1); |
478 | < | } |
479 | < | printf("Count : %d\n",counter++); |
480 | < | printf("waiting %d\n",ihost_state.tcp_update_time); |
481 | < | sleep(ihost_state.tcp_update_time); |
475 | > | |
476 | > | if(tcp_time<udp_time){ |
477 | > | sleep_delay=tcp_time-time(NULL); |
478 | > | }else{ |
479 | > | sleep_delay=udp_time-time(NULL); |
480 | > | } |
481 | > | |
482 | > | /*printf("tcp epoc: %ld \t udp epoc: %ld\ntime:%ld \tsleeping: %d\n", tcp_time, udp_time, time(NULL), sleep_delay);*/ |
483 | > | if(sleep_delay>0) sleep(sleep_delay); |
484 | } | |
485 | return 0; | |
486 | } |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |