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