2 * collectd - src/vmware.c
3 * Copyright (C) 2010 Edward Muller
4 * Copyright (C) 2011 Keith Chambers
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; only version 2.1 of the License is
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 * Edward Muller <emuller at engineyard.com>
22 * Keith Chambers <chambers_keith at yahoo.com>
30 #include <vmGuestLib.h>
32 /* functions to dynamically load from the GuestLib library */
33 static char const * (*GuestLib_GetErrorText)(VMGuestLibError);
34 static VMGuestLibError (*GuestLib_OpenHandle)(VMGuestLibHandle*);
35 static VMGuestLibError (*GuestLib_CloseHandle)(VMGuestLibHandle);
36 static VMGuestLibError (*GuestLib_UpdateInfo)(VMGuestLibHandle handle);
37 static VMGuestLibError (*GuestLib_GetSessionId)(VMGuestLibHandle handle, VMSessionId *id);
38 static VMGuestLibError (*GuestLib_GetElapsedMs)(VMGuestLibHandle handle, uint64_t *elapsedMs);
39 static VMGuestLibError (*GuestLib_GetCpuUsedMs)(VMGuestLibHandle handle, uint64_t *cpuUsedMs);
40 static VMGuestLibError (*GuestLib_GetCpuStolenMs)(VMGuestLibHandle handle, uint64_t *cpuStolenMs);
41 static VMGuestLibError (*GuestLib_GetCpuReservationMHz)(VMGuestLibHandle handle, uint32_t *cpuReservationMHz);
42 static VMGuestLibError (*GuestLib_GetCpuLimitMHz)(VMGuestLibHandle handle, uint32_t *cpuLimitMHz);
43 static VMGuestLibError (*GuestLib_GetCpuShares)(VMGuestLibHandle handle, uint32_t *cpuShares);
44 static VMGuestLibError (*GuestLib_GetHostProcessorSpeed)(VMGuestLibHandle handle, uint32_t *mhz);
45 static VMGuestLibError (*GuestLib_GetMemUsedMB)(VMGuestLibHandle handle, uint32_t *memUsedMB);
46 static VMGuestLibError (*GuestLib_GetMemMappedMB)(VMGuestLibHandle handle, uint32_t *memMappedMB);
47 static VMGuestLibError (*GuestLib_GetMemActiveMB)(VMGuestLibHandle handle, uint32_t *memActiveMB);
48 static VMGuestLibError (*GuestLib_GetMemTargetSizeMB)(VMGuestLibHandle handle, uint64_t *memTargetSizeMB);
49 static VMGuestLibError (*GuestLib_GetMemOverheadMB)(VMGuestLibHandle handle, uint32_t *memOverheadMB);
50 static VMGuestLibError (*GuestLib_GetMemSharedMB)(VMGuestLibHandle handle, uint32_t *memSharedMB);
51 static VMGuestLibError (*GuestLib_GetMemSharedSavedMB)(VMGuestLibHandle handle, uint32_t *memSharedSavedMB);
52 static VMGuestLibError (*GuestLib_GetMemBalloonedMB)(VMGuestLibHandle handle, uint32_t *memBalloonedMB);
53 static VMGuestLibError (*GuestLib_GetMemSwappedMB)(VMGuestLibHandle handle, uint32_t *memSwappedMB);
54 static VMGuestLibError (*GuestLib_GetMemReservationMB)(VMGuestLibHandle handle, uint32_t *memReservationMB);
55 static VMGuestLibError (*GuestLib_GetMemLimitMB)(VMGuestLibHandle handle, uint32_t *memLimitMB);
56 static VMGuestLibError (*GuestLib_GetMemShares)(VMGuestLibHandle handle, uint32_t *memShares);
58 /* handle for use with shared library */
59 static VMGuestLibHandle gl_handle;
60 static VMSessionId gl_session;
62 /* used when converting megabytes to bytes for memory counters */
63 #define BYTES_PER_MB 1024*1024
65 /* macro to load a single GuestLib function from the shared library */
66 #define LOAD_ONE_FUNC(funcname) do { \
68 funcname = dlsym(dl_handle, "VM" #funcname); \
69 if ((errmsg = dlerror()) != NULL) { \
70 ERROR ("vmware plugin: Failed to load \"%s\": %s", \
76 _Bool static vmware_load_functions (void)
80 dl_handle = dlopen("libvmGuestLib.so", RTLD_NOW);
86 ERROR("vmware plugin: dlopen (\"libvmGuestLib.so\") failed: %s",
91 /* Load all the individual library functions */
92 LOAD_ONE_FUNC(GuestLib_GetErrorText);
93 LOAD_ONE_FUNC(GuestLib_OpenHandle);
94 LOAD_ONE_FUNC(GuestLib_CloseHandle);
95 LOAD_ONE_FUNC(GuestLib_UpdateInfo);
96 LOAD_ONE_FUNC(GuestLib_GetSessionId);
97 LOAD_ONE_FUNC(GuestLib_GetElapsedMs);
98 LOAD_ONE_FUNC(GuestLib_GetCpuStolenMs);
99 LOAD_ONE_FUNC(GuestLib_GetCpuUsedMs);
100 LOAD_ONE_FUNC(GuestLib_GetCpuReservationMHz);
101 LOAD_ONE_FUNC(GuestLib_GetCpuLimitMHz);
102 LOAD_ONE_FUNC(GuestLib_GetCpuShares);
103 LOAD_ONE_FUNC(GuestLib_GetHostProcessorSpeed);
104 LOAD_ONE_FUNC(GuestLib_GetMemReservationMB);
105 LOAD_ONE_FUNC(GuestLib_GetMemLimitMB);
106 LOAD_ONE_FUNC(GuestLib_GetMemShares);
107 LOAD_ONE_FUNC(GuestLib_GetMemMappedMB);
108 LOAD_ONE_FUNC(GuestLib_GetMemActiveMB);
109 LOAD_ONE_FUNC(GuestLib_GetMemOverheadMB);
110 LOAD_ONE_FUNC(GuestLib_GetMemBalloonedMB);
111 LOAD_ONE_FUNC(GuestLib_GetMemSwappedMB);
112 LOAD_ONE_FUNC(GuestLib_GetMemSharedMB);
113 LOAD_ONE_FUNC(GuestLib_GetMemSharedSavedMB);
114 LOAD_ONE_FUNC(GuestLib_GetMemUsedMB);
115 LOAD_ONE_FUNC(GuestLib_GetMemTargetSizeMB);
120 static int vmware_init (void)
122 VMGuestLibError status;
124 if (!vmware_load_functions()) {
125 ERROR ("vmware plugin: Unable to load GuestLib functions");
129 /* try to load the library */
130 status = GuestLib_OpenHandle(&gl_handle);
131 if (status != VMGUESTLIB_ERROR_SUCCESS)
133 ERROR ("vmware plugin: OpenHandle failed: %s",
134 GuestLib_GetErrorText (status));
141 static void submit_vmw_counter (const char *type, const char *type_inst,
145 value_list_t vl = VALUE_LIST_INIT;
147 values[0].derive = value;
152 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
153 sstrncpy (vl.plugin, "vmware", sizeof (vl.plugin));
154 sstrncpy (vl.type, type, sizeof (vl.type));
155 sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
157 plugin_dispatch_values (&vl);
160 static void submit_vmw_gauge (const char *type, const char *type_inst,
164 value_list_t vl = VALUE_LIST_INIT;
166 values[0].gauge = value;
171 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
172 sstrncpy (vl.plugin, "vmware", sizeof (vl.plugin));
173 sstrncpy (vl.type, type, sizeof (vl.type));
174 sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
176 plugin_dispatch_values (&vl);
179 static int vmw_query_memory (VMGuestLibHandle handle,
180 char const *function_name,
181 VMGuestLibError (*function) (VMGuestLibHandle, uint32_t *),
182 char const *type_instance)
185 VMGuestLibError status;
187 status = (*function) (handle, &value);
188 if (status != VMGUESTLIB_ERROR_SUCCESS)
190 WARNING ("vmware plugin: %s failed: %s",
191 function_name, GuestLib_GetErrorText (status));
195 /* The returned value is in megabytes, so multiply it by 2^20. It's not
196 * 10^6, because we're talking about memory. */
197 submit_vmw_gauge ("memory", type_instance,
198 (gauge_t) (BYTES_PER_MB * value));
200 } /* }}} int vmw_query_megabyte */
202 static int vmware_read (void)
205 VMGuestLibError status;
210 status = GuestLib_UpdateInfo(gl_handle);
211 if (status != VMGUESTLIB_ERROR_SUCCESS) {
212 ERROR ("vmware plugin: UpdateInfo failed: %s",
213 GuestLib_GetErrorText(status));
217 /* retrieve and check the session ID */
218 status = GuestLib_GetSessionId(gl_handle, &gl_session);
219 if (status != VMGUESTLIB_ERROR_SUCCESS) {
220 ERROR ("vmware plugin: Failed to get session ID: %s",
221 GuestLib_GetErrorText(status));
225 if (gl_session == 0) {
226 ERROR ("vmware plugin: Error: Got zero sessionId from GuestLib");
231 status = GuestLib_GetElapsedMs(gl_handle, &tmp64);
232 if (status != VMGUESTLIB_ERROR_SUCCESS)
233 WARNING ("vmware plugin: Failed to get elapsed ms: %s",
234 GuestLib_GetErrorText(status));
236 submit_vmw_counter ("total_time_in_ms", "elapsed", (derive_t) tmp64);
239 status = GuestLib_GetCpuUsedMs(gl_handle, &tmp64);
240 if (status != VMGUESTLIB_ERROR_SUCCESS)
241 WARNING ("vmware plugin: Failed to get used ms: %s",
242 GuestLib_GetErrorText(status));
244 submit_vmw_counter ("virt_vcpu", "used", (derive_t) tmp64);
247 status = GuestLib_GetCpuStolenMs(gl_handle, &tmp64);
248 if (status == VMGUESTLIB_ERROR_UNSUPPORTED_VERSION)
250 else if (status != VMGUESTLIB_ERROR_SUCCESS)
251 WARNING ("vmware plugin: Failed to get CPU stolen: %s",
252 GuestLib_GetErrorText(status));
254 submit_vmw_counter ("virt_vcpu", "stolen", (derive_t) tmp64);
256 /* GetCpuReservationMHz */
257 status = GuestLib_GetCpuReservationMHz(gl_handle, &tmp32);
258 if (status != VMGUESTLIB_ERROR_SUCCESS)
259 WARNING ("vmware plugin: Failed to get CPU reservation: %s",
260 GuestLib_GetErrorText(status));
262 submit_vmw_gauge ("vcpu", "reservation", (gauge_t) tmp32);
265 status = GuestLib_GetCpuLimitMHz(gl_handle, &tmp32);
266 if (status != VMGUESTLIB_ERROR_SUCCESS)
267 WARNING ("vmware plugin: Failed to get CPU limit: %s",
268 GuestLib_GetErrorText(status));
270 submit_vmw_gauge ("vcpu", "limit", (gauge_t) tmp32);
273 status = GuestLib_GetCpuShares(gl_handle, &tmp32);
274 if (status != VMGUESTLIB_ERROR_SUCCESS)
275 WARNING ("vmware plugin: Failed to get cpu shares: %s",
276 GuestLib_GetErrorText(status));
278 submit_vmw_gauge ("vcpu", "shares", (gauge_t) tmp32);
280 /* GetHostProcessorSpeed */
281 status = GuestLib_GetHostProcessorSpeed(gl_handle, &tmp32);
282 if (status != VMGUESTLIB_ERROR_SUCCESS)
283 WARNING ("vmware plugin: Failed to get host proc speed: %s",
284 GuestLib_GetErrorText(status));
286 submit_vmw_gauge ("cpufreq", "", 1.0e6 * (gauge_t) tmp32);
288 /* GetMemTargetSizeMB */
289 status = GuestLib_GetMemTargetSizeMB(gl_handle, &tmp64);
290 if (status != VMGUESTLIB_ERROR_SUCCESS)
291 WARNING ("vmware plugin: GuestLib_GetMemTargetSizeMB failed: %s",
292 GuestLib_GetErrorText (status));
294 submit_vmw_gauge ("memory", "target", (gauge_t) (BYTES_PER_MB * tmp64));
296 #define VMW_QUERY_MEMORY(func, type) \
297 vmw_query_memory (gl_handle, #func, GuestLib_ ## func, type)
299 VMW_QUERY_MEMORY (GetMemUsedMB, "used"); /* pysical; used = mapped - shared_saved */
300 VMW_QUERY_MEMORY (GetMemMappedMB, "mapped"); /* mapped = used + shared_saved */
301 VMW_QUERY_MEMORY (GetMemActiveMB, "active");
302 VMW_QUERY_MEMORY (GetMemOverheadMB, "overhead");
303 VMW_QUERY_MEMORY (GetMemSharedMB, "shared"); /* physical */
304 VMW_QUERY_MEMORY (GetMemSharedSavedMB, "shared_saved");
305 VMW_QUERY_MEMORY (GetMemBalloonedMB, "ballooned");
306 VMW_QUERY_MEMORY (GetMemSwappedMB, "swapped"); /* physical? */
307 /* min memory available to the guest */
308 VMW_QUERY_MEMORY (GetMemReservationMB, "reservation");
309 /* max memory available to the guest */
310 VMW_QUERY_MEMORY (GetMemLimitMB, "limit");
312 VMW_QUERY_MEMORY (GetMemShares, "shares");
314 #undef VMW_QUERY_MEMORY
319 void module_register (void)
321 plugin_register_init ("vmware", vmware_init);
322 plugin_register_read ("vmware", vmware_read);