123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- /*
- This file is part of GNUnet.
- Copyright (C) 2008--2013 GNUnet e.V.
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: AGPL3.0-or-later
- */
- #include "platform.h"
- #include "gnunet_util_lib.h"
- /*
- * File for parsing top-level /proc entities.
- * Copyright Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com
- * Copyright 1998-2003 Albert Cahalan
- * June 2003, Fabian Frederick, disk and slab info
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #define BAD_OPEN_MESSAGE \
- "Error: /proc must be mounted\n" \
- " To mount /proc at boot you need an /etc/fstab line like:\n" \
- " proc /proc proc defaults\n" \
- " In the meantime, run \"mount proc /proc -t proc\"\n"
- #define STAT_FILE "/proc/stat"
- // static int stat_fd = -1;
- #define UPTIME_FILE "/proc/uptime"
- // static int uptime_fd = -1;
- #define LOADAVG_FILE "/proc/loadavg"
- // static int loadavg_fd = -1;
- #define MEMINFO_FILE "/proc/meminfo"
- static int meminfo_fd = -1;
- #define VMINFO_FILE "/proc/vmstat"
- // static int vminfo_fd = -1;
- // As of 2.6.24 /proc/meminfo seems to need 888 on 64-bit,
- // and would need 1258 if the obsolete fields were there.
- static char buf[2048];
- /* This macro opens filename only if necessary and seeks to 0 so
- * that successive calls to the functions are more efficient.
- * It also reads the current contents of the file into the global buf.
- */
- #define FILE_TO_BUF(filename, fd) do { \
- static int local_n; \
- if (fd == -1 && (fd = open (filename, O_RDONLY)) == -1) { \
- fputs (BAD_OPEN_MESSAGE, stderr); \
- fflush (NULL); \
- _exit (102); \
- } \
- lseek (fd, 0L, SEEK_SET); \
- if ((local_n = read (fd, buf, sizeof buf - 1)) < 0) { \
- perror (filename); \
- fflush (NULL); \
- _exit (103); \
- } \
- buf[local_n] = '\0'; \
- } while (0)
- /***********************************************************************/
- /*
- * Copyright 1999 by Albert Cahalan; all rights reserved.
- * This file may be used subject to the terms and conditions of the
- * GNU Library General Public License Version 2, or any later version
- * at your option, as published by the Free Software Foundation.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- */
- typedef struct mem_table_struct
- {
- const char *name; /* memory type name */
- unsigned long *slot; /* slot in return struct */
- } mem_table_struct;
- static int compare_mem_table_structs (const void *a, const void *b)
- {
- return strcmp (((const mem_table_struct*) a)->name, ((const
- mem_table_struct*) b)->
- name);
- }
- /* example data, following junk, with comments added:
- *
- * MemTotal: 61768 kB old
- * MemFree: 1436 kB old
- * MemShared: 0 kB old (now always zero; not calculated)
- * Buffers: 1312 kB old
- * Cached: 20932 kB old
- * Active: 12464 kB new
- * Inact_dirty: 7772 kB new
- * Inact_clean: 2008 kB new
- * Inact_target: 0 kB new
- * Inact_laundry: 0 kB new, and might be missing too
- * HighTotal: 0 kB
- * HighFree: 0 kB
- * LowTotal: 61768 kB
- * LowFree: 1436 kB
- * SwapTotal: 122580 kB old
- * SwapFree: 60352 kB old
- * Inactive: 20420 kB 2.5.41+
- * Dirty: 0 kB 2.5.41+
- * Writeback: 0 kB 2.5.41+
- * Mapped: 9792 kB 2.5.41+
- * Slab: 4564 kB 2.5.41+
- * Committed_AS: 8440 kB 2.5.41+
- * PageTables: 304 kB 2.5.41+
- * ReverseMaps: 5738 2.5.41+
- * SwapCached: 0 kB 2.5.??+
- * HugePages_Total: 220 2.5.??+
- * HugePages_Free: 138 2.5.??+
- * Hugepagesize: 4096 kB 2.5.??+
- */
- /* obsolete */
- unsigned long kb_main_shared;
- /* old but still kicking -- the important stuff */
- unsigned long kb_main_buffers;
- unsigned long kb_main_cached;
- unsigned long kb_main_free;
- unsigned long kb_main_total;
- unsigned long kb_swap_free;
- unsigned long kb_swap_total;
- /* recently introduced */
- unsigned long kb_high_free;
- unsigned long kb_high_total;
- unsigned long kb_low_free;
- unsigned long kb_low_total;
- /* 2.4.xx era */
- unsigned long kb_active;
- unsigned long kb_inact_laundry;
- unsigned long kb_inact_dirty;
- unsigned long kb_inact_clean;
- unsigned long kb_inact_target;
- unsigned long kb_swap_cached; /* late 2.4 and 2.6+ only */
- /* derived values */
- unsigned long kb_swap_used;
- unsigned long kb_main_used;
- /* 2.5.41+ */
- unsigned long kb_writeback;
- unsigned long kb_slab;
- unsigned long nr_reversemaps;
- unsigned long kb_committed_as;
- unsigned long kb_dirty;
- unsigned long kb_inactive;
- unsigned long kb_mapped;
- unsigned long kb_pagetables;
- // seen on a 2.6.x kernel:
- static unsigned long kb_vmalloc_chunk;
- static unsigned long kb_vmalloc_total;
- static unsigned long kb_vmalloc_used;
- // seen on 2.6.24-rc6-git12
- static unsigned long kb_anon_pages;
- static unsigned long kb_bounce;
- static unsigned long kb_commit_limit;
- static unsigned long kb_nfs_unstable;
- static unsigned long kb_swap_reclaimable;
- static unsigned long kb_swap_unreclaimable;
- void meminfo (void)
- {
- char namebuf[16]; /* big enough to hold any row name */
- mem_table_struct findme = { namebuf, NULL };
- mem_table_struct *found;
- char *head;
- char *tail;
- static const mem_table_struct mem_table[] = {
- { "Active", &kb_active }, // important
- { "AnonPages", &kb_anon_pages },
- { "Bounce", &kb_bounce },
- { "Buffers", &kb_main_buffers }, // important
- { "Cached", &kb_main_cached }, // important
- { "CommitLimit", &kb_commit_limit },
- { "Committed_AS", &kb_committed_as },
- { "Dirty", &kb_dirty }, // kB version of vmstat nr_dirty
- { "HighFree", &kb_high_free },
- { "HighTotal", &kb_high_total },
- { "Inact_clean", &kb_inact_clean },
- { "Inact_dirty", &kb_inact_dirty },
- { "Inact_laundry", &kb_inact_laundry },
- { "Inact_target", &kb_inact_target },
- { "Inactive", &kb_inactive }, // important
- { "LowFree", &kb_low_free },
- { "LowTotal", &kb_low_total },
- { "Mapped", &kb_mapped }, // kB version of vmstat nr_mapped
- { "MemFree", &kb_main_free }, // important
- { "MemShared", &kb_main_shared }, // important, but now gone!
- { "MemTotal", &kb_main_total }, // important
- { "NFS_Unstable", &kb_nfs_unstable },
- { "PageTables", &kb_pagetables }, // kB version of vmstat nr_page_table_pages
- { "ReverseMaps", &nr_reversemaps }, // same as vmstat nr_page_table_pages
- { "SReclaimable", &kb_swap_reclaimable }, // "swap reclaimable" (dentry and inode structures)
- { "SUnreclaim", &kb_swap_unreclaimable },
- { "Slab", &kb_slab }, // kB version of vmstat nr_slab
- { "SwapCached", &kb_swap_cached },
- { "SwapFree", &kb_swap_free }, // important
- { "SwapTotal", &kb_swap_total }, // important
- { "VmallocChunk", &kb_vmalloc_chunk },
- { "VmallocTotal", &kb_vmalloc_total },
- { "VmallocUsed", &kb_vmalloc_used },
- { "Writeback", &kb_writeback }, // kB version of vmstat nr_writeback
- };
- const int mem_table_count = sizeof(mem_table) / sizeof(mem_table_struct);
- FILE_TO_BUF (MEMINFO_FILE, meminfo_fd);
- kb_inactive = ~0UL;
- head = buf;
- for (;;)
- {
- tail = strchr (head, ':');
- if (! tail)
- break;
- *tail = '\0';
- if (strlen (head) >= sizeof(namebuf))
- {
- head = tail + 1;
- goto nextline;
- }
- strcpy (namebuf, head);
- found = bsearch (&findme, mem_table, mem_table_count,
- sizeof(mem_table_struct), compare_mem_table_structs
- );
- head = tail + 1;
- if (! found)
- goto nextline;
- *(found->slot) = (unsigned long) strtoull (head, &tail, 10);
- nextline:
- tail = strchr (head, '\n');
- if (! tail)
- break;
- head = tail + 1;
- }
- if (! kb_low_total) /* low==main except with large-memory support */
- {
- kb_low_total = kb_main_total;
- kb_low_free = kb_main_free;
- }
- if (kb_inactive == ~0UL)
- {
- kb_inactive = kb_inact_dirty + kb_inact_clean + kb_inact_laundry;
- }
- kb_swap_used = kb_swap_total - kb_swap_free;
- kb_main_used = kb_main_total - kb_main_free;
- }
|