ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/ihost/libstatgrab/memory_stats.c
Revision: 1.9
Committed: Tue May 28 14:40:41 2002 UTC (22 years, 6 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.8: +4 -4 lines
Log Message:
A few bug fixes. Firstly on linux the cache value being sent was actually
the same as the free value ;) Secondly, on linux used was not including the
cache value. To clarify, total=used+free. cache is merely and indication of
how much of the used is being used for cache. The final bug fix was in the
XML generation. The values were all "long long", but were being treated as
"long" in the strf. Unfortunately strf doesn't seem to know about "long
long" values, so we just cast them to long's ;) It's hacky, but works for
now.

File Contents

# User Rev Content
1 tdb 1.5 /*
2     * i-scream central monitoring system
3 tdb 1.8 * http://www.i-scream.org.uk
4 tdb 1.5 * Copyright (C) 2000-2002 i-scream
5     *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     */
20    
21 pajs 1.1 #include <stdio.h>
22 pajs 1.2 #ifdef LINUX
23 pajs 1.1 #include <string.h>
24 pajs 1.2 #endif
25     #ifdef SOLARIS
26     #include <unistd.h>
27     #include <kstat.h>
28     #endif
29     #ifdef FREEBSD
30     #include <sys/types.h>
31     #include <sys/sysctl.h>
32     #include <unistd.h>
33     #endif
34 tdb 1.3 #include "ukcprog.h"
35 pajs 1.1
36     char *get_memory_stats(){
37 pajs 1.6 long long total=0;
38     long long free=0;
39     long long used=0;
40     long long cache=0;
41 pajs 1.1 char *xml_memory_stats;
42     #ifdef LINUX
43     FILE *f;
44     char *line;
45 pajs 1.7 long long buffers;
46 pajs 1.1 #endif
47 pajs 1.2 #ifdef SOLARIS
48     kstat_ctl_t *kc;
49     kstat_t *ksp;
50     kstat_named_t *kn;
51     u_long totalmem;
52     int pagesize;
53     #endif
54     #ifdef FREEBSD
55     #define TOTAL_MEM_NAME "hw.physmem"
56     #define FREE_MEM_NAME "vm.stats.vm.v_free_count"
57     #define INACTIVE_MEM_NAME "vm.stats.vm.v_inactive_count"
58     #define CACHE_MEM_NAME "vm.stats.vm.v_cache_count"
59     int pagesize;
60     long inactive;
61     size_t size;
62     #endif
63 pajs 1.1
64     #ifdef LINUX
65     if ((f=fopen("/proc/meminfo", "r" ))==NULL) {
66     errf("Failed to open memory stats (%m)");
67     return NULL;
68     }
69     while((line=fpgetline(f)) != NULL){
70     if (((strncmp(line,"Mem:",4)) == 0)) {
71 pajs 1.7 if((sscanf(line, "%*s %lld %lld %lld %*s %lld %lld", &total, &used, &free, &buffers, &cache)) != 5){
72 pajs 1.1 errf("Failed to read memory details (%m)");
73     return NULL;
74     }
75     break;
76     }
77     }
78     if ((fclose(f)) != 0) {
79     errf("Failed to close file (%m)");
80     return NULL;
81     }
82    
83     cache=cache+buffers;
84 tdb 1.9 used=total-free;
85 pajs 1.1
86     total=(total/1024)/1024;
87     used=(used/1024)/1024;
88     free=(free/1024)/1024;
89 tdb 1.9 cache=(cache/1024)/1024;
90 pajs 1.1 #endif
91 pajs 1.2 #ifdef SOLARIS
92     if((pagesize=sysconf(_SC_PAGESIZE)) == -1){
93     errf("Failed to get pagesize (%m)");
94     return NULL;
95     }
96    
97     if((totalmem=sysconf(_SC_PHYS_PAGES)) == -1){
98     errf("Failed to get total memory");
99     return NULL;
100     }
101    
102     if ((kc = kstat_open()) == NULL) {
103     errf("kstat_open failure (%m)");
104     return NULL;
105     }
106     if((ksp=kstat_lookup(kc, "unix", 0, "system_pages")) == NULL){
107     errf("kstat lookup for \"system_pages\" (%m)");
108     return NULL;
109     }
110     if (kstat_read(kc, ksp, 0) == -1) {
111     errf("Failed to read kstat details (%m)");
112     return NULL;
113     }
114     if((kn=kstat_data_lookup(ksp, "freemem")) == NULL){
115     errf("Failed to get free memory (%m)");
116     return NULL;
117     }
118 pajs 1.4 if((kstat_close(kc)) != 0){
119     errf("Failed to close kstat control structure (%m)");
120     return NULL;
121     }
122 pajs 1.2 total=((totalmem*pagesize)/1024)/1024;
123     free=(((kn->value.ul)*pagesize)/1024)/1024;
124     used=total-free;
125     #endif
126     #ifdef FREEBSD
127     if ((pagesize=getpagesize()) == -1){
128     errf("Failed to get page size (%m)");
129     return NULL;
130     }
131    
132     if (sysctlbyname(TOTAL_MEM_NAME, NULL, &size, NULL, NULL) < 0){
133     errf("sysctlbyname failed to get total memory (%m)");
134     return NULL;
135     }
136     if (sysctlbyname(TOTAL_MEM_NAME, &total, &size, NULL, NULL) < 0){
137     errf("Failed to get total memory stats (%m)");
138     return NULL;
139     }
140    
141     if (sysctlbyname(FREE_MEM_NAME, NULL, &size, NULL, NULL) < 0){
142     errf("sysctlbyname failed to get free memory (%m)");
143     return NULL;
144     }
145     if (sysctlbyname(FREE_MEM_NAME, &free, &size, NULL, NULL) < 0){
146     errf("Failed to get free memory stats (%m)");
147     return NULL;
148     }
149    
150     if (sysctlbyname(INACTIVE_MEM_NAME, NULL, &size, NULL, NULL) < 0){
151     errf("sysctlbyname failed to get inactive memory (%m)");
152     return NULL;
153     }
154     if (sysctlbyname(INACTIVE_MEM_NAME, &inactive, &size, NULL, NULL) < 0){
155     errf("Failed to get inactive memory stats (%m)");
156     return NULL;
157     }
158    
159     if (sysctlbyname(CACHE_MEM_NAME, NULL, &size, NULL, NULL) < 0){
160     errf("sysctlbyname failed to get cache memory (%m)");
161     return NULL;
162     }
163     if (sysctlbyname(CACHE_MEM_NAME, &cache, &size, NULL, NULL) < 0){
164     errf("Failed to get cache memory stats (%m)");
165     return NULL;
166     }
167    
168     total/=(1024*1024);
169     free=((free*pagesize)/(1024*1024))+((inactive*pagesize)/(1024*1024));
170     cache=((cache*pagesize)/(1024*1024));
171    
172     /* used should also be cache+active+wired but its less effort this way :) */
173     used=total-free;
174    
175     #endif
176    
177 tdb 1.9 /* casting these from a long long to a long is a KLUDGE! please fix it :) */
178     if((xml_memory_stats=strf("<memory><total>%ld</total><free>%ld</free><used>%ld</used><cache>%ld</cache></memory>", (long)total, (long)free, (long)used, (long)cache)) == NULL){
179 pajs 1.1 errf("strf failed (%m)");
180     return NULL;
181     }
182 pajs 1.2 return xml_memory_stats;
183 pajs 1.1 }