gnunet-service-testbed_meminfo.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2008--2013 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. #include "platform.h"
  18. #include "gnunet_util_lib.h"
  19. /*
  20. * File for parsing top-level /proc entities.
  21. * Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com
  22. * Copyright 1998-2003 Albert Cahalan
  23. * June 2003, Fabian Frederick, disk and slab info
  24. *
  25. * This library is free software; you can redistribute it and/or
  26. * modify it under the terms of the GNU Lesser General Public
  27. * License as published by the Free Software Foundation; either
  28. * version 2.1 of the License, or (at your option) any later version.
  29. *
  30. * This library is distributed in the hope that it will be useful,
  31. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  32. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  33. * Lesser General Public License for more details.
  34. *
  35. * You should have received a copy of the GNU Lesser General Public
  36. * License along with this library; if not, write to the Free Software
  37. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  38. */
  39. #define BAD_OPEN_MESSAGE \
  40. "Error: /proc must be mounted\n" \
  41. " To mount /proc at boot you need an /etc/fstab line like:\n" \
  42. " proc /proc proc defaults\n" \
  43. " In the meantime, run \"mount proc /proc -t proc\"\n"
  44. #define STAT_FILE "/proc/stat"
  45. //static int stat_fd = -1;
  46. #define UPTIME_FILE "/proc/uptime"
  47. //static int uptime_fd = -1;
  48. #define LOADAVG_FILE "/proc/loadavg"
  49. //static int loadavg_fd = -1;
  50. #define MEMINFO_FILE "/proc/meminfo"
  51. static int meminfo_fd = -1;
  52. #define VMINFO_FILE "/proc/vmstat"
  53. //static int vminfo_fd = -1;
  54. // As of 2.6.24 /proc/meminfo seems to need 888 on 64-bit,
  55. // and would need 1258 if the obsolete fields were there.
  56. static char buf[2048];
  57. /* This macro opens filename only if necessary and seeks to 0 so
  58. * that successive calls to the functions are more efficient.
  59. * It also reads the current contents of the file into the global buf.
  60. */
  61. #define FILE_TO_BUF(filename, fd) do{ \
  62. static int local_n; \
  63. if (fd == -1 && (fd = open(filename, O_RDONLY)) == -1) { \
  64. fputs(BAD_OPEN_MESSAGE, stderr); \
  65. fflush(NULL); \
  66. _exit(102); \
  67. } \
  68. lseek(fd, 0L, SEEK_SET); \
  69. if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) { \
  70. perror(filename); \
  71. fflush(NULL); \
  72. _exit(103); \
  73. } \
  74. buf[local_n] = '\0'; \
  75. }while(0)
  76. /***********************************************************************/
  77. /*
  78. * Copyright 1999 by Albert Cahalan; all rights reserved.
  79. * This file may be used subject to the terms and conditions of the
  80. * GNU Library General Public License Version 2, or any later version
  81. * at your option, as published by the Free Software Foundation.
  82. * This program is distributed in the hope that it will be useful,
  83. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  84. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  85. * GNU Library General Public License for more details.
  86. */
  87. typedef struct mem_table_struct {
  88. const char *name; /* memory type name */
  89. unsigned long *slot; /* slot in return struct */
  90. } mem_table_struct;
  91. static int compare_mem_table_structs(const void *a, const void *b){
  92. return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name);
  93. }
  94. /* example data, following junk, with comments added:
  95. *
  96. * MemTotal: 61768 kB old
  97. * MemFree: 1436 kB old
  98. * MemShared: 0 kB old (now always zero; not calculated)
  99. * Buffers: 1312 kB old
  100. * Cached: 20932 kB old
  101. * Active: 12464 kB new
  102. * Inact_dirty: 7772 kB new
  103. * Inact_clean: 2008 kB new
  104. * Inact_target: 0 kB new
  105. * Inact_laundry: 0 kB new, and might be missing too
  106. * HighTotal: 0 kB
  107. * HighFree: 0 kB
  108. * LowTotal: 61768 kB
  109. * LowFree: 1436 kB
  110. * SwapTotal: 122580 kB old
  111. * SwapFree: 60352 kB old
  112. * Inactive: 20420 kB 2.5.41+
  113. * Dirty: 0 kB 2.5.41+
  114. * Writeback: 0 kB 2.5.41+
  115. * Mapped: 9792 kB 2.5.41+
  116. * Slab: 4564 kB 2.5.41+
  117. * Committed_AS: 8440 kB 2.5.41+
  118. * PageTables: 304 kB 2.5.41+
  119. * ReverseMaps: 5738 2.5.41+
  120. * SwapCached: 0 kB 2.5.??+
  121. * HugePages_Total: 220 2.5.??+
  122. * HugePages_Free: 138 2.5.??+
  123. * Hugepagesize: 4096 kB 2.5.??+
  124. */
  125. /* obsolete */
  126. unsigned long kb_main_shared;
  127. /* old but still kicking -- the important stuff */
  128. unsigned long kb_main_buffers;
  129. unsigned long kb_main_cached;
  130. unsigned long kb_main_free;
  131. unsigned long kb_main_total;
  132. unsigned long kb_swap_free;
  133. unsigned long kb_swap_total;
  134. /* recently introduced */
  135. unsigned long kb_high_free;
  136. unsigned long kb_high_total;
  137. unsigned long kb_low_free;
  138. unsigned long kb_low_total;
  139. /* 2.4.xx era */
  140. unsigned long kb_active;
  141. unsigned long kb_inact_laundry;
  142. unsigned long kb_inact_dirty;
  143. unsigned long kb_inact_clean;
  144. unsigned long kb_inact_target;
  145. unsigned long kb_swap_cached; /* late 2.4 and 2.6+ only */
  146. /* derived values */
  147. unsigned long kb_swap_used;
  148. unsigned long kb_main_used;
  149. /* 2.5.41+ */
  150. unsigned long kb_writeback;
  151. unsigned long kb_slab;
  152. unsigned long nr_reversemaps;
  153. unsigned long kb_committed_as;
  154. unsigned long kb_dirty;
  155. unsigned long kb_inactive;
  156. unsigned long kb_mapped;
  157. unsigned long kb_pagetables;
  158. // seen on a 2.6.x kernel:
  159. static unsigned long kb_vmalloc_chunk;
  160. static unsigned long kb_vmalloc_total;
  161. static unsigned long kb_vmalloc_used;
  162. // seen on 2.6.24-rc6-git12
  163. static unsigned long kb_anon_pages;
  164. static unsigned long kb_bounce;
  165. static unsigned long kb_commit_limit;
  166. static unsigned long kb_nfs_unstable;
  167. static unsigned long kb_swap_reclaimable;
  168. static unsigned long kb_swap_unreclaimable;
  169. void meminfo(void){
  170. char namebuf[16]; /* big enough to hold any row name */
  171. mem_table_struct findme = { namebuf, NULL};
  172. mem_table_struct *found;
  173. char *head;
  174. char *tail;
  175. static const mem_table_struct mem_table[] = {
  176. {"Active", &kb_active}, // important
  177. {"AnonPages", &kb_anon_pages},
  178. {"Bounce", &kb_bounce},
  179. {"Buffers", &kb_main_buffers}, // important
  180. {"Cached", &kb_main_cached}, // important
  181. {"CommitLimit", &kb_commit_limit},
  182. {"Committed_AS", &kb_committed_as},
  183. {"Dirty", &kb_dirty}, // kB version of vmstat nr_dirty
  184. {"HighFree", &kb_high_free},
  185. {"HighTotal", &kb_high_total},
  186. {"Inact_clean", &kb_inact_clean},
  187. {"Inact_dirty", &kb_inact_dirty},
  188. {"Inact_laundry",&kb_inact_laundry},
  189. {"Inact_target", &kb_inact_target},
  190. {"Inactive", &kb_inactive}, // important
  191. {"LowFree", &kb_low_free},
  192. {"LowTotal", &kb_low_total},
  193. {"Mapped", &kb_mapped}, // kB version of vmstat nr_mapped
  194. {"MemFree", &kb_main_free}, // important
  195. {"MemShared", &kb_main_shared}, // important, but now gone!
  196. {"MemTotal", &kb_main_total}, // important
  197. {"NFS_Unstable", &kb_nfs_unstable},
  198. {"PageTables", &kb_pagetables}, // kB version of vmstat nr_page_table_pages
  199. {"ReverseMaps", &nr_reversemaps}, // same as vmstat nr_page_table_pages
  200. {"SReclaimable", &kb_swap_reclaimable}, // "swap reclaimable" (dentry and inode structures)
  201. {"SUnreclaim", &kb_swap_unreclaimable},
  202. {"Slab", &kb_slab}, // kB version of vmstat nr_slab
  203. {"SwapCached", &kb_swap_cached},
  204. {"SwapFree", &kb_swap_free}, // important
  205. {"SwapTotal", &kb_swap_total}, // important
  206. {"VmallocChunk", &kb_vmalloc_chunk},
  207. {"VmallocTotal", &kb_vmalloc_total},
  208. {"VmallocUsed", &kb_vmalloc_used},
  209. {"Writeback", &kb_writeback}, // kB version of vmstat nr_writeback
  210. };
  211. const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct);
  212. FILE_TO_BUF(MEMINFO_FILE,meminfo_fd);
  213. kb_inactive = ~0UL;
  214. head = buf;
  215. for(;;){
  216. tail = strchr(head, ':');
  217. if(!tail) break;
  218. *tail = '\0';
  219. if(strlen(head) >= sizeof(namebuf)){
  220. head = tail+1;
  221. goto nextline;
  222. }
  223. strcpy(namebuf,head);
  224. found = bsearch(&findme, mem_table, mem_table_count,
  225. sizeof(mem_table_struct), compare_mem_table_structs
  226. );
  227. head = tail+1;
  228. if(!found) goto nextline;
  229. *(found->slot) = (unsigned long)strtoull(head,&tail,10);
  230. nextline:
  231. tail = strchr(head, '\n');
  232. if(!tail) break;
  233. head = tail+1;
  234. }
  235. if(!kb_low_total){ /* low==main except with large-memory support */
  236. kb_low_total = kb_main_total;
  237. kb_low_free = kb_main_free;
  238. }
  239. if(kb_inactive==~0UL){
  240. kb_inactive = kb_inact_dirty + kb_inact_clean + kb_inact_laundry;
  241. }
  242. kb_swap_used = kb_swap_total - kb_swap_free;
  243. kb_main_used = kb_main_total - kb_main_free;
  244. }