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 (23 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

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org.uk
4 * 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 #include <stdio.h>
22 #ifdef LINUX
23 #include <string.h>
24 #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 #include "ukcprog.h"
35
36 char *get_memory_stats(){
37 long long total=0;
38 long long free=0;
39 long long used=0;
40 long long cache=0;
41 char *xml_memory_stats;
42 #ifdef LINUX
43 FILE *f;
44 char *line;
45 long long buffers;
46 #endif
47 #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
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 if((sscanf(line, "%*s %lld %lld %lld %*s %lld %lld", &total, &used, &free, &buffers, &cache)) != 5){
72 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 used=total-free;
85
86 total=(total/1024)/1024;
87 used=(used/1024)/1024;
88 free=(free/1024)/1024;
89 cache=(cache/1024)/1024;
90 #endif
91 #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 if((kstat_close(kc)) != 0){
119 errf("Failed to close kstat control structure (%m)");
120 return NULL;
121 }
122 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 /* 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 errf("strf failed (%m)");
180 return NULL;
181 }
182 return xml_memory_stats;
183 }