123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /*
- This file is part of GNUnet.
- (C) 2008--2013 Christian Grothoff (and other contributing authors)
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, 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
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
- */
- #include "platform.h"
- #include "gnunet_util_lib.h"
- /*
- * File for parsing top-level /proc entities.
- * 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;
- }
|