ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.1
Committed: Tue Feb 18 19:28:30 2003 UTC (21 years, 2 months ago) by pajs
Content type: text/plain
Branch: MAIN
Log Message:
The new revesion of libstatgrab, which is a complete rewrite essentially.

Firstly the data is now returned in structures rather than xml strings.
The structures returned are all static, so what ever calls the library doesn't
have to deal with the memory management of it.

Secondly the general efficency of the code is now significantly faster. It no
longer needs to fork a process, connect file descriptors and run ps, and then
parse the output like it used to. Now it walks /proc and reads it into the
correct data structures. This works without needing any special privilages, so
it can still run as a normal mortal without needing any special group. (Freebsd
will be an exception to this, but this commit only works with solaris, and that
requires nothing special)

Thridly it has more functionality than it used to. It not for instance is capable
of showing network traffic stats, (although its not completely finished yet). It
also in the near future be able to disk io stats as well. Several bug fixes have
been aplied over the original version. For example the cpu_stats used to only reply
the stats for the first processor. This now will report the total stats of all of
them. Paging stats will also be fixed, but haven't been done yet.

File Contents

# User Rev Content
1 pajs 1.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     #ifdef HAVE_CONFIG_H
22     #include "config.h"
23     #endif
24    
25     #include "statgrab.h"
26     #include <stdlib.h>
27     #include <stdio.h>
28     #include "ukcprog.h"
29     #include <string.h>
30    
31     #ifdef SOLARIS
32     #include <sys/mnttab.h>
33     #include <sys/types.h>
34     #include <sys/statvfs.h>
35    
36     #define VALID_FS_TYPES {"ufs", "tmpfs"}
37    
38     #endif
39    
40     #define START_VAL 1
41    
42     char *copy_string(char *orig_ptr, const char *newtext){
43    
44     /* Maybe free if not NULL, and strdup rather than realloc and strcpy? */
45     orig_ptr=realloc(orig_ptr, (1+strlen(newtext)));
46     if(orig_ptr==NULL){
47     return NULL;
48     }
49     strcpy(orig_ptr, newtext);
50    
51     return orig_ptr;
52     }
53    
54    
55     void init_disk_stat(int start, int end, disk_stat_t *disk_stats){
56    
57     for(disk_stats+=start; start<=end; start++){
58     disk_stats->device_name=NULL;
59     disk_stats->fs_type=NULL;
60     disk_stats->mnt_point=NULL;
61    
62     disk_stats++;
63     }
64    
65     }
66    
67     disk_stat_t *get_disk_stats(int *entries){
68    
69     static disk_stat_t *disk_stats;
70     static int watermark=-1;
71    
72     char *fs_types[] = VALID_FS_TYPES;
73     int x, valid_type;
74    
75     int num_disks=0;
76     struct mnttab mp;
77     struct statvfs fs;
78     FILE *f;
79    
80     disk_stat_t *disk_ptr;
81    
82     if(watermark==-1){
83     disk_stats=malloc(START_VAL * sizeof(disk_stat_t));
84     if(disk_stats==NULL){
85     return NULL;
86     }
87     watermark=START_VAL;
88     init_disk_stat(0, watermark-1, disk_stats);
89     }
90    
91    
92     if ((f=fopen("/etc/mnttab", "r" ))==NULL){
93     return NULL;
94     }
95     while((getmntent(f, &mp)) == 0){
96     if ((statvfs(mp.mnt_mountp, &fs)) !=0){
97     continue;
98     }
99    
100     valid_type=0;
101     for(x=0;x<((sizeof(fs_types))/(sizeof(char*)));x++){
102     if(strcmp(mp.mnt_fstype, fs_types[x]) ==0){
103     valid_type=1;
104     break;
105     }
106     }
107    
108     if(valid_type){
109     if(num_disks>watermark-1){
110     disk_ptr=disk_stats;
111     if((disk_stats=realloc(disk_stats, (watermark*2 * sizeof(disk_stat_t))))==NULL){
112     disk_stats=disk_ptr;
113     return NULL;
114     }
115    
116     watermark=watermark*2;
117     init_disk_stat(num_disks, watermark-1, disk_stats);
118     }
119    
120     disk_ptr=disk_stats+num_disks;
121    
122     /* Memory leak in event of realloc failing */
123     /* Maybe make this char[bigenough] and do strncpy's and put a null in the end?
124     Downside is its a bit hungry for a lot of mounts, as MNT_MAX_SIZE woul prob be upwards
125     of a k each */
126     if((disk_ptr->device_name=copy_string(disk_ptr->device_name, mp.mnt_special))==NULL){
127     return NULL;
128     }
129    
130     if((disk_ptr->fs_type=copy_string(disk_ptr->fs_type, mp.mnt_fstype))==NULL){
131     return NULL;
132     }
133    
134     if((disk_ptr->mnt_point=copy_string(disk_ptr->mnt_point, mp.mnt_mountp))==NULL){
135     return NULL;
136     }
137    
138     disk_ptr->size = (long long)fs.f_frsize * (long long)fs.f_blocks;
139     disk_ptr->avail = (long long)fs.f_frsize * (long long)fs.f_bavail;
140     disk_ptr->used = (disk_ptr->size) - ((long long)fs.f_frsize * (long long)fs.f_bfree);
141    
142     disk_ptr->total_inodes=(long long)fs.f_files;
143     disk_ptr->used_inodes=disk_ptr->total_inodes - (long long)fs.f_ffree;
144     disk_ptr->free_inodes=(long long)fs.f_favail;
145    
146     num_disks++;
147     }
148     }
149    
150     *entries=num_disks;
151    
152     /* If this fails, there is very little i can do about it, so i'll ignore it :) */
153     fclose(f);
154    
155     return disk_stats;
156    
157     }