Icinga-core 1.4.0
next gen monitoring
common/statusdata.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * STATUSDATA.C - External status data for Icinga CGIs
00004  *
00005  * Copyright (c) 2000-2008 Ethan Galstad (egalstad@nagios.org)
00006  * Copyright (c) 2009-2011 Icinga Development Team (http://www.icinga.org)
00007  *
00008  * License:
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License version 2 as
00012  * published by the Free Software Foundation.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022  *
00023  *****************************************************************************/
00024 
00025 /*********** COMMON HEADER FILES ***********/
00026 
00027 #include "../include/config.h"
00028 #include "../include/common.h"
00029 #include "../include/objects.h"
00030 #include "../include/statusdata.h"
00031 
00032 #ifdef NSCORE
00033 #include "../include/icinga.h"
00034 #include "../include/broker.h"
00035 #endif
00036 #ifdef NSCGI
00037 #include "../include/cgiutils.h"
00038 #endif
00039 
00040 /**** IMPLEMENTATION SPECIFIC HEADER FILES ****/
00041 
00042 #ifdef USE_XSDDEFAULT
00043 #include "../xdata/xsddefault.h"                /* default routines */
00044 #endif
00045 
00046 
00047 #ifdef NSCORE
00048 extern int      aggregate_status_updates;
00049 #endif
00050 
00051 #ifdef NSCGI
00052 hoststatus      *hoststatus_list=NULL;
00053 hoststatus      *hoststatus_list_tail=NULL;
00054 servicestatus   *servicestatus_list=NULL;
00055 servicestatus   *servicestatus_list_tail=NULL;
00056 
00057 hoststatus      **hoststatus_hashlist=NULL;
00058 servicestatus   **servicestatus_hashlist=NULL;
00059 
00060 extern int      use_pending_states;
00061 #endif
00062 
00063 int dummy;      /* reduce compiler warnings */
00064 
00065 #ifdef NSCORE
00066 
00067 /******************************************************************/
00068 /****************** TOP-LEVEL OUTPUT FUNCTIONS ********************/
00069 /******************************************************************/
00070 
00071 /* initializes status data at program start */
00072 int initialize_status_data(char *config_file){
00073         int result=OK;
00074 
00075         /**** IMPLEMENTATION-SPECIFIC CALLS ****/
00076 #ifdef USE_XSDDEFAULT
00077         result=xsddefault_initialize_status_data(config_file);
00078 #endif
00079 
00080         return result;
00081         }
00082 
00083 
00084 /* update all status data (aggregated dump) */
00085 int update_all_status_data(void){
00086         int result=OK;
00087 
00088 #ifdef USE_EVENT_BROKER
00089         /* send data to event broker */
00090         broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_STARTDUMP,NEBFLAG_NONE,NEBATTR_NONE,NULL);
00091 #endif
00092 
00093         /**** IMPLEMENTATION-SPECIFIC CALLS ****/
00094 #ifdef USE_XSDDEFAULT
00095         result=xsddefault_save_status_data();
00096 #endif
00097 
00098 #ifdef USE_EVENT_BROKER
00099         /* send data to event broker */
00100         broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_ENDDUMP,NEBFLAG_NONE,NEBATTR_NONE,NULL);
00101 #endif
00102 
00103         if(result!=OK)
00104                 return ERROR;
00105 
00106         return OK;
00107         }
00108 
00109 
00110 /* cleans up status data before program termination */
00111 int cleanup_status_data(char *config_file,int delete_status_data){
00112         int result=OK;
00113 
00114         /**** IMPLEMENTATION-SPECIFIC CALLS ****/
00115 #ifdef USE_XSDDEFAULT
00116         result=xsddefault_cleanup_status_data(config_file,delete_status_data);
00117 #endif
00118 
00119         return result;
00120         }
00121 
00122 
00123 
00124 /* updates program status info */
00125 int update_program_status(int aggregated_dump){
00126 
00127 #ifdef USE_EVENT_BROKER
00128         /* send data to event broker (non-aggregated dumps only) */
00129         if(aggregated_dump==FALSE)
00130                 broker_program_status(NEBTYPE_PROGRAMSTATUS_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,NULL);
00131 #endif
00132 
00133         /* currently a noop if aggregated updates is TRUE */
00134 
00135         /* update all status data if we're not aggregating updates */
00136         if(aggregate_status_updates==FALSE)
00137                 update_all_status_data();
00138 
00139         return OK;
00140         }
00141 
00142 
00143 
00144 /* updates host status info */
00145 int update_host_status(host *hst,int aggregated_dump){
00146 
00147 #ifdef USE_EVENT_BROKER
00148         /* send data to event broker (non-aggregated dumps only) */
00149         if(aggregated_dump==FALSE)
00150                   broker_host_status(NEBTYPE_HOSTSTATUS_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,hst,NULL);
00151 #endif
00152 
00153         /* currently a noop if aggregated updates is TRUE */
00154 
00155         /* update all status data if we're not aggregating updates */
00156         if(aggregate_status_updates==FALSE)
00157                 update_all_status_data();
00158 
00159         return OK;
00160         }
00161 
00162 
00163 
00164 /* updates service status info */
00165 int update_service_status(service *svc,int aggregated_dump){
00166 
00167 #ifdef USE_EVENT_BROKER
00168         /* send data to event broker (non-aggregated dumps only) */
00169         if(aggregated_dump==FALSE)
00170                 broker_service_status(NEBTYPE_SERVICESTATUS_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,svc,NULL);
00171 #endif
00172 
00173         /* currently a noop if aggregated updates is TRUE */
00174 
00175         /* update all status data if we're not aggregating updates */
00176         if(aggregate_status_updates==FALSE)
00177                 update_all_status_data();
00178 
00179         return OK;
00180         }
00181 
00182 
00183 
00184 /* updates contact status info */
00185 int update_contact_status(contact *cntct,int aggregated_dump){
00186 
00187 #ifdef USE_EVENT_BROKER
00188         /* send data to event broker (non-aggregated dumps only) */
00189         if(aggregated_dump==FALSE)
00190                 broker_contact_status(NEBTYPE_CONTACTSTATUS_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,cntct,NULL);
00191 #endif
00192 
00193         /* currently a noop if aggregated updates is TRUE */
00194 
00195         /* update all status data if we're not aggregating updates */
00196         if(aggregate_status_updates==FALSE)
00197                 update_all_status_data();
00198 
00199         return OK;
00200         }
00201 #endif
00202 
00203 
00204 
00205 
00206 
00207 #ifdef NSCGI
00208 
00209 /******************************************************************/
00210 /******************* TOP-LEVEL INPUT FUNCTIONS ********************/
00211 /******************************************************************/
00212 
00213 
00214 /* reads in all status data */
00215 int read_status_data(char *config_file,int options){
00216         int result=OK;
00217 
00218         /**** IMPLEMENTATION-SPECIFIC CALLS ****/
00219 #ifdef USE_XSDDEFAULT
00220         result=xsddefault_read_status_data(config_file,options);
00221 #endif
00222 #ifdef USE_XSDDB
00223         result=xsddb_read_status_data(config_file,options);
00224 #endif
00225 
00226         return result;
00227         }
00228 
00229 
00230 
00231 /******************************************************************/
00232 /****************** CHAINED HASH FUNCTIONS ************************/
00233 /******************************************************************/
00234 
00235 /* adds hoststatus to hash list in memory */
00236 int add_hoststatus_to_hashlist(hoststatus *new_hoststatus){
00237         hoststatus *temp_hoststatus=NULL;
00238         hoststatus *lastpointer=NULL;
00239         int hashslot=0;
00240         int i=0;
00241 
00242         /* initialize hash list */
00243         if(hoststatus_hashlist==NULL){
00244 
00245                 hoststatus_hashlist=(hoststatus **)malloc(sizeof(hoststatus *)*HOSTSTATUS_HASHSLOTS);
00246                 if(hoststatus_hashlist==NULL)
00247                         return 0;
00248                 
00249                 for(i=0;i<HOSTSTATUS_HASHSLOTS;i++)
00250                         hoststatus_hashlist[i]=NULL;
00251                 }
00252 
00253         if(!new_hoststatus)
00254                 return 0;
00255 
00256         hashslot=hashfunc(new_hoststatus->host_name,NULL,HOSTSTATUS_HASHSLOTS);
00257         lastpointer=NULL;
00258         for(temp_hoststatus=hoststatus_hashlist[hashslot];temp_hoststatus && compare_hashdata(temp_hoststatus->host_name,NULL,new_hoststatus->host_name,NULL)<0;temp_hoststatus=temp_hoststatus->nexthash)
00259                 lastpointer=temp_hoststatus;
00260 
00261         if(!temp_hoststatus || (compare_hashdata(temp_hoststatus->host_name,NULL,new_hoststatus->host_name,NULL)!=0)){
00262                 if(lastpointer)
00263                         lastpointer->nexthash=new_hoststatus;
00264                 else
00265                         hoststatus_hashlist[hashslot]=new_hoststatus;
00266                 new_hoststatus->nexthash=temp_hoststatus;
00267 
00268                 return 1;
00269                 }
00270 
00271         /* else already exists */
00272         return 0;
00273         }
00274 
00275 
00276 int add_servicestatus_to_hashlist(servicestatus *new_servicestatus){
00277         servicestatus *temp_servicestatus=NULL, *lastpointer=NULL;
00278         int hashslot=0;
00279         int i=0;
00280 
00281         /* initialize hash list */
00282         if(servicestatus_hashlist==NULL){
00283 
00284                 servicestatus_hashlist=(servicestatus **)malloc(sizeof(servicestatus *)*SERVICESTATUS_HASHSLOTS);
00285                 if(servicestatus_hashlist==NULL)
00286                         return 0;
00287                 
00288                 for(i=0;i< SERVICESTATUS_HASHSLOTS;i++)
00289                         servicestatus_hashlist[i]=NULL;
00290                 }
00291 
00292         if(!new_servicestatus)
00293                 return 0;
00294 
00295         hashslot=hashfunc(new_servicestatus->host_name,new_servicestatus->description,SERVICESTATUS_HASHSLOTS);
00296         lastpointer=NULL;
00297         for(temp_servicestatus=servicestatus_hashlist[hashslot];temp_servicestatus && compare_hashdata(temp_servicestatus->host_name,temp_servicestatus->description,new_servicestatus->host_name,new_servicestatus->description)<0;temp_servicestatus=temp_servicestatus->nexthash)
00298                 lastpointer=temp_servicestatus;
00299 
00300         if(!temp_servicestatus || (compare_hashdata(temp_servicestatus->host_name,temp_servicestatus->description,new_servicestatus->host_name,new_servicestatus->description)!=0)){
00301                 if(lastpointer)
00302                         lastpointer->nexthash=new_servicestatus;
00303                 else
00304                         servicestatus_hashlist[hashslot]=new_servicestatus;
00305                 new_servicestatus->nexthash=temp_servicestatus;
00306 
00307 
00308                 return 1;
00309                 }
00310 
00311         /* else already exists */
00312         return 0;
00313         }
00314 
00315 
00316 
00317 /******************************************************************/
00318 /********************** ADDITION FUNCTIONS ************************/
00319 /******************************************************************/
00320 
00321 
00322 /* adds a host status entry to the list in memory */
00323 int add_host_status(hoststatus *new_hoststatus){
00324         char date_string[MAX_DATETIME_LENGTH];
00325 
00326         /* make sure we have what we need */
00327         if(new_hoststatus==NULL)
00328                 return ERROR;
00329         if(new_hoststatus->host_name==NULL)
00330                 return ERROR;
00331 
00332         /* massage host status a bit */
00333         if(new_hoststatus!=NULL){
00334                 switch(new_hoststatus->status){
00335                 case 0:
00336                         new_hoststatus->status=HOST_UP;
00337                         break;
00338                 case 1:
00339                         new_hoststatus->status=HOST_DOWN;
00340                         break;
00341                 case 2:
00342                         new_hoststatus->status=HOST_UNREACHABLE;
00343                         break;
00344                 default:
00345                         new_hoststatus->status=HOST_UP;
00346                         break;
00347                         }
00348                 if(new_hoststatus->has_been_checked==FALSE){
00349                         if(use_pending_states==TRUE)
00350                                 new_hoststatus->status=HOST_PENDING;
00351                         my_free(new_hoststatus->plugin_output);
00352                         if(new_hoststatus->should_be_scheduled==TRUE){
00353                                 get_time_string(&new_hoststatus->next_check,date_string,sizeof(date_string),LONG_DATE_TIME);
00354                                 dummy=asprintf(&new_hoststatus->plugin_output,"Host check scheduled for %s",date_string);
00355                                 }
00356                         else{
00357                                 /* passive-only hosts that have just been scheduled for a forced check */
00358                                 if(new_hoststatus->checks_enabled==FALSE && new_hoststatus->next_check!=(time_t)0L && (new_hoststatus->check_options & CHECK_OPTION_FORCE_EXECUTION)){
00359                                         get_time_string(&new_hoststatus->next_check,date_string,sizeof(date_string),LONG_DATE_TIME);
00360                                         dummy=asprintf(&new_hoststatus->plugin_output,"Forced host check scheduled for %s",date_string);
00361                                         }
00362                                 /* passive-only hosts not scheduled to be checked */
00363                                 else
00364                                         new_hoststatus->plugin_output=(char *)strdup("Host is not scheduled to be checked...");
00365                                 }
00366                         }
00367                 }
00368 
00369         new_hoststatus->next=NULL;
00370         new_hoststatus->nexthash=NULL;
00371 
00372         /* add new hoststatus to hoststatus chained hash list */
00373         if(!add_hoststatus_to_hashlist(new_hoststatus))
00374                 return ERROR;
00375 
00376         /* object cache file is already sorted, so just add new items to end of list */
00377         if(hoststatus_list==NULL){
00378                 hoststatus_list=new_hoststatus;
00379                 hoststatus_list_tail=new_hoststatus;
00380                 }
00381         else{
00382                 hoststatus_list_tail->next=new_hoststatus;
00383                 hoststatus_list_tail=new_hoststatus;
00384                 }
00385 
00386         return OK;
00387         }
00388 
00389 
00390 /* adds a service status entry to the list in memory */
00391 int add_service_status(servicestatus *new_svcstatus){
00392         char date_string[MAX_DATETIME_LENGTH];
00393 
00394         /* make sure we have what we need */
00395         if(new_svcstatus==NULL)
00396                 return ERROR;
00397         if(new_svcstatus->host_name==NULL || new_svcstatus->description==NULL)
00398                 return ERROR;
00399 
00400 
00401         /* massage service status a bit */
00402         if(new_svcstatus!=NULL){
00403                 switch(new_svcstatus->status){
00404                 case 0:
00405                         new_svcstatus->status=SERVICE_OK;
00406                         break;
00407                 case 1:
00408                         new_svcstatus->status=SERVICE_WARNING;
00409                         break;
00410                 case 2:
00411                         new_svcstatus->status=SERVICE_CRITICAL;
00412                         break;
00413                 case 3:
00414                         new_svcstatus->status=SERVICE_UNKNOWN;
00415                         break;
00416                 default:
00417                         new_svcstatus->status=SERVICE_OK;
00418                         break;
00419                         }
00420                 if(new_svcstatus->has_been_checked==FALSE){
00421                         if(use_pending_states==TRUE)
00422                                 new_svcstatus->status=SERVICE_PENDING;
00423                         my_free(new_svcstatus->plugin_output);
00424                         if(new_svcstatus->should_be_scheduled==TRUE){
00425                                 get_time_string(&new_svcstatus->next_check,date_string,sizeof(date_string),LONG_DATE_TIME);
00426                                 dummy=asprintf(&new_svcstatus->plugin_output,"Service check scheduled for %s",date_string);
00427                                 }
00428                         else{
00429                                 /* passive-only services that have just been scheduled for a forced check */
00430                                 if(new_svcstatus->checks_enabled==FALSE && new_svcstatus->next_check!=(time_t)0L && (new_svcstatus->check_options & CHECK_OPTION_FORCE_EXECUTION)){
00431                                         get_time_string(&new_svcstatus->next_check,date_string,sizeof(date_string),LONG_DATE_TIME);
00432                                         dummy=asprintf(&new_svcstatus->plugin_output,"Forced service check scheduled for %s",date_string);
00433                                         }
00434                                 /* passive-only services not scheduled to be checked */
00435                                 else
00436                                         new_svcstatus->plugin_output=(char *)strdup("Service is not scheduled to be checked...");
00437                                 }
00438                         }
00439                 }
00440 
00441         new_svcstatus->next=NULL;
00442         new_svcstatus->nexthash=NULL;
00443 
00444         /* add new servicestatus to servicestatus chained hash list */
00445         if(!add_servicestatus_to_hashlist(new_svcstatus))
00446                 return ERROR;
00447 
00448         /* object cache file is already sorted, so just add new items to end of list */
00449         if(servicestatus_list==NULL){
00450                 servicestatus_list=new_svcstatus;
00451                 servicestatus_list_tail=new_svcstatus;
00452                 }
00453         else{
00454                 servicestatus_list_tail->next=new_svcstatus;
00455                 servicestatus_list_tail=new_svcstatus;
00456                 }
00457 
00458         return OK;
00459         }
00460 
00461 
00462 
00463 
00464 
00465 /******************************************************************/
00466 /*********************** CLEANUP FUNCTIONS ************************/
00467 /******************************************************************/
00468 
00469 
00470 /* free all memory for status data */
00471 void free_status_data(void){
00472         hoststatus *this_hoststatus=NULL;
00473         hoststatus *next_hoststatus=NULL;
00474         servicestatus *this_svcstatus=NULL;
00475         servicestatus *next_svcstatus=NULL;
00476 
00477         /* free memory for the host status list */
00478         for(this_hoststatus=hoststatus_list;this_hoststatus!=NULL;this_hoststatus=next_hoststatus){
00479                 next_hoststatus=this_hoststatus->next;
00480                 my_free(this_hoststatus->host_name);
00481                 my_free(this_hoststatus->plugin_output);
00482                 my_free(this_hoststatus->long_plugin_output);
00483                 my_free(this_hoststatus->perf_data);
00484                 my_free(this_hoststatus);
00485                 }
00486 
00487         /* free memory for the service status list */
00488         for(this_svcstatus=servicestatus_list;this_svcstatus!=NULL;this_svcstatus=next_svcstatus){
00489                 next_svcstatus=this_svcstatus->next;
00490                 my_free(this_svcstatus->host_name);
00491                 my_free(this_svcstatus->description);
00492                 my_free(this_svcstatus->plugin_output);
00493                 my_free(this_svcstatus->long_plugin_output);
00494                 my_free(this_svcstatus->perf_data);
00495                 my_free(this_svcstatus);
00496                 }
00497 
00498         /* free hash lists reset list pointers */
00499         my_free(hoststatus_hashlist);
00500         my_free(servicestatus_hashlist);
00501         hoststatus_list=NULL;
00502         servicestatus_list=NULL;
00503 
00504         return;
00505         }
00506 
00507 
00508 
00509 
00510 /******************************************************************/
00511 /************************ SEARCH FUNCTIONS ************************/
00512 /******************************************************************/
00513 
00514 
00515 /* find a host status entry */
00516 hoststatus *find_hoststatus(char *host_name){
00517         hoststatus *temp_hoststatus=NULL;
00518 
00519         if(host_name==NULL || hoststatus_hashlist==NULL)
00520                 return NULL;
00521 
00522         for(temp_hoststatus=hoststatus_hashlist[hashfunc(host_name,NULL,HOSTSTATUS_HASHSLOTS)];temp_hoststatus && compare_hashdata(temp_hoststatus->host_name,NULL,host_name,NULL)<0;temp_hoststatus=temp_hoststatus->nexthash);
00523 
00524         if(temp_hoststatus && (compare_hashdata(temp_hoststatus->host_name,NULL,host_name,NULL)==0))
00525                 return temp_hoststatus;
00526 
00527         return NULL;
00528         }
00529 
00530 
00531 /* find a service status entry */
00532 servicestatus *find_servicestatus(char *host_name,char *svc_desc){
00533         servicestatus *temp_servicestatus=NULL;
00534 
00535         if(host_name==NULL || svc_desc==NULL || servicestatus_hashlist==NULL)
00536                 return NULL;
00537 
00538         for(temp_servicestatus=servicestatus_hashlist[hashfunc(host_name,svc_desc,SERVICESTATUS_HASHSLOTS)];temp_servicestatus && compare_hashdata(temp_servicestatus->host_name,temp_servicestatus->description,host_name,svc_desc)<0;temp_servicestatus=temp_servicestatus->nexthash);
00539 
00540         if(temp_servicestatus && (compare_hashdata(temp_servicestatus->host_name,temp_servicestatus->description,host_name,svc_desc)==0))
00541                 return temp_servicestatus;
00542 
00543         return NULL;
00544         }
00545 
00546 
00547 
00548 
00549 /******************************************************************/
00550 /*********************** UTILITY FUNCTIONS ************************/
00551 /******************************************************************/
00552 
00553 
00554 /* gets the total number of services of a certain state for a specific host */
00555 int get_servicestatus_count(char *host_name, int type){
00556         servicestatus *temp_status=NULL;
00557         int count=0;
00558 
00559         if(host_name==NULL)
00560                 return 0;
00561 
00562         for(temp_status=servicestatus_list;temp_status!=NULL;temp_status=temp_status->next){
00563                 if(temp_status->status & type){
00564                         if(!strcmp(host_name,temp_status->host_name))
00565                                 count++;
00566                         }
00567                 }
00568 
00569         return count;
00570         }
00571 
00572 
00573 
00574 #endif
00575 
 All Data Structures Files Functions Variables Typedefs Defines