aboutsummaryrefslogtreecommitdiff
path: root/collector/devstat_freebsd.c
diff options
context:
space:
mode:
authorDominik Honnef <dominik@honnef.co>2016-12-31 06:52:44 +0100
committerDominik Honnef <dominik@honnef.co>2017-01-05 05:38:26 +0100
commitea55d0f5cb8062f311891c20f2d5d11c62241cf8 (patch)
tree4111c55ae92b5c21b7ace6722a6fc8fa5e0e406f /collector/devstat_freebsd.c
parent5e220c1665e1cdbdb69cdcf6789f176ca907bd6e (diff)
downloadprometheus_node_collector-ea55d0f5cb8062f311891c20f2d5d11c62241cf8.tar.bz2
prometheus_node_collector-ea55d0f5cb8062f311891c20f2d5d11c62241cf8.tar.xz
prometheus_node_collector-ea55d0f5cb8062f311891c20f2d5d11c62241cf8.zip
Don't race in FreeBSD devstat collector
Querying the number of devices separately from the device list itself is racy. Devices may be added or removed between the two calls; and removed devices would lead to a segfault.
Diffstat (limited to 'collector/devstat_freebsd.c')
-rw-r--r--collector/devstat_freebsd.c99
1 files changed, 46 insertions, 53 deletions
diff --git a/collector/devstat_freebsd.c b/collector/devstat_freebsd.c
index 3a8e6d3..80a24e4 100644
--- a/collector/devstat_freebsd.c
+++ b/collector/devstat_freebsd.c
@@ -9,66 +9,59 @@
9#include <string.h> 9#include <string.h>
10#include <devstat_freebsd.h> 10#include <devstat_freebsd.h>
11 11
12int _get_ndevs() {
13 struct statinfo current;
14 struct devinfo info = {};
15 current.dinfo = &info;
16
17 devstat_checkversion(NULL);
18
19 if (devstat_getdevs(NULL, &current) == -1)
20 return -1;
21 12
22 return current.dinfo->numdevs; 13int _get_stats(Stats **stats) {
23}
24
25Stats _get_stats(int i) {
26 struct statinfo current; 14 struct statinfo current;
27 struct devinfo info = {}; 15 struct devinfo info = {};
28 current.dinfo = &info; 16 current.dinfo = &info;
29 17
30 devstat_getdevs(NULL, &current); 18 if (devstat_getdevs(NULL, &current) == -1) {
19 return -1;
20 }
31 21
32 Stats stats; 22 Stats *p = (Stats*)calloc(current.dinfo->numdevs, sizeof(Stats));
33 uint64_t bytes_read, bytes_write, bytes_free; 23 for (int i = 0; i < current.dinfo->numdevs; i++) {
34 uint64_t transfers_other, transfers_read, transfers_write, transfers_free; 24 uint64_t bytes_read, bytes_write, bytes_free;
35 long double duration_other, duration_read, duration_write, duration_free; 25 uint64_t transfers_other, transfers_read, transfers_write, transfers_free;
36 long double busy_time; 26 long double duration_other, duration_read, duration_write, duration_free;
37 uint64_t blocks; 27 long double busy_time;
28 uint64_t blocks;
38 29
39 strcpy(stats.device, current.dinfo->devices[i].device_name); 30 strcpy(p[i].device, current.dinfo->devices[i].device_name);
40 stats.unit = current.dinfo->devices[i].unit_number; 31 p[i].unit = current.dinfo->devices[i].unit_number;
41 devstat_compute_statistics(&current.dinfo->devices[i], 32 devstat_compute_statistics(&current.dinfo->devices[i],
42 NULL, 33 NULL,
43 1.0, 34 1.0,
44 DSM_TOTAL_BYTES_READ, &bytes_read, 35 DSM_TOTAL_BYTES_READ, &bytes_read,
45 DSM_TOTAL_BYTES_WRITE, &bytes_write, 36 DSM_TOTAL_BYTES_WRITE, &bytes_write,
46 DSM_TOTAL_BYTES_FREE, &bytes_free, 37 DSM_TOTAL_BYTES_FREE, &bytes_free,
47 DSM_TOTAL_TRANSFERS_OTHER, &transfers_other, 38 DSM_TOTAL_TRANSFERS_OTHER, &transfers_other,
48 DSM_TOTAL_TRANSFERS_READ, &transfers_read, 39 DSM_TOTAL_TRANSFERS_READ, &transfers_read,
49 DSM_TOTAL_TRANSFERS_WRITE, &transfers_write, 40 DSM_TOTAL_TRANSFERS_WRITE, &transfers_write,
50 DSM_TOTAL_TRANSFERS_FREE, &transfers_free, 41 DSM_TOTAL_TRANSFERS_FREE, &transfers_free,
51 DSM_TOTAL_DURATION_OTHER, &duration_other, 42 DSM_TOTAL_DURATION_OTHER, &duration_other,
52 DSM_TOTAL_DURATION_READ, &duration_read, 43 DSM_TOTAL_DURATION_READ, &duration_read,
53 DSM_TOTAL_DURATION_WRITE, &duration_write, 44 DSM_TOTAL_DURATION_WRITE, &duration_write,
54 DSM_TOTAL_DURATION_FREE, &duration_free, 45 DSM_TOTAL_DURATION_FREE, &duration_free,
55 DSM_TOTAL_BUSY_TIME, &busy_time, 46 DSM_TOTAL_BUSY_TIME, &busy_time,
56 DSM_TOTAL_BLOCKS, &blocks, 47 DSM_TOTAL_BLOCKS, &blocks,
57 DSM_NONE); 48 DSM_NONE);
58 49
59 stats.bytes.read = bytes_read; 50 p[i].bytes.read = bytes_read;
60 stats.bytes.write = bytes_write; 51 p[i].bytes.write = bytes_write;
61 stats.bytes.free = bytes_free; 52 p[i].bytes.free = bytes_free;
62 stats.transfers.other = transfers_other; 53 p[i].transfers.other = transfers_other;
63 stats.transfers.read = transfers_read; 54 p[i].transfers.read = transfers_read;
64 stats.transfers.write = transfers_write; 55 p[i].transfers.write = transfers_write;
65 stats.transfers.free = transfers_free; 56 p[i].transfers.free = transfers_free;
66 stats.duration.other = duration_other; 57 p[i].duration.other = duration_other;
67 stats.duration.read = duration_read; 58 p[i].duration.read = duration_read;
68 stats.duration.write = duration_write; 59 p[i].duration.write = duration_write;
69 stats.duration.free = duration_free; 60 p[i].duration.free = duration_free;
70 stats.busyTime = busy_time; 61 p[i].busyTime = busy_time;
71 stats.blocks = blocks; 62 p[i].blocks = blocks;
63 }
72 64
73 return stats; 65 *stats = p;
66 return current.dinfo->numdevs;
74} 67}