s4:torture/vfs/fruit: enable AAPL extensions in a bunch of tests
[samba.git] / examples / perfcounter / perf_writer_disk.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Performance Counter Daemon
4  *
5  *  Copyright (C) Marcin Krzysztof Porwit    2005
6  *  
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License, or
10  *  (at your option) any later version.
11  *  
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *  
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "perf.h"
22
23 void init_diskdata_desc(PERF_DATA_BLOCK *data)
24 {
25         init_perf_counter(&(data->diskInfo.diskObjDesc),
26                           &(data->diskInfo.diskObjDesc),
27                           get_counter_id(data),
28                           "Logical Disk",
29                           "The Logical Disk object consists of counters that show information about disks.",
30                           0,
31                           PERF_OBJECT);
32         init_perf_counter(&(data->diskInfo.freeMegs),
33                           &(data->diskInfo.diskObjDesc),
34                           get_counter_id(data),
35                           "Megabytes Free",
36                           "The amount of available disk space, in megabytes.",
37                           PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX,
38                           PERF_COUNTER);
39         init_perf_counter(&(data->diskInfo.writesPerSec),
40                           &(data->diskInfo.diskObjDesc),
41                           get_counter_id(data),
42                           "Writes/sec",
43                           "The number of writes per second to that disk.",
44                           PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC,
45                           PERF_COUNTER);
46         init_perf_counter(&(data->diskInfo.readsPerSec),
47                           &(data->diskInfo.diskObjDesc),
48                           get_counter_id(data),
49                           "Reads/sec",
50                           "The number of reads of that disk per second.",
51                           PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC,
52                           PERF_COUNTER);
53
54         return;
55 }
56 void init_num_disks(PERF_DATA_BLOCK *data)
57 {
58         FILE *mtab;
59         char buf[PROC_BUF];
60         char *start, *stop;
61         int i = 0, num;
62
63         if(!(mtab = fopen("/etc/mtab", "r")))
64         {
65                 perror("init_disk_names: fopen");
66                 exit(1);
67         }
68
69         rewind(mtab);
70         fflush(mtab);
71
72         while(fgets(buf, sizeof(buf), mtab))
73         {
74                 if(start = strstr(buf, "/dev/"))
75                 {
76                         if(start = strstr(start, "da"))
77                         {
78                                 i++;
79                         }
80                 }
81         }
82
83         data->diskInfo.numDisks = i;
84         fclose(mtab);
85
86         return;
87 }
88         
89 void init_disk_names(PERF_DATA_BLOCK *data)
90 {
91         FILE *mtab;
92         char buf[PROC_BUF];
93         char *start, *stop;
94         int i = 0, num;
95
96         if(!(mtab = fopen("/etc/mtab", "r")))
97         {
98                 perror("init_disk_names: fopen");
99                 exit(1);
100         }
101
102         rewind(mtab);
103         fflush(mtab);
104
105         while(fgets(buf, sizeof(buf), mtab))
106         {
107                 if(start = strstr(buf, "/dev/"))
108                 {
109                         if(start = strstr(start, "da"))
110                         {
111                                 start -=1;
112                                 stop = strstr(start, " ");
113                                 memcpy(data->diskInfo.mdata[i].name, start, stop - start);
114                                 start = stop +1;
115                                 stop = strstr(start, " ");
116                                 memcpy(data->diskInfo.mdata[i].mountpoint, start, stop - start);
117                                 i++;
118                         }
119                 }
120         }
121
122         fclose(mtab);
123
124         return;
125 }
126
127 void get_diskinfo(PERF_DATA_BLOCK *data)
128 {
129         int i;
130         DiskData *p;
131         struct statfs statfsbuf;
132         int status, num;
133         char buf[LARGE_BUF], *start;
134         FILE *diskstats;
135         unsigned long reads, writes, discard;
136
137         diskstats = fopen("/proc/diskstats", "r");
138         rewind(diskstats);
139         fflush(diskstats);
140         status = fread(buf, sizeof(char), LARGE_BUF, diskstats);
141         fclose(diskstats);
142
143         for(i = 0; i < data->diskInfo.numDisks; i++)
144         {
145                 p = &(data->diskInfo.data[i]);
146                 status = statfs(data->diskInfo.mdata[i].mountpoint, &statfsbuf);
147                 p->freeMegs = (statfsbuf.f_bfree*statfsbuf.f_bsize)/1048576;
148                 start = strstr(buf, data->diskInfo.mdata[i].name);
149                 start += strlen(data->diskInfo.mdata[i].name) + 1;
150                 num = sscanf(start, "%lu %lu %lu %lu",
151                              &reads,
152                              &discard,
153                              &writes,
154                              &discard);
155                 p->writesPerSec = writes;
156                 p->readsPerSec = reads;
157                 fprintf(stderr, "%s:\t%u\t%u\n",
158                         data->diskInfo.mdata[i].mountpoint,
159                         reads, writes);
160         }
161         return;
162 }
163 void init_disk_data(PERF_DATA_BLOCK *data)
164 {
165         init_diskdata_desc(data);
166         
167         init_num_disks(data);
168
169         data->diskInfo.mdata = calloc(data->diskInfo.numDisks, sizeof(DiskMetaData));
170         if(!data->diskInfo.mdata)
171         {
172                 fatal("init_disk_data: out of memory");
173         }
174
175         init_disk_names(data);
176
177         data->diskInfo.data = calloc(data->diskInfo.numDisks, sizeof(DiskData));
178         if(!data->diskInfo.data)
179         {
180                 fatal("init_disk_data: out of memory");
181         }
182
183         get_diskinfo(data);
184
185         return;
186 }
187
188 void output_disk_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt)
189 {
190         output_perf_desc(data->diskInfo.diskObjDesc, rt);
191         output_perf_desc(data->diskInfo.freeMegs, rt);
192         output_perf_desc(data->diskInfo.writesPerSec, rt);
193         output_perf_desc(data->diskInfo.readsPerSec, rt);
194         output_num_instances(data->diskInfo.diskObjDesc, data->diskInfo.numDisks, rt);
195
196         return;
197 }
198
199 void output_diskinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
200 {
201         int i;
202         
203         output_perf_counter(data->diskInfo.freeMegs,
204                             data->diskInfo.data[0].freeMegs,
205                             rt, tdb_flags);
206         output_perf_counter(data->diskInfo.writesPerSec,
207                             (unsigned long long)data->diskInfo.data[0].writesPerSec,
208                             rt, tdb_flags);
209         output_perf_counter(data->diskInfo.readsPerSec,
210                             (unsigned long long)data->diskInfo.data[0].readsPerSec,
211                             rt, tdb_flags);
212
213         for(i = 0; i < data->diskInfo.numDisks; i++)
214         {
215                 output_perf_instance(data->diskInfo.diskObjDesc.index,
216                                      i,
217                                      (void *)&(data->diskInfo.data[i]),
218                                      sizeof(DiskData),
219                                      data->diskInfo.mdata[i].mountpoint,
220                                      rt, tdb_flags);
221         }
222
223         return;
224 }