#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; }
|