@@ -14,6 +14,7 @@ use std::{
14
14
15
15
use aya_obj:: generated:: { TC_H_MAJ_MASK , TC_H_MIN_MASK } ;
16
16
use libc:: { if_nametoindex, sysconf, uname, utsname, _SC_PAGESIZE} ;
17
+ use log:: warn;
17
18
18
19
use crate :: Pod ;
19
20
@@ -48,7 +49,35 @@ impl KernelVersion {
48
49
49
50
/// Returns the kernel version of the currently running kernel.
50
51
pub fn current ( ) -> Result < Self , impl Error > {
51
- Self :: get_kernel_version ( )
52
+ thread_local ! {
53
+ // TODO(https://github.com/rust-lang/rust/issues/109737): Use
54
+ // `std::cell::OnceCell` when `get_or_try_init` is stabilized.
55
+ static CACHE : once_cell:: unsync:: OnceCell <KernelVersion > = const { once_cell:: unsync:: OnceCell :: new( ) } ;
56
+ }
57
+ CACHE . with ( |cell| {
58
+ // TODO(https://github.com/rust-lang/rust/issues/109737): Replace `once_cell` with
59
+ // `std::cell::OnceCell`.
60
+ cell. get_or_try_init ( || {
61
+ // error: unsupported operation: `open` not available when isolation is enabled
62
+ if cfg ! ( miri) {
63
+ Ok ( Self :: new ( 0xff , 0xff , 0xff ) )
64
+ } else {
65
+ Self :: get_kernel_version ( )
66
+ }
67
+ } )
68
+ . copied ( )
69
+ } )
70
+ }
71
+
72
+ /// Returns true iff the current kernel version is greater than or equal to the given version.
73
+ pub ( crate ) fn at_least ( major : u8 , minor : u8 , patch : u16 ) -> bool {
74
+ match Self :: current ( ) {
75
+ Ok ( current) => current >= Self :: new ( major, minor, patch) ,
76
+ Err ( error) => {
77
+ warn ! ( "failed to get current kernel version: {error}" ) ;
78
+ false
79
+ }
80
+ }
52
81
}
53
82
54
83
/// The equivalent of LINUX_VERSION_CODE.
0 commit comments