@@ -35,9 +35,11 @@ const (
35
35
bsdSysctlTypeUint32 bsdSysctlType = iota
36
36
bsdSysctlTypeUint64
37
37
bsdSysctlTypeStructTimeval
38
+ bsdSysctlTypeCLong
38
39
)
39
40
40
- // Contains all the info needed to map a single bsd-sysctl to a prometheus value.
41
+ // Contains all the info needed to map a single bsd-sysctl to a prometheus
42
+ // value.
41
43
type bsdSysctl struct {
42
44
// Prometheus name
43
45
name string
@@ -72,42 +74,9 @@ func (b bsdSysctl) Value() (float64, error) {
72
74
tmp64 , err = unix .SysctlUint64 (b .mib )
73
75
tmpf64 = float64 (tmp64 )
74
76
case bsdSysctlTypeStructTimeval :
75
- raw , err := unix .SysctlRaw (b .mib )
76
- if err != nil {
77
- return 0 , err
78
- }
79
-
80
- /*
81
- * From 10.3-RELEASE sources:
82
- *
83
- * /usr/include/sys/_timeval.h:47
84
- * time_t tv_sec
85
- * suseconds_t tv_usec
86
- *
87
- * /usr/include/sys/_types.h:60
88
- * long __suseconds_t
89
- *
90
- * ... architecture dependent, via #ifdef:
91
- * typedef __int64_t __time_t;
92
- * typedef __int32_t __time_t;
93
- */
94
- if len (raw ) != (C .sizeof_time_t + C .sizeof_suseconds_t ) {
95
- // Shouldn't get here, unless the ABI changes...
96
- return 0 , fmt .Errorf (
97
- "length of bytes received from sysctl (%d) does not match expected bytes (%d)" ,
98
- len (raw ),
99
- C .sizeof_time_t + C .sizeof_suseconds_t ,
100
- )
101
- }
102
-
103
- secondsUp := unsafe .Pointer (& raw [0 ])
104
- susecondsUp := uintptr (secondsUp ) + C .sizeof_time_t
105
- unix := float64 (* (* C .time_t )(secondsUp ))
106
- usec := float64 (* (* C .suseconds_t )(unsafe .Pointer (susecondsUp )))
107
-
108
- // This conversion maintains the usec precision. Using
109
- // the time package did not.
110
- tmpf64 = unix + (usec / float64 (1000 * 1000 ))
77
+ tmpf64 , err = b .getStructTimeval ()
78
+ case bsdSysctlTypeCLong :
79
+ tmpf64 , err = b .getCLong ()
111
80
}
112
81
113
82
if err != nil {
@@ -120,3 +89,69 @@ func (b bsdSysctl) Value() (float64, error) {
120
89
121
90
return tmpf64 , nil
122
91
}
92
+
93
+ func (b bsdSysctl ) getStructTimeval () (float64 , error ) {
94
+ raw , err := unix .SysctlRaw (b .mib )
95
+ if err != nil {
96
+ return 0 , err
97
+ }
98
+
99
+ /*
100
+ * From 10.3-RELEASE sources:
101
+ *
102
+ * /usr/include/sys/_timeval.h:47
103
+ * time_t tv_sec
104
+ * suseconds_t tv_usec
105
+ *
106
+ * /usr/include/sys/_types.h:60
107
+ * long __suseconds_t
108
+ *
109
+ * ... architecture dependent, via #ifdef:
110
+ * typedef __int64_t __time_t;
111
+ * typedef __int32_t __time_t;
112
+ */
113
+ if len (raw ) != (C .sizeof_time_t + C .sizeof_suseconds_t ) {
114
+ // Shouldn't get here, unless the ABI changes...
115
+ return 0 , fmt .Errorf (
116
+ "length of bytes received from sysctl (%d) does not match expected bytes (%d)" ,
117
+ len (raw ),
118
+ C .sizeof_time_t + C .sizeof_suseconds_t ,
119
+ )
120
+ }
121
+
122
+ secondsUp := unsafe .Pointer (& raw [0 ])
123
+ susecondsUp := uintptr (secondsUp ) + C .sizeof_time_t
124
+ unix := float64 (* (* C .time_t )(secondsUp ))
125
+ usec := float64 (* (* C .suseconds_t )(unsafe .Pointer (susecondsUp )))
126
+
127
+ // This conversion maintains the usec precision. Using the time
128
+ // package did not.
129
+ return (unix + (usec / float64 (1000 * 1000 ))), nil
130
+ }
131
+
132
+ func (b bsdSysctl ) getCLong () (float64 , error ) {
133
+ raw , err := unix .SysctlRaw (b .mib )
134
+ if err != nil {
135
+ return 0 , err
136
+ }
137
+
138
+ if len (raw ) == C .sizeof_long {
139
+ return float64 (* (* C .long )(unsafe .Pointer (& raw [0 ]))), nil
140
+ }
141
+
142
+ if len (raw ) == C .sizeof_int {
143
+ // This is valid for at least vfs.bufspace, and the default
144
+ // long handler - which can clamp longs to 32-bits:
145
+ // https://github.com/freebsd/freebsd/blob/releng/10.3/sys/kern/vfs_bio.c#L338
146
+ // https://github.com/freebsd/freebsd/blob/releng/10.3/sys/kern/kern_sysctl.c#L1062
147
+ return float64 (* (* C .int )(unsafe .Pointer (& raw [0 ]))), nil
148
+ }
149
+
150
+ return 0 , fmt .Errorf (
151
+ "length of bytes received from sysctl (%d) does not match expected bytes (long: %d), (int: %d)" ,
152
+ len (raw ),
153
+ C .sizeof_long ,
154
+ C .sizeof_int ,
155
+ )
156
+
157
+ }
0 commit comments