--- projects/cms/source/ihost/ihost.c 2002/05/29 23:03:53 1.27
+++ projects/cms/source/ihost/ihost.c 2003/03/03 12:18:35 1.28
@@ -24,622 +24,795 @@
#include
#include
-#include
#include
-#include
-#include
-#include "ukcprog.h"
-#include
#include
-#include "statgrab.h"
-#include
+#include
#include
-#include
-#include
+#include
+#include
+#include
-#define RECONFIGURE_RETURN_CODE 2
+#include
+#include "statgrab.h"
-#define logmessage(level, ...) do { cur_level = level; errf(__VA_ARGS__); } while (0)
+#define LOG_CRIT 0
+#define LOG_ERR 1
+#define LOG_INFO 2
+#define LOG_DEBUG 3
+#define PID_FILE "/var/run/ihost.pid"
+#define LOGFILE_PATH "/var/log/ihost.log"
+#define VERSION ".03"
+
+#define MAX_UDP_PACKET_SIZE 8192
+
typedef struct{
- int fm_port;
- char *fm_host;
+ int filtermanager_port;
+ char *filtermanager_host;
- char *my_ip;
- char *my_fqdn;
+ char *host_ip;
+ char *host_fqdn;
+
char *server_fqdn;
int server_udp_port;
- int server_tcp_port;
+
+ /* Weird stuff iscream wants sent to it */
char *last_modified;
- char *files_list;
- char *key;
+ char *file_list;
+
int udp_update_time;
- int tcp_update_time;
+// int config_ttl;
+ time_t config_ttl;
+
}ihost_state_t;
-static int log_level;
-static int cur_level;
-static int syslog_logging;
+typedef struct{
+ int verbose;
+ int daemon;
-void log_errors(const char *message){
- if(log_level>=cur_level){
- if (syslog_logging==1){
- syslog(cur_level, "%s\n", message);
+ FILE *log;
+}ihost_config_t;
+
+typedef struct{
+ struct sockaddr_in addr;
+ int sock;
+}udp_sockinfo_t;
+
+ihost_config_t ihost_config;
+
+void log_msg(int level, char *format, ...){
+ extern int errno;
+ int cur_errno;
+ va_list ap;
+
+ cur_errno=errno;
+
+ if(level<=ihost_config.verbose){
+ va_start(ap, format);
+ vfprintf(ihost_config.log, format, ap);
+ va_end(ap);
+ if(level==LOG_CRIT){
+ fprintf(ihost_config.log, " (%s)\n", strerror(cur_errno));
}else{
- fprintf(stderr, "%s\n", message);
+ fprintf(ihost_config.log, "\n");
}
- }
+ }
}
-char* sock_comm(FILE *f_r, FILE *f_w, char *sendString){
- char *reply;
- logmessage(LOG_DEBUG, "Sending %s",sendString);
- fprintf(f_w, "%s\n", sendString);
- fflush(f_w);
- reply=fpgetline(f_r);
- if (reply!=NULL) logmessage(LOG_DEBUG, "Received %s", reply);
- /* Returns pointer to static buffer */
- return reply;
-}
+/* Takes many pointers, checks if they are NULL or not, and then free's them */
+/* Deprciated - and i only wrote it today! :)
+void m_free(int num_pointers, ...){
+ int x=0;
+ va_list ap;
+ void *p;
-int ihost_configure(ihost_state_t *ihost_state){
- struct sockaddr_in addr;
- struct in_addr haddr;
- struct sockaddr ip;
- int ip_len;
- int sd;
- FILE *fm_fd_r, *fm_fd_w;
- char *reply;
- char *reply_ptr;
+ va_start(ap, num_pointers);
+ for(;xmy_fqdn!=NULL) free(ihost_state->my_fqdn);
- if (ihost_state->server_fqdn!=NULL) free(ihost_state->server_fqdn);
- if (ihost_state->last_modified!=NULL) free(ihost_state->last_modified);
- if (ihost_state->files_list!=NULL) free(ihost_state->files_list);
+int create_udp_sockinfo(udp_sockinfo_t *udp_sockinfo, char *hostname, int port){
- logmessage(LOG_DEBUG, "Setting up configure socket to %s on port %d", ihost_state->fm_host, ihost_state->fm_port);
- if ((sd = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
- logmessage(LOG_ERR, "Can't create AF_INET socket (%m)");
- return -1;
- }
+ struct in_addr haddr;
- if (get_host_addr(ihost_state->fm_host, &haddr) != 0){
- logmessage(LOG_ERR, "Failed to resolve address %s (%m)", ihost_state->fm_host);
- return -1;
+ log_msg(LOG_DEBUG, "Resolving name for udp connection");
+ if(get_host_addr(hostname, &haddr) != 0){
+ log_msg(LOG_CRIT, "Failed to lookup name");
+ return 1;
}
- memset(&addr, 0, sizeof addr);
- addr.sin_family = AF_INET;
- memcpy(&addr.sin_addr, &haddr, sizeof haddr);
- addr.sin_port = htons(ihost_state->fm_port);
+ if((udp_sockinfo->sock=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
+ log_msg(LOG_CRIT, "Failed to create UDP socket");
+ return 1;
+ }
- if (connect(sd, (struct sockaddr *)&addr, sizeof addr) != 0) {
- logmessage(LOG_ERR, "Failed to connect to %s on port %d (%m)", ihost_state->fm_host, ihost_state->fm_port);
- return -1;
+ memset(&(udp_sockinfo->addr), 0, sizeof(struct sockaddr_in));
+ udp_sockinfo->addr.sin_family=AF_INET;
+ memcpy((char *)&(udp_sockinfo->addr.sin_addr), &haddr, sizeof(haddr));
+ udp_sockinfo->addr.sin_port = htons(port);
+
+ log_msg(LOG_DEBUG, "Socket created");
+ return 0;
+}
+
+FILE *create_tcp_connection(char *hostname, int port){
+ int sock;
+ struct sockaddr_in addr;
+ struct in_addr haddr;
+ FILE *f;
+
+ log_msg(LOG_DEBUG, "Creating tcp socket");
+ if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0){
+ log_msg(LOG_CRIT, "Failed to make TCP Socket");
+ return NULL;
}
- /* Need to open 2 files, one for reading one for writing, as it gets confused if we only use 1 :) */
- if ((fm_fd_r=fdopen(sd,"r")) == NULL){
- logmessage(LOG_ERR, "Failed to open read stream (%m)");
- return -1;
+ if((get_host_addr(hostname, &haddr))!=0){
+ log_msg(LOG_CRIT, "Failed to lookup name for %s", hostname);
+ return NULL;
}
- if ((fm_fd_w=fdopen(dup(sd),"w")) == NULL){
- logmessage(LOG_ERR, "Failed to open write stream (%m)");
- return -1;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ memcpy(&addr.sin_addr, &haddr, sizeof(haddr));
+ addr.sin_port = htons(port);
+
+ log_msg(LOG_DEBUG, "Creating a tcp connection");
+ if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) !=0){
+ log_msg(LOG_CRIT, "Failed to connect to hostname %s on port %d", hostname, port);
+ return NULL;
}
- ip_len=sizeof ip;
- memset(&ip, 0, ip_len);
- if((getsockname(sd, &ip, &ip_len)) != 0){
- logmessage(LOG_ERR, "Failed to get IP address (%m)");
- return -1;
+
+ if((f=fdopen(sock, "r+"))==NULL){
+ log_msg(LOG_CRIT, "Failed to connect to open filedescriptor on tcp connection");
+ close(sock);
+ return NULL;
}
- if (ip.sa_family!=AF_INET){
- logmessage(LOG_ERR, "sa family is wrong type");
- return -1;
- }
- if(ihost_state->my_ip!=NULL) free(ihost_state->my_ip);
- if((ihost_state->my_ip=strdup(inet_ntoa(((struct sockaddr_in *)&ip)->sin_addr)))==NULL){
- logmessage(LOG_ERR, "Failed to get IP (%m)");
- return -1;
- }
+ return f;
+}
+
+int tcp_comm(FILE *f, char *send, char **response, char *expected){
+
+ log_msg(LOG_DEBUG, "Sending %s", send);
+ fprintf(f, "%s\n", send);
+ fflush(f);
+ *response=fpgetline(f);
+ fseek(f, 0, SEEK_CUR);
+
+ if(*response!=NULL) log_msg(LOG_DEBUG, "Recieved %s", *response);
+
+ if( (*response==NULL) || (strcmp(*response, "ERROR")==0) ) return -1;
- reply=sock_comm(fm_fd_r, fm_fd_w, "STARTCONFIG");
- if ((reply==NULL) || (strncasecmp(reply, "OK", 2) != 0) ) {
- logmessage(LOG_ERR, "Server error on STARTCONFIG");
- return -1;
- }
+ if(expected==NULL) return 0;
- reply=sock_comm(fm_fd_r, fm_fd_w, "LASTMODIFIED");
- if((reply== NULL) || (strncasecmp(reply, "ERROR", 5) ==0)){
- logmessage(LOG_ERR, "Server error on LASTMODIFIED (%m)");
- return -1;
- }
- if((ihost_state->last_modified=strdup(reply)) == NULL){
- logmessage(LOG_ERR, "strdup failed (%m)");
- return -1;
- }
+ if((strcmp(expected, *response))==0) return 0;
- reply=sock_comm(fm_fd_r, fm_fd_w, "FILELIST");
- if((reply== NULL) || (strncasecmp(reply, "ERROR", 5) ==0)){
- logmessage(LOG_ERR, "Server error on FILELIST (%m)");
- return -1;
- }
- if((ihost_state->files_list=strdup(reply)) == NULL){
- logmessage(LOG_ERR, "strdup failed (%m)");
- return -1;
- }
+ log_msg(LOG_DEBUG, "Did not get expected response");
+ return -1;
+}
- reply=sock_comm(fm_fd_r, fm_fd_w, "FQDN");
- if((reply== NULL) || (strncasecmp(reply, "ERROR", 5)==0)){
- logmessage(LOG_ERR, "Server error on FQDN (%m)");
+int tcp_comm_strdup(FILE *f, char *send, char **response, char *expected){
+ if((tcp_comm(f, send, response, expected))!=0){
return -1;
}
- if((ihost_state->my_fqdn=strdup(reply)) == NULL){
- logmessage(LOG_ERR, "strdup failed (%m)");
- return -1;
- }
- reply=sock_comm(fm_fd_r, fm_fd_w, "UDPUpdateTime");
- if(reply== NULL){
- logmessage(LOG_ERR, "Server error (%m)");
- return -1;
- }
- if (strncasecmp(reply, "ERROR", 5) != 0){
- ihost_state->udp_update_time=atoi(reply);
- }
+ *response=strdup(*response);
+ if (response==NULL) return -1;
+
+ return 0;
+}
- reply=sock_comm(fm_fd_r, fm_fd_w, "TCPUpdateTime");
- if(reply== NULL){
- logmessage(LOG_ERR, "Server error on TCPUpdateTime (%m)");
- return -1;
+int ihost_getconfig(ihost_state_t *ihost_state){
+
+ FILE *tcp_con;
+ char *response;
+ char *response_ptr;
+
+ /* Keep these in case of a failure and so it can keep running on the old config */
+ char *file_list=NULL;
+ char *last_modified=NULL;
+ char *host_fqdn=NULL;
+ char *host_ip=NULL;
+ int udp_update_time=0;
+ char *server_fqdn=NULL;
+ int server_udp_port=0;
+ time_t config_ttl=0;
+
+ tcp_con=create_tcp_connection(ihost_state->filtermanager_host, ihost_state->filtermanager_port);
+
+ if(ihost_state->file_list!=NULL || ihost_state->last_modified!=NULL){
+ if(tcp_con==NULL){
+ goto error;
+ }
+
+ if((tcp_comm(tcp_con, "CHECKCONFIG", &response, "OK"))!=0){
+ goto error;
+ }
+
+ if((tcp_comm(tcp_con, ihost_state->file_list, &response, "OK"))!=0){
+ goto error;
+ }
+
+ if((tcp_comm(tcp_con, ihost_state->last_modified, &response, "OK"))==0){
+ if((tcp_comm(tcp_con, "END", &response, "OK"))==0){
+ goto error;
+ }
+ fclose(tcp_con);
+ return 0;
+ }else{
+ if((strcmp(response, "EXPIRED"))!=0){
+ goto error;
+ }
+ }
}
- if (strncasecmp(reply, "ERROR", 5) != 0){
- ihost_state->tcp_update_time=atoi(reply);
- }
- reply=sock_comm(fm_fd_r, fm_fd_w, "ENDCONFIG");
- if(reply== NULL){
- logmessage(LOG_ERR, "Server error on ENDCONFIG (%m)");
- return -1;
+ /* If we got to here, the config must of expired */
+
+ if((tcp_comm(tcp_con, "STARTCONFIG", &response, "OK"))!=0){
+ goto error;
}
- reply=sock_comm(fm_fd_r, fm_fd_w, "FILTER");
- if((reply== NULL) || (strncasecmp(reply, "ERROR", 5)==0)){
- logmessage(LOG_ERR, "Server error FILTER failed (%m)");
- return -1;
+ if((tcp_comm_strdup(tcp_con, "LASTMODIFIED", &response, NULL))!=0){
+ goto error;
}
- reply_ptr=strchr(reply,';');
- if (reply_ptr==NULL){
- logmessage(LOG_ERR, "Incorrect data returned");
- return -1;
+ last_modified=response;
+
+ if((tcp_comm_strdup(tcp_con, "FILELIST", &response, NULL))!=0){
+ goto error;
}
- *reply_ptr='\0';
- if((ihost_state->server_fqdn=strdup(reply)) == NULL){
- logmessage(LOG_ERR, "strdup failed (%m)");
- return -1;
+ file_list=response;
+
+ if((tcp_comm_strdup(tcp_con, "FQDN", &response, NULL))!=0){
+ goto error;
}
- reply=reply_ptr + 1;
- reply_ptr=strchr(reply,';');
- if (reply_ptr==NULL){
- logmessage(LOG_ERR, "Incorrect data returned 2");
- return -1;
+ host_fqdn=response;
+
+ if((tcp_comm_strdup(tcp_con, "IP", &response, NULL))!=0){
+ goto error;
}
- *reply_ptr='\0';
- ihost_state->server_udp_port=atoi(reply);
- reply=reply_ptr+1;
- ihost_state->server_tcp_port=atoi(reply);
- if ((ihost_state->server_tcp_port==0) || (ihost_state->server_udp_port==0)){
- logmessage(LOG_ERR, "Incorrect data returned 3 ");
- return -1;
+ host_ip=response;
+
+ if((tcp_comm(tcp_con, "UDPUpdateTime", &response, NULL))!=0){
+ goto error;
}
+ udp_update_time=atoi(response);
- reply=sock_comm(fm_fd_r, fm_fd_w, "END");
- if((reply== NULL) || (strncasecmp(reply, "ERROR", 5) ==0 )){
- logmessage(LOG_ERR, "Server error on END (%m)");
- return -1;
+ if((tcp_comm(tcp_con, "ConfigTTL", &response, NULL))!=0){
+ goto error;
}
+ config_ttl=atoi(response);
- if(fclose(fm_fd_r) !=0){
- logmessage(LOG_ERR, "Failed to close read FD (%m)");
- return -1;
+ if((tcp_comm(tcp_con, "ENDCONFIG", &response, NULL))!=0){
+ goto error;
}
- if(fclose(fm_fd_w) !=0){
- logmessage(LOG_ERR, "Failed to close write FD (%m)");
- return -1;
+
+ if((tcp_comm(tcp_con, "FILTER", &response, NULL))!=0){
+ goto error;
+ }else{
+ response_ptr=strchr(response,';');
+ if(response_ptr==NULL){
+ log_msg(LOG_ERR, "Incorrect data sent by server");
+ goto error;
+ }
+ *response_ptr='\0';
+ server_fqdn=strdup(response);
+ if(server_fqdn==NULL){
+ goto error;
+ }
+ response_ptr++;
+ if(response_ptr==NULL){
+ log_msg(LOG_ERR, "Incorrect data sent by server");
+ goto error;
+ }
+
+ printf("string : %s\n", response_ptr);
+ server_udp_port=atoi(response_ptr);
+
+ if (server_udp_port==0){
+ log_msg(LOG_ERR, "Incorrect data sent by server");
+ goto error;
+ }
}
+
+ if((tcp_comm(tcp_con, "END", &response, "OK"))!=0){
+ goto error;
+ }
+ fclose(tcp_con);
+
+ /* We have the data we need, and its all been read correctly */
+
+ /* Free the old data before pointing them to the new data. m_free copes should
+ * this already be NULL */
+ if(ihost_state->file_list!=NULL) free(ihost_state->file_list);
+ if(ihost_state->last_modified!=NULL) free(ihost_state->last_modified);
+ if(ihost_state->host_fqdn!=NULL) free(ihost_state->host_fqdn);
+ if(ihost_state->server_fqdn!=NULL) free(ihost_state->server_fqdn);
+ if(ihost_state->host_ip!=NULL) free(ihost_state->host_ip);
+
+ ihost_state->file_list=file_list;
+ ihost_state->last_modified=last_modified;
+ ihost_state->host_fqdn=host_fqdn;
+ ihost_state->host_ip=host_ip;
+ ihost_state->server_fqdn=server_fqdn;
+ ihost_state->server_udp_port=server_udp_port;
+ ihost_state->udp_update_time=udp_update_time;
+ ihost_state->config_ttl=config_ttl;
+
+ log_msg(LOG_DEBUG, "UDP Update time %d", udp_update_time);
+ log_msg(LOG_DEBUG, "Configure ttl %d", config_ttl);
+
return 0;
-}
-int heartbeat(ihost_state_t *ihost_state){
- struct sockaddr_in addr;
- struct in_addr haddr;
- int sd;
- FILE *fm_fd_r, *fm_fd_w;
- char *reply;
- int exitcode=0;
+error:
- logmessage(LOG_DEBUG, "Setting up configure socket to %s on port %d", ihost_state->server_fqdn, ihost_state->server_tcp_port);
- if ((sd = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
- logmessage(LOG_ERR, "Can't create AF_INET socket (%m)");
- return -1;
- }
+ if(file_list!=NULL) free(file_list);
+ if(last_modified!=NULL) free(last_modified);
+ if(host_fqdn!=NULL) free(host_fqdn);
+ if(server_fqdn!=NULL) free(server_fqdn);
+ if(host_ip!=NULL) free(host_ip);
+ fclose(tcp_con);
- if (get_host_addr(ihost_state->server_fqdn, &haddr) != 0){
- logmessage(LOG_ERR, "Failed to resolve address %s (%m)", ihost_state->server_fqdn);
- return -1;
- }
+ return -1;
+}
- memset(&addr, 0, sizeof addr);
- addr.sin_family = AF_INET;
- memcpy(&addr.sin_addr, &haddr, sizeof haddr);
- addr.sin_port = htons(ihost_state->server_tcp_port);
+int get_system_stats(int seq_no, ihost_state_t *ihost_state, char *xml, int size){
+ char tmp[size];
+ cpu_percent_t *cpu_percent;
+ mem_stat_t *mem_stats;
+ load_stat_t *load_stats;
+ user_stat_t *user_stats;
+ swap_stat_t *swap_stats;
+ general_stat_t *general_stats;
+ disk_stat_t *disk_stats;
+ diskio_stat_t *diskio_stats;
+ process_stat_t *process_stats;
+ network_stat_t *network_stats;
+ page_stat_t *page_stats;
+ int disk_entries=0;
+ int diskio_entries=0;
+ int network_entries=0;
- if (connect(sd, (struct sockaddr *)&addr, sizeof addr) != 0) {
- logmessage(LOG_ERR, "Failed to connect to %s on port %d (%m)", ihost_state->server_fqdn, ihost_state->server_tcp_port);
- return -1;
- }
+ int counter;
+ long long x;
+ long long y;
- /* Need to open 2 files, one for reading one for writing, as it gets confused if we only use 1 :) */
- if ((fm_fd_r=fdopen(sd,"r")) == NULL){
- logmessage(LOG_ERR, "Failed to open stream (%m)");
- return -1;
- }
+ /* Print start of the packet we want */
+ snprintf(xml, size, "", \
+ seq_no, ihost_state->host_fqdn, time(NULL), ihost_state->host_ip);
- if ((fm_fd_w=fdopen(dup(sd),"w")) == NULL){
- logmessage(LOG_ERR, "Failed to open stream (%m)");
- return -1;
- }
+ /* Get cpu stats, check it is correct, then fill in its entry for the xml */
+ if((cpu_percent=cpu_percent_usage())==NULL){
+ log_msg(LOG_CRIT, "Failed to get cpu statistics");
+ }else{
+ snprintf(tmp, size, \
+ "%3.2f%3.2f%3.2f%3.2f%3.2f", \
+ cpu_percent->user, \
+ cpu_percent->kernel, \
+ cpu_percent->idle, \
+ cpu_percent->iowait, \
+ cpu_percent->swap);
- reply=sock_comm(fm_fd_r, fm_fd_w, "HEARTBEAT");
- if ((reply==NULL) || (strncasecmp(reply, "ERROR", 5) == 0) ) {
- logmessage(LOG_ERR, "Server error on HEARTBEAT");
- return -1;
- }
+ if(strlcat(xml, tmp, size) >= size) goto too_big_error;
+ }
- reply=sock_comm(fm_fd_r, fm_fd_w, "CONFIG");
- if ((reply==NULL) || (strncasecmp(reply, "ERROR", 5) == 0) ) {
- logmessage(LOG_ERR, "Server error on CONFIG");
- return -1;
- }
+
+ /*Get mem stats, and fill in xml */
+ if((mem_stats=get_memory_stats())==NULL){
+ log_msg(LOG_CRIT, "Failed to get memory statistics");
+ }else{
+ snprintf(tmp, size, \
+ "%lld%lld%lld%lld", \
+ mem_stats->total, \
+ mem_stats->free, \
+ mem_stats->used, \
+ mem_stats->cache);
+
+ if(strlcat(xml, tmp, size) >= size) goto too_big_error;
+ }
- reply=sock_comm(fm_fd_r, fm_fd_w, ihost_state->files_list);
- if ((reply==NULL) || (strncasecmp(reply, "OK", 2) != 0) ) {
- logmessage(LOG_ERR, "Server error on fileslist");
- return -1;
- }
- reply=sock_comm(fm_fd_r, fm_fd_w, ihost_state->last_modified);
- if (reply==NULL) {
- logmessage(LOG_ERR, "Server error NULL recieved on lastmodified");
- return -1;
- }
- if (strncasecmp(reply, "ERROR", 5) == 0){
- /* Means the config has changed */
- logmessage(LOG_INFO, "Recieved ERROR from server for a reconfigure required");
- exitcode=RECONFIGURE_RETURN_CODE;
+ /* Get load stats */
+ if((load_stats=get_load_stats())==NULL){
+ log_msg(LOG_CRIT, "Failed to get load statistics");
+ }else{
+ snprintf(tmp, size, \
+ "%.2lf%.2lf%.2lf", \
+ load_stats->min1, \
+ load_stats->min5, \
+ load_stats->min15);
+ if(strlcat(xml, tmp, size) >= size) goto too_big_error;
}
- reply=sock_comm(fm_fd_r, fm_fd_w, "KEY");
- if ((reply==NULL) || (strncasecmp(reply, "ERROR", 5) == 0) ) {
- logmessage(LOG_ERR, "Server error on KEY");
- return -1;
- }
- if (ihost_state->key!=NULL) free(ihost_state->key);
-
- if((ihost_state->key=strdup(reply)) == NULL){
- logmessage(LOG_ERR, "strdup failed (%m)");
- return -1;
- }
- reply=sock_comm(fm_fd_r, fm_fd_w, "ENDHEARTBEAT");
- if((reply== NULL) || (strncasecmp(reply, "ERROR", 5) ==0 )){
- logmessage(LOG_ERR, "Server error on ENDHEARTBEAT (%m)");
- return -1;
- }
+ /* get user stats */
+
+ if((user_stats=get_user_stats())==NULL){
+ log_msg(LOG_CRIT, "Failed to get user statistics");
+ }else{
- fflush(fm_fd_r);
- fflush(fm_fd_w);
+ snprintf(tmp, size, \
+ "%s
%d", \
+ user_stats->name_list, \
+ user_stats->num_entries);
+
+ if(strlcat(xml, tmp, size) >= size) goto too_big_error;
+ }
- if(fclose(fm_fd_r) !=0){
- logmessage(LOG_ERR, "Failed to close read FD (%m)");
- return -1;
- }
- if(fclose(fm_fd_w) !=0){
- logmessage(LOG_ERR, "Failed to close write FD (%m)");
- return -1;
- }
- return exitcode;
-}
+ /* swap stats */
+ if((swap_stats=get_swap_stats())==NULL){
+ log_msg(LOG_CRIT, "Failed to get swap statistics");
+ }else{
+ snprintf(tmp, size, \
+ "%lld%lld%lld",\
+ swap_stats->total, \
+ swap_stats->used, \
+ swap_stats->free);
+
+ if(strlcat(xml, tmp, size) >= size) goto too_big_error;
+ }
-char *stat_grab(ihost_state_t *ihost_state, int counter){
-#define NUM_STATS 9
- char *stats[NUM_STATS];
- char *xml_data=NULL;
- char *xml_data_p;
- int xml_size=0;
- int x=0;
- logmessage(LOG_DEBUG,"get_cpu_stats");
- stats[0]=get_cpu_stats();
- logmessage(LOG_DEBUG,"get_disk_stats");
- stats[1]=get_disk_stats();
- logmessage(LOG_DEBUG,"get_load_stats");
- stats[2]=get_load_stats();
- logmessage(LOG_DEBUG,"get_memory_stats");
- stats[3]=get_memory_stats();
- logmessage(LOG_DEBUG,"get_os_info");
- stats[4]=get_os_info();
- logmessage(LOG_DEBUG,"get_page_stats");
- stats[5]=get_page_stats();
- logmessage(LOG_DEBUG,"get_process_stats");
- stats[6]=get_process_stats();
- logmessage(LOG_DEBUG,"get_swap_stats");
- stats[7]=get_swap_stats();
- logmessage(LOG_DEBUG,"get_user_stats");
- stats[8]=get_user_stats();
+ /* general stats */
+ if((general_stats=get_general_stats())==NULL){
+ log_msg(LOG_CRIT, "Failed to get general statistics");
+ }else{
+ snprintf(tmp, size, \
+ "%s%s%s%s%s%ld", \
+ general_stats->os_name, \
+ general_stats->os_release, \
+ general_stats->os_version, \
+ general_stats->hostname, \
+ general_stats->platform, \
+ (long)general_stats->uptime);
+
+ if(strlcat(xml, tmp, size) >= size) goto too_big_error;
+
+ }
- for(x=0;x%d%d%d%d%d",\
+ process_stats->sleeping, \
+ process_stats->running, \
+ process_stats->zombie, \
+ process_stats->stopped, \
+ process_stats->total);
+
+ if(strlcat(xml, tmp, size) >= size) goto too_big_error;
+
+ }
+
+
+ /* Get paging stats */
+ if((page_stats=get_page_stats_diff())==NULL){
+ log_msg(LOG_CRIT, "Failed to get paging statistics");
+ }else{
+ if(page_stats->systime!=0){
+ x=page_stats->pages_pagein / page_stats->systime;
+ y=page_stats->pages_pageout / page_stats->systime;
+ }else{
+ x=page_stats->pages_pagein;
+ y=page_stats->pages_pageout;
}
- xml_size+=strlen(stats[x]);
+ snprintf(tmp, size, \
+ "%lld%lld", \
+ x, \
+ y);
+
+ if(strlcat(xml, tmp, size) >= size) goto too_big_error;
}
- xml_data=malloc(xml_size+1);
- xml_data=strcpy(xml_data, stats[0]);
- free(stats[0]);
- for(x=1;x", size);
+ for(counter=0;countersystime!=0){
+ x=diskio_stats->read_bytes / diskio_stats->systime;
+ y=diskio_stats->write_bytes / diskio_stats->systime;
+ }else{
+ x=diskio_stats->read_bytes;
+ y=diskio_stats->write_bytes;
+ }
+
+ snprintf(tmp, size, \
+ "", \
+ counter, \
+ diskio_stats->disk_name, \
+ x, \
+ y, \
+ counter);
+
+ strlcat(xml, tmp, size);
+ diskio_stats++;
+ }
+
+ if(strlcat(xml, "", size) >= size) goto too_big_error;
+
}
- xml_data_p=xml_data;
- xml_data=strf("%s", counter, ihost_state->my_fqdn, time(NULL), ihost_state->my_ip, ihost_state->key, xml_data);
- free(xml_data_p);
+
+ /* get networks stats */
+
+ if((network_stats=get_network_stats_diff(&network_entries))==NULL){
+ log_msg(LOG_CRIT, "Failed to get network statistics");
+ }else{
+ strlcat(xml, "", size);
+ for(counter=0;countersystime!=0){
+ x=network_stats->rx / network_stats->systime;
+ y=network_stats->tx / network_stats->systime;
+ }else{
+ x=network_stats->rx;
+ y=network_stats->tx;
+ }
- logmessage(LOG_DEBUG,"Generated XML Data of : %s", xml_data);
- return xml_data;
-}
+ snprintf(tmp, size, \
+ "", \
+ counter, \
+ network_stats->interface_name, \
+ x, \
+ y, \
+ counter);
-int send_stats(ihost_state_t *ihost_state, char *data_stream){
- struct sockaddr_in addr;
- struct in_addr haddr;
+ strlcat(xml, tmp, size);
+ network_stats++;
+ }
- int sd;
- size_t len;
+ if(strlcat(xml, "", size) >= size) goto too_big_error;
- len=strlen(data_stream);
- if(len>UDP_MAX_PACKET_SIZE){
- logmessage(LOG_ERR, "Too big to send to server. Please reconfigure client and server and recompile");
- exit(1);
}
- logmessage(LOG_DEBUG,"Resolving IP of server");
- if (get_host_addr(ihost_state->server_fqdn, &haddr) != 0){
- logmessage(LOG_ERR, "Failed to resolve address %s (%m)", ihost_state->server_fqdn);
- return -1;
- }
- logmessage(LOG_DEBUG,"Creating UDP socket to %s on %d",ihost_state->server_fqdn, ihost_state->server_udp_port);
- if((sd=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
- logmessage(LOG_ERR, "failed to create UDP socket (%m)");
- return -1;
- }
- memset(&addr, 0, sizeof(addr));
- addr.sin_family=AF_INET;
- memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr);
- addr.sin_port = htons(ihost_state->server_udp_port);
- logmessage(LOG_INFO,"Sending packet : %s", data_stream);
- if((sendto(sd, data_stream, len, 0, (struct sockaddr *) &addr, sizeof(addr))) != len){
- logmessage(LOG_ERR, "Send the wrong number of bytes (%m)");
- return -1;
+ /* get disk stats */
+
+ if((disk_stats=get_disk_stats(&disk_entries))==NULL){
+ log_msg(LOG_CRIT, "Failed to get disk statistics");
+ }else{
+ strlcat(xml, "", size);
+ for(counter=0;counter
", \
+ counter, \
+ disk_stats->device_name, \
+ disk_stats->mnt_point, \
+ disk_stats->fs_type, \
+ disk_stats->size, \
+ disk_stats->used, \
+ disk_stats->avail, \
+ disk_stats->total_inodes, \
+ disk_stats->used_inodes, \
+ disk_stats->free_inodes, \
+ counter);
+
+ strlcat(xml, tmp, size);
+
+ disk_stats++;
+ }
+
+ if(strlcat(xml, "", size) >= size) goto too_big_error;
+
}
+
- close(sd);
+ if(strlcat(xml, "", size) >= size) goto too_big_error;
- return 0;
+ /*If we got to here, it should of all been filled in nicely now */
+ return 0;
+
+too_big_error:
+ log_msg(LOG_ERR, "UDP Packet is too large. Throwing away the packet");
+ return -1;
}
+
+
void usage(char *progname){
- fprintf(stderr, "Usage %s [options] server port\n", progname);
- fprintf(stderr, "Options\n");
- fprintf(stderr, " -v Verbose, the more v flags the more verbose, eg -vv\n");
- fprintf(stderr, " -d Daemon mode, self backgrounding\n");
- fprintf(stderr, " -s Send errors to syslog\n");
- fprintf(stderr, " -V Print version number\n");
- fprintf(stderr, " -h Prints this help page\n");
- exit(1);
+ fprintf(stderr, "Usage %s [options] server port\n", progname);
+ fprintf(stderr, "Options\n");
+ fprintf(stderr, " -v Verbose mode,-vv would make even more verbose\n");
+ fprintf(stderr, " -f Foreground mode, print errors to stderr\n");
+ fprintf(stderr, " -V Print version number\n");
+ fprintf(stderr, " -h Prints this help page\n");
+ exit(1);
}
int main(int argc, char **argv){
+
ihost_state_t ihost_state;
- int heartbeat_exit;
- int counter=0;
- long udp_time=0, tcp_time=0, stat_grab_time=0, cur_time=0;
- int sleep_delay=0;
- char *xml_stats;
- pid_t pid;
+ udp_sockinfo_t udp_sockinfo;
+
int cmdopt;
extern int optind;
- int verbose=0, daemon=0;
- extern int syslog_logging;
- extern int log_level;
- extern int cur_level;
+ pid_t pid;
FILE *f;
+ int packet_num=0;
+ int len;
- log_level=1;
- cur_level=1;
- syslog_logging=0;
+ char packet[MAX_UDP_PACKET_SIZE];
- errf_set_ofunc(log_errors);
- /* NULL'ify so i can tell if i need to free it or not */
- ihost_state.fm_host=NULL;
- ihost_state.my_fqdn=NULL;
- ihost_state.server_fqdn=NULL;
- ihost_state.last_modified=NULL;
- ihost_state.files_list=NULL;
- ihost_state.key=NULL;
- ihost_state.my_ip=NULL;
+ time_t cur_time, sleep_delay, udp_time=0, config_time=0;
- errf_set_progname(argv[0]);
-
+ /* Set default settings */
+ ihost_config.verbose=1;
+ ihost_config.daemon=1;
+ /* Set all errors to go down stderr until told otherwise */
+ ihost_config.log=stderr;
- while((cmdopt=getopt(argc, argv, "vdshV")) != -1){
- switch(cmdopt){
- case 'v':
- verbose++;
- break;
-
- case 'd':
- /* Force syslog logging since stderr will be closed in this case */
- syslog_logging=1;
- daemon=1;
- break;
-
- case 's':
- syslog_logging=1;
- break;
-
- case 'h':
- usage(argv[0]);
- break;
+ /* Blank ihost_state to default settings */
+ ihost_state.filtermanager_host=NULL;
+ ihost_state.host_fqdn=NULL;
+ ihost_state.host_ip=NULL;
+ ihost_state.server_fqdn=NULL;
+ ihost_state.file_list=NULL;
+ ihost_state.last_modified=NULL;
- case 'V':
- errf("%s version %s",argv[0], VERSION);
- break;
+ while((cmdopt=getopt(argc, argv, "vfhV")) != -1){
+ switch(cmdopt){
+ case 'v':
+ ihost_config.verbose++;
+ break;
- default:
- usage(argv[0]);
- exit(1);
- }
- }
+ case 'f':
+ /* Force syslog logging since stderr will be closed in this case */
+ ihost_config.daemon=0;
+ break;
- if(argc!=optind+2){
- usage(argv[0]);
+ case 'h':
+ usage(argv[0]);
+ break;
+
+ case 'V':
+ fprintf(stderr, "%s version %s", argv[0], VERSION);
+ break;
+
+ default:
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ if(argc!=optind+2){
+ usage(argv[0]);
+ exit(1);
+ }
+
+ ihost_state.filtermanager_host=strdup(argv[optind]);
+ ihost_state.filtermanager_port=atoi(argv[optind+1]);
+
+ if(gethostbyname(ihost_state.filtermanager_host)==NULL){
+ log_msg(LOG_CRIT, "Failed to lookup hostname. Please check settings");
exit(1);
}
- ihost_state.fm_host=argv[optind];
- ihost_state.fm_port=atoi(argv[optind+1]);
- if(ihost_state.fm_port==0){
- errf("Invalid port number");
- usage(argv[0]);
+ if(ihost_state.filtermanager_port==0){
+ log_msg(LOG_ERR, "Invalid port number");
+ exit(1);
}
- if(daemon==1){
+ if(ihost_config.daemon){
pid=fork();
if(pid==-1){
- errf("Fork failed, can't background. Exiting");
- exit(1);
+ log_msg(LOG_CRIT, "Failed to background exiting");
+ exit(1);
}else if(pid!=0){
- /* Parent process */
- return 0;
- }
- /* We should now be in the background*/
- if(setsid()==-1){
- errf("setsid failed (%m)");
+ /* Parent process */
+ return 0;
+ }
+ /* We should now be in the background*/
+ if(setsid()==-1){
+ log_msg(LOG_CRIT, "setsid failed");
+ exit(1);
+ }
+
+ if((ihost_config.log=fopen(LOGFILE_PATH, "a"))==NULL){
+ ihost_config.log=stderr;
+ log_msg(LOG_CRIT, "Failed to open Logfiles %s for writing", LOGFILE_PATH);
exit(1);
}
- fclose(stdin);
- fclose(stdout);
- fclose(stderr);
- }
- if(syslog_logging==1){
- openlog(errf_get_progname(),0,LOG_ERR);
- setlogmask(LOG_UPTO(LOG_DEBUG));
- }
-
- switch(verbose){
- case 0:
- /* Critical errors + */
- log_level=LOG_ERR;
- break;
- case 1:
- /* Recoverable errors */
- log_level=LOG_WARNING;
- break;
- case 2:
- /* Print stuff like the XML packets */
- log_level=LOG_INFO;
- break;
- default:
- /* Must have lots of v's */
- /* Print out everything its doing */
- log_level=LOG_DEBUG;
- break;
- }
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
- logmessage(LOG_DEBUG,"Writing PID FILE");
- pid=getpid();
- if((f=fopen(PID_FILE,"w")) == NULL){
- logmessage(LOG_WARNING, "Failed to write PID file (%m)");
- }else{
- if((fprintf(f,"%d",(int)pid)) <= 0 ){
- logmessage(LOG_WARNING, "Failed to write PID file (%m)");
- }
- if((fclose(f))!=0){
- logmessage(LOG_ERR, "failed to close PID file");
- exit(1);
- }
+ }
+
+ log_msg(LOG_INFO, "Starting ihost");
+
+ log_msg(LOG_DEBUG,"Writing PID FILE");
+
+ pid=getpid();
+
+ if((f=fopen(PID_FILE,"w")) == NULL){
+ log_msg(LOG_CRIT, "Failed to write PID file");
+ }else{
+ if((fprintf(f,"%d",(int)pid)) <= 0 ){
+ log_msg(LOG_CRIT, "Failed to write PID file");
+ }
+ if((fclose(f))!=0){
+ log_msg(LOG_CRIT, "failed to close PID file");
+ }
+ }
+
+ /* Get the initial config from the filter manager. Should this fail,
+ * wait, and then try again. */
+
+ get_diskio_stats_diff(&packet_num);
+ packet_num=0;
+
+ while(ihost_getconfig(&ihost_state)!=0){
+ log_msg(LOG_ERR, "Failed to get ihost config");
+ sleep(10);
}
- if(ihost_configure(&ihost_state)!=0){
- logmessage(LOG_ERR,"configure failed");
- /* Ok, ideally we prob should have 2 copies of the structure and carry on if this
- happens.. But we dont :) (at the moment) */
- exit(1);
+ printf("%s\n%d\n", ihost_state.server_fqdn, ihost_state.server_udp_port);
+ while((create_udp_sockinfo(&udp_sockinfo, ihost_state.server_fqdn, ihost_state.server_udp_port))!=0){
+ log_msg(LOG_ERR, "Failed to create udp socket");
+ sleep(10);
}
+ config_time=time(NULL)+ihost_state.config_ttl;
+
+ /* Now have config.. collect data and send as often as required */
for(;;){
cur_time=time(NULL);
- if(cur_time>=tcp_time){
- logmessage(LOG_DEBUG,"Sending heartbeat");
- heartbeat_exit=heartbeat(&ihost_state);
- if(heartbeat_exit==RECONFIGURE_RETURN_CODE){
- logmessage(LOG_INFO,"heartbeat needs to be reconfigured");
- ihost_configure(&ihost_state);
- udp_time=0;
- }
- if(heartbeat_exit==-1){
- logmessage(LOG_ERR,"Heartbeat failed");
- exit(1);
- }
- tcp_time=time(NULL)+ihost_state.tcp_update_time;
- logmessage(LOG_DEBUG,"next tcp time should be %d", tcp_time);
- }
if(cur_time>=udp_time){
- logmessage(LOG_DEBUG,"Sending udp data");
- /* Work out how long it takes to get the stats for next time round
- so the sleep time can be adjusted accordingly */
- stat_grab_time=time(NULL);
- if((xml_stats=stat_grab(&ihost_state, counter++)) == NULL){
- logmessage(LOG_ERR,"Failed to get stats (%m)");
- exit(1);
+ if((get_system_stats(packet_num++, &ihost_state, packet, MAX_UDP_PACKET_SIZE))!=0){
+ log_msg(LOG_ERR, "Failed to get system stats");
}
- stat_grab_time=time(NULL)-stat_grab_time;
- send_stats(&ihost_state, xml_stats);
- free(xml_stats);
- udp_time=time(NULL)+ihost_state.udp_update_time-stat_grab_time;
- logmessage(LOG_DEBUG,"next udp time should be %d", udp_time);
+
+ len=strlen(packet);
+ log_msg(LOG_DEBUG, "Packet size: %d\nPacket: %s\n", len, packet);
+
+ if((sendto(udp_sockinfo.sock, packet, len, 0, (struct sockaddr *) &udp_sockinfo.addr, sizeof(udp_sockinfo.addr)))!=len){
+ log_msg(LOG_CRIT, "Failed to send packet");
+ }
+ udp_time=cur_time+ihost_state.udp_update_time;
+ log_msg(LOG_DEBUG, "Next packet should be sent on %d", udp_time);
}
+
+ if(cur_time>=config_time){
+ if(ihost_getconfig(&ihost_state)!=0){
+ /* If we can't get the config, try again 5 minutes time */
+ log_msg(LOG_ERR, "Failed to get config, try again 5 minutes time");
+ config_time=time(NULL)+300;
+ }else{
+ close(udp_sockinfo.sock);
- if(tcp_time0) sleep(sleep_delay);
- }
- return 0;
+ }
+
+ return(0);
}
-