Skip to content

Commit 238d71b

Browse files
Add devstat items
1 parent 72cf180 commit 238d71b

File tree

2 files changed

+293
-0
lines changed

2 files changed

+293
-0
lines changed

libc-test/build.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,6 +1875,7 @@ fn test_freebsd(target: &str) {
18751875
"sys/vmmeter.h",
18761876
"sys/wait.h",
18771877
"libprocstat.h",
1878+
"devstat.h",
18781879
"syslog.h",
18791880
"termios.h",
18801881
"time.h",
@@ -1918,6 +1919,7 @@ fn test_freebsd(target: &str) {
19181919
// Field is named `type` in C but that is a Rust keyword,
19191920
// so these fields are translated to `type_` in the bindings.
19201921
"type_" if struct_ == "rtprio" => "type".to_string(),
1922+
"type_" if struct_ == "devstat_match_table" => "type".to_string(),
19211923
s => s.to_string(),
19221924
}
19231925
});
@@ -2157,6 +2159,10 @@ fn test_freebsd(target: &str) {
21572159
// https://github.com/gnzlbg/ctest/issues/68
21582160
"lio_listio" => true,
21592161

2162+
// It returns a `long double`, but it's a nightmare to bind correctly in rust
2163+
// for the moment, so it's a best effort thing...
2164+
"devstat_compute_etime" => true,
2165+
21602166
_ => false,
21612167
}
21622168
});
@@ -2224,6 +2230,11 @@ fn test_freebsd(target: &str) {
22242230

22252231
// `__sem_base` is a private struct field
22262232
("semid_ds", "__sem_base") => true,
2233+
2234+
// `snap_time` is a `long double`, but it's a nightmare to bind correctly in rust
2235+
// for the moment, so it's a best effort thing...
2236+
("statinfo", "snap_time") => true,
2237+
22272238
_ => false,
22282239
}
22292240
});

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

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,143 @@ pub type u_char = ::c_uchar;
3737
pub type u_long = ::c_ulong;
3838
pub type u_short = ::c_ushort;
3939

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

54+
e! {
55+
pub enum devstat_support_flags {
56+
DEVSTAT_ALL_SUPPORTED = 0x00,
57+
DEVSTAT_NO_BLOCKSIZE = 0x01,
58+
DEVSTAT_NO_ORDERED_TAGS = 0x02,
59+
DEVSTAT_BS_UNAVAILABLE = 0x04,
60+
}
61+
62+
pub enum devstat_trans_flags {
63+
DEVSTAT_NO_DATA = 0x00,
64+
DEVSTAT_READ = 0x01,
65+
DEVSTAT_WRITE = 0x02,
66+
DEVSTAT_FREE = 0x03,
67+
}
68+
69+
pub enum devstat_tag_type {
70+
DEVSTAT_TAG_SIMPLE = 0x00,
71+
DEVSTAT_TAG_HEAD = 0x01,
72+
DEVSTAT_TAG_ORDERED = 0x02,
73+
DEVSTAT_TAG_NONE = 0x03,
74+
}
75+
76+
pub enum devstat_match_flags {
77+
DEVSTAT_MATCH_NONE = 0x00,
78+
DEVSTAT_MATCH_TYPE = 0x01,
79+
DEVSTAT_MATCH_IF = 0x02,
80+
DEVSTAT_MATCH_PASS = 0x04,
81+
}
82+
83+
pub enum devstat_priority {
84+
DEVSTAT_PRIORITY_MIN = 0x000,
85+
DEVSTAT_PRIORITY_OTHER = 0x020,
86+
DEVSTAT_PRIORITY_PASS = 0x030,
87+
DEVSTAT_PRIORITY_FD = 0x040,
88+
DEVSTAT_PRIORITY_WFD = 0x050,
89+
DEVSTAT_PRIORITY_TAPE = 0x060,
90+
DEVSTAT_PRIORITY_CD = 0x090,
91+
DEVSTAT_PRIORITY_DISK = 0x110,
92+
DEVSTAT_PRIORITY_ARRAY = 0x120,
93+
DEVSTAT_PRIORITY_MAX = 0xfff,
94+
}
95+
96+
pub enum devstat_type_flags {
97+
DEVSTAT_TYPE_DIRECT = 0x000,
98+
DEVSTAT_TYPE_SEQUENTIAL = 0x001,
99+
DEVSTAT_TYPE_PRINTER = 0x002,
100+
DEVSTAT_TYPE_PROCESSOR = 0x003,
101+
DEVSTAT_TYPE_WORM = 0x004,
102+
DEVSTAT_TYPE_CDROM = 0x005,
103+
DEVSTAT_TYPE_SCANNER = 0x006,
104+
DEVSTAT_TYPE_OPTICAL = 0x007,
105+
DEVSTAT_TYPE_CHANGER = 0x008,
106+
DEVSTAT_TYPE_COMM = 0x009,
107+
DEVSTAT_TYPE_ASC0 = 0x00a,
108+
DEVSTAT_TYPE_ASC1 = 0x00b,
109+
DEVSTAT_TYPE_STORARRAY = 0x00c,
110+
DEVSTAT_TYPE_ENCLOSURE = 0x00d,
111+
DEVSTAT_TYPE_FLOPPY = 0x00e,
112+
DEVSTAT_TYPE_MASK = 0x00f,
113+
DEVSTAT_TYPE_IF_SCSI = 0x010,
114+
DEVSTAT_TYPE_IF_IDE = 0x020,
115+
DEVSTAT_TYPE_IF_OTHER = 0x030,
116+
DEVSTAT_TYPE_IF_MASK = 0x0f0,
117+
DEVSTAT_TYPE_PASS = 0x100,
118+
}
119+
120+
pub enum devstat_metric {
121+
DSM_NONE,
122+
DSM_TOTAL_BYTES,
123+
DSM_TOTAL_BYTES_READ,
124+
DSM_TOTAL_BYTES_WRITE,
125+
DSM_TOTAL_TRANSFERS,
126+
DSM_TOTAL_TRANSFERS_READ,
127+
DSM_TOTAL_TRANSFERS_WRITE,
128+
DSM_TOTAL_TRANSFERS_OTHER,
129+
DSM_TOTAL_BLOCKS,
130+
DSM_TOTAL_BLOCKS_READ,
131+
DSM_TOTAL_BLOCKS_WRITE,
132+
DSM_KB_PER_TRANSFER,
133+
DSM_KB_PER_TRANSFER_READ,
134+
DSM_KB_PER_TRANSFER_WRITE,
135+
DSM_TRANSFERS_PER_SECOND,
136+
DSM_TRANSFERS_PER_SECOND_READ,
137+
DSM_TRANSFERS_PER_SECOND_WRITE,
138+
DSM_TRANSFERS_PER_SECOND_OTHER,
139+
DSM_MB_PER_SECOND,
140+
DSM_MB_PER_SECOND_READ,
141+
DSM_MB_PER_SECOND_WRITE,
142+
DSM_BLOCKS_PER_SECOND,
143+
DSM_BLOCKS_PER_SECOND_READ,
144+
DSM_BLOCKS_PER_SECOND_WRITE,
145+
DSM_MS_PER_TRANSACTION,
146+
DSM_MS_PER_TRANSACTION_READ,
147+
DSM_MS_PER_TRANSACTION_WRITE,
148+
DSM_SKIP,
149+
DSM_TOTAL_BYTES_FREE,
150+
DSM_TOTAL_TRANSFERS_FREE,
151+
DSM_TOTAL_BLOCKS_FREE,
152+
DSM_KB_PER_TRANSFER_FREE,
153+
DSM_MB_PER_SECOND_FREE,
154+
DSM_TRANSFERS_PER_SECOND_FREE,
155+
DSM_BLOCKS_PER_SECOND_FREE,
156+
DSM_MS_PER_TRANSACTION_OTHER,
157+
DSM_MS_PER_TRANSACTION_FREE,
158+
DSM_BUSY_PCT,
159+
DSM_QUEUE_LENGTH,
160+
DSM_TOTAL_DURATION,
161+
DSM_TOTAL_DURATION_READ,
162+
DSM_TOTAL_DURATION_WRITE,
163+
DSM_TOTAL_DURATION_FREE,
164+
DSM_TOTAL_DURATION_OTHER,
165+
DSM_TOTAL_BUSY_TIME,
166+
DSM_MAX,
167+
}
168+
169+
pub enum devstat_select_mode {
170+
DS_SELECT_ADD,
171+
DS_SELECT_ONLY,
172+
DS_SELECT_REMOVE,
173+
DS_SELECT_ADDONLY,
174+
}
175+
}
176+
44177
s! {
45178
pub struct aiocb {
46179
pub aio_fildes: ::c_int,
@@ -380,6 +513,97 @@ s! {
380513
pub rux_su: u64,
381514
pub rux_tu: u64,
382515
}
516+
517+
pub struct bintime {
518+
pub sec: ::time_t,
519+
pub frac: u64,
520+
}
521+
522+
pub struct clockinfo {
523+
/// clock frequency
524+
pub hz: ::c_int,
525+
/// micro-seconds per hz tick
526+
pub tick: ::c_int,
527+
pub spare: ::c_int,
528+
/// statistics clock frequency
529+
pub stathz: ::c_int,
530+
/// profiling clock frequency
531+
pub profhz: ::c_int,
532+
}
533+
534+
pub struct devstat {
535+
/// Update sequence
536+
pub sequence0: ::u_int,
537+
/// Allocated entry
538+
pub allocated: ::c_int,
539+
/// started ops
540+
pub start_count: ::u_int,
541+
/// completed ops
542+
pub end_count: ::u_int,
543+
/// busy time unaccounted for since this time
544+
pub busy_from: bintime,
545+
pub dev_links: *mut devstat,
546+
/// Devstat device number.
547+
pub device_number: u32,
548+
pub device_name: [::c_char; DEVSTAT_NAME_LEN as usize],
549+
pub unit_number: ::c_int,
550+
pub bytes: [u64; DEVSTAT_N_TRANS_FLAGS as usize],
551+
pub operations: [u64; DEVSTAT_N_TRANS_FLAGS as usize],
552+
pub duration: [bintime; DEVSTAT_N_TRANS_FLAGS as usize],
553+
pub busy_time: bintime,
554+
/// Time the device was created.
555+
pub creation_time: bintime,
556+
/// Block size, bytes
557+
pub block_size: u32,
558+
/// The number of simple, ordered, and head of queue tags sent.
559+
pub tag_types: [u64; 3],
560+
/// Which statistics are supported by a given device.
561+
pub flags: devstat_support_flags,
562+
/// Device type
563+
pub device_type: devstat_type_flags,
564+
/// Controls list pos.
565+
pub priority: devstat_priority,
566+
/// Identification for GEOM nodes
567+
pub id: *const ::c_void,
568+
/// Update sequence
569+
pub sequence1: ::u_int,
570+
}
571+
572+
pub struct devstat_match {
573+
pub match_fields: devstat_match_flags,
574+
pub device_type: devstat_type_flags,
575+
pub num_match_categories: ::c_int,
576+
}
577+
578+
pub struct devstat_match_table {
579+
pub match_str: *const ::c_char,
580+
pub type_: devstat_type_flags,
581+
pub match_field: devstat_match_flags,
582+
}
583+
584+
pub struct device_selection {
585+
pub device_number: u32,
586+
pub device_name: [::c_char; DEVSTAT_NAME_LEN as usize],
587+
pub unit_number: ::c_int,
588+
pub selected: ::c_int,
589+
pub bytes: u64,
590+
pub position: ::c_int,
591+
}
592+
593+
pub struct devinfo {
594+
pub devices: *mut devstat,
595+
pub mem_ptr: *mut u8,
596+
pub generation: ::c_long,
597+
pub numdevs: ::c_int,
598+
}
599+
600+
pub struct statinfo {
601+
pub cp_time: [::c_long; CPUSTATES as usize],
602+
pub tk_nin: ::c_long,
603+
pub tk_nout: ::c_long,
604+
pub dinfo: *mut devinfo,
605+
pub snap_time: c_long_double,
606+
}
383607
}
384608

385609
s_no_extra_traits! {
@@ -722,6 +946,10 @@ cfg_if! {
722946
}
723947
}
724948

949+
// sys/devicestat.h
950+
pub const DEVSTAT_N_TRANS_FLAGS: ::c_int = 4;
951+
pub const DEVSTAT_NAME_LEN: ::c_int = 16;
952+
725953
pub const SIGEV_THREAD_ID: ::c_int = 4;
726954

727955
pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0;
@@ -2119,6 +2347,26 @@ pub const P2_ASLR_DISABLE: ::c_int = 0x00000080;
21192347
pub const P2_ASLR_IGNSTART: ::c_int = 0x00000100;
21202348
pub const P_TREE_GRPEXITED: ::c_int = 0x00000008;
21212349

2350+
// time.h
2351+
2352+
/// not on dst
2353+
pub const DST_NONE: ::c_int = 0;
2354+
/// USA style dst
2355+
pub const DST_USA: ::c_int = 1;
2356+
/// Australian style dst
2357+
pub const DST_AUST: ::c_int = 2;
2358+
/// Western European dst
2359+
pub const DST_WET: ::c_int = 3;
2360+
/// Middle European dst
2361+
pub const DST_MET: ::c_int = 4;
2362+
/// Eastern European dst
2363+
pub const DST_EET: ::c_int = 5;
2364+
/// Canada
2365+
pub const DST_CAN: ::c_int = 6;
2366+
2367+
pub const CPUCLOCK_WHICH_PID: ::c_int = 0;
2368+
pub const CPUCLOCK_WHICH_TID: ::c_int = 1;
2369+
21222370
const_fn! {
21232371
{const} fn _ALIGN(p: usize) -> usize {
21242372
(p + _ALIGNBYTES) & !_ALIGNBYTES
@@ -2591,6 +2839,9 @@ extern "C" {
25912839
pub fn procctl(idtype: ::idtype_t, id: ::id_t, cmd: ::c_int, data: *mut ::c_void) -> ::c_int;
25922840

25932841
pub fn getpagesize() -> ::c_int;
2842+
2843+
pub fn adjtime(arg1: *const ::timeval, arg2: *mut ::timeval) -> ::c_int;
2844+
pub fn clock_getcpuclockid2(arg1: ::id_t, arg2: ::c_int, arg3: *mut clockid_t) -> ::c_int;
25942845
}
25952846

25962847
#[link(name = "kvm")]
@@ -2735,6 +2986,37 @@ extern "C" {
27352986
) -> ::c_int;
27362987
}
27372988

2989+
#[link(name = "devstat")]
2990+
extern "C" {
2991+
pub fn devstat_getnumdevs(kd: *mut kvm_t) -> ::c_int;
2992+
pub fn devstat_getgeneration(kd: *mut kvm_t) -> ::c_long;
2993+
pub fn devstat_getversion(kd: *mut kvm_t) -> ::c_int;
2994+
pub fn devstat_checkversion(kd: *mut kvm_t) -> ::c_int;
2995+
pub fn devstat_getdevs(kd: *mut kvm_t, stats: *mut statinfo) -> ::c_int;
2996+
pub fn devstat_selectdevs(
2997+
dev_select: *mut *mut device_selection,
2998+
num_selected: *mut ::c_int,
2999+
num_selections: *mut ::c_int,
3000+
select_generation: *mut ::c_long,
3001+
current_generation: ::c_long,
3002+
devices: *mut devstat,
3003+
numdevs: ::c_int,
3004+
matches: *mut devstat_match,
3005+
num_matches: ::c_int,
3006+
dev_selections: *mut *mut ::c_char,
3007+
num_dev_selections: ::c_int,
3008+
select_mode: devstat_select_mode,
3009+
maxshowdevs: ::c_int,
3010+
perf_select: ::c_int,
3011+
) -> ::c_int;
3012+
pub fn devstat_buildmatch(
3013+
match_str: *mut ::c_char,
3014+
matches: *mut *mut devstat_match,
3015+
num_matches: *mut ::c_int,
3016+
) -> ::c_int;
3017+
pub fn devstat_compute_etime(cur_time: *mut bintime, prev_time: *mut bintime) -> c_long_double;
3018+
}
3019+
27383020
cfg_if! {
27393021
if #[cfg(freebsd14)] {
27403022
mod freebsd14;

0 commit comments

Comments
 (0)