Skip to content

Commit 8e7db86

Browse files
Add devstat items
1 parent 72cf180 commit 8e7db86

File tree

2 files changed

+301
-0
lines changed

2 files changed

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

385617
s_no_extra_traits! {
@@ -722,6 +954,10 @@ cfg_if! {
722954
}
723955
}
724956

957+
// sys/devicestat.h
958+
pub const DEVSTAT_N_TRANS_FLAGS: ::c_int = 4;
959+
pub const DEVSTAT_NAME_LEN: ::c_int = 16;
960+
725961
pub const SIGEV_THREAD_ID: ::c_int = 4;
726962

727963
pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0;
@@ -2119,6 +2355,26 @@ pub const P2_ASLR_DISABLE: ::c_int = 0x00000080;
21192355
pub const P2_ASLR_IGNSTART: ::c_int = 0x00000100;
21202356
pub const P_TREE_GRPEXITED: ::c_int = 0x00000008;
21212357

2358+
// time.h
2359+
2360+
/// not on dst
2361+
pub const DST_NONE: ::c_int = 0;
2362+
/// USA style dst
2363+
pub const DST_USA: ::c_int = 1;
2364+
/// Australian style dst
2365+
pub const DST_AUST: ::c_int = 2;
2366+
/// Western European dst
2367+
pub const DST_WET: ::c_int = 3;
2368+
/// Middle European dst
2369+
pub const DST_MET: ::c_int = 4;
2370+
/// Eastern European dst
2371+
pub const DST_EET: ::c_int = 5;
2372+
/// Canada
2373+
pub const DST_CAN: ::c_int = 6;
2374+
2375+
pub const CPUCLOCK_WHICH_PID: ::c_int = 0;
2376+
pub const CPUCLOCK_WHICH_TID: ::c_int = 1;
2377+
21222378
const_fn! {
21232379
{const} fn _ALIGN(p: usize) -> usize {
21242380
(p + _ALIGNBYTES) & !_ALIGNBYTES
@@ -2591,6 +2847,9 @@ extern "C" {
25912847
pub fn procctl(idtype: ::idtype_t, id: ::id_t, cmd: ::c_int, data: *mut ::c_void) -> ::c_int;
25922848

25932849
pub fn getpagesize() -> ::c_int;
2850+
2851+
pub fn adjtime(arg1: *const ::timeval, arg2: *mut ::timeval) -> ::c_int;
2852+
pub fn clock_getcpuclockid2(arg1: ::id_t, arg2: ::c_int, arg3: *mut clockid_t) -> ::c_int;
25942853
}
25952854

25962855
#[link(name = "kvm")]
@@ -2735,6 +2994,37 @@ extern "C" {
27352994
) -> ::c_int;
27362995
}
27372996

2997+
#[link(name = "devstat")]
2998+
extern "C" {
2999+
pub fn devstat_getnumdevs(kd: *mut kvm_t) -> ::c_int;
3000+
pub fn devstat_getgeneration(kd: *mut kvm_t) -> ::c_long;
3001+
pub fn devstat_getversion(kd: *mut kvm_t) -> ::c_int;
3002+
pub fn devstat_checkversion(kd: *mut kvm_t) -> ::c_int;
3003+
pub fn devstat_getdevs(kd: *mut kvm_t, stats: *mut statinfo) -> ::c_int;
3004+
pub fn devstat_selectdevs(
3005+
dev_select: *mut *mut device_selection,
3006+
num_selected: *mut ::c_int,
3007+
num_selections: *mut ::c_int,
3008+
select_generation: *mut ::c_long,
3009+
current_generation: ::c_long,
3010+
devices: *mut devstat,
3011+
numdevs: ::c_int,
3012+
matches: *mut devstat_match,
3013+
num_matches: ::c_int,
3014+
dev_selections: *mut *mut ::c_char,
3015+
num_dev_selections: ::c_int,
3016+
select_mode: devstat_select_mode,
3017+
maxshowdevs: ::c_int,
3018+
perf_select: ::c_int,
3019+
) -> ::c_int;
3020+
pub fn devstat_buildmatch(
3021+
match_str: *mut ::c_char,
3022+
matches: *mut *mut devstat_match,
3023+
num_matches: *mut ::c_int,
3024+
) -> ::c_int;
3025+
pub fn devstat_compute_etime(cur_time: *mut bintime, prev_time: *mut bintime) -> c_longdouble;
3026+
}
3027+
27383028
cfg_if! {
27393029
if #[cfg(freebsd14)] {
27403030
mod freebsd14;

0 commit comments

Comments
 (0)