summaryrefslogtreecommitdiffstats
path: root/examples/perfcounter/perf_writer_disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/perfcounter/perf_writer_disk.c')
-rw-r--r--examples/perfcounter/perf_writer_disk.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/examples/perfcounter/perf_writer_disk.c b/examples/perfcounter/perf_writer_disk.c
new file mode 100644
index 0000000..18a63a4
--- /dev/null
+++ b/examples/perfcounter/perf_writer_disk.c
@@ -0,0 +1,224 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Performance Counter Daemon
+ *
+ * Copyright (C) Marcin Krzysztof Porwit 2005
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "perf.h"
+
+void init_diskdata_desc(PERF_DATA_BLOCK *data)
+{
+ init_perf_counter(&(data->diskInfo.diskObjDesc),
+ &(data->diskInfo.diskObjDesc),
+ get_counter_id(data),
+ "Logical Disk",
+ "The Logical Disk object consists of counters that show information about disks.",
+ 0,
+ PERF_OBJECT);
+ init_perf_counter(&(data->diskInfo.freeMegs),
+ &(data->diskInfo.diskObjDesc),
+ get_counter_id(data),
+ "Megabytes Free",
+ "The amount of available disk space, in megabytes.",
+ PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX,
+ PERF_COUNTER);
+ init_perf_counter(&(data->diskInfo.writesPerSec),
+ &(data->diskInfo.diskObjDesc),
+ get_counter_id(data),
+ "Writes/sec",
+ "The number of writes per second to that disk.",
+ PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC,
+ PERF_COUNTER);
+ init_perf_counter(&(data->diskInfo.readsPerSec),
+ &(data->diskInfo.diskObjDesc),
+ get_counter_id(data),
+ "Reads/sec",
+ "The number of reads of that disk per second.",
+ PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC,
+ PERF_COUNTER);
+
+ return;
+}
+void init_num_disks(PERF_DATA_BLOCK *data)
+{
+ FILE *mtab;
+ char buf[PROC_BUF];
+ char *start, *stop;
+ int i = 0, num;
+
+ if(!(mtab = fopen("/etc/mtab", "r")))
+ {
+ perror("init_disk_names: fopen");
+ exit(1);
+ }
+
+ rewind(mtab);
+ fflush(mtab);
+
+ while(fgets(buf, sizeof(buf), mtab))
+ {
+ if(start = strstr(buf, "/dev/"))
+ {
+ if(start = strstr(start, "da"))
+ {
+ i++;
+ }
+ }
+ }
+
+ data->diskInfo.numDisks = i;
+ fclose(mtab);
+
+ return;
+}
+
+void init_disk_names(PERF_DATA_BLOCK *data)
+{
+ FILE *mtab;
+ char buf[PROC_BUF];
+ char *start, *stop;
+ int i = 0, num;
+
+ if(!(mtab = fopen("/etc/mtab", "r")))
+ {
+ perror("init_disk_names: fopen");
+ exit(1);
+ }
+
+ rewind(mtab);
+ fflush(mtab);
+
+ while(fgets(buf, sizeof(buf), mtab))
+ {
+ if(start = strstr(buf, "/dev/"))
+ {
+ if(start = strstr(start, "da"))
+ {
+ start -=1;
+ stop = strstr(start, " ");
+ memcpy(data->diskInfo.mdata[i].name, start, stop - start);
+ start = stop +1;
+ stop = strstr(start, " ");
+ memcpy(data->diskInfo.mdata[i].mountpoint, start, stop - start);
+ i++;
+ }
+ }
+ }
+
+ fclose(mtab);
+
+ return;
+}
+
+void get_diskinfo(PERF_DATA_BLOCK *data)
+{
+ int i;
+ DiskData *p;
+ struct statfs statfsbuf;
+ int status, num;
+ char buf[LARGE_BUF], *start;
+ FILE *diskstats;
+ unsigned long reads, writes, discard;
+
+ diskstats = fopen("/proc/diskstats", "r");
+ rewind(diskstats);
+ fflush(diskstats);
+ status = fread(buf, sizeof(char), LARGE_BUF, diskstats);
+ fclose(diskstats);
+
+ for(i = 0; i < data->diskInfo.numDisks; i++)
+ {
+ p = &(data->diskInfo.data[i]);
+ status = statfs(data->diskInfo.mdata[i].mountpoint, &statfsbuf);
+ p->freeMegs = (statfsbuf.f_bfree*statfsbuf.f_bsize)/1048576;
+ start = strstr(buf, data->diskInfo.mdata[i].name);
+ start += strlen(data->diskInfo.mdata[i].name) + 1;
+ num = sscanf(start, "%lu %lu %lu %lu",
+ &reads,
+ &discard,
+ &writes,
+ &discard);
+ p->writesPerSec = writes;
+ p->readsPerSec = reads;
+ fprintf(stderr, "%s:\t%u\t%u\n",
+ data->diskInfo.mdata[i].mountpoint,
+ reads, writes);
+ }
+ return;
+}
+void init_disk_data(PERF_DATA_BLOCK *data)
+{
+ init_diskdata_desc(data);
+
+ init_num_disks(data);
+
+ data->diskInfo.mdata = calloc(data->diskInfo.numDisks, sizeof(DiskMetaData));
+ if(!data->diskInfo.mdata)
+ {
+ fatal("init_disk_data: out of memory");
+ }
+
+ init_disk_names(data);
+
+ data->diskInfo.data = calloc(data->diskInfo.numDisks, sizeof(DiskData));
+ if(!data->diskInfo.data)
+ {
+ fatal("init_disk_data: out of memory");
+ }
+
+ get_diskinfo(data);
+
+ return;
+}
+
+void output_disk_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt)
+{
+ output_perf_desc(data->diskInfo.diskObjDesc, rt);
+ output_perf_desc(data->diskInfo.freeMegs, rt);
+ output_perf_desc(data->diskInfo.writesPerSec, rt);
+ output_perf_desc(data->diskInfo.readsPerSec, rt);
+ output_num_instances(data->diskInfo.diskObjDesc, data->diskInfo.numDisks, rt);
+
+ return;
+}
+
+void output_diskinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
+{
+ int i;
+
+ output_perf_counter(data->diskInfo.freeMegs,
+ data->diskInfo.data[0].freeMegs,
+ rt, tdb_flags);
+ output_perf_counter(data->diskInfo.writesPerSec,
+ (unsigned long long)data->diskInfo.data[0].writesPerSec,
+ rt, tdb_flags);
+ output_perf_counter(data->diskInfo.readsPerSec,
+ (unsigned long long)data->diskInfo.data[0].readsPerSec,
+ rt, tdb_flags);
+
+ for(i = 0; i < data->diskInfo.numDisks; i++)
+ {
+ output_perf_instance(data->diskInfo.diskObjDesc.index,
+ i,
+ (void *)&(data->diskInfo.data[i]),
+ sizeof(DiskData),
+ data->diskInfo.mdata[i].mountpoint,
+ rt, tdb_flags);
+ }
+
+ return;
+}