2 * collectd - src/wpar.c
3 * Copyright (C) 2010 Manuel Sanmartin
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; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Manuel Sanmartin <manuel.luis at gmail.com>
27 # error "No applicable input method."
30 #include <sys/proc.h> /* AIX 5 */
31 #include <sys/protosw.h>
32 #include <libperfstat.h>
35 static int wpar_total_num;
36 static perfstat_wpar_total_t *wpar_total = NULL;
38 static int wpar_init(void) /* {{{ */
40 pagesize = getpagesize ();
42 } /* }}} int wpar_init */
44 static void memory_submit (const char *plugin_instance, const char *type_instance, gauge_t value) /* {{{ */
47 value_list_t vl = VALUE_LIST_INIT;
49 values[0].gauge = value;
53 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
54 sstrncpy (vl.plugin, "wpar", sizeof (vl.plugin));
55 sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
56 sstrncpy (vl.type, "memory", sizeof (vl.type));
57 sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
59 plugin_dispatch_values (&vl);
60 } /* }}} void memory_submit */
62 static void cpu_submit (const char *plugin_instance, const char *type_instance, derive_t value) /* {{{ */
65 value_list_t vl = VALUE_LIST_INIT;
67 values[0].counter = value;
71 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
72 sstrncpy (vl.plugin, "wpar", sizeof (vl.plugin));
73 sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
74 sstrncpy (vl.type, "cpu", sizeof (vl.type));
75 sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
77 plugin_dispatch_values (&vl);
78 } /* }}} void cpu_submit */
80 static void load_submit (const char *plugin_instance, gauge_t snum, gauge_t mnum, gauge_t lnum) /* {{{ */
83 value_list_t vl = VALUE_LIST_INIT;
85 values[0].gauge = snum;
86 values[1].gauge = mnum;
87 values[2].gauge = lnum;
90 vl.values_len = STATIC_ARRAY_SIZE (values);
91 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
92 sstrncpy (vl.plugin, "wpar", sizeof (vl.plugin));
93 sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
94 sstrncpy (vl.type, "load", sizeof (vl.type));
96 plugin_dispatch_values (&vl);
97 } /* }}} void load_submit */
99 static int wpar_read_memory (const perfstat_id_wpar_t *id_wpar, /* {{{ */
102 perfstat_memory_total_wpar_t wmemory;
105 status = perfstat_memory_total_wpar(/* id = */ id_wpar,
106 /* (out) */ &wmemory,
107 /* size = */ sizeof(wmemory), /* nmemb = */ 1);
111 WARNING ("wpar plugin: perfstat_memory_total_wpar(%s) failed: %s",
112 wname, sstrerror (errno, errbuf, sizeof (errbuf)));
116 memory_submit (wname, "used", wmemory.real_inuse * pagesize);
117 memory_submit (wname, "free", wmemory.real_free * pagesize);
118 memory_submit (wname, "cached", wmemory.numperm * pagesize);
119 /* XXX: In which case would total != used + free + cached? */
120 memory_submit (wname, "total", wmemory.real_total * pagesize);
123 } /* }}} int wpar_read_memory */
125 /* Read CPU and load information of one workload partition. */
126 static int wpar_read_cpu_load (const perfstat_id_wpar_t *id_wpar, /* {{{ */
129 perfstat_cpu_total_wpar_t wcpu;
130 double factor, snum, mnum, lnum;
133 status = perfstat_cpu_total_wpar(/* id = */ id_wpar,
135 /* size = */ sizeof(wcpu), /* nmemb = */ 1);
139 WARNING ("wpar plugin: perfstat_cpu_total_wpar(%s) failed: %s",
140 wname, sstrerror (errno, errbuf, sizeof (errbuf)));
144 factor = 1.0 / ((gauge_t) (1 << SBITS));
145 snum = ((gauge_t) wcpu.loadavg[0]) * factor;
146 mnum = ((gauge_t) wcpu.loadavg[1]) * factor;
147 lnum = ((gauge_t) wcpu.loadavg[2]) * factor;
149 load_submit (wname, snum, mnum, lnum);
151 cpu_submit (wname, "idle", (derive_t) wcpu.pidle);
152 cpu_submit (wname, "system", (derive_t) wcpu.psys);
153 cpu_submit (wname, "user", (derive_t) wcpu.puser);
154 cpu_submit (wname, "wait", (derive_t) wcpu.pwait);
157 } /* }}} int wpar_read_cpu_load */
159 static int wpar_read (void) /* {{{ */
164 do /* while (!have_data) */
166 perfstat_id_wpar_t id_wpar;
169 if (wpar_total != NULL)
170 memset (wpar_total, 0, wpar_total_num * sizeof (*wpar_total));
172 /* Assume the number of partitions has not been changed since the last run.
173 * On the first run, wpar_total will be NULL and only the number of elements
175 status = perfstat_wpar_total (/* id = */ &id_wpar,
176 /* (out) wpar_total */ wpar_total,
177 /* size = */ sizeof (*wpar_total),
178 /* nmemb = */ wpar_total_num);
182 WARNING ("wpar plugin: perfstat_wpar_total failed: %s",
183 sstrerror (errno, errbuf, sizeof (errbuf)));
186 else if (status == 0)
188 /* Avoid "realloc returned NULL" messages */
189 INFO ("wpar plugin: perfstat_wpar_total returned zero.");
193 /* If the number of values returned fitted into our buffer, we're done. If
194 * the number of partitions increased, we will have to try again. */
196 if (status <= wpar_total_num)
199 /* If the call returned a different number than before, call realloc(3) to
200 * adjust the buffer size. */
201 if (status != wpar_total_num) /* {{{ */
203 perfstat_wpar_total_t *tmp;
205 tmp = realloc (wpar_total, status * sizeof (*wpar_total));
208 /* We tried to allocate more memory. */
209 if (status > wpar_total_num)
211 ERROR ("wpar plugin: realloc(3) failed.");
216 /* decreasing the buffer size failed: Big whoop! We must adjust
217 * "wpar_total_num" though otherwise the loop below will do too much
219 wpar_total_num = status;
222 else /* if (tmp != NULL) */
225 wpar_total_num = status;
227 } /* }}} if (status != wpar_total_num) */
230 /* Iterate over all WPARs and dispatch information */
231 for (i = 0; i < wpar_total_num; i++)
233 perfstat_id_wpar_t id_wpar;
234 const char *wname = wpar_total[i].name;
237 /* Update the ID structure */
238 memset (&id_wpar, 0, sizeof (id_wpar));
239 id_wpar.spec = WPARID;
240 id_wpar.u.wpar_id = wpar_total[i].wpar_id;
242 wpar_read_memory (&id_wpar, wname);
243 wpar_read_cpu_load (&id_wpar, wname);
247 } /* }}} int wpar_read */
249 static int wpar_shutdown (void) /* {{{ */
255 } /* }}} int wpar_shutdown */
257 void module_register (void)
259 plugin_register_init ("wpar", wpar_init);
260 plugin_register_read ("wpar", wpar_read);
261 plugin_register_shutdown ("wpar", wpar_shutdown);
264 /* vim: set sw=2 sts=2 et fdm=marker : */