home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.10 / util-lin / util-linux-1.10 / bdflush.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-23  |  6.5 KB  |  234 lines

  1. /* do: "sh -x bdupdate.c" to make the executable */
  2.  
  3. /*
  4.  * v1.0 - released to Eric Youngdale 17 jan 1994
  5.  * v1.1 - added exit() statements after two loops, DEBUG, argv0 diags
  6.  * v1.2 - added getopt and a buch of flags to set params
  7.  * v1.3 - Call setsid after each fork, print version number.
  8.  * v1.4 - Minor bugfix - sync_delay and flush_delay were not being used.
  9.  */
  10.  
  11. #undef DEBUG
  12.  
  13. #include <stdio.h>
  14. #include <sys/types.h>
  15. #include <unistd.h>
  16. #include <limits.h>
  17. #include <signal.h>
  18. #include <linux/unistd.h>
  19.  
  20. /*
  21.  * bdupdate: an attempt to unify the update and bdflush programs; this
  22.  * should be a drop-in replacement for "update", but calls bdflush (if
  23.  * it works) every 5 seconds, too.
  24.  *
  25.  * If invoked with an argument, it prints stats as-per bdflush.
  26.  *
  27.  * - alec <Alec.Muffett@UK.Sun.COM>
  28.  */
  29.  
  30. _syscall2(int, bdflush, int, func, int, data);
  31.  
  32. static char * version_string = "1.4";
  33.  
  34. char *bdparam[] =
  35. {
  36.     "Max fraction of LRU list to examine for dirty blocks",
  37.     "Max number of dirty blocks to write each time bdflush activated",
  38.     "Num of clean buffers to be loaded onto free list by refill_freelist",
  39.     "Dirty block threshold for activating bdflush in refill_freelist",
  40.     "Percentage of cache to scan for free clusters",
  41.     "Time for data buffers to age before flushing",
  42.     "Time for non-data (dir, bitmap, etc) buffers to age before flushing",
  43.     "Time buffer cache load average constant",
  44.     "LAV ratio (used to determine threshold for buffer fratricide).",
  45.     (char *) 0
  46. };
  47.  
  48. void
  49. inststr(char *dst[], int argc, char *src)
  50. {
  51.     if (strlen(src) <= strlen(dst[0]))
  52.     {
  53.         char *ptr;
  54.  
  55.         for (ptr = dst[0]; *ptr; *(ptr++) = '\0');
  56.  
  57.         strcpy(dst[0], src);
  58.     } else
  59.     {
  60.         /* stolen from the source to perl 4.036 (assigning to $0) */
  61.         char *ptr, *ptr2;
  62.         int count;
  63.         ptr = dst[0] + strlen(dst[0]);
  64.         for (count = 1; count < argc; count++) {
  65.             if (dst[count] == ptr + 1)
  66.                 ptr += strlen(++ptr);
  67.         }
  68.         if (environ[0] == ptr + 1) {
  69.             for (count = 0; environ[count]; count++)
  70.                 if (environ[count] == ptr + 1)
  71.                     ptr += strlen(++ptr);
  72.         }
  73.         count = 0;
  74.         for (ptr2 = dst[0]; ptr2 <= ptr; ptr2++) {
  75.             *ptr2 = '\0';
  76.             count++;
  77.         }
  78.         strncpy(dst[0], src, count);
  79.     }
  80. }
  81.  
  82. void
  83. usage(argv)
  84.      char ** argv;
  85. {
  86.     fprintf(stderr,"Usage:%s [-d][-s sync-delay][-f flush-delay]\n",argv[0]);
  87.     fprintf(stderr,"            [-0 Max fraction of LRU list to examine for dirty blocks] \n");
  88.     fprintf(stderr,"            [-1 Max number of dirty blocks to write each time bdflush activated] \n");
  89.     fprintf(stderr,"            [-2 Num of clean buffers to be loaded onto free list by refill_freelist] \n");
  90.     fprintf(stderr,"            [-3 Dirty block threshold for activating bdflush in refill_freelist] \n");
  91.     fprintf(stderr,"            [-4 Percentage of cache to scan for free clusters] \n");
  92.     fprintf(stderr,"            [-5 Time for data buffers to age before flushing] \n");
  93.     fprintf(stderr,"            [-6 Time for non-data (dir, bitmap, etc) buffers to age before flushing] \n");
  94.     fprintf(stderr,"            [-7 Time buffer cache load average constant] \n");
  95.     fprintf(stderr,"            [-8 LAV ratio (used to determine threshold for buffer fratricide)] \n");
  96.     exit(1);
  97. }
  98.  
  99.  
  100. int
  101. main(int argc, char *argv[])
  102. {
  103.     int sync_delay = 30 , flush_delay = 5;
  104.     int i;
  105.     int go = 0;
  106.     int ch;
  107.  
  108.     /* shame on whomever wrote getopt - global variables */
  109.     extern char * optarg;
  110.     extern int optind, optopt;
  111.  
  112.     /* Start by parseing command line options */
  113.     while((ch = getopt(argc, argv, "ds:f:1:2:3:4:5:6:7:8:0:")) != EOF)
  114.         switch(ch) {
  115.         case 'd':
  116.             /* print out the current parameters */
  117.         printf("bdflush version %s\n", version_string);
  118.             for (i = 0; bdparam[i]; i++)
  119.             {
  120.                 int j;
  121.                 int data;
  122.                 int bdflag;
  123.             
  124.                 bdflag = 2 + (i << 1);
  125.             
  126.                 j = bdflush(bdflag, (int) &data);
  127.             
  128.                 printf("%d: %5d %s\n", i, data, bdparam[i]);
  129.             
  130.                 if (j)
  131.                 {
  132.                     fprintf(stderr, "bdupdate:(%d) bdflush(%08x,&d)=%d %d\n",
  133.                             i, bdflag, j, errno);
  134.                     break;
  135.                 }
  136.             }
  137.        
  138.             go = 1; 
  139.  
  140.             break;
  141.     case 's':
  142.         sync_delay = atoi(optarg);
  143.             break;
  144.     case 'f':
  145.             flush_delay = atoi(optarg);
  146.         break;
  147.     case '1': case '2': case '3': case '4':
  148.     case '5': case '6': case '7': case '8':
  149.     case '0':
  150.  
  151.                if (i = bdflush(1+((ch - '0' + 1) <<1 ), atoi(optarg)))  
  152.             {
  153.                 fprintf(stderr, "bdupdate: bdflush(%d,%d)=%d %d\n",1+((ch - '0') <<1 ), atoi(optarg), i, errno);
  154.             exit(1);
  155.             }
  156.  
  157.         break;
  158.         case ':':
  159.             fprintf(stderr, "Option -%c requires an argument!\n",
  160.                     optopt);
  161.         usage(argv);
  162.             break;
  163.         default:
  164.             usage(argv);
  165.             break;
  166.         }
  167.  
  168.     if(go) exit(0);
  169.  
  170. #ifndef DEBUG
  171.     for (i = 0; i < OPEN_MAX; i++)
  172.     {
  173.         close(i);
  174.     }
  175. #endif
  176.  
  177.     chdir("/");
  178.  
  179.     signal(SIGTERM, SIG_IGN);
  180.     signal(SIGINT, SIG_IGN);
  181.     signal(SIGCLD, SIG_IGN);
  182.  
  183.     if (!fork())                /* fork off a daemon */
  184.     {
  185.         inststr(argv, argc, "bdflush (daemon)");
  186.     setsid();  /* Release terminal */
  187.  
  188.         if (i = bdflush(0, 0))  /* should never return */
  189.         {
  190. #ifdef DEBUG                    /* this should not happen */
  191.             fprintf(stderr, "bdupdate: bdflush(0,0)=%d %d\n", i, errno);
  192. #endif
  193.         }
  194.         exit(1);
  195.     }
  196.  
  197.     if (!fork())                /* fork off a daemon */
  198.     {
  199.         int has_bdflush;
  200.  
  201.         inststr(argv, argc, "update (bdflush)");
  202.     setsid();  /* Release terminal */
  203.  
  204.         has_bdflush = 1;
  205.  
  206.         for (;;)                /* flush expired buffers */
  207.         {
  208.             if (has_bdflush)
  209.             {
  210.                 sleep(flush_delay);
  211.  
  212.                 if (i = bdflush(1, 0))
  213.                 {
  214.                     has_bdflush = 0;    /* oopsie! */
  215.  
  216.                     inststr(argv, argc, "update (sync)");
  217. #ifdef DEBUG
  218.                     fprintf(stderr, "bdupdate: bdflush(1,0)=%d %d\n", i, errno);
  219. #endif
  220.                 }
  221.             } else
  222.             {
  223.                 sleep(sync_delay);
  224.  
  225.                 sync();
  226.             }
  227.         }
  228.  
  229.         exit(1);
  230.     }
  231.     /* parent exits */
  232.     return (0);
  233. }
  234.