#include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #include <sys/time.h> #include <sys/resource.h>
  // Defines, Data structures, global vars #define MAX_DATA 100 #define SLEEP_TIME 2 #define AFTER 3
  #define TODO_VFS_CACHE_INC 1 #define TODO_VFS_CACHE_DEC 2 #define TODO_DIRTY_INC 3 #define TODO_DIRTY_DEC 4 #define TODO_REBALANCE_READ 5 #define TODO_REBALANCE_WRITE 6 #define TODO_READAHEAD_UP 7 #define TODO_READAHEAD_DOWN 8 #define TODO_SWAPPINESS_UP 9 #define TODO_SWAPPINESS_DOWN 10 #define TODO_SWAPPINESS_ONE 11 #define TODO_PAGECLUSTER_UP 12 #define TODO_PAGECLUSTER_NORM 13 #define TODO_FLUSH_SWAP 14 #define TODO_CHECK_FILENR 15 #define TODO_RECVBUF_UP 16 #define TODO_RECVBUF_DOWN 17 #define TODO_SENDBUF_UP 18 #define TODO_SENDBUF_DOWN 19
 
 
  // system-data struct struct tcinfo {     int id;     float loadavg;     int memused;     int memmax;     int memuse;     int buffers;     int cached;     int swapcached;     int swapused;     int swapmax;     int swapuse;     int dirty;     int writeback;     int uswap;     int ioread;     int iowrite;     int recv;     int send; };
  // statistics struct struct tcstat {     float loadavg[3];     int memused[3];     int memmax[3];     int memuse[4];     int buffers[4];     int cached[3];     int swapcached[3];     int swapused[3];     int swapmax[3];     int swapuse[3];     int dirty[3];     int writeback[3];     int uswap[3];     long ioread[3];     long iowrite[3];     int recv[4];     int send[4]; };
  // vars struct tcinfo cia[MAX_DATA]; struct tcstat cst; int cindex; // read over write marker int sched=0; // Read-ahead, marker int read_ahb=1; char *ulog="/var/log/tune.log";
  // recover after X passes int vfsd_after=0; int vfsu_after=0; int recu_after=0; int recd_after=0; int senu_after=0; int send_after=0;
  // Log into file void logme(char *data) {     FILE *fd;     fd=fopen(ulog,"a+");     fputs(data,fd);     fclose(fd); } // Get system data void getdata(int time) {     FILE *fd;     char *buf;     char *buf1;     char *buf2;     char *buf3;     char *buf4;     int t1,t2;     long tt1,tt2;     float l;
 
      for (cindex=1;cindex<=time;cindex++)         {         cia[cindex].id=cindex; // Parse networking stats         buf=malloc(300);         fd=fopen("/proc/net/snmp","r");         fgets(buf,300,fd);         fgets(buf,300,fd);         fclose(fd);         buf1=strtok_r(buf," ",&buf4);         for (t1=1;t1<=9;t1++) buf1=strtok_r(NULL," ",&buf4);         l=strtod(buf1,NULL);         cia[cindex].recv=l;         buf1=strtok_r(NULL," ",&buf4);         l=strtod(buf1,NULL);         cia[cindex].send=l;         free(buf);
 
 
  // Parse loadavg data         buf=malloc(100);         fd=fopen("/proc/loadavg","r");         fgets(buf,100,fd);         buf1=strtok(buf," ");         l=strtod(buf1,NULL);         cia[cindex].loadavg=l;         free(buf); // Parse meminfo stats         buf=malloc(300); //memleakshit         buf4=buf;         fd=fopen("/proc/meminfo","r");         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         t1=strtod(buf1,NULL);         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         t2=strtod(buf1,NULL);         cia[cindex].memused=((t1-t2)*100/t1);         cia[cindex].memuse=t2;         cia[cindex].memmax=t1; // Buffers         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         cia[cindex].buffers=strtod(buf1,NULL);
  // Cached         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         cia[cindex].cached=strtod(buf1,NULL);
  // SwapCached         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         cia[cindex].swapcached=strtod(buf1,NULL); // Jumpto..         for (t1=1;t1<=6;t1++) fgets(buf,300,fd); // Parse swapinfo         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         t1=strtod(buf1,NULL);         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         t2=strtod(buf1,NULL);         cia[cindex].swapused=((t1-t2)*100/t1);         cia[cindex].swapuse=t2;         cia[cindex].swapmax=t1; // Dirty, writeback         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         cia[cindex].dirty=strtod(buf1,NULL);         fgets(buf,300,fd);         buf1=strtok_r(buf,":",&buf2);         buf1=strtok_r(NULL,":",&buf2);         cia[cindex].writeback=strtod(buf1,NULL); // Close it, free it..         fclose(fd);         free(buf); // Get I/O stats, the dumbest way  '>         fd=fopen("/proc/diskstats","r");         tt1=0;tt2=0;         while (feof(fd)==0)             {                 buf=malloc(200);                 if (fgets(buf,200,fd)!=NULL)                 {                     buf1=strtok_r(buf," ",&buf2);                     buf1=strtok_r(NULL," ",&buf2);                     buf1=strtok_r(NULL," ",&buf2);                     buf1=strtok_r(NULL," ",&buf2);                     tt1=tt1+(strtol(buf1,NULL,0)/100);                     buf1=strtok_r(NULL," ",&buf2);                     buf1=strtok_r(NULL," ",&buf2);                     buf1=strtok_r(NULL," ",&buf2);                     tt2=tt2+(strtol(buf1,NULL,0)/100);                 }                 free(buf);
              }         fclose(fd);         cia[cindex].ioread=tt1;         cia[cindex].iowrite=tt2;
  // Sleep...         sleep(SLEEP_TIME);         } }
 
  // Analyze data: some stats analysis void analyze_data() {     int a,b;     int mean,mxdev,mndev;     float mmean,mmxdev,mmndev;
  // Network stats prepare     cst.send[4]=cst.send[3];     cst.recv[4]=cst.recv[3];     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].recv;             if (mxdev<abs(cia[a].recv-cia[a-1].recv)) mxdev=abs(cia[a].recv-cia[a-1].recv);             mndev=mndev+cia[a].recv-cia[a-1].recv;         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("recv:  Average:%d kb  Max_deviation:%dkb Mean_deviation:%dkb\n",mean,mxdev,m ndev);     cst.recv[1]=mean;cst.recv[2]=mxdev;cst.recv[3]=mndev;
      mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].send;             if (mxdev<abs(cia[a].send-cia[a-1].send)) mxdev=abs(cia[a].send-cia[a-1].send);             mndev=mndev+abs(cia[a].send-cia[a-1].send);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("send:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mxdev,m ndev);     cst.send[1]=mean;cst.send[2]=mxdev;cst.send[3]=mndev;
 
 
  // Loadavg stats parse     mmean=0;mmxdev=0;mmndev=0;     for (a=2;a!=cindex;a++)         {             mmean=mmean+cia[a].loadavg;             if (mmxdev<fabsf(cia[a].loadavg-cia[a-1].loadavg)) mmxdev=fabsf(cia[a].loadavg-cia[a-1].loadavg);             mmndev=mmndev+fabsf(cia[a].loadavg-cia[a-1].loadavg);         }     mmean=mmean/(cindex-2);     mmndev=mmndev/(cindex-2); //    printf("loadavg:  Average:%.2f percent  Max_deviation:%.2f  Mean_deviation:%.2f\n",mm ean,mmxdev,mmndev);     cst.loadavg[1]=mmean;cst.loadavg[2]=mmxdev;cst.loadavg[3]=mmndev;
  // Memory Usage stats     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].memused;             if (mxdev<abs(cia[a].memused-cia[a-1].memused)) mxdev=abs(cia[a].memused-cia[a-1].memused);             mndev=mndev+abs(cia[a].memused-cia[a-1].memused);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("Memusage:  Average:%d percent  Max_deviation:%d  Mean_deviation:%d\n",mean,mx dev,mndev);     cst.memused[1]=mean;cst.memused[2]=mxdev;cst.memused[3]=mndev;
  // Memory use stats     mean=0;mxdev=0;mndev=0;     cst.memuse[4]=cst.memuse[3];     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].memuse;             if (mxdev<abs(cia[a].memuse-cia[a-1].memuse)) mxdev=abs(cia[a].memuse-cia[a-1].memuse);             mndev=mndev+(cia[a].memuse-cia[a-1].memuse);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("Memuse:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mxdev ,mndev);     cst.memuse[1]=mean;cst.memuse[2]=mxdev;cst.memuse[3]=mndev;
 
  // Buffers stats     cst.buffers[4]=cst.buffers[3];     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].buffers;             if (mxdev<abs(cia[a].buffers-cia[a-1].buffers)) mxdev=abs(cia[a].buffers-cia[a-1].buffers);             mndev=mndev+(cia[a].buffers-cia[a-1].buffers);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("buffers:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mxde v,mndev);     cst.buffers[1]=mean;cst.buffers[2]=mxdev;cst.buffers[3]=mndev;
 
  // Cached stats     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].cached;             if (mxdev<abs(cia[a].cached-cia[a-1].cached)) mxdev=abs(cia[a].cached-cia[a-1].cached);             mndev=mndev+abs(cia[a].cached-cia[a-1].cached);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("cached:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mxdev ,mndev);     cst.cached[1]=mean;cst.cached[2]=mxdev;cst.cached[3]=mndev;
 
  // swapcached stats     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].swapcached;             if (mxdev<abs(cia[a].swapcached-cia[a-1].swapcached)) mxdev=abs(cia[a].swapcached-cia[a-1].swapcached);             mndev=mndev+abs(cia[a].swapcached-cia[a-1].swapcached);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("swapcached:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,m xdev,mndev);
  cst.swapcached[1]=mean;cst.swapcached[2]=mxdev;cst.swapcached[3]=mndev;
 
  // Swap Usage stats    mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].swapused;             if (mxdev<abs(cia[a].swapused-cia[a-1].swapused)) mxdev=abs(cia[a].swapused-cia[a-1].swapused);             mndev=mndev+abs(cia[a].swapused-cia[a-1].swapused);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("swapusage:  Average:%d percent  Max_deviation:%d  Mean_deviation:%d\n",mean,m xdev,mndev);     cst.swapused[1]=mean;cst.swapused[2]=mxdev;cst.swapused[3]=mndev;
 
  // swap use stats     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].swapuse;             if (mxdev<abs(cia[a].swapuse-cia[a-1].swapuse)) mxdev=abs(cia[a].swapuse-cia[a-1].swapuse);             mndev=mndev+abs(cia[a].swapuse-cia[a-1].swapuse);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("swapuse:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mxdev,mndev);     cst.swapuse[1]=mean;cst.swapuse[2]=mxdev;cst.swapuse[3]=mndev;
 
  // dirty stats     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].dirty;             if (mxdev<abs(cia[a].dirty-cia[a-1].dirty)) mxdev=abs(cia[a].dirty-cia[a-1].dirty);             mndev=mndev+abs(cia[a].dirty-cia[a-1].dirty);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("dirty:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mxdev, mndev);     cst.dirty[1]=mean;cst.dirty[2]=mxdev;cst.dirty[3]=mndev;
 
  // writeback stats     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].writeback;             if (mxdev<abs(cia[a].writeback-cia[a-1].writeback)) mxdev=abs(cia[a].writeback-cia[a-1].writeback);             mndev=mndev+abs(cia[a].writeback-cia[a-1].writeback);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("writeback:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mx dev,mndev);
  cst.writeback[1]=mean;cst.writeback[2]=mxdev;cst.writeback[3]=mndev;
  // ioread stats     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)         {             mean=mean+cia[a].ioread;             if (mxdev<abs(cia[a].ioread-cia[a-1].ioread)) mxdev=abs(cia[a].ioread-cia[a-1].ioread);             mndev=mndev+abs(cia[a].ioread-cia[a-1].ioread);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("ioread:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mxdev ,mndev);     cst.ioread[1]=mean;cst.ioread[2]=mxdev;cst.ioread[3]=mndev;
  // iowrite stats     mean=0;mxdev=0;mndev=0;     for (a=2;a!=cindex;a++)        {             mean=mean+cia[a].iowrite;             if (mxdev<abs(cia[a].iowrite-cia[a-1].iowrite)) mxdev=abs(cia[a].iowrite-cia[a-1].iowrite);             mndev=mndev+abs(cia[a].iowrite-cia[a-1].iowrite);         }     mean=mean/(cindex-2);     mndev=mndev/cindex; //    printf("iowrite:  Average:%d kb  Max_deviation:%dkb  Mean_deviation:%dkb\n",mean,mxde v,mndev); cst.iowrite[1]=mean;cst.iowrite[2]=mxdev;cst.iowrite[3]=mndev;
  }
 
  // The funny part: react accordingly void makescript(int TODO) {     char *str=malloc(100);     FILE *fd;     char *buff=malloc(100);     int value;
  // Re-balance IO scheduller     void rebalance()         {         if (sched>0) {                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/iosched/read_expire|awk '{print  \"echo %d > \"$1}'`\"",(sched)*125*2);                 system(str);                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/iosched/read_batch_expire|awk ' {print \"echo %d > \"$1}'`\"",(sched)*125);                 system(str);                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/iosched/write_expire|awk '{prin t \"echo %d > \"$1}'`\"",(sched)*125);                 system(str);                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/iosched/write_batch_expire|awk '{print \"echo %d > \"$1}'`\"",(sched)*125*4);                 system(str);                 }         else if (sched<0)       {                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/iosched/read_expire|awk '{print  \"echo %d > \"$1}'`\"",((0-sched)+1)*125);                 system(str);                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/iosched/read_batch_expire|awk ' {print \"echo %d > \"$1}'`\"",((0-sched)+1)*125*4);                 system(str);                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/iosched/write_expire|awk '{prin t \"echo %d > \"$1}'`\"",(1-sched)*125*4);                 system(str);                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/iosched/write_batch_expire|awk '{print \"echo %d > \"$1}'`\"",(1-sched)*125);                 system(str);         }     }
  // Resize readahead buffer     void resizerabuffer()         {                 sprintf(str,"sh -c \"`ls /sys/block/*/queue/read_ahead_kb|awk '{print \"ech o %d > \"$1}'`\"",(read_ahb)*128);                 system(str);         }
  // Set maximum FDs     void filenr()     {         char *buf1;         int i,j;
  //      buff=malloc(300);         fd=fopen("/proc/sys/fs/file-nr","r");         fgets(buff,300,fd);         fclose(fd);         buf1=strtok(buff," ");         i=strtod(buf1,NULL);         fd=fopen("/proc/sys/fs/file-max","r");         fgets(buff,300,fd);         fclose(fd);         j=strtod(buff,NULL);         if ((j-i) < 10000)             {             j=j+10000;             logme("Tune FS: Raise maximum file handles...\n");             sprintf(buff,"echo %d > /proc/sys/fs/file-max",j);             system(buff);             }
          if ((j-i) > 20000)             {             j=j-10000;             logme("Tune FS: Don't need so much available file handles...\n");             sprintf(buff,"echo %d > /proc/sys/fs/file-max",j);             system(buff);             }
          }
 
      switch (TODO)     {
  // Increase vfs_cache_pressure     case TODO_VFS_CACHE_INC:         {         logme("Tune VM: Increase VFS cache pressure -> pagecache..\n");         fd=fopen("/proc/sys/vm/vfs_cache_pressure","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         value=value+10;         sprintf(str,"echo %d > /proc/sys/vm/vfs_cache_pressure",value);         system(str);         if ((vfsu_after==0)&&(vfsd_after!=1)) vfsu_after=AFTER;
          } break;
  //decrease vfs_cache_pressure     case TODO_VFS_CACHE_DEC:         {         logme("Tune VM: Decrease VFS cache pressure -> inode/dentry cache...\n");         fd=fopen("/proc/sys/vm/vfs_cache_pressure","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         value=value-10;         sprintf(str,"echo %d > /proc/sys/vm/vfs_cache_pressure",value);         system(str);         if ((vfsd_after==0) && (vfsu_after!=1)) vfsd_after=AFTER;         } break;
  // Increase dirty expire time     case TODO_DIRTY_INC:         {         logme("Tune VM: Increase dirty cache expire time..\n");        fd=fopen("/proc/sys/vm/dirty_expire_centisecs","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         value=value+500;         sprintf(str,"echo %i > /proc/sys/vm/dirty_expire_centisecs",value);         system(str);         fd=fopen("/proc/sys/vm/dirty_writeback_centisecs","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         value=value+500;         sprintf(str,"echo %i > /proc/sys/vm/dirty_writeback_centisecs",value);         system(str);         } break;
  //  Decrease dirty expire time     case TODO_DIRTY_DEC:         {         fd=fopen("/proc/sys/vm/dirty_expire_centisecs","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         if (value>=1000)        {value=value-500;logme("Tune VM: Decrease dirty cache expir e time..\n");}         sprintf(str,"echo %i > /proc/sys/vm/dirty_expire_centisecs",value);         system(str);        fd=fopen("/proc/sys/vm/dirty_writeback_centisecs","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         if (value>=500) {value=value-500;}         sprintf(str,"echo %i > /proc/sys/vm/dirty_writeback_centisecs",value);         system(str);         } break;
  // Rebalance iosched - we have more reads     case TODO_REBALANCE_READ:         {         if (sched>-2)          {sched=sched-1;          logme("Tune IOsched: Peak reads,rebalancing..\n");          rebalance();          }         } break;
  // Rebalance iosched - we have more writes     case TODO_REBALANCE_WRITE:         {         if (sched<2) {             sched=sched+1;             logme("Tune IOsched: Peak writes,rebalancing..\n");             rebalance();             }         } break;
  // Increase swappiness     case TODO_SWAPPINESS_UP:         {         fd=fopen("/proc/sys/vm/swappiness","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         if (value<=90)         {logme("Tune VM: Increase swappiness, don't need better responsiveness now..\n");va lue=value+10;}         sprintf(str,"echo %i > /proc/sys/vm/swappiness",value);         system(str);         } break;
  // Decrease swappiness     case TODO_SWAPPINESS_DOWN:         {         fd=fopen("/proc/sys/vm/swappiness","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         if (value>=30)         {logme("Tune VM: Decrease swappiness, we want better responsiveness now...\n");valu e=value-30;}         else if ((value>10)&&(value<30)) {logme("Tune VM: Decrease swappiness, we want better responsiveness now...\n");value=10;}         sprintf(str,"echo %i > /proc/sys/vm/swappiness",value);         system(str);         } break;
  // (Almost) no swappiness     case TODO_SWAPPINESS_ONE:         {         value=10;         logme("Tune VM: Set swappiness at minimum, we don't need swapping now...\n");         sprintf(str,"echo %i > /proc/sys/vm/swappiness",value);         system(str);         } break;
  // Increase page-cluster     case TODO_PAGECLUSTER_UP:         {         fd=fopen("/proc/sys/vm/page-cluster","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         logme("Tune VM: Increase page-cluster for better swap I/O performance..\n");value=v alue+1;         sprintf(str,"echo %i > /proc/sys/vm/page-cluster",value);         system(str);         } break; // Normalize page-cluster     case TODO_PAGECLUSTER_NORM:         {         fd=fopen("/proc/sys/vm/page-cluster","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         if (value!=3)             {             logme("Tune VM: Return page-cluster to its normal value..\n");value=3;                 sprintf(str,"echo %i > /proc/sys/vm/page-cluster",value);                 system(str);             }         } break;
  // Bye-bye swap...     case TODO_FLUSH_SWAP:         {             logme("Tune VM: It's a good time to flush all your swap...\n");value=3;             sprintf(str,"swapoff -a;swapon -a",value);             system(str);         } break;
 
  // Increase readahead buffers     case TODO_READAHEAD_UP:         {             if (read_ahb<20)             {             logme("Tune IO: Increase read-ahead buffers size...\n");             read_ahb=read_ahb+1;             resizerabuffer();             }         } break;
  // Decrease readahead buffers     case TODO_READAHEAD_DOWN:         {             if (read_ahb>1)             {             logme("Tune IO: Decrease read-ahead buffers size...\n");             read_ahb=read_ahb-1;             resizerabuffer();             }         } break;
  // Check file-nr against file-max     case TODO_CHECK_FILENR:         {         filenr();         } break;
  // Increase receive network buffers size..     case TODO_RECVBUF_UP:         {         fd=fopen("/proc/sys/net/core/rmem_max","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         logme("Tune NET: Increase receive network buffers size..\n");value=value+20000;         sprintf(str,"echo %i > /proc/sys/net/core/rmem_max",value);         system(str);         fd=fopen("/proc/sys/net/core/rmem_default","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         value=value+20000;         sprintf(str,"echo %i > /proc/sys/net/core/rmem_default",value);         system(str);         if ((recu_after==0)&&(recd_after!=1)) recu_after=AFTER;
          } break;
  // Decrease receive network buffers..     case TODO_RECVBUF_DOWN:         {         fd=fopen("/proc/sys/net/core/rmem_max","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         logme("Tune NET: Decrease receive network buffers size..\n");value=value-20000;
         sprintf(str,"echo %i > /proc/sys/net/core/rmem_max",value);         system(str);         fd=fopen("/proc/sys/net/core/rmem_default","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         value=value-20000;         sprintf(str,"echo %i > /proc/sys/net/core/rmem_default",value);         system(str);         if ((recd_after==0)&&(recu_after!=1)) recd_after=AFTER;         } break;
  // Increase send network buffers size..     case TODO_SENDBUF_UP:         {         fd=fopen("/proc/sys/net/core/wmem_max","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         logme("Tune NET: Increase send network buffers size..\n");value=value+20000;         sprintf(str,"echo %i > /proc/sys/net/core/wmem_max",value);         system(str);         fd=fopen("/proc/sys/net/core/wmem_default","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         value=value+20000;         sprintf(str,"echo %i > /proc/sys/net/core/wmem_default",value);         system(str);         if ((senu_after==0)&&(send_after!=1)) senu_after=AFTER;         } break;
  // Decrease receive network buffers..     case TODO_SENDBUF_DOWN:         {         fd=fopen("/proc/sys/net/core/wmem_max","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         logme("Tune NET: Decrease send network buffers size..\n");value=value-20000;         sprintf(str,"echo %i > /proc/sys/net/core/wmem_max",value);         system(str);         fd=fopen("/proc/sys/net/core/wmem_default","r");         fgets(buff,100,fd);         value=strtod(buff,NULL);         fclose(fd);         value=value-20000;         sprintf(str,"echo %i > /proc/sys/net/core/wmem_default",value);         system(str);         if ((send_after==0)&&(senu_after!=1)) send_after=AFTER;
          } break;     }     free(buff);free(str); }
 
  // Teh Delphi Oracle: void givemyadvice() {
  /* Must not: - Rely on absolute ratios (value_X more than X), only relative (value_X more than N*value_Y) - Keep it eventually unbalanced */     if ( (cst.buffers[3]>cst.buffers[4]+1) && ((cst.buffers[3]+cst.buffers[4])>0) && (cst.memuse[4]>cst.memuse[3]) ){makescript(TODO_VFS_CACHE_INC);}     else if ((cst.buffers[3]<cst.buffers[4]+1)  && ((cst.buffers[3]+cst.buffers[4])<0) && (cst.memuse[4]<cst.memuse[3]) ) {makescript(TODO_VFS_CACHE_DEC);}     if (3*cst.dirty[2]<cst.dirty[1]) {makescript(TODO_DIRTY_DEC);}     if (cst.dirty[1]<cst.dirty[2]) {makescript(TODO_DIRTY_INC);}     if (cst.ioread[2]>cst.iowrite[2]) {makescript(TODO_REBALANCE_READ);}     else if (cst.iowrite[2]>3*cst.ioread[2]) {makescript(TODO_REBALANCE_WRITE);}     if (cst.swapuse[1]==0) {makescript(TODO_SWAPPINESS_ONE);}     if ((cst.loadavg[2]>0.05)&& (cst.swapused[1]>0)) {makescript(TODO_SWAPPINESS_DOWN);}     if ((cst.loadavg[2]<=0.05) && (cst.swapused[1]>0)){makescript(TODO_SWAPPINESS_UP);}     if (cst.swapuse[2]>0) {makescript(TODO_PAGECLUSTER_UP);}     else {makescript(TODO_PAGECLUSTER_NORM);}     if ( (cst.swapcached[1]>0) && (cst.swapuse[2]==0) && (cst.swapuse[3]==0) && (cst.loadav g[3]<0.01)) {makescript(TODO_FLUSH_SWAP);}     if (cst.ioread[3]<1) {makescript(TODO_READAHEAD_DOWN);}     if (cst.ioread[3]<1) {makescript(TODO_READAHEAD_DOWN);}     if (cst.ioread[2]>5*(cst.ioread[3]+1)) {makescript(TODO_READAHEAD_UP);}     if ((cst.recv[3]>35*cst.recv[4]+1) && (cst.recv[3]+cst.recv[4]>0)) {makescript(TODO_RECVBUF_UP);}     if ((cst.recv[4]>35*cst.recv[3]+1)  && (cst.recv[3]+cst.recv[4]<0)) {makescript(TODO_RECVBUF_DOWN);}     if ((cst.send[3]>35*cst.send[4]+1) && (cst.send[3]+cst.send[4]>0)) {makescript(TODO_SENDBUF_UP);}     if ((cst.send[4]>35*cst.send[3]+1) && (cst.send[3]+cst.send[4]<0)) {makescript(TODO_SENDBUF_DOWN);}
  if (vfsu_after>0) vfsu_after=vfsu_after-1; if (vfsd_after>0) vfsd_after=vfsd_after-1; if (recu_after>0) recu_after=recu_after-1; if (recd_after>0) recd_after=recd_after-1; if (senu_after>0) senu_after=senu_after-1; if (send_after>0) send_after=send_after-1; // These are mandatory
  // Deprecate! //    makescript(TODO_CHECK_FILENR);     if (vfsu_after==1) makescript(TODO_VFS_CACHE_DEC);     if (vfsd_after==1) makescript(TODO_VFS_CACHE_INC);     if (recu_after==1) makescript(TODO_RECVBUF_DOWN);     if (recd_after==1) makescript(TODO_RECVBUF_UP);     if (senu_after==1) makescript(TODO_SENDBUF_DOWN);     if (send_after==1) makescript(TODO_SENDBUF_UP);
  }
  // Here we are now, entertain us.. int main() {     struct rlimit *rlm;
      cst.send[3]=0;     cst.memuse[3]=0;     cst.recv[3]=0;     cst.buffers[3]=0;     cst.cached[3]=0;     logme("***dktune started***\n"); // DO NOT FALL VICTIM TO STUPID RESTRICTIONS!!!     rlm->rlim_cur=5000;     rlm->rlim_max=30000;     setrlimit(RLIMIT_NOFILE,rlm);
      printf("Dynamic kernel tunning wannabe\nBy Milen Rangelov <mrangelov_@_globul_._bg>\n\nDaemonizing...\n");
  // Detach from tty..     if ((fork())!=0) exit(0);     setsid();     if ((fork())!=0) exit(0);
  // Main Loop     while (cindex!=-2)         {         getdata(10);         analyze_data();         givemyadvice();         } return 0; }
 
  |