checkarenas.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "stdinc.h"
  2. #include "dat.h"
  3. #include "fns.h"
  4. static int verbose;
  5. static void
  6. checkarena(Arena *arena, int scan, int fix)
  7. {
  8. ATailStats old;
  9. int err, e;
  10. if(verbose && arena->memstats.clumps)
  11. printarena(2, arena);
  12. old = arena->memstats;
  13. if(scan){
  14. arena->memstats.used = 0;
  15. arena->memstats.clumps = 0;
  16. arena->memstats.cclumps = 0;
  17. arena->memstats.uncsize = 0;
  18. }
  19. err = 0;
  20. for(;;){
  21. e = syncarena(arena, 1000, 0, fix);
  22. err |= e;
  23. if(!(e & SyncHeader))
  24. break;
  25. if(verbose && arena->memstats.clumps)
  26. fprint(2, ".");
  27. }
  28. if(verbose && arena->memstats.clumps)
  29. fprint(2, "\n");
  30. err &= ~SyncHeader;
  31. if(arena->memstats.used != old.used
  32. || arena->memstats.clumps != old.clumps
  33. || arena->memstats.cclumps != old.cclumps
  34. || arena->memstats.uncsize != old.uncsize){
  35. fprint(2, "%s: incorrect arena header fields\n", arena->name);
  36. printarena(2, arena);
  37. err |= SyncHeader;
  38. }
  39. if(!err || !fix)
  40. return;
  41. fprint(2, "%s: writing fixed arena header fields\n", arena->name);
  42. arena->diskstats = arena->memstats;
  43. if(wbarena(arena) < 0)
  44. fprint(2, "arena header write failed: %r\n");
  45. flushdcache();
  46. }
  47. void
  48. usage(void)
  49. {
  50. fprint(2, "usage: checkarenas [-afv] file [arenaname...]\n");
  51. threadexitsall(0);
  52. }
  53. int
  54. should(char *name, int argc, char **argv)
  55. {
  56. int i;
  57. if(argc == 0)
  58. return 1;
  59. for(i=0; i<argc; i++)
  60. if(strcmp(name, argv[i]) == 0)
  61. return 1;
  62. return 0;
  63. }
  64. void
  65. threadmain(int argc, char *argv[])
  66. {
  67. ArenaPart *ap;
  68. Part *part;
  69. char *file;
  70. int i, fix, scan;
  71. ventifmtinstall();
  72. statsinit();
  73. fix = 0;
  74. scan = 0;
  75. ARGBEGIN{
  76. case 'f':
  77. fix++;
  78. break;
  79. case 'a':
  80. scan = 1;
  81. break;
  82. case 'v':
  83. verbose++;
  84. break;
  85. default:
  86. usage();
  87. break;
  88. }ARGEND
  89. if(!fix)
  90. readonly = 1;
  91. if(argc < 1)
  92. usage();
  93. file = argv[0];
  94. argc--;
  95. argv++;
  96. part = initpart(file, (fix ? ORDWR : OREAD)|ODIRECT);
  97. if(part == nil)
  98. sysfatal("can't open partition %s: %r", file);
  99. ap = initarenapart(part);
  100. if(ap == nil)
  101. sysfatal("can't initialize arena partition in %s: %r", file);
  102. if(verbose > 1){
  103. printarenapart(2, ap);
  104. fprint(2, "\n");
  105. }
  106. initdcache(8 * MaxDiskBlock);
  107. for(i = 0; i < ap->narenas; i++)
  108. if(should(ap->arenas[i]->name, argc, argv)) {
  109. debugarena = i;
  110. checkarena(ap->arenas[i], scan, fix);
  111. }
  112. if(verbose > 1)
  113. printstats();
  114. threadexitsall(0);
  115. }