meminfo-writer.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <fcntl.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <xs.h>
  6. #include <syslog.h>
  7. #include <string.h>
  8. unsigned long prev_used_mem;
  9. int used_mem_change_threshold;
  10. int delay;
  11. char *parse(char *buf)
  12. {
  13. char *ptr = buf;
  14. char name[256];
  15. static char outbuf[4096];
  16. int val;
  17. int len;
  18. int MemTotal = 0, MemFree = 0, Buffers = 0, Cached = 0, SwapTotal =
  19. 0, SwapFree = 0;
  20. unsigned long long key;
  21. long used_mem, used_mem_diff;
  22. int nitems = 0;
  23. while (nitems != 6) {
  24. sscanf(ptr, "%s %d kB\n%n", name, &val, &len);
  25. key = *(unsigned long long *) ptr;
  26. if (key == *(unsigned long long *) "MemTotal:") {
  27. MemTotal = val;
  28. nitems++;
  29. } else if (key == *(unsigned long long *) "MemFree:") {
  30. MemFree = val;
  31. nitems++;
  32. } else if (key == *(unsigned long long *) "Buffers:") {
  33. Buffers = val;
  34. nitems++;
  35. } else if (key == *(unsigned long long *) "Cached: ") {
  36. Cached = val;
  37. nitems++;
  38. } else if (key == *(unsigned long long *) "SwapTotal:") {
  39. SwapTotal = val;
  40. nitems++;
  41. } else if (key == *(unsigned long long *) "SwapFree:") {
  42. SwapFree = val;
  43. nitems++;
  44. }
  45. ptr += len;
  46. }
  47. used_mem =
  48. MemTotal - Buffers - Cached - MemFree + SwapTotal - SwapFree;
  49. if (used_mem < 0)
  50. return NULL;
  51. used_mem_diff = used_mem - prev_used_mem;
  52. if (used_mem_diff < 0)
  53. used_mem_diff = -used_mem_diff;
  54. if (used_mem_diff > used_mem_change_threshold
  55. || (used_mem > prev_used_mem && used_mem * 13 / 10 > MemTotal
  56. && used_mem_diff > used_mem_change_threshold/2)) {
  57. prev_used_mem = used_mem;
  58. sprintf(outbuf,
  59. "MemTotal: %d kB\nMemFree: %d kB\nBuffers: %d kB\nCached: %d kB\n"
  60. "SwapTotal: %d kB\nSwapFree: %d kB\n", MemTotal,
  61. MemFree, Buffers, Cached, SwapTotal, SwapFree);
  62. return outbuf;
  63. }
  64. return NULL;
  65. }
  66. void usage()
  67. {
  68. fprintf(stderr,
  69. "usage: meminfo_writer threshold_in_kb delay_in_us\n");
  70. exit(1);
  71. }
  72. void send_to_qmemman(struct xs_handle *xs, char *data)
  73. {
  74. if (!xs_write(xs, XBT_NULL, "memory/meminfo", data, strlen(data))) {
  75. syslog(LOG_DAEMON | LOG_ERR, "error writing xenstore ?");
  76. exit(1);
  77. }
  78. }
  79. int main(int argc, char **argv)
  80. {
  81. char buf[4096];
  82. int n;
  83. char *meminfo_data;
  84. int fd;
  85. struct xs_handle *xs;
  86. if (argc != 3)
  87. usage();
  88. used_mem_change_threshold = atoi(argv[1]);
  89. delay = atoi(argv[2]);
  90. if (!used_mem_change_threshold || !delay)
  91. usage();
  92. fd = open("/proc/meminfo", O_RDONLY);
  93. if (fd < 0) {
  94. perror("open meminfo");
  95. exit(1);
  96. }
  97. xs = xs_domain_open();
  98. if (!xs) {
  99. perror("xs_domain_open");
  100. exit(1);
  101. }
  102. for (;;) {
  103. n = pread(fd, buf, sizeof(buf), 0);
  104. buf[n] = 0;
  105. meminfo_data = parse(buf);
  106. if (meminfo_data)
  107. send_to_qmemman(xs, meminfo_data);
  108. usleep(delay);
  109. }
  110. }