Changed modules `cpu' through `sensors' to compile in `read-only' mode if dependencie...
[collectd.git] / src / cpufreq.c
1 /**
2  * collectd - src/cpufreq.c
3  * Copyright (C) 2005  Peter Holik
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  *
19  * Authors:
20  *   Peter Holik <peter at holik.at>
21  **/
22
23 #include "collectd.h"
24 #include "common.h"
25 #include "plugin.h"
26
27 #define MODULE_NAME "cpufreq"
28
29 static char *cpufreq_file = "cpufreq-%s.rrd";
30
31 static char *ds_def[] =
32 {
33         "DS:value:GAUGE:25:0:U",
34         NULL
35 };
36 static int ds_num = 1;
37
38 #ifdef KERNEL_LINUX
39 static int num_cpu = 0;
40 #endif
41
42 #define BUFSIZE 256
43
44 static void cpufreq_init (void)
45 {
46 #ifdef KERNEL_LINUX
47         int status;
48         char filename[BUFSIZE];
49
50         num_cpu = 0;
51
52         while (1)
53         {
54                 status = snprintf (filename, BUFSIZE, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", num_cpu);
55                 if (status < 1 || status >= BUFSIZE)
56                         break;
57
58                 if (access(filename, R_OK))
59                         break;
60
61                 num_cpu++;
62         }
63
64         syslog (LOG_INFO, MODULE_NAME" found %d cpu(s)", num_cpu);
65 #endif /* defined(KERNEL_LINUX) */
66
67         return;
68 }
69
70 static void cpufreq_write (char *host, char *inst, char *val)
71 {
72         int status;
73         char file[BUFSIZE];
74
75         status = snprintf (file, BUFSIZE, cpufreq_file, inst);
76         if (status < 1 || status >= BUFSIZE)
77                 return;
78
79         rrd_update_file (host, file, val, ds_def, ds_num);
80 }
81
82 static void cpufreq_submit (int cpu_num, unsigned long long val)
83 {
84         char buf[BUFSIZE];
85         char cpu[16];
86
87         if (snprintf (buf, BUFSIZE, "%u:%llu", (unsigned int) curtime, val) >= BUFSIZE)
88                 return;
89         snprintf (cpu, 16, "%i", cpu_num);
90
91         plugin_submit (MODULE_NAME, cpu, buf);
92 }
93
94 static void cpufreq_read (void)
95 {
96 #ifdef KERNEL_LINUX
97         int status;
98         unsigned long long val;
99         int i = 0;
100         FILE *fp;
101         char filename[BUFSIZE];
102         char buffer[16];
103
104         for (i = 0; i < num_cpu; i++)
105         {
106                 status = snprintf (filename, BUFSIZE, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", i);
107                 if (status < 1 || status >= BUFSIZE)
108                         return;
109
110                 if ((fp = fopen (filename, "r")) == NULL)
111                 {
112                         syslog (LOG_WARNING, "cpufreq: fopen: %s", strerror (errno));
113                         return;
114                 }
115
116                 if (fgets (buffer, 16, fp) == NULL)
117                 {
118                         syslog (LOG_WARNING, "cpufreq: fgets: %s", strerror (errno));
119                         return;
120                 }
121
122                 if (fclose (fp))
123                         syslog (LOG_WARNING, "cpufreq: fclose: %s", strerror (errno));
124
125                 /* You're seeing correctly: The file is reporting kHz values.. */
126                 val = atoll (buffer) * 1000;
127
128                 cpufreq_submit (i, val);
129         }
130 #endif /* defined(KERNEL_LINUX) */
131
132         return;
133 }
134 #undef BUFSIZE
135
136 void module_register (void)
137 {
138         plugin_register (MODULE_NAME, cpufreq_init, cpufreq_read, cpufreq_write);
139 }
140
141 #undef MODULE_NAME