xref: /aosp_15_r20/external/crosvm/base/src/lib.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2020 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! Safe, cross-platform-compatible wrappers for system interfaces.
6 
7 mod alloc;
8 mod clock;
9 pub mod custom_serde;
10 pub mod descriptor;
11 pub mod descriptor_reflection;
12 mod errno;
13 mod event;
14 mod file_traits;
15 mod iobuf;
16 mod mmap;
17 mod notifiers;
18 mod periodic_logger;
19 mod shm;
20 pub mod syslog;
21 pub mod test_utils;
22 mod timer;
23 mod tube;
24 mod volatile_memory;
25 mod wait_context;
26 mod worker_thread;
27 mod write_zeroes;
28 
29 pub mod sys;
30 pub use alloc::LayoutAllocation;
31 
32 pub use clock::Clock;
33 pub use clock::FakeClock;
34 pub use errno::errno_result;
35 pub use errno::Error;
36 pub use errno::Result;
37 pub use event::Event;
38 pub use event::EventWaitResult;
39 pub use file_traits::FileAllocate;
40 pub use file_traits::FileGetLen;
41 pub use file_traits::FileReadWriteAtVolatile;
42 pub use file_traits::FileReadWriteVolatile;
43 pub use file_traits::FileSetLen;
44 pub use file_traits::FileSync;
45 pub use iobuf::IoBufMut;
46 pub use mmap::Error as MmapError;
47 pub use mmap::ExternalMapping;
48 pub use mmap::MappedRegion;
49 pub use mmap::MemoryMapping;
50 pub use mmap::MemoryMappingBuilder;
51 pub use mmap::Result as MmapResult;
52 pub use notifiers::CloseNotifier;
53 pub use notifiers::ReadNotifier;
54 pub use platform::ioctl::ioctl;
55 pub use platform::ioctl::ioctl_with_mut_ptr;
56 pub use platform::ioctl::ioctl_with_mut_ref;
57 pub use platform::ioctl::ioctl_with_ptr;
58 pub use platform::ioctl::ioctl_with_ref;
59 pub use platform::ioctl::ioctl_with_val;
60 pub use platform::ioctl::IoctlNr;
61 pub use shm::SharedMemory;
62 use sys::platform;
63 pub use timer::FakeTimer;
64 pub use timer::Timer;
65 pub use timer::TimerTrait;
66 pub use tube::Error as TubeError;
67 #[cfg(any(windows, feature = "proto_tube"))]
68 pub use tube::ProtoTube;
69 pub use tube::RecvTube;
70 pub use tube::Result as TubeResult;
71 pub use tube::SendTube;
72 pub use tube::Tube;
73 pub use volatile_memory::VolatileMemory;
74 pub use volatile_memory::VolatileMemoryError;
75 pub use volatile_memory::VolatileMemoryResult;
76 pub use volatile_memory::VolatileSlice;
77 pub use wait_context::EventToken;
78 pub use wait_context::EventType;
79 pub use wait_context::TriggeredEvent;
80 pub use wait_context::WaitContext;
81 pub use worker_thread::WorkerThread;
82 pub use write_zeroes::PunchHole;
83 pub use write_zeroes::WriteZeroesAt;
84 
85 // TODO(b/233233301): reorganize platform specific exports under platform
86 // namespaces instead of exposing them directly in base::.
87 cfg_if::cfg_if! {
88     if #[cfg(any(target_os = "android", target_os = "linux"))] {
89         pub use sys::linux;
90 
91         // descriptor/fd related exports.
92         pub use linux::{
93             clone_descriptor, safe_descriptor_from_path,
94             validate_raw_descriptor, clear_descriptor_cloexec,
95             safe_descriptor_from_cmdline_fd,
96         };
97 
98         // Event/signal related exports.
99         pub use linux::{
100             block_signal, clear_signal, get_blocked_signals, new_pipe_full,
101             register_rt_signal_handler, signal, unblock_signal, Killable, SIGRTMIN,
102             AcpiNotifyEvent, NetlinkGenericSocket, SignalFd, Terminal,
103         };
104 
105         pub use linux::{
106             drop_capabilities, pipe, read_raw_stdin
107         };
108         pub use linux::{enable_core_scheduling, set_rt_prio_limit, set_rt_round_robin};
109         pub use linux::{flock, FlockOperation};
110         pub use linux::{getegid, geteuid};
111         pub use linux::{gettid, kill_process_group, reap_child};
112         pub use linux::logical_core_capacity;
113         pub use linux::logical_core_cluster_id;
114         pub use linux::logical_core_frequencies_khz;
115         pub use linux::logical_core_max_freq_khz;
116         pub use linux::sched_attr;
117         pub use linux::sched_setattr;
118         pub use linux::UnlinkUnixListener;
119         pub use linux::EventExt;
120         pub use linux::Gid;
121     }
122 }
123 
124 cfg_if::cfg_if! {
125      if #[cfg(windows)] {
126         pub use sys::windows;
127 
128         pub use windows::{EventTrigger, EventExt, WaitContextExt};
129         pub use windows::IoBuf;
130         pub use windows::MemoryMappingBuilderWindows;
131         pub use windows::set_thread_priority;
132         pub use windows::{give_foregrounding_permission, Console};
133         pub use windows::{named_pipes, named_pipes::PipeConnection};
134         pub use windows::{SafeMultimediaHandle, MAXIMUM_WAIT_OBJECTS};
135         pub use windows::set_sparse_file;
136         pub use windows::ioctl::ioctl_with_ptr_sized;
137         pub use windows::create_overlapped;
138         pub use windows::device_io_control;
139         pub use windows::number_of_logical_cores;
140         pub use windows::pagesize;
141         pub use windows::read_overlapped_blocking;
142 
143         pub use tube::{
144             deserialize_and_recv, serialize_and_send, set_alias_pid, set_duplicate_handle_tube,
145             DuplicateHandleRequest, DuplicateHandleResponse, DuplicateHandleTube
146         };
147         pub use tube::PipeTube;
148         pub use tube::FlushOnDropTube;
149         pub use windows::{set_audio_thread_priority, thread};
150         pub use windows::Pid;
151         pub use windows::Terminal;
152     }
153 }
154 
155 cfg_if::cfg_if! {
156     if #[cfg(unix)] {
157         pub use sys::unix;
158 
159         pub use unix::IoBuf;
160         pub use unix::net::UnixSeqpacket;
161         pub use unix::net::UnixSeqpacketListener;
162         pub use unix::net::UnlinkUnixSeqpacketListener;
163         pub use unix::ScmSocket;
164         pub use unix::SCM_SOCKET_MAX_FD_COUNT;
165         pub use unix::add_fd_flags;
166         pub use unix::clear_fd_flags;
167         pub use unix::number_of_logical_cores;
168         pub use unix::pagesize;
169         pub use unix::Pid;
170     }
171 }
172 
173 pub use descriptor_reflection::deserialize_with_descriptors;
174 pub use descriptor_reflection::with_as_descriptor;
175 pub use descriptor_reflection::with_raw_descriptor;
176 pub use descriptor_reflection::FileSerdeWrapper;
177 pub use descriptor_reflection::SerializeDescriptors;
178 pub use log::debug;
179 pub use log::error;
180 pub use log::info;
181 pub use log::trace;
182 pub use log::warn;
183 pub use mmap::Protection;
184 pub use platform::get_cpu_affinity;
185 pub use platform::getpid;
186 pub use platform::open_file_or_duplicate;
187 pub use platform::platform_timer_resolution::enable_high_res_timers;
188 pub use platform::set_cpu_affinity;
189 pub use platform::set_thread_name;
190 pub use platform::BlockingMode;
191 pub use platform::EventContext;
192 pub use platform::FramingMode;
193 pub use platform::MemoryMappingArena;
194 pub use platform::RawDescriptor;
195 pub use platform::StreamChannel;
196 pub use platform::INVALID_DESCRIPTOR;
197 use uuid::Uuid;
198 
199 pub use crate::descriptor::AsRawDescriptor;
200 pub use crate::descriptor::AsRawDescriptors;
201 pub use crate::descriptor::Descriptor;
202 pub use crate::descriptor::FromRawDescriptor;
203 pub use crate::descriptor::IntoRawDescriptor;
204 pub use crate::descriptor::SafeDescriptor;
205 
206 /// An empty trait that helps reset timer resolution to its previous state.
207 // TODO(b:232103460): Maybe this needs to be thought through.
208 pub trait EnabledHighResTimer {}
209 
210 /// Creates a UUID.
generate_uuid() -> String211 pub fn generate_uuid() -> String {
212     let mut buf = Uuid::encode_buffer();
213     Uuid::new_v4()
214         .as_hyphenated()
215         .encode_lower(&mut buf)
216         .to_owned()
217 }
218 
219 use serde::Deserialize;
220 use serde::Serialize;
221 #[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
222 pub enum VmEventType {
223     Exit,
224     Reset,
225     Crash,
226     Panic(u8),
227     WatchdogReset,
228 }
229 
230 /// Uses the system's page size in bytes to round the given value up to the nearest page boundary.
231 #[inline(always)]
round_up_to_page_size(v: usize) -> usize232 pub fn round_up_to_page_size(v: usize) -> usize {
233     let page_mask = pagesize() - 1;
234     (v + page_mask) & !page_mask
235 }
236