diff options
author | Dominik Honnef <dominik@honnef.co> | 2016-12-31 06:52:44 +0100 |
---|---|---|
committer | Dominik Honnef <dominik@honnef.co> | 2017-01-05 05:38:26 +0100 |
commit | ea55d0f5cb8062f311891c20f2d5d11c62241cf8 (patch) | |
tree | 4111c55ae92b5c21b7ace6722a6fc8fa5e0e406f /collector/devstat_freebsd.c | |
parent | 5e220c1665e1cdbdb69cdcf6789f176ca907bd6e (diff) | |
download | prometheus_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.c | 99 |
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 | ||
12 | int _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, ¤t) == -1) | ||
20 | return -1; | ||
21 | 12 | ||
22 | return current.dinfo->numdevs; | 13 | int _get_stats(Stats **stats) { |
23 | } | ||
24 | |||
25 | Stats _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, ¤t); | 18 | if (devstat_getdevs(NULL, ¤t) == -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(¤t.dinfo->devices[i], | 32 | devstat_compute_statistics(¤t.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 | } |