gnunet-service-testbed_meminfo.c 9.3 KB

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