00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "../pub/getopt.h"
00037 #include "cf.defs.h"
00038 #include "cf.extern.h"
00039 #ifdef HAVE_SYS_LOADAVG_H
00040 # include <sys/loadavg.h>
00041 #else
00042 # define LOADAVG_5MIN 1
00043 #endif
00044 #include <math.h>
00045 #include <db.h>
00046
00047
00048
00049
00050
00051 #define CFGRACEPERIOD 4.0
00052
00053 unsigned int HISTOGRAM[ATTR*2+5+PH_LIMIT][7][GRAINS];
00054
00055 int HISTO = false;
00056 int NUMBER_OF_USERS;
00057 int ROOTPROCS;
00058 int OTHERPROCS;
00059 int DISKFREE;
00060 int LOADAVG;
00061 int INCOMING[ATTR];
00062 int OUTGOING[ATTR];
00063 int PH_SAMP[PH_LIMIT];
00064 int PH_LAST[PH_LIMIT];
00065 int PH_DELTA[PH_LIMIT];
00066 int SLEEPTIME = 5 * 60;
00067 int BATCH_MODE = false;
00068 double ITER = 0.0;
00069 double AGE,WAGE;
00070
00071 char OUTPUT[bufsize*2];
00072
00073 char BATCHFILE[bufsize];
00074 char STATELOG[bufsize];
00075 char ENV_NEW[bufsize];
00076 char ENV[bufsize];
00077
00078 struct Averages LOCALAV;
00079 struct Item *ALL_INCOMING = NULL;
00080 struct Item *ALL_OUTGOING = NULL;
00081
00082 double ENTROPY = 0.0;
00083 double LAST_HOUR_ENTROPY = 0.0;
00084 double LAST_DAY_ENTROPY = 0.0;
00085
00086 struct Item *PREVIOUS_STATE = NULL;
00087
00088 struct option CFDENVOPTIONS[] =
00089 {
00090 {"help",no_argument,0,'h'},
00091 {"debug",optional_argument,0,'d'},
00092 {"verbose",no_argument,0,'v'},
00093 {"no-fork",no_argument,0,'F'},
00094 {"histograms",no_argument,0,'H'},
00095 {"file",optional_argument,0,'f'},
00096 {NULL,0,0,0}
00097 };
00098
00099 short NO_FORK = false;
00100
00101
00102
00103 enum socks
00104 {
00105 netbiosns,
00106 netbiosdgm,
00107 netbiosssn,
00108 irc,
00109 cfengine,
00110 nfsd,
00111 smtp,
00112 www,
00113 ftp,
00114 ssh,
00115 telnet
00116 };
00117
00118 char *ECGSOCKS[ATTR][2] =
00119 {
00120 {"137","netbiosns"},
00121 {"138","netbiosdgm"},
00122 {"139","netbiosssn"},
00123 {"194","irc"},
00124 {"5308","cfengine"},
00125 {"2049","nfsd"},
00126 {"25","smtp"},
00127 {"80","www"},
00128 {"21","ftp"},
00129 {"22","ssh"},
00130 {"23","telnet"},
00131 };
00132
00133 char *PH_BINARIES[PH_LIMIT] =
00134 {
00135 "usr/sbin/atd",
00136 "sbin/getty",
00137 "bin/bash",
00138 "usr/sbin/exim",
00139 "bin/run-parts",
00140 };
00141
00142
00143
00144
00145
00146 void CheckOptsAndInit ARGLIST((int argc,char **argv));
00147 void Syntax ARGLIST((void));
00148 void StartServer ARGLIST((int argc, char **argv));
00149 void DoBatch ARGLIST((void));
00150 void *ExitCleanly ARGLIST((void));
00151 void yyerror ARGLIST((char *s));
00152 void FatalError ARGLIST((char *s));
00153 void RotateFiles ARGLIST((char *s, int n));
00154
00155 void GetDatabaseAge ARGLIST((void));
00156 void LoadHistogram ARGLIST((void));
00157 void GetQ ARGLIST((void));
00158 char *GetTimeKey ARGLIST((void));
00159 struct Averages EvalAvQ ARGLIST((char *timekey));
00160 void ArmClasses ARGLIST((struct Averages newvals,char *timekey));
00161
00162 void GatherProcessData ARGLIST((void));
00163 void GatherDiskData ARGLIST((void));
00164 void GatherLoadData ARGLIST((void));
00165 void GatherSocketData ARGLIST((void));
00166 void GatherPhData ARGLIST((void));
00167 struct Averages *GetCurrentAverages ARGLIST((char *timekey));
00168 void UpdateAverages ARGLIST((char *timekey, struct Averages newvals));
00169 void UpdateDistributions ARGLIST((char *timekey, struct Averages *av));
00170 double WAverage ARGLIST((double newvals,double oldvals, double age));
00171 void SetClasses ARGLIST((double expect,double delta,double sigma,double lexpect,double ldelta,double lsigma,char *name,struct Item **list,char *timekey));
00172 void SetVariable ARGLIST((char *name,double now, double average, double stddev, struct Item **list));
00173 void RecordChangeOfState ARGLIST((struct Item *list,char *timekey));
00174 double RejectAnomaly ARGLIST((double new,double av,double var,double av2,double var2));
00175 int HashPhKey ARGLIST((char *s));
00176
00177
00178
00179
00180
00181 int main (argc,argv)
00182
00183 int argc;
00184 char **argv;
00185
00186 {
00187 CheckOptsAndInit(argc,argv);
00188 GetNameInfo();
00189
00190 if (BATCH_MODE)
00191 {
00192 DoBatch();
00193 }
00194 else
00195 {
00196 StartServer(argc,argv);
00197 }
00198
00199 return 0;
00200 }
00201
00202
00203
00204
00205
00206 void CheckOptsAndInit(argc,argv)
00207
00208 int argc;
00209 char **argv;
00210
00211 { extern char *optarg;
00212 int optindex = 0;
00213 int c, i,j,k;
00214
00215 umask(077);
00216 sprintf(VPREFIX,"cfenvd");
00217 openlog(VPREFIX,LOG_PID|LOG_NOWAIT|LOG_ODELAY,LOG_DAEMON);
00218
00219 strcpy(CFLOCK,"cfenvd");
00220
00221 IGNORELOCK = false;
00222 OUTPUT[0] = '\0';
00223
00224 while ((c=getopt_long(argc,argv,"d:f:vhHFV",CFDENVOPTIONS,&optindex)) != EOF)
00225 {
00226 switch ((char) c)
00227 {
00228 case 'd':
00229
00230 switch ((optarg==NULL)?3:*optarg)
00231 {
00232 case '1': D1 = true;
00233 break;
00234 case '2': D2 = true;
00235 break;
00236 default: DEBUG = true;
00237 break;
00238 }
00239
00240 NO_FORK = true;
00241 printf("cfenvd: Debug mode: running in foreground\n");
00242 break;
00243
00244 case 'f':
00245
00246 strcpy(BATCHFILE,optarg);
00247 NO_FORK = true;
00248 BATCH_MODE = true;
00249 printf("Working in batch mode on file %s\n",BATCHFILE);
00250 break;
00251
00252 case 'v': VERBOSE = true;
00253 break;
00254
00255 case 'V': printf("GNU %s-%s daemon\n%s\n",PACKAGE,VERSION,COPYRIGHT);
00256 printf("This program is covered by the GNU Public License and may be\n");
00257 printf("copied free of charge. No warrenty is implied.\n\n");
00258 exit(0);
00259 break;
00260
00261 case 'F': NO_FORK = true;
00262 break;
00263
00264 case 'H': HISTO = true;
00265 break;
00266
00267 default: Syntax();
00268 exit(1);
00269
00270 }
00271 }
00272
00273 LOGGING = true;
00274
00275 sprintf(VBUFF,"%s/test",WORKDIR);
00276 MakeDirectoriesFor(VBUFF,'y');
00277 sprintf(VBUFF,"%s/state/test",WORKDIR);
00278 MakeDirectoriesFor(VBUFF,'y');
00279 strncpy(VLOCKDIR,WORKDIR,bufsize-1);
00280 strncpy(VLOGDIR,WORKDIR,bufsize-1);
00281
00282 for (i = 0; i < ATTR; i++)
00283 {
00284 sprintf(VBUFF,"%s/state/cf_incoming.%s",WORKDIR,ECGSOCKS[i][1]);
00285 CreateEmptyFile(VBUFF);
00286 sprintf(VBUFF,"%s/state/cf_outgoing.%s",WORKDIR,ECGSOCKS[i][1]);
00287 CreateEmptyFile(VBUFF);
00288 }
00289
00290 sprintf(VBUFF,"%s/state/cf_users",WORKDIR);
00291 CreateEmptyFile(VBUFF);
00292
00293 snprintf(AVDB,bufsize,"%s/state/%s",WORKDIR,AVDB_FILE);
00294 snprintf(STATELOG,bufsize,"%s/state/%s",WORKDIR,STATELOG_FILE);
00295 snprintf(ENV_NEW,bufsize,"%s/state/%s",WORKDIR,ENV_NEW_FILE);
00296 snprintf(ENV,bufsize,"%s/state/%s",WORKDIR,ENV_FILE);
00297
00298 if (!BATCH_MODE)
00299 {
00300 GetDatabaseAge();
00301 LOCALAV.expect_number_of_users = 0.0;
00302 LOCALAV.expect_rootprocs = 0.0;
00303 LOCALAV.expect_otherprocs = 0.0;
00304 LOCALAV.expect_diskfree = 0.0;
00305 LOCALAV.expect_loadavg = 0.0;
00306 LOCALAV.var_number_of_users = 0.0;
00307 LOCALAV.var_rootprocs = 0.0;
00308 LOCALAV.var_otherprocs = 0.0;
00309 LOCALAV.var_diskfree = 0.0;
00310 LOCALAV.var_loadavg = 0.0;
00311
00312 for (i = 0; i < ATTR; i++)
00313 {
00314 LOCALAV.expect_incoming[i] = 0.0;
00315 LOCALAV.expect_outgoing[i] = 0.0;
00316 LOCALAV.var_incoming[i] = 0.0;
00317 LOCALAV.var_outgoing[i] = 0.0;
00318 }
00319
00320 for (i = 0; i < PH_LIMIT; i++)
00321 {
00322 LOCALAV.expect_pH[i] = 0.0;
00323 LOCALAV.var_pH[i] = 0.0;
00324 }
00325
00326 }
00327
00328 for (i = 0; i < 7; i++)
00329 {
00330 for (j = 0; j < ATTR*2+5+PH_LIMIT; j++)
00331 {
00332 for (k = 0; k < GRAINS; k++)
00333 {
00334 HISTOGRAM[i][j][k] = 0;
00335 }
00336 }
00337 }
00338
00339 for (i = 0; i < PH_LIMIT; i++)
00340 {
00341 PH_SAMP[i] = PH_LAST[i] = 0.0;
00342 }
00343
00344 srand((unsigned int)time(NULL));
00345 LoadHistogram();
00346 }
00347
00348
00349
00350
00351
00352 void Syntax()
00353
00354 { int i;
00355
00356 printf("GNU cfengine environment daemon\n%s-%s\n%s\n",PACKAGE,VERSION,COPYRIGHT);
00357 printf("\n");
00358 printf("Options:\n\n");
00359
00360 for (i=0; CFDENVOPTIONS[i].name != NULL; i++)
00361 {
00362 printf("--%-20s (-%c)\n",CFDENVOPTIONS[i].name,(char)CFDENVOPTIONS[i].val);
00363 }
00364
00365 printf("\nBug reports to bug-cfengine@gnu.org (News: gnu.cfengine.bug)\n");
00366 printf("General help to help-cfengine@gnu.org (News: gnu.cfengine.help)\n");
00367 printf("Info & fixes at http://www.iu.hio.no/cfengine\n");
00368 }
00369
00370
00371
00372 void GetDatabaseAge()
00373
00374 { int errno;
00375 DBT key,value;
00376 DB *dbp;
00377
00378 if ((errno = db_create(&dbp,NULL,0)) != 0)
00379 {
00380 snprintf(OUTPUT,bufsize,"Couldn't open average database %s\n",AVDB);
00381 CfLog(cferror,OUTPUT,"db_open");
00382 return;
00383 }
00384
00385 #ifdef CF_OLD_DB
00386 if ((errno = dbp->open(dbp,AVDB,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
00387 #else
00388 if ((errno = dbp->open(dbp,NULL,AVDB,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
00389 #endif
00390 {
00391 snprintf(OUTPUT,bufsize,"Couldn't open average database %s\n",AVDB);
00392 CfLog(cferror,OUTPUT,"db_open");
00393 return;
00394 }
00395
00396 chmod(AVDB,0644);
00397
00398 bzero(&key,sizeof(key));
00399 bzero(&value,sizeof(value));
00400
00401 key.data = "DATABASE_AGE";
00402 key.size = strlen("DATABASE_AGE")+1;
00403
00404 if ((errno = dbp->get(dbp,NULL,&key,&value,0)) != 0)
00405 {
00406 if (errno != DB_NOTFOUND)
00407 {
00408 dbp->err(dbp,errno,NULL);
00409 dbp->close(dbp,0);
00410 return;
00411 }
00412 }
00413
00414 dbp->close(dbp,0);
00415
00416 if (value.data != NULL)
00417 {
00418 AGE = *(double *)(value.data);
00419 WAGE = AGE / CFWEEK * MEASURE_INTERVAL;
00420 Debug("\n\nPrevious DATABASE_AGE %f\n\n",AGE);
00421 }
00422 else
00423 {
00424 Debug("No previous AGE\n");
00425 AGE = 0.0;
00426 }
00427 }
00428
00429
00430
00431 void LoadHistogram()
00432
00433 { FILE *fp;
00434 int position,i,day;
00435
00436 if (HISTO)
00437 {
00438 char filename[bufsize];
00439
00440 snprintf(filename,bufsize,"%s/state/histograms",WORKDIR);
00441
00442 if ((fp = fopen(filename,"r")) == NULL)
00443 {
00444 CfLog(cfverbose,"Unable to load histogram data","fopen");
00445 return;
00446 }
00447
00448 for (position = 0; position < GRAINS; position++)
00449 {
00450 fscanf(fp,"%d ",&position);
00451
00452 for (i = 0; i < 5 + 2*ATTR+PH_LIMIT; i++)
00453 {
00454 for (day = 0; day < 7; day++)
00455 {
00456 fscanf(fp,"%d ",&(HISTOGRAM[i][day][position]));
00457 }
00458 }
00459 }
00460
00461 fclose(fp);
00462 }
00463 }
00464
00465
00466
00467 void DoBatch()
00468
00469 { FILE *fp;
00470 char buffer[4096],time[256],timekey[256];
00471 float v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24,v25,v26;
00472 DB *dbp;
00473 int i = 0;
00474
00475 sprintf(AVDB,"/tmp/cfenv.tmp.db");
00476 unlink(AVDB);
00477
00478 if ((errno = db_create(&dbp,NULL,0)) != 0)
00479 {
00480 sprintf(OUTPUT,"Couldn't open average database %s\n",AVDB);
00481 CfLog(cferror,OUTPUT,"db_open");
00482 return;
00483 }
00484
00485 #ifdef CF_OLD_DB
00486 if ((errno = dbp->open(dbp,AVDB,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
00487 #else
00488 if ((errno = dbp->open(dbp,NULL,AVDB,NULL,DB_BTREE,DB_CREATE,0644)) != 0)
00489 #endif
00490 {
00491 sprintf(OUTPUT,"Couldn't open average database %s\n",AVDB);
00492 CfLog(cferror,OUTPUT,"db_open");
00493 return;
00494 }
00495
00496 if ((fp=fopen(BATCHFILE,"r")) == NULL)
00497 {
00498 printf("Cannot open %s\n",BATCHFILE);
00499 return;
00500 }
00501
00502 while (!feof(fp))
00503 {
00504 bzero(buffer,4096);
00505 fgets(buffer,1024,fp);
00506 if (i++ % 1024 == 0)
00507 {
00508 printf(" * Working %d ... *\r",i);
00509 }
00510
00511 sscanf(buffer,"%[^,],%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f",time,&v1,&v2,&v3,&v4,&v5,&v6,&v7,&v8,&v9,&v10,&v11,&v12,&v13,&v14,&v15,&v16,&v17,&v18,&v19,&v20,&v21,&v22,&v23,&v24,&v25,&v26);
00512
00513 Debug("%s,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",time,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24,v25,v26);
00514
00515 NUMBER_OF_USERS = (double)v1;
00516 ROOTPROCS = (double)v4;
00517 OTHERPROCS = (double)v5;
00518 DISKFREE = (double)v6;
00519 INCOMING[cfengine] = (double)v13;
00520 OUTGOING[cfengine] = (double)v14;
00521 INCOMING[nfsd] = (double)v15;
00522 OUTGOING[nfsd] = (double)v16;
00523 INCOMING[smtp] = (double)v17;
00524 OUTGOING[smtp] = (double)v18;
00525 INCOMING[www] = (double)v19;
00526 OUTGOING[www] = (double)v20;
00527 INCOMING[ftp] = (double)v21;
00528 OUTGOING[ftp] = (double)v22;
00529 INCOMING[ssh] = (double)v23;
00530 OUTGOING[ssh] = (double)v24;
00531 INCOMING[telnet] = (double)v25;
00532 OUTGOING[telnet] = (double)v26;
00533
00534 strcpy(timekey,ConvTimeKey(time));
00535
00536 (void)EvalAvQ(timekey);
00537 }
00538
00539 fclose(fp);
00540 dbp->close(dbp,0);
00541 printf("\nDone - database saved to %s\n",AVDB);
00542 printf("Run cfenvgraph -f %s to generate graphs\n\n",AVDB);
00543 }
00544
00545
00546
00547 void StartServer(argc,argv)
00548
00549 int argc;
00550 char **argv;
00551
00552 { char *timekey;
00553 struct Averages averages;
00554 void HandleSignal();
00555
00556 if ((!NO_FORK) && (fork() != 0))
00557 {
00558 sprintf(OUTPUT,"cfenvd: starting\n");
00559 CfLog(cfinform,OUTPUT,"");
00560 exit(0);
00561 }
00562
00563 if (!NO_FORK)
00564 {
00565 ActAsDaemon(0);
00566 }
00567
00568 signal (SIGTERM,HandleSignal);
00569 signal (SIGHUP,HandleSignal);
00570 signal (SIGINT,HandleSignal);
00571 signal (SIGPIPE,HandleSignal);
00572 signal (SIGSEGV,HandleSignal);
00573
00574 VCANONICALFILE = strdup("db");
00575
00576 if (!GetLock("cfenvd","daemon",0,1,"localhost",(time_t)time(NULL)))
00577 {
00578 return;
00579 }
00580
00581 while (true)
00582 {
00583 GetQ();
00584 timekey = GetTimeKey();
00585 averages = EvalAvQ(timekey);
00586 ArmClasses(averages,timekey);
00587 sleep(SLEEPTIME);
00588 ITER++;
00589 }
00590 }
00591
00592
00593
00594 void yyerror(s)
00595
00596 char *s;
00597
00598 {
00599
00600 }
00601
00602
00603
00604 void RotateFiles(name,number)
00605
00606 char *name;
00607 int number;
00608
00609 {
00610
00611 }
00612
00613
00614
00615 void FatalError(s)
00616
00617 char *s;
00618
00619 {
00620 fprintf (stderr,"%s:%s:%s\n",VPREFIX,VCURRENTFILE,s);
00621 closelog();
00622 exit(1);
00623 }
00624
00625
00626
00627
00628
00629 void GetQ()
00630
00631 {
00632 Debug("========================= GET Q ==============================\n");
00633 GatherProcessData();
00634 GatherLoadData();
00635 GatherDiskData();
00636 GatherSocketData();
00637 GatherPhData();
00638 }
00639
00640
00641
00642
00643 char *GetTimeKey()
00644
00645 { time_t now;
00646 char str[64];
00647
00648 if ((now = time((time_t *)NULL)) == -1)
00649 {
00650 exit(1);
00651 }
00652
00653 sprintf(str,"%s",ctime(&now));
00654
00655 return ConvTimeKey(str);
00656 }
00657
00658
00659
00660
00661 struct Averages EvalAvQ(t)
00662
00663 char *t;
00664
00665 { struct Averages *currentvals,newvals;
00666 int i;
00667 double Number_Of_Users,Rootprocs,Otherprocs,Diskfree,LoadAvg;
00668 double Incoming[ATTR],Outgoing[ATTR],pH_delta[PH_LIMIT];
00669
00670 if ((currentvals = GetCurrentAverages(t)) == NULL)
00671 {
00672 CfLog(cferror,"Error reading average database","");
00673 exit(1);
00674 }
00675
00676
00677
00678 Number_Of_Users = RejectAnomaly(NUMBER_OF_USERS,
00679 currentvals->expect_number_of_users,
00680 currentvals->var_number_of_users,
00681 LOCALAV.expect_number_of_users,
00682 LOCALAV.var_number_of_users);
00683 Rootprocs = RejectAnomaly(ROOTPROCS,
00684 currentvals->expect_rootprocs,
00685 currentvals->var_rootprocs,
00686 LOCALAV.expect_rootprocs,
00687 LOCALAV.var_rootprocs);
00688
00689 Otherprocs = RejectAnomaly(OTHERPROCS,
00690 currentvals->expect_otherprocs,
00691 currentvals->var_otherprocs,
00692 LOCALAV.expect_otherprocs,
00693 LOCALAV.var_otherprocs);
00694
00695 Diskfree = RejectAnomaly(DISKFREE,
00696 currentvals->expect_diskfree,
00697 currentvals->var_diskfree,
00698 LOCALAV.expect_diskfree,
00699 LOCALAV.var_diskfree);
00700
00701 LoadAvg = RejectAnomaly(LOADAVG,
00702 currentvals->expect_loadavg,
00703 currentvals->var_loadavg,
00704 LOCALAV.expect_loadavg,
00705 LOCALAV.var_loadavg);
00706
00707
00708 for (i = 0; i < ATTR; i++)
00709 {
00710 Incoming[i] = RejectAnomaly(INCOMING[i],
00711 currentvals->expect_incoming[i],
00712 currentvals->var_incoming[i],
00713 LOCALAV.expect_incoming[i],
00714 LOCALAV.var_incoming[i]);
00715
00716 Outgoing[i] = RejectAnomaly(OUTGOING[i],
00717 currentvals->expect_outgoing[i],
00718 currentvals->var_outgoing[i],
00719 LOCALAV.expect_outgoing[i],
00720 LOCALAV.var_outgoing[i]);
00721 }
00722
00723
00724 for (i = 0; i < PH_LIMIT; i++)
00725 {
00726 pH_delta[i] = RejectAnomaly(PH_DELTA[i],
00727 currentvals->expect_pH[i],
00728 currentvals->var_pH[i],
00729 LOCALAV.expect_pH[i],
00730 LOCALAV.var_pH[i]);
00731 }
00732
00733 newvals.expect_number_of_users = WAverage(Number_Of_Users,currentvals->expect_number_of_users,WAGE);
00734 newvals.expect_rootprocs = WAverage(Rootprocs,currentvals->expect_rootprocs,WAGE);
00735 newvals.expect_otherprocs = WAverage(Otherprocs,currentvals->expect_otherprocs,WAGE);
00736 newvals.expect_diskfree = WAverage(Diskfree,currentvals->expect_diskfree,WAGE);
00737 newvals.expect_loadavg = WAverage(LoadAvg,currentvals->expect_loadavg,WAGE);
00738
00739 LOCALAV.expect_number_of_users = WAverage(newvals.expect_number_of_users,LOCALAV.expect_number_of_users,ITER);
00740 LOCALAV.expect_rootprocs = WAverage(newvals.expect_rootprocs,LOCALAV.expect_rootprocs,ITER);
00741 LOCALAV.expect_otherprocs = WAverage(newvals.expect_otherprocs,LOCALAV.expect_otherprocs,ITER);
00742 LOCALAV.expect_diskfree = WAverage(newvals.expect_diskfree,LOCALAV.expect_diskfree,ITER);
00743 LOCALAV.expect_loadavg = WAverage(newvals.expect_loadavg,LOCALAV.expect_loadavg,ITER);
00744
00745 newvals.var_number_of_users = WAverage((Number_Of_Users-newvals.expect_number_of_users)*(Number_Of_Users-newvals.expect_number_of_users),currentvals->var_number_of_users,WAGE);
00746 newvals.var_rootprocs = WAverage((Rootprocs-newvals.expect_rootprocs)*(Rootprocs-newvals.expect_rootprocs),currentvals->var_rootprocs,WAGE);
00747 newvals.var_otherprocs = WAverage((Otherprocs-newvals.expect_otherprocs)*(Otherprocs-newvals.expect_otherprocs),currentvals->var_otherprocs,WAGE);
00748 newvals.var_diskfree = WAverage((Diskfree-newvals.expect_diskfree)*(Diskfree-newvals.expect_diskfree),currentvals->var_diskfree,WAGE);
00749 newvals.var_loadavg = WAverage((LoadAvg-newvals.expect_loadavg)*(LoadAvg-newvals.expect_loadavg),currentvals->var_loadavg,WAGE);
00750
00751 LOCALAV.var_number_of_users = WAverage((Number_Of_Users-LOCALAV.expect_number_of_users)*(Number_Of_Users-LOCALAV.expect_number_of_users),LOCALAV.var_number_of_users,ITER);
00752 LOCALAV.var_rootprocs = WAverage((Rootprocs-LOCALAV.expect_rootprocs)*(Rootprocs-LOCALAV.expect_rootprocs),LOCALAV.var_rootprocs,ITER);
00753 LOCALAV.var_otherprocs = WAverage((Otherprocs-LOCALAV.expect_otherprocs)*(Otherprocs-LOCALAV.expect_otherprocs),LOCALAV.var_otherprocs,ITER);
00754 LOCALAV.var_diskfree = WAverage((Diskfree-LOCALAV.expect_diskfree)*(Diskfree-LOCALAV.expect_diskfree),LOCALAV.var_diskfree,ITER);
00755 LOCALAV.var_loadavg = WAverage((LoadAvg-LOCALAV.expect_loadavg)*(LoadAvg-LOCALAV.expect_loadavg),currentvals->var_loadavg,WAGE);
00756
00757 Verbose("Users = %4d -> (%f#%f) local [%f#%f]\n",NUMBER_OF_USERS,newvals.expect_number_of_users,sqrt(newvals.var_number_of_users),LOCALAV.expect_number_of_users,sqrt(LOCALAV.var_number_of_users));
00758 Verbose("Rootproc = %4d -> (%f#%f) local [%f#%f]\n",ROOTPROCS,newvals.expect_rootprocs,sqrt(newvals.var_rootprocs),LOCALAV.expect_rootprocs,sqrt(LOCALAV.var_rootprocs));
00759 Verbose("Otherproc = %4d -> (%f#%f) local [%f#%f]\n",OTHERPROCS,newvals.expect_otherprocs,sqrt(newvals.var_otherprocs),LOCALAV.expect_otherprocs,sqrt(LOCALAV.var_otherprocs));
00760 Verbose("Diskpercent = %4d -> (%f#%f) local [%f#%f]\n",DISKFREE,newvals.expect_diskfree,sqrt(newvals.var_diskfree),LOCALAV.expect_diskfree,sqrt(LOCALAV.var_diskfree));
00761 Verbose("Load Average = %4d -> (%f#%f) local [%f#%f]\n",LOADAVG,newvals.expect_loadavg,sqrt(newvals.var_loadavg),LOCALAV.expect_loadavg,sqrt(LOCALAV.var_loadavg));
00762
00763 for (i = 0; i < ATTR; i++)
00764 {
00765 newvals.expect_incoming[i] = WAverage(Incoming[i],currentvals->expect_incoming[i],WAGE);
00766 newvals.expect_outgoing[i] = WAverage(Outgoing[i],currentvals->expect_outgoing[i],WAGE);
00767 newvals.var_incoming[i] = WAverage((Incoming[i]-newvals.expect_incoming[i])*(Incoming[i]-newvals.expect_incoming[i]),currentvals->var_incoming[i],WAGE);
00768 newvals.var_outgoing[i] = WAverage((Outgoing[i]-newvals.expect_outgoing[i])*(Outgoing[i]-newvals.expect_outgoing[i]),currentvals->var_outgoing[i],WAGE);
00769
00770 LOCALAV.expect_incoming[i] = WAverage(newvals.expect_incoming[i],LOCALAV.expect_incoming[i],ITER);
00771 LOCALAV.expect_outgoing[i] = WAverage(newvals.expect_outgoing[i],LOCALAV.expect_outgoing[i],ITER);
00772 LOCALAV.var_incoming[i] = WAverage((Incoming[i]-LOCALAV.expect_incoming[i])*(Incoming[i]-LOCALAV.expect_incoming[i]),LOCALAV.var_incoming[i],ITER);
00773
00774 LOCALAV.var_outgoing[i] = WAverage((Outgoing[i]-LOCALAV.expect_outgoing[i])*(Outgoing[i]-LOCALAV.expect_outgoing[i]),LOCALAV.var_outgoing[i],ITER);
00775
00776 Verbose("%-15s-in = %4d -> (%f#%f) local [%f#%f]\n",ECGSOCKS[i][1],INCOMING[i],newvals.expect_incoming[i],sqrt(newvals.var_incoming[i]),LOCALAV.expect_incoming[i],sqrt(LOCALAV.var_incoming[i]));
00777 Verbose("%-14s-out = %4d -> (%f#%f) local [%f#%f]\n",ECGSOCKS[i][1],OUTGOING[i],newvals.expect_outgoing[i],sqrt(newvals.var_outgoing[i]),LOCALAV.expect_outgoing[i],sqrt(LOCALAV.var_outgoing[i]));
00778 }
00779
00780
00781 for (i = 0; i < PH_LIMIT; i++)
00782 {
00783 if (PH_BINARIES[i] == NULL)
00784 {
00785 continue;
00786 }
00787
00788 newvals.expect_pH[i] = WAverage(pH_delta[i],currentvals->expect_pH[i],WAGE);
00789 newvals.var_pH[i] = WAverage((pH_delta[i]-newvals.expect_pH[i])*(pH_delta[i]-newvals.expect_pH[i]),currentvals->var_pH[i],WAGE);
00790
00791
00792 LOCALAV.expect_pH[i] = WAverage(newvals.expect_pH[i],LOCALAV.expect_pH[i],ITER);
00793 LOCALAV.var_pH[i] = WAverage((pH_delta[i]-LOCALAV.expect_pH[i])*(pH_delta[i]-LOCALAV.expect_pH[i]),LOCALAV.var_pH[i],ITER);
00794
00795 Verbose("%-15s-in = %4d -> (%f#%f) local [%f#%f]\n",CanonifyName(PH_BINARIES[i]),PH_DELTA[i],newvals.expect_pH[i],sqrt(newvals.var_pH[i]),LOCALAV.expect_pH[i],sqrt(LOCALAV.var_pH[i]));
00796
00797 }
00798
00799 UpdateAverages(t,newvals);
00800
00801 if (WAGE > CFGRACEPERIOD)
00802 {
00803 UpdateDistributions(t,currentvals);
00804 }
00805
00806 return newvals;
00807 }
00808
00809
00810
00811 void ArmClasses(av,timekey)
00812
00813 struct Averages av;
00814 char *timekey;
00815
00816 { double sigma,delta,lsigma,ldelta;
00817 struct Item *classlist = NULL, *ip;
00818 int i;
00819 FILE *fp;
00820
00821 delta = NUMBER_OF_USERS - av.expect_number_of_users;
00822 sigma = sqrt(av.var_number_of_users);
00823 ldelta = NUMBER_OF_USERS - LOCALAV.expect_number_of_users;
00824 lsigma = sqrt(LOCALAV.var_number_of_users);
00825
00826 SetClasses(av.expect_number_of_users,delta,sigma,
00827 LOCALAV.expect_number_of_users,ldelta,lsigma,
00828 "Users",&classlist,timekey);
00829
00830 SetVariable("users",NUMBER_OF_USERS,av.expect_number_of_users,lsigma,&classlist);
00831
00832 delta = ROOTPROCS - av.expect_rootprocs;
00833 sigma = sqrt(av.var_rootprocs);
00834 ldelta = ROOTPROCS - LOCALAV.expect_rootprocs;
00835 lsigma = sqrt(LOCALAV.var_rootprocs);
00836
00837 SetClasses(av.expect_rootprocs,delta,sigma,
00838 LOCALAV.expect_rootprocs,ldelta,lsigma,
00839 "RootProcs",&classlist,timekey);
00840
00841 SetVariable("rootprocs",ROOTPROCS,av.expect_rootprocs,lsigma,&classlist);
00842
00843 delta = OTHERPROCS - av.expect_otherprocs;
00844 sigma = sqrt(av.var_otherprocs);
00845 ldelta = OTHERPROCS - LOCALAV.expect_otherprocs;
00846 lsigma = sqrt(LOCALAV.var_otherprocs);
00847
00848 SetClasses(av.expect_otherprocs,delta,sigma,
00849 LOCALAV.expect_otherprocs,ldelta,lsigma,
00850 "UserProcs",&classlist,timekey);
00851
00852
00853 SetVariable("userprocs",OTHERPROCS,av.expect_otherprocs,lsigma,&classlist);
00854
00855 delta = DISKFREE - av.expect_diskfree;
00856 sigma = sqrt(av.var_diskfree);
00857 ldelta = DISKFREE - LOCALAV.expect_diskfree;
00858 lsigma = sqrt(LOCALAV.var_diskfree);
00859
00860 SetClasses(av.expect_diskfree,delta,sigma,
00861 LOCALAV.expect_diskfree,ldelta,lsigma,
00862 "DiskFree",&classlist,timekey);
00863
00864 SetVariable("diskfree",DISKFREE,av.expect_diskfree,lsigma,&classlist);
00865
00866 SetClasses(av.expect_loadavg,delta,sigma,
00867 LOCALAV.expect_loadavg,ldelta,lsigma,
00868 "LoadAvg",&classlist,timekey);
00869
00870 SetVariable("loadavg",LOADAVG,av.expect_loadavg,lsigma,&classlist);
00871
00872 for (i = 0; i < ATTR; i++)
00873 {
00874 char name[256];
00875 strcpy(name,ECGSOCKS[i][1]);
00876 strcat(name,"_in");
00877 delta = INCOMING[i] - av.expect_incoming[i];
00878 sigma = sqrt(av.var_incoming[i]);
00879 ldelta = INCOMING[i] - LOCALAV.expect_incoming[i];
00880 lsigma = sqrt(LOCALAV.var_incoming[i]);
00881
00882 SetClasses(av.expect_incoming[i],delta,sigma,
00883 LOCALAV.expect_incoming[i],ldelta,lsigma,
00884 name,&classlist,timekey);
00885
00886 SetVariable(name,INCOMING[i],av.expect_incoming[i],lsigma,&classlist);
00887
00888 strcpy(name,ECGSOCKS[i][1]);
00889 strcat(name,"_out");
00890 delta = OUTGOING[i] - av.expect_outgoing[i];
00891 sigma = sqrt(av.var_outgoing[i]);
00892 ldelta = OUTGOING[i] - LOCALAV.expect_outgoing[i];
00893 lsigma = sqrt(LOCALAV.var_outgoing[i]);
00894
00895 SetClasses(av.expect_outgoing[i],delta,sigma,
00896 LOCALAV.expect_outgoing[i],ldelta,lsigma,
00897 name,&classlist,timekey);
00898
00899 SetVariable(name,OUTGOING[i],av.expect_outgoing[i],lsigma,&classlist);
00900 }
00901
00902 for (i = 0; i < PH_LIMIT; i++)
00903 {
00904 if (PH_BINARIES[i] == NULL)
00905 {
00906 continue;
00907 }
00908
00909 delta = PH_DELTA[i] - av.expect_pH[i];
00910 sigma = sqrt(av.var_pH[i]);
00911 ldelta = PH_DELTA[i] - LOCALAV.expect_pH[i];
00912 lsigma = sqrt(LOCALAV.var_pH[i]);
00913
00914 SetClasses(av.expect_pH[i],delta,sigma,
00915 LOCALAV.expect_pH[i],ldelta,lsigma,
00916 CanonifyName(PH_BINARIES[i]),&classlist,timekey);
00917
00918 SetVariable(CanonifyName(PH_BINARIES[i]),PH_DELTA[i],av.expect_pH[i],lsigma,&classlist);
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932 unlink(ENV_NEW);
00933
00934 if ((fp = fopen(ENV_NEW,"w")) == NULL)
00935 {
00936 DeleteItemList(PREVIOUS_STATE);
00937 PREVIOUS_STATE = classlist;
00938 return;
00939 }
00940
00941 for (ip = classlist; ip != NULL; ip=ip->next)
00942 {
00943 fprintf(fp,"%s\n",ip->name);
00944 }
00945
00946 DeleteItemList(PREVIOUS_STATE);
00947 PREVIOUS_STATE = classlist;
00948
00949 for (ip = ALL_INCOMING; ip != NULL; ip=ip->next)
00950 { char *sp;
00951 int print=true;
00952
00953 for (sp = ip->name; *sp != '\0'; sp++)
00954 {
00955 if (!isdigit((int)*sp))
00956 {
00957 print = false;
00958 }
00959 }
00960
00961 if (print)
00962 {
00963 Debug("Port(in,%s) ",ip->name);
00964 fprintf(fp,"pin-%s\n",ip->name);
00965 }
00966 }
00967
00968 Debug("\n\n");
00969
00970 for (ip = ALL_OUTGOING; ip != NULL; ip=ip->next)
00971 { char *sp;
00972 int print=true;
00973
00974 for (sp = ip->name; *sp != '\0'; sp++)
00975 {
00976 if (!isdigit((int)*sp))
00977 {
00978 continue;
00979 }
00980 }
00981
00982 if (print)
00983 {
00984 Debug("Port(out,%s) ",ip->name);
00985
00986 }
00987 }
00988
00989 Debug("\n\n");
00990 fclose(fp);
00991
00992 rename(ENV_NEW,ENV);
00993 }
00994
00995
00996
00997
00998
00999 void GatherProcessData()
01000
01001 { FILE *pp;
01002 char pscomm[bufsize];
01003 char user[maxvarsize];
01004 struct Item *list = NULL;
01005
01006 snprintf(pscomm,bufsize,"%s %s",VPSCOMM[VSYSTEMHARDCLASS],VPSOPTS[VSYSTEMHARDCLASS]);
01007
01008 NUMBER_OF_USERS = ROOTPROCS = OTHERPROCS = 0;
01009
01010 if ((pp = cfpopen(pscomm,"r")) == NULL)
01011 {
01012 return;
01013 }
01014
01015 ReadLine(VBUFF,bufsize,pp);
01016
01017 while (!feof(pp))
01018 {
01019 ReadLine(VBUFF,bufsize,pp);
01020 sscanf(VBUFF,"%s",user);
01021 if (!IsItemIn(list,user))
01022 {
01023 PrependItem(&list,user,NULL);
01024 NUMBER_OF_USERS++;
01025 }
01026
01027 if (strcmp(user,"root") == 0)
01028 {
01029 ROOTPROCS++;
01030 }
01031 else
01032 {
01033 OTHERPROCS++;
01034 }
01035
01036 }
01037
01038 cfpclose(pp);
01039
01040 snprintf(VBUFF,maxvarsize,"%s/state/cf_users",WORKDIR);
01041 SaveItemList(list,VBUFF,"none");
01042
01043 Verbose("(Users,root,other) = (%d,%d,%d)\n",NUMBER_OF_USERS,ROOTPROCS,OTHERPROCS);
01044 }
01045
01046
01047
01048 void GatherDiskData()
01049
01050 {
01051 DISKFREE = GetDiskUsage("/",cfpercent);
01052 Verbose("Disk free = %d %%\n",DISKFREE);
01053 }
01054
01055
01056
01057
01058 void GatherLoadData()
01059
01060 { double load[4] = {0,0,0,0}, sum = 0.0;
01061 int i,n = 1;
01062
01063 Debug("GatherLoadData\n\n");
01064
01065 #ifdef HAVE_GETLOADAVG
01066 if ((n = getloadavg(load,LOADAVG_5MIN)) == -1)
01067 {
01068 LOADAVG = 0.0;
01069 }
01070 else
01071 {
01072 for (i = 0; i < n; i++)
01073 {
01074 Debug("Found load average to be %lf of %d samples\n", load[i],n);
01075 sum += load[i];
01076 }
01077 }
01078 #endif
01079
01080
01081
01082 LOADAVG = (int) (100.0 * sum);
01083 Verbose("100 x Load Average = %d\n",LOADAVG);
01084 }
01085
01086
01087
01088 void GatherSocketData()
01089
01090 { FILE *pp,*fpout;
01091 char local[bufsize],remote[bufsize],comm[bufsize];
01092 struct Item *in[ATTR],*out[ATTR];
01093 char *sp;
01094 int i;
01095
01096 Debug("GatherSocketData()\n");
01097
01098 for (i = 0; i < ATTR; i++)
01099 {
01100 INCOMING[i] = OUTGOING[i] = 0;
01101 in[i] = out[i] = NULL;
01102 }
01103
01104 if (ALL_INCOMING != NULL)
01105 {
01106 DeleteItemList(ALL_INCOMING);
01107 ALL_INCOMING = NULL;
01108 }
01109
01110 if (ALL_OUTGOING != NULL)
01111 {
01112 DeleteItemList(ALL_OUTGOING);
01113 ALL_OUTGOING = NULL;
01114 }
01115
01116 sscanf(VNETSTAT[VSYSTEMHARDCLASS],"%s",comm);
01117
01118 strcat(comm," -n");
01119
01120 if ((pp = cfpopen(comm,"r")) == NULL)
01121 {
01122 return;
01123 }
01124
01125 while (!feof(pp))
01126 {
01127 bzero(local,bufsize);
01128 bzero(remote,bufsize);
01129
01130 ReadLine(VBUFF,bufsize,pp);
01131
01132 if (strstr(VBUFF,"UNIX"))
01133 {
01134 break;
01135 }
01136
01137 if (!strstr(VBUFF,"."))
01138 {
01139 continue;
01140 }
01141
01142
01143
01144 if (strncmp(VBUFF,"tcp",3) == 0)
01145 {
01146 sscanf(VBUFF,"%*s %*s %*s %s %s",local,remote);
01147 }
01148 else
01149 {
01150 sscanf(VBUFF,"%s %s",local,remote);
01151 }
01152
01153 if (strlen(local) == 0)
01154 {
01155 continue;
01156 }