Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 97ac38e

Browse files
committedNov 28, 2021
Add devstat items
1 parent cc44550 commit 97ac38e

File tree

2 files changed

+368
-1
lines changed

2 files changed

+368
-1
lines changed
 

‎libc-test/build.rs‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1876,6 +1876,7 @@ fn test_freebsd(target: &str) {
18761876
"sys/vmmeter.h",
18771877
"sys/wait.h",
18781878
"libprocstat.h",
1879+
"devstat.h",
18791880
"syslog.h",
18801881
"termios.h",
18811882
"time.h",
@@ -1918,7 +1919,9 @@ fn test_freebsd(target: &str) {
19181919
}
19191920
// Field is named `type` in C but that is a Rust keyword,
19201921
// so these fields are translated to `type_` in the bindings.
1921-
"type_" if struct_ == "rtprio" || struct_ == "sockstat" => "type".to_string(),
1922+
"type_" if struct_ == "rtprio" => "type".to_string(),
1923+
"type_" if struct_ == "sockstat" => "type".to_string(),
1924+
"type_" if struct_ == "devstat_match_table" => "type".to_string(),
19221925
s => s.to_string(),
19231926
}
19241927
});
@@ -2172,6 +2175,10 @@ fn test_freebsd(target: &str) {
21722175
// https://github.com/gnzlbg/ctest/issues/68
21732176
"lio_listio" => true,
21742177

2178+
// It returns a `long double`, but it's a nightmare to bind correctly in rust
2179+
// for the moment, so it's a best effort thing...
2180+
"devstat_compute_etime" => true,
2181+
21752182
_ => false,
21762183
}
21772184
});
@@ -2244,6 +2251,11 @@ fn test_freebsd(target: &str) {
22442251

22452252
// `__sem_base` is a private struct field
22462253
("semid_ds", "__sem_base") => true,
2254+
2255+
// `snap_time` is a `long double`, but it's a nightmare to bind correctly in rust
2256+
// for the moment, so it's a best effort thing...
2257+
("statinfo", "snap_time") => true,
2258+
22472259
_ => false,
22482260
}
22492261
});

‎src/unix/bsd/freebsdlike/freebsd/mod.rs‎

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,206 @@ pub type u_short = ::c_ushort;
3939

4040
pub type caddr_t = *mut ::c_char;
4141

42+
// This is mosty a hack to keep the length somewhat similar. However, based on
43+
// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html, it might very well be incorrect.
44+
cfg_if! {
45+
if #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] {
46+
pub type c_longdouble = ::c_double;
47+
} else {
48+
pub type c_longdouble = u128;
49+
}
50+
}
51+
4252
// It's an alias over "struct __kvm_t". However, its fields aren't supposed to be used directly,
4353
// making the type definition system dependent. Better not bind it exactly.
4454
pub type kvm_t = ::c_void;
4555

56+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
57+
#[repr(u32)]
58+
pub enum devstat_support_flags {
59+
DEVSTAT_ALL_SUPPORTED = 0x00,
60+
DEVSTAT_NO_BLOCKSIZE = 0x01,
61+
DEVSTAT_NO_ORDERED_TAGS = 0x02,
62+
DEVSTAT_BS_UNAVAILABLE = 0x04,
63+
}
64+
impl ::Copy for devstat_support_flags {}
65+
impl ::Clone for devstat_support_flags {
66+
fn clone(&self) -> devstat_support_flags {
67+
*self
68+
}
69+
}
70+
71+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
72+
#[repr(u32)]
73+
pub enum devstat_trans_flags {
74+
DEVSTAT_NO_DATA = 0x00,
75+
DEVSTAT_READ = 0x01,
76+
DEVSTAT_WRITE = 0x02,
77+
DEVSTAT_FREE = 0x03,
78+
}
79+
80+
impl ::Copy for devstat_trans_flags {}
81+
impl ::Clone for devstat_trans_flags {
82+
fn clone(&self) -> devstat_trans_flags {
83+
*self
84+
}
85+
}
86+
87+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
88+
#[repr(u32)]
89+
pub enum devstat_tag_type {
90+
DEVSTAT_TAG_SIMPLE = 0x00,
91+
DEVSTAT_TAG_HEAD = 0x01,
92+
DEVSTAT_TAG_ORDERED = 0x02,
93+
DEVSTAT_TAG_NONE = 0x03,
94+
}
95+
impl ::Copy for devstat_tag_type {}
96+
impl ::Clone for devstat_tag_type {
97+
fn clone(&self) -> devstat_tag_type {
98+
*self
99+
}
100+
}
101+
102+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
103+
#[repr(u32)]
104+
pub enum devstat_match_flags {
105+
DEVSTAT_MATCH_NONE = 0x00,
106+
DEVSTAT_MATCH_TYPE = 0x01,
107+
DEVSTAT_MATCH_IF = 0x02,
108+
DEVSTAT_MATCH_PASS = 0x04,
109+
}
110+
impl ::Copy for devstat_match_flags {}
111+
impl ::Clone for devstat_match_flags {
112+
fn clone(&self) -> devstat_match_flags {
113+
*self
114+
}
115+
}
116+
117+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
118+
#[repr(u32)]
119+
pub enum devstat_priority {
120+
DEVSTAT_PRIORITY_MIN = 0x000,
121+
DEVSTAT_PRIORITY_OTHER = 0x020,
122+
DEVSTAT_PRIORITY_PASS = 0x030,
123+
DEVSTAT_PRIORITY_FD = 0x040,
124+
DEVSTAT_PRIORITY_WFD = 0x050,
125+
DEVSTAT_PRIORITY_TAPE = 0x060,
126+
DEVSTAT_PRIORITY_CD = 0x090,
127+
DEVSTAT_PRIORITY_DISK = 0x110,
128+
DEVSTAT_PRIORITY_ARRAY = 0x120,
129+
DEVSTAT_PRIORITY_MAX = 0xfff,
130+
}
131+
impl ::Copy for devstat_priority {}
132+
impl ::Clone for devstat_priority {
133+
fn clone(&self) -> devstat_priority {
134+
*self
135+
}
136+
}
137+
138+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
139+
#[repr(u32)]
140+
pub enum devstat_type_flags {
141+
DEVSTAT_TYPE_DIRECT = 0x000,
142+
DEVSTAT_TYPE_SEQUENTIAL = 0x001,
143+
DEVSTAT_TYPE_PRINTER = 0x002,
144+
DEVSTAT_TYPE_PROCESSOR = 0x003,
145+
DEVSTAT_TYPE_WORM = 0x004,
146+
DEVSTAT_TYPE_CDROM = 0x005,
147+
DEVSTAT_TYPE_SCANNER = 0x006,
148+
DEVSTAT_TYPE_OPTICAL = 0x007,
149+
DEVSTAT_TYPE_CHANGER = 0x008,
150+
DEVSTAT_TYPE_COMM = 0x009,
151+
DEVSTAT_TYPE_ASC0 = 0x00a,
152+
DEVSTAT_TYPE_ASC1 = 0x00b,
153+
DEVSTAT_TYPE_STORARRAY = 0x00c,
154+
DEVSTAT_TYPE_ENCLOSURE = 0x00d,
155+
DEVSTAT_TYPE_FLOPPY = 0x00e,
156+
DEVSTAT_TYPE_MASK = 0x00f,
157+
DEVSTAT_TYPE_IF_SCSI = 0x010,
158+
DEVSTAT_TYPE_IF_IDE = 0x020,
159+
DEVSTAT_TYPE_IF_OTHER = 0x030,
160+
DEVSTAT_TYPE_IF_MASK = 0x0f0,
161+
DEVSTAT_TYPE_PASS = 0x100,
162+
}
163+
impl ::Copy for devstat_type_flags {}
164+
impl ::Clone for devstat_type_flags {
165+
fn clone(&self) -> devstat_type_flags {
166+
*self
167+
}
168+
}
169+
170+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
171+
#[repr(u32)]
172+
pub enum devstat_metric {
173+
DSM_NONE,
174+
DSM_TOTAL_BYTES,
175+
DSM_TOTAL_BYTES_READ,
176+
DSM_TOTAL_BYTES_WRITE,
177+
DSM_TOTAL_TRANSFERS,
178+
DSM_TOTAL_TRANSFERS_READ,
179+
DSM_TOTAL_TRANSFERS_WRITE,
180+
DSM_TOTAL_TRANSFERS_OTHER,
181+
DSM_TOTAL_BLOCKS,
182+
DSM_TOTAL_BLOCKS_READ,
183+
DSM_TOTAL_BLOCKS_WRITE,
184+
DSM_KB_PER_TRANSFER,
185+
DSM_KB_PER_TRANSFER_READ,
186+
DSM_KB_PER_TRANSFER_WRITE,
187+
DSM_TRANSFERS_PER_SECOND,
188+
DSM_TRANSFERS_PER_SECOND_READ,
189+
DSM_TRANSFERS_PER_SECOND_WRITE,
190+
DSM_TRANSFERS_PER_SECOND_OTHER,
191+
DSM_MB_PER_SECOND,
192+
DSM_MB_PER_SECOND_READ,
193+
DSM_MB_PER_SECOND_WRITE,
194+
DSM_BLOCKS_PER_SECOND,
195+
DSM_BLOCKS_PER_SECOND_READ,
196+
DSM_BLOCKS_PER_SECOND_WRITE,
197+
DSM_MS_PER_TRANSACTION,
198+
DSM_MS_PER_TRANSACTION_READ,
199+
DSM_MS_PER_TRANSACTION_WRITE,
200+
DSM_SKIP,
201+
DSM_TOTAL_BYTES_FREE,
202+
DSM_TOTAL_TRANSFERS_FREE,
203+
DSM_TOTAL_BLOCKS_FREE,
204+
DSM_KB_PER_TRANSFER_FREE,
205+
DSM_MB_PER_SECOND_FREE,
206+
DSM_TRANSFERS_PER_SECOND_FREE,
207+
DSM_BLOCKS_PER_SECOND_FREE,
208+
DSM_MS_PER_TRANSACTION_OTHER,
209+
DSM_MS_PER_TRANSACTION_FREE,
210+
DSM_BUSY_PCT,
211+
DSM_QUEUE_LENGTH,
212+
DSM_TOTAL_DURATION,
213+
DSM_TOTAL_DURATION_READ,
214+
DSM_TOTAL_DURATION_WRITE,
215+
DSM_TOTAL_DURATION_FREE,
216+
DSM_TOTAL_DURATION_OTHER,
217+
DSM_TOTAL_BUSY_TIME,
218+
DSM_MAX,
219+
}
220+
impl ::Copy for devstat_metric {}
221+
impl ::Clone for devstat_metric {
222+
fn clone(&self) -> devstat_metric {
223+
*self
224+
}
225+
}
226+
227+
#[cfg_attr(feature = "extra_traits", derive(Debug))]
228+
#[repr(u32)]
229+
pub enum devstat_select_mode {
230+
DS_SELECT_ADD,
231+
DS_SELECT_ONLY,
232+
DS_SELECT_REMOVE,
233+
DS_SELECT_ADDONLY,
234+
}
235+
impl ::Copy for devstat_select_mode {}
236+
impl ::Clone for devstat_select_mode {
237+
fn clone(&self) -> devstat_select_mode {
238+
*self
239+
}
240+
}
241+
46242
s! {
47243
pub struct aiocb {
48244
pub aio_fildes: ::c_int,
@@ -645,6 +841,101 @@ s! {
645841
pub ph1: u64,
646842
pub ph2: u64,
647843
}
844+
845+
pub struct bintime {
846+
pub sec: ::time_t,
847+
pub frac: u64,
848+
}
849+
850+
pub struct clockinfo {
851+
/// clock frequency
852+
pub hz: ::c_int,
853+
/// micro-seconds per hz tick
854+
pub tick: ::c_int,
855+
pub spare: ::c_int,
856+
/// statistics clock frequency
857+
pub stathz: ::c_int,
858+
/// profiling clock frequency
859+
pub profhz: ::c_int,
860+
}
861+
862+
pub struct __c_anonymous_stailq_entry_devstat {
863+
pub stqe_next: *mut devstat,
864+
}
865+
866+
pub struct devstat {
867+
/// Update sequence
868+
pub sequence0: ::u_int,
869+
/// Allocated entry
870+
pub allocated: ::c_int,
871+
/// started ops
872+
pub start_count: ::u_int,
873+
/// completed ops
874+
pub end_count: ::u_int,
875+
/// busy time unaccounted for since this time
876+
pub busy_from: bintime,
877+
pub dev_links: __c_anonymous_stailq_entry_devstat,
878+
/// Devstat device number.
879+
pub device_number: u32,
880+
pub device_name: [::c_char; DEVSTAT_NAME_LEN as usize],
881+
pub unit_number: ::c_int,
882+
pub bytes: [u64; DEVSTAT_N_TRANS_FLAGS as usize],
883+
pub operations: [u64; DEVSTAT_N_TRANS_FLAGS as usize],
884+
pub duration: [bintime; DEVSTAT_N_TRANS_FLAGS as usize],
885+
pub busy_time: bintime,
886+
/// Time the device was created.
887+
pub creation_time: bintime,
888+
/// Block size, bytes
889+
pub block_size: u32,
890+
/// The number of simple, ordered, and head of queue tags sent.
891+
pub tag_types: [u64; 3],
892+
/// Which statistics are supported by a given device.
893+
pub flags: devstat_support_flags,
894+
/// Device type
895+
pub device_type: devstat_type_flags,
896+
/// Controls list pos.
897+
pub priority: devstat_priority,
898+
/// Identification for GEOM nodes
899+
pub id: *const ::c_void,
900+
/// Update sequence
901+
pub sequence1: ::u_int,
902+
}
903+
904+
pub struct devstat_match {
905+
pub match_fields: devstat_match_flags,
906+
pub device_type: devstat_type_flags,
907+
pub num_match_categories: ::c_int,
908+
}
909+
910+
pub struct devstat_match_table {
911+
pub match_str: *const ::c_char,
912+
pub type_: devstat_type_flags,
913+
pub match_field: devstat_match_flags,
914+
}
915+
916+
pub struct device_selection {
917+
pub device_number: u32,
918+
pub device_name: [::c_char; DEVSTAT_NAME_LEN as usize],
919+
pub unit_number: ::c_int,
920+
pub selected: ::c_int,
921+
pub bytes: u64,
922+
pub position: ::c_int,
923+
}
924+
925+
pub struct devinfo {
926+
pub devices: *mut devstat,
927+
pub mem_ptr: *mut u8,
928+
pub generation: ::c_long,
929+
pub numdevs: ::c_int,
930+
}
931+
932+
pub struct statinfo {
933+
pub cp_time: [::c_long; CPUSTATES as usize],
934+
pub tk_nin: ::c_long,
935+
pub tk_nout: ::c_long,
936+
pub dinfo: *mut devinfo,
937+
pub snap_time: c_longdouble,
938+
}
648939
}
649940

650941
s_no_extra_traits! {
@@ -1499,6 +1790,10 @@ impl ::Clone for dot3Vendors {
14991790
}
15001791
}
15011792

1793+
// sys/devicestat.h
1794+
pub const DEVSTAT_N_TRANS_FLAGS: ::c_int = 4;
1795+
pub const DEVSTAT_NAME_LEN: ::c_int = 16;
1796+
15021797
pub const SIGEV_THREAD_ID: ::c_int = 4;
15031798

15041799
pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0;
@@ -3125,6 +3420,26 @@ pub const PS_FST_FFLAG_DIRECT: ::c_int = 0x1000;
31253420
pub const PS_FST_FFLAG_EXEC: ::c_int = 0x2000;
31263421
pub const PS_FST_FFLAG_HASLOCK: ::c_int = 0x4000;
31273422

3423+
// time.h
3424+
3425+
/// not on dst
3426+
pub const DST_NONE: ::c_int = 0;
3427+
/// USA style dst
3428+
pub const DST_USA: ::c_int = 1;
3429+
/// Australian style dst
3430+
pub const DST_AUST: ::c_int = 2;
3431+
/// Western European dst
3432+
pub const DST_WET: ::c_int = 3;
3433+
/// Middle European dst
3434+
pub const DST_MET: ::c_int = 4;
3435+
/// Eastern European dst
3436+
pub const DST_EET: ::c_int = 5;
3437+
/// Canada
3438+
pub const DST_CAN: ::c_int = 6;
3439+
3440+
pub const CPUCLOCK_WHICH_PID: ::c_int = 0;
3441+
pub const CPUCLOCK_WHICH_TID: ::c_int = 1;
3442+
31283443
const_fn! {
31293444
{const} fn _ALIGN(p: usize) -> usize {
31303445
(p + _ALIGNBYTES) & !_ALIGNBYTES
@@ -3597,6 +3912,9 @@ extern "C" {
35973912
pub fn procctl(idtype: ::idtype_t, id: ::id_t, cmd: ::c_int, data: *mut ::c_void) -> ::c_int;
35983913

35993914
pub fn getpagesize() -> ::c_int;
3915+
3916+
pub fn adjtime(arg1: *const ::timeval, arg2: *mut ::timeval) -> ::c_int;
3917+
pub fn clock_getcpuclockid2(arg1: ::id_t, arg2: ::c_int, arg3: *mut clockid_t) -> ::c_int;
36003918
}
36013919

36023920
#[link(name = "kvm")]
@@ -3808,6 +4126,43 @@ extern "C" {
38084126
) -> ::c_int;
38094127
}
38104128

4129+
#[link(name = "devstat")]
4130+
extern "C" {
4131+
pub fn devstat_getnumdevs(kd: *mut kvm_t) -> ::c_int;
4132+
pub fn devstat_getgeneration(kd: *mut kvm_t) -> ::c_long;
4133+
pub fn devstat_getversion(kd: *mut kvm_t) -> ::c_int;
4134+
pub fn devstat_checkversion(kd: *mut kvm_t) -> ::c_int;
4135+
pub fn devstat_getdevs(kd: *mut kvm_t, stats: *mut statinfo) -> ::c_int;
4136+
pub fn devstat_selectdevs(
4137+
dev_select: *mut *mut device_selection,
4138+
num_selected: *mut ::c_int,
4139+
num_selections: *mut ::c_int,
4140+
select_generation: *mut ::c_long,
4141+
current_generation: ::c_long,
4142+
devices: *mut devstat,
4143+
numdevs: ::c_int,
4144+
matches: *mut devstat_match,
4145+
num_matches: ::c_int,
4146+
dev_selections: *mut *mut ::c_char,
4147+
num_dev_selections: ::c_int,
4148+
select_mode: devstat_select_mode,
4149+
maxshowdevs: ::c_int,
4150+
perf_select: ::c_int,
4151+
) -> ::c_int;
4152+
pub fn devstat_buildmatch(
4153+
match_str: *mut ::c_char,
4154+
matches: *mut *mut devstat_match,
4155+
num_matches: *mut ::c_int,
4156+
) -> ::c_int;
4157+
pub fn devstat_compute_statistics(
4158+
current: *mut devstat,
4159+
previous: *mut devstat,
4160+
etime: c_longdouble,
4161+
...
4162+
) -> ::c_int;
4163+
pub fn devstat_compute_etime(cur_time: *mut bintime, prev_time: *mut bintime) -> c_longdouble;
4164+
}
4165+
38114166
cfg_if! {
38124167
if #[cfg(freebsd14)] {
38134168
mod freebsd14;

0 commit comments

Comments
 (0)
Please sign in to comment.