xref: /aosp_15_r20/external/crosvm/base/src/sys/linux/mod.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2017 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker //! Small system utility modules for usage by other modules.
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_os = "android")]
8*bb4ee6a4SAndroid Build Coastguard Worker mod android;
9*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_os = "android")]
10*bb4ee6a4SAndroid Build Coastguard Worker use android as target_os;
11*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_os = "linux")]
12*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::module_inception)]
13*bb4ee6a4SAndroid Build Coastguard Worker mod linux;
14*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_os = "linux")]
15*bb4ee6a4SAndroid Build Coastguard Worker use linux as target_os;
16*bb4ee6a4SAndroid Build Coastguard Worker use log::warn;
17*bb4ee6a4SAndroid Build Coastguard Worker #[macro_use]
18*bb4ee6a4SAndroid Build Coastguard Worker pub mod ioctl;
19*bb4ee6a4SAndroid Build Coastguard Worker #[macro_use]
20*bb4ee6a4SAndroid Build Coastguard Worker pub mod syslog;
21*bb4ee6a4SAndroid Build Coastguard Worker mod acpi_event;
22*bb4ee6a4SAndroid Build Coastguard Worker mod capabilities;
23*bb4ee6a4SAndroid Build Coastguard Worker mod descriptor;
24*bb4ee6a4SAndroid Build Coastguard Worker mod event;
25*bb4ee6a4SAndroid Build Coastguard Worker mod file;
26*bb4ee6a4SAndroid Build Coastguard Worker mod file_traits;
27*bb4ee6a4SAndroid Build Coastguard Worker mod mmap;
28*bb4ee6a4SAndroid Build Coastguard Worker mod net;
29*bb4ee6a4SAndroid Build Coastguard Worker mod netlink;
30*bb4ee6a4SAndroid Build Coastguard Worker mod notifiers;
31*bb4ee6a4SAndroid Build Coastguard Worker pub mod platform_timer_resolution;
32*bb4ee6a4SAndroid Build Coastguard Worker mod poll;
33*bb4ee6a4SAndroid Build Coastguard Worker mod priority;
34*bb4ee6a4SAndroid Build Coastguard Worker mod sched;
35*bb4ee6a4SAndroid Build Coastguard Worker mod shm;
36*bb4ee6a4SAndroid Build Coastguard Worker pub mod signal;
37*bb4ee6a4SAndroid Build Coastguard Worker mod signalfd;
38*bb4ee6a4SAndroid Build Coastguard Worker mod terminal;
39*bb4ee6a4SAndroid Build Coastguard Worker mod timer;
40*bb4ee6a4SAndroid Build Coastguard Worker pub mod vsock;
41*bb4ee6a4SAndroid Build Coastguard Worker mod write_zeroes;
42*bb4ee6a4SAndroid Build Coastguard Worker 
43*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::CString;
44*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::remove_file;
45*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::File;
46*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::OpenOptions;
47*bb4ee6a4SAndroid Build Coastguard Worker use std::mem;
48*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::MaybeUninit;
49*bb4ee6a4SAndroid Build Coastguard Worker use std::ops::Deref;
50*bb4ee6a4SAndroid Build Coastguard Worker use std::os::unix::io::FromRawFd;
51*bb4ee6a4SAndroid Build Coastguard Worker use std::os::unix::io::RawFd;
52*bb4ee6a4SAndroid Build Coastguard Worker use std::os::unix::net::UnixDatagram;
53*bb4ee6a4SAndroid Build Coastguard Worker use std::os::unix::net::UnixListener;
54*bb4ee6a4SAndroid Build Coastguard Worker use std::os::unix::process::ExitStatusExt;
55*bb4ee6a4SAndroid Build Coastguard Worker use std::path::Path;
56*bb4ee6a4SAndroid Build Coastguard Worker use std::path::PathBuf;
57*bb4ee6a4SAndroid Build Coastguard Worker use std::process::ExitStatus;
58*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr;
59*bb4ee6a4SAndroid Build Coastguard Worker use std::time::Duration;
60*bb4ee6a4SAndroid Build Coastguard Worker 
61*bb4ee6a4SAndroid Build Coastguard Worker pub use acpi_event::*;
62*bb4ee6a4SAndroid Build Coastguard Worker pub use capabilities::drop_capabilities;
63*bb4ee6a4SAndroid Build Coastguard Worker pub use event::EventExt;
64*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) use event::PlatformEvent;
65*bb4ee6a4SAndroid Build Coastguard Worker pub use file::find_next_data;
66*bb4ee6a4SAndroid Build Coastguard Worker pub use file::FileDataIterator;
67*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) use file_traits::lib::*;
68*bb4ee6a4SAndroid Build Coastguard Worker pub use ioctl::*;
69*bb4ee6a4SAndroid Build Coastguard Worker use libc::c_int;
70*bb4ee6a4SAndroid Build Coastguard Worker use libc::c_long;
71*bb4ee6a4SAndroid Build Coastguard Worker use libc::fcntl;
72*bb4ee6a4SAndroid Build Coastguard Worker use libc::pipe2;
73*bb4ee6a4SAndroid Build Coastguard Worker use libc::prctl;
74*bb4ee6a4SAndroid Build Coastguard Worker use libc::syscall;
75*bb4ee6a4SAndroid Build Coastguard Worker use libc::waitpid;
76*bb4ee6a4SAndroid Build Coastguard Worker use libc::SYS_getpid;
77*bb4ee6a4SAndroid Build Coastguard Worker use libc::SYS_getppid;
78*bb4ee6a4SAndroid Build Coastguard Worker use libc::SYS_gettid;
79*bb4ee6a4SAndroid Build Coastguard Worker use libc::EINVAL;
80*bb4ee6a4SAndroid Build Coastguard Worker use libc::O_CLOEXEC;
81*bb4ee6a4SAndroid Build Coastguard Worker use libc::PR_SET_NAME;
82*bb4ee6a4SAndroid Build Coastguard Worker use libc::SIGKILL;
83*bb4ee6a4SAndroid Build Coastguard Worker use libc::WNOHANG;
84*bb4ee6a4SAndroid Build Coastguard Worker pub use mmap::*;
85*bb4ee6a4SAndroid Build Coastguard Worker pub(in crate::sys) use net::sendmsg_nosignal as sendmsg;
86*bb4ee6a4SAndroid Build Coastguard Worker pub(in crate::sys) use net::sockaddr_un;
87*bb4ee6a4SAndroid Build Coastguard Worker pub(in crate::sys) use net::sockaddrv4_to_lib_c;
88*bb4ee6a4SAndroid Build Coastguard Worker pub(in crate::sys) use net::sockaddrv6_to_lib_c;
89*bb4ee6a4SAndroid Build Coastguard Worker pub use netlink::*;
90*bb4ee6a4SAndroid Build Coastguard Worker use once_cell::sync::OnceCell;
91*bb4ee6a4SAndroid Build Coastguard Worker pub use poll::EventContext;
92*bb4ee6a4SAndroid Build Coastguard Worker pub use priority::*;
93*bb4ee6a4SAndroid Build Coastguard Worker pub use sched::*;
94*bb4ee6a4SAndroid Build Coastguard Worker pub use shm::MemfdSeals;
95*bb4ee6a4SAndroid Build Coastguard Worker pub use shm::SharedMemoryLinux;
96*bb4ee6a4SAndroid Build Coastguard Worker pub use signal::*;
97*bb4ee6a4SAndroid Build Coastguard Worker pub use signalfd::Error as SignalFdError;
98*bb4ee6a4SAndroid Build Coastguard Worker pub use signalfd::*;
99*bb4ee6a4SAndroid Build Coastguard Worker pub use terminal::*;
100*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) use write_zeroes::file_punch_hole;
101*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) use write_zeroes::file_write_zeroes_at;
102*bb4ee6a4SAndroid Build Coastguard Worker 
103*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::FromRawDescriptor;
104*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::SafeDescriptor;
105*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::errno::Error;
106*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::errno::Result;
107*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::errno::*;
108*bb4ee6a4SAndroid Build Coastguard Worker use crate::number_of_logical_cores;
109*bb4ee6a4SAndroid Build Coastguard Worker use crate::round_up_to_page_size;
110*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::sys::unix::descriptor::*;
111*bb4ee6a4SAndroid Build Coastguard Worker use crate::syscall;
112*bb4ee6a4SAndroid Build Coastguard Worker use crate::AsRawDescriptor;
113*bb4ee6a4SAndroid Build Coastguard Worker use crate::Pid;
114*bb4ee6a4SAndroid Build Coastguard Worker 
115*bb4ee6a4SAndroid Build Coastguard Worker /// Re-export libc types that are part of the API.
116*bb4ee6a4SAndroid Build Coastguard Worker pub type Uid = libc::uid_t;
117*bb4ee6a4SAndroid Build Coastguard Worker pub type Gid = libc::gid_t;
118*bb4ee6a4SAndroid Build Coastguard Worker pub type Mode = libc::mode_t;
119*bb4ee6a4SAndroid Build Coastguard Worker 
120*bb4ee6a4SAndroid Build Coastguard Worker /// Safe wrapper for PR_SET_NAME(2const)
121*bb4ee6a4SAndroid Build Coastguard Worker #[inline(always)]
122*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_thread_name(name: &str) -> Result<()> {
123*bb4ee6a4SAndroid Build Coastguard Worker     let name = CString::new(name).or(Err(Error::new(EINVAL)))?;
124*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: prctl copies name and doesn't expect it to outlive this function.
125*bb4ee6a4SAndroid Build Coastguard Worker     let ret = unsafe { prctl(PR_SET_NAME, name.as_c_str()) };
126*bb4ee6a4SAndroid Build Coastguard Worker     if ret == 0 {
127*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
128*bb4ee6a4SAndroid Build Coastguard Worker     } else {
129*bb4ee6a4SAndroid Build Coastguard Worker         errno_result()
130*bb4ee6a4SAndroid Build Coastguard Worker     }
131*bb4ee6a4SAndroid Build Coastguard Worker }
132*bb4ee6a4SAndroid Build Coastguard Worker 
133*bb4ee6a4SAndroid Build Coastguard Worker /// This bypasses `libc`'s caching `getpid(2)` wrapper which can be invalid if a raw clone was used
134*bb4ee6a4SAndroid Build Coastguard Worker /// elsewhere.
135*bb4ee6a4SAndroid Build Coastguard Worker #[inline(always)]
136*bb4ee6a4SAndroid Build Coastguard Worker pub fn getpid() -> Pid {
137*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
138*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because this syscall can never fail and we give it a valid syscall number.
139*bb4ee6a4SAndroid Build Coastguard Worker     unsafe { syscall(SYS_getpid as c_long) as Pid }
140*bb4ee6a4SAndroid Build Coastguard Worker }
141*bb4ee6a4SAndroid Build Coastguard Worker 
142*bb4ee6a4SAndroid Build Coastguard Worker /// Safe wrapper for the geppid Linux systemcall.
143*bb4ee6a4SAndroid Build Coastguard Worker #[inline(always)]
144*bb4ee6a4SAndroid Build Coastguard Worker pub fn getppid() -> Pid {
145*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
146*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because this syscall can never fail and we give it a valid syscall number.
147*bb4ee6a4SAndroid Build Coastguard Worker     unsafe { syscall(SYS_getppid as c_long) as Pid }
148*bb4ee6a4SAndroid Build Coastguard Worker }
149*bb4ee6a4SAndroid Build Coastguard Worker 
150*bb4ee6a4SAndroid Build Coastguard Worker /// Safe wrapper for the gettid Linux systemcall.
151*bb4ee6a4SAndroid Build Coastguard Worker pub fn gettid() -> Pid {
152*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
153*bb4ee6a4SAndroid Build Coastguard Worker     // Calling the gettid() sycall is always safe.
154*bb4ee6a4SAndroid Build Coastguard Worker     unsafe { syscall(SYS_gettid as c_long) as Pid }
155*bb4ee6a4SAndroid Build Coastguard Worker }
156*bb4ee6a4SAndroid Build Coastguard Worker 
157*bb4ee6a4SAndroid Build Coastguard Worker /// Safe wrapper for `geteuid(2)`.
158*bb4ee6a4SAndroid Build Coastguard Worker #[inline(always)]
159*bb4ee6a4SAndroid Build Coastguard Worker pub fn geteuid() -> Uid {
160*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
161*bb4ee6a4SAndroid Build Coastguard Worker     // trivially safe
162*bb4ee6a4SAndroid Build Coastguard Worker     unsafe { libc::geteuid() }
163*bb4ee6a4SAndroid Build Coastguard Worker }
164*bb4ee6a4SAndroid Build Coastguard Worker 
165*bb4ee6a4SAndroid Build Coastguard Worker /// Safe wrapper for `getegid(2)`.
166*bb4ee6a4SAndroid Build Coastguard Worker #[inline(always)]
167*bb4ee6a4SAndroid Build Coastguard Worker pub fn getegid() -> Gid {
168*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
169*bb4ee6a4SAndroid Build Coastguard Worker     // trivially safe
170*bb4ee6a4SAndroid Build Coastguard Worker     unsafe { libc::getegid() }
171*bb4ee6a4SAndroid Build Coastguard Worker }
172*bb4ee6a4SAndroid Build Coastguard Worker 
173*bb4ee6a4SAndroid Build Coastguard Worker /// The operation to perform with `flock`.
174*bb4ee6a4SAndroid Build Coastguard Worker pub enum FlockOperation {
175*bb4ee6a4SAndroid Build Coastguard Worker     LockShared,
176*bb4ee6a4SAndroid Build Coastguard Worker     LockExclusive,
177*bb4ee6a4SAndroid Build Coastguard Worker     Unlock,
178*bb4ee6a4SAndroid Build Coastguard Worker }
179*bb4ee6a4SAndroid Build Coastguard Worker 
180*bb4ee6a4SAndroid Build Coastguard Worker /// Safe wrapper for flock(2) with the operation `op` and optionally `nonblocking`. The lock will be
181*bb4ee6a4SAndroid Build Coastguard Worker /// dropped automatically when `file` is dropped.
182*bb4ee6a4SAndroid Build Coastguard Worker #[inline(always)]
183*bb4ee6a4SAndroid Build Coastguard Worker pub fn flock<F: AsRawDescriptor>(file: &F, op: FlockOperation, nonblocking: bool) -> Result<()> {
184*bb4ee6a4SAndroid Build Coastguard Worker     let mut operation = match op {
185*bb4ee6a4SAndroid Build Coastguard Worker         FlockOperation::LockShared => libc::LOCK_SH,
186*bb4ee6a4SAndroid Build Coastguard Worker         FlockOperation::LockExclusive => libc::LOCK_EX,
187*bb4ee6a4SAndroid Build Coastguard Worker         FlockOperation::Unlock => libc::LOCK_UN,
188*bb4ee6a4SAndroid Build Coastguard Worker     };
189*bb4ee6a4SAndroid Build Coastguard Worker 
190*bb4ee6a4SAndroid Build Coastguard Worker     if nonblocking {
191*bb4ee6a4SAndroid Build Coastguard Worker         operation |= libc::LOCK_NB;
192*bb4ee6a4SAndroid Build Coastguard Worker     }
193*bb4ee6a4SAndroid Build Coastguard Worker 
194*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
195*bb4ee6a4SAndroid Build Coastguard Worker     // Safe since we pass in a valid fd and flock operation, and check the return value.
196*bb4ee6a4SAndroid Build Coastguard Worker     syscall!(unsafe { libc::flock(file.as_raw_descriptor(), operation) }).map(|_| ())
197*bb4ee6a4SAndroid Build Coastguard Worker }
198*bb4ee6a4SAndroid Build Coastguard Worker 
199*bb4ee6a4SAndroid Build Coastguard Worker /// The operation to perform with `fallocate`.
200*bb4ee6a4SAndroid Build Coastguard Worker pub enum FallocateMode {
201*bb4ee6a4SAndroid Build Coastguard Worker     PunchHole,
202*bb4ee6a4SAndroid Build Coastguard Worker     ZeroRange,
203*bb4ee6a4SAndroid Build Coastguard Worker     Allocate,
204*bb4ee6a4SAndroid Build Coastguard Worker }
205*bb4ee6a4SAndroid Build Coastguard Worker 
206*bb4ee6a4SAndroid Build Coastguard Worker impl From<FallocateMode> for i32 {
207*bb4ee6a4SAndroid Build Coastguard Worker     fn from(value: FallocateMode) -> Self {
208*bb4ee6a4SAndroid Build Coastguard Worker         match value {
209*bb4ee6a4SAndroid Build Coastguard Worker             FallocateMode::Allocate => libc::FALLOC_FL_KEEP_SIZE,
210*bb4ee6a4SAndroid Build Coastguard Worker             FallocateMode::PunchHole => libc::FALLOC_FL_PUNCH_HOLE | libc::FALLOC_FL_KEEP_SIZE,
211*bb4ee6a4SAndroid Build Coastguard Worker             FallocateMode::ZeroRange => libc::FALLOC_FL_ZERO_RANGE | libc::FALLOC_FL_KEEP_SIZE,
212*bb4ee6a4SAndroid Build Coastguard Worker         }
213*bb4ee6a4SAndroid Build Coastguard Worker     }
214*bb4ee6a4SAndroid Build Coastguard Worker }
215*bb4ee6a4SAndroid Build Coastguard Worker 
216*bb4ee6a4SAndroid Build Coastguard Worker impl From<FallocateMode> for u32 {
217*bb4ee6a4SAndroid Build Coastguard Worker     fn from(value: FallocateMode) -> Self {
218*bb4ee6a4SAndroid Build Coastguard Worker         Into::<i32>::into(value) as u32
219*bb4ee6a4SAndroid Build Coastguard Worker     }
220*bb4ee6a4SAndroid Build Coastguard Worker }
221*bb4ee6a4SAndroid Build Coastguard Worker 
222*bb4ee6a4SAndroid Build Coastguard Worker /// Safe wrapper for `fallocate()`.
223*bb4ee6a4SAndroid Build Coastguard Worker pub fn fallocate<F: AsRawDescriptor>(
224*bb4ee6a4SAndroid Build Coastguard Worker     file: &F,
225*bb4ee6a4SAndroid Build Coastguard Worker     mode: FallocateMode,
226*bb4ee6a4SAndroid Build Coastguard Worker     offset: u64,
227*bb4ee6a4SAndroid Build Coastguard Worker     len: u64,
228*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()> {
229*bb4ee6a4SAndroid Build Coastguard Worker     let offset = if offset > libc::off64_t::MAX as u64 {
230*bb4ee6a4SAndroid Build Coastguard Worker         return Err(Error::new(libc::EINVAL));
231*bb4ee6a4SAndroid Build Coastguard Worker     } else {
232*bb4ee6a4SAndroid Build Coastguard Worker         offset as libc::off64_t
233*bb4ee6a4SAndroid Build Coastguard Worker     };
234*bb4ee6a4SAndroid Build Coastguard Worker 
235*bb4ee6a4SAndroid Build Coastguard Worker     let len = if len > libc::off64_t::MAX as u64 {
236*bb4ee6a4SAndroid Build Coastguard Worker         return Err(Error::new(libc::EINVAL));
237*bb4ee6a4SAndroid Build Coastguard Worker     } else {
238*bb4ee6a4SAndroid Build Coastguard Worker         len as libc::off64_t
239*bb4ee6a4SAndroid Build Coastguard Worker     };
240*bb4ee6a4SAndroid Build Coastguard Worker 
241*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
242*bb4ee6a4SAndroid Build Coastguard Worker     // Safe since we pass in a valid fd and fallocate mode, validate offset and len,
243*bb4ee6a4SAndroid Build Coastguard Worker     // and check the return value.
244*bb4ee6a4SAndroid Build Coastguard Worker     syscall!(unsafe { libc::fallocate64(file.as_raw_descriptor(), mode.into(), offset, len) })
245*bb4ee6a4SAndroid Build Coastguard Worker         .map(|_| ())
246*bb4ee6a4SAndroid Build Coastguard Worker }
247*bb4ee6a4SAndroid Build Coastguard Worker 
248*bb4ee6a4SAndroid Build Coastguard Worker /// Safe wrapper for `fstat()`.
249*bb4ee6a4SAndroid Build Coastguard Worker pub fn fstat<F: AsRawDescriptor>(f: &F) -> Result<libc::stat64> {
250*bb4ee6a4SAndroid Build Coastguard Worker     let mut st = MaybeUninit::<libc::stat64>::zeroed();
251*bb4ee6a4SAndroid Build Coastguard Worker 
252*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
253*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because the kernel will only write data in `st` and we check the return
254*bb4ee6a4SAndroid Build Coastguard Worker     // value.
255*bb4ee6a4SAndroid Build Coastguard Worker     syscall!(unsafe { libc::fstat64(f.as_raw_descriptor(), st.as_mut_ptr()) })?;
256*bb4ee6a4SAndroid Build Coastguard Worker 
257*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
258*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because the kernel guarantees that the struct is now fully initialized.
259*bb4ee6a4SAndroid Build Coastguard Worker     Ok(unsafe { st.assume_init() })
260*bb4ee6a4SAndroid Build Coastguard Worker }
261*bb4ee6a4SAndroid Build Coastguard Worker 
262*bb4ee6a4SAndroid Build Coastguard Worker /// Checks whether a file is a block device fie or not.
263*bb4ee6a4SAndroid Build Coastguard Worker pub fn is_block_file<F: AsRawDescriptor>(file: &F) -> Result<bool> {
264*bb4ee6a4SAndroid Build Coastguard Worker     let stat = fstat(file)?;
265*bb4ee6a4SAndroid Build Coastguard Worker     Ok((stat.st_mode & libc::S_IFMT) == libc::S_IFBLK)
266*bb4ee6a4SAndroid Build Coastguard Worker }
267*bb4ee6a4SAndroid Build Coastguard Worker 
268*bb4ee6a4SAndroid Build Coastguard Worker const BLOCK_IO_TYPE: u32 = 0x12;
269*bb4ee6a4SAndroid Build Coastguard Worker ioctl_io_nr!(BLKDISCARD, BLOCK_IO_TYPE, 119);
270*bb4ee6a4SAndroid Build Coastguard Worker 
271*bb4ee6a4SAndroid Build Coastguard Worker /// Discards the given range of a block file.
272*bb4ee6a4SAndroid Build Coastguard Worker pub fn discard_block<F: AsRawDescriptor>(file: &F, offset: u64, len: u64) -> Result<()> {
273*bb4ee6a4SAndroid Build Coastguard Worker     let range: [u64; 2] = [offset, len];
274*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
275*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because
276*bb4ee6a4SAndroid Build Coastguard Worker     // - we check the return value.
277*bb4ee6a4SAndroid Build Coastguard Worker     // - ioctl(BLKDISCARD) does not hold the descriptor after the call.
278*bb4ee6a4SAndroid Build Coastguard Worker     // - ioctl(BLKDISCARD) does not break the file descriptor.
279*bb4ee6a4SAndroid Build Coastguard Worker     // - ioctl(BLKDISCARD) does not modify the given range.
280*bb4ee6a4SAndroid Build Coastguard Worker     syscall!(unsafe { libc::ioctl(file.as_raw_descriptor(), BLKDISCARD, &range) }).map(|_| ())
281*bb4ee6a4SAndroid Build Coastguard Worker }
282*bb4ee6a4SAndroid Build Coastguard Worker 
283*bb4ee6a4SAndroid Build Coastguard Worker /// A trait used to abstract types that provide a process id that can be operated on.
284*bb4ee6a4SAndroid Build Coastguard Worker pub trait AsRawPid {
285*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_pid(&self) -> Pid;
286*bb4ee6a4SAndroid Build Coastguard Worker }
287*bb4ee6a4SAndroid Build Coastguard Worker 
288*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawPid for Pid {
289*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_pid(&self) -> Pid {
290*bb4ee6a4SAndroid Build Coastguard Worker         *self
291*bb4ee6a4SAndroid Build Coastguard Worker     }
292*bb4ee6a4SAndroid Build Coastguard Worker }
293*bb4ee6a4SAndroid Build Coastguard Worker 
294*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawPid for std::process::Child {
295*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_pid(&self) -> Pid {
296*bb4ee6a4SAndroid Build Coastguard Worker         self.id() as Pid
297*bb4ee6a4SAndroid Build Coastguard Worker     }
298*bb4ee6a4SAndroid Build Coastguard Worker }
299*bb4ee6a4SAndroid Build Coastguard Worker 
300*bb4ee6a4SAndroid Build Coastguard Worker /// A safe wrapper around waitpid.
301*bb4ee6a4SAndroid Build Coastguard Worker ///
302*bb4ee6a4SAndroid Build Coastguard Worker /// On success if a process was reaped, it will be returned as the first value.
303*bb4ee6a4SAndroid Build Coastguard Worker /// The second returned value is the ExitStatus from the libc::waitpid() call.
304*bb4ee6a4SAndroid Build Coastguard Worker ///
305*bb4ee6a4SAndroid Build Coastguard Worker /// Note: this can block if libc::WNOHANG is not set and EINTR is not handled internally.
306*bb4ee6a4SAndroid Build Coastguard Worker pub fn wait_for_pid<A: AsRawPid>(pid: A, options: c_int) -> Result<(Option<Pid>, ExitStatus)> {
307*bb4ee6a4SAndroid Build Coastguard Worker     let pid = pid.as_raw_pid();
308*bb4ee6a4SAndroid Build Coastguard Worker     let mut status: c_int = 1;
309*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
310*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because status is owned and the error is checked.
311*bb4ee6a4SAndroid Build Coastguard Worker     let ret = unsafe { libc::waitpid(pid, &mut status, options) };
312*bb4ee6a4SAndroid Build Coastguard Worker     if ret < 0 {
313*bb4ee6a4SAndroid Build Coastguard Worker         return errno_result();
314*bb4ee6a4SAndroid Build Coastguard Worker     }
315*bb4ee6a4SAndroid Build Coastguard Worker     Ok((
316*bb4ee6a4SAndroid Build Coastguard Worker         if ret == 0 { None } else { Some(ret) },
317*bb4ee6a4SAndroid Build Coastguard Worker         ExitStatus::from_raw(status),
318*bb4ee6a4SAndroid Build Coastguard Worker     ))
319*bb4ee6a4SAndroid Build Coastguard Worker }
320*bb4ee6a4SAndroid Build Coastguard Worker 
321*bb4ee6a4SAndroid Build Coastguard Worker /// Reaps a child process that has terminated.
322*bb4ee6a4SAndroid Build Coastguard Worker ///
323*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `Ok(pid)` where `pid` is the process that was reaped or `Ok(0)` if none of the children
324*bb4ee6a4SAndroid Build Coastguard Worker /// have terminated. An `Error` is with `errno == ECHILD` if there are no children left to reap.
325*bb4ee6a4SAndroid Build Coastguard Worker ///
326*bb4ee6a4SAndroid Build Coastguard Worker /// # Examples
327*bb4ee6a4SAndroid Build Coastguard Worker ///
328*bb4ee6a4SAndroid Build Coastguard Worker /// Reaps all child processes until there are no terminated children to reap.
329*bb4ee6a4SAndroid Build Coastguard Worker ///
330*bb4ee6a4SAndroid Build Coastguard Worker /// ```
331*bb4ee6a4SAndroid Build Coastguard Worker /// fn reap_children() {
332*bb4ee6a4SAndroid Build Coastguard Worker ///     loop {
333*bb4ee6a4SAndroid Build Coastguard Worker ///         match base::linux::reap_child() {
334*bb4ee6a4SAndroid Build Coastguard Worker ///             Ok(0) => println!("no children ready to reap"),
335*bb4ee6a4SAndroid Build Coastguard Worker ///             Ok(pid) => {
336*bb4ee6a4SAndroid Build Coastguard Worker ///                 println!("reaped {}", pid);
337*bb4ee6a4SAndroid Build Coastguard Worker ///                 continue
338*bb4ee6a4SAndroid Build Coastguard Worker ///             },
339*bb4ee6a4SAndroid Build Coastguard Worker ///             Err(e) if e.errno() == libc::ECHILD => println!("no children left"),
340*bb4ee6a4SAndroid Build Coastguard Worker ///             Err(e) => println!("error reaping children: {}", e),
341*bb4ee6a4SAndroid Build Coastguard Worker ///         }
342*bb4ee6a4SAndroid Build Coastguard Worker ///         break
343*bb4ee6a4SAndroid Build Coastguard Worker ///     }
344*bb4ee6a4SAndroid Build Coastguard Worker /// }
345*bb4ee6a4SAndroid Build Coastguard Worker /// ```
346*bb4ee6a4SAndroid Build Coastguard Worker pub fn reap_child() -> Result<Pid> {
347*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
348*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because we pass in no memory, prevent blocking with WNOHANG, and check for error.
349*bb4ee6a4SAndroid Build Coastguard Worker     let ret = unsafe { waitpid(-1, ptr::null_mut(), WNOHANG) };
350*bb4ee6a4SAndroid Build Coastguard Worker     if ret == -1 {
351*bb4ee6a4SAndroid Build Coastguard Worker         errno_result()
352*bb4ee6a4SAndroid Build Coastguard Worker     } else {
353*bb4ee6a4SAndroid Build Coastguard Worker         Ok(ret)
354*bb4ee6a4SAndroid Build Coastguard Worker     }
355*bb4ee6a4SAndroid Build Coastguard Worker }
356*bb4ee6a4SAndroid Build Coastguard Worker 
357*bb4ee6a4SAndroid Build Coastguard Worker /// Kill all processes in the current process group.
358*bb4ee6a4SAndroid Build Coastguard Worker ///
359*bb4ee6a4SAndroid Build Coastguard Worker /// On success, this kills all processes in the current process group, including the current
360*bb4ee6a4SAndroid Build Coastguard Worker /// process, meaning this will not return. This is equivalent to a call to `kill(0, SIGKILL)`.
361*bb4ee6a4SAndroid Build Coastguard Worker pub fn kill_process_group() -> Result<()> {
362*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: Safe because pid is 'self group' and return value doesn't matter.
363*bb4ee6a4SAndroid Build Coastguard Worker     unsafe { kill(0, SIGKILL) }?;
364*bb4ee6a4SAndroid Build Coastguard Worker     // Kill succeeded, so this process never reaches here.
365*bb4ee6a4SAndroid Build Coastguard Worker     unreachable!();
366*bb4ee6a4SAndroid Build Coastguard Worker }
367*bb4ee6a4SAndroid Build Coastguard Worker 
368*bb4ee6a4SAndroid Build Coastguard Worker /// Spawns a pipe pair where the first pipe is the read end and the second pipe is the write end.
369*bb4ee6a4SAndroid Build Coastguard Worker ///
370*bb4ee6a4SAndroid Build Coastguard Worker /// The `O_CLOEXEC` flag will be set during pipe creation.
371*bb4ee6a4SAndroid Build Coastguard Worker pub fn pipe() -> Result<(File, File)> {
372*bb4ee6a4SAndroid Build Coastguard Worker     let mut pipe_fds = [-1; 2];
373*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
374*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because pipe2 will only write 2 element array of i32 to the given pointer, and we check
375*bb4ee6a4SAndroid Build Coastguard Worker     // for error.
376*bb4ee6a4SAndroid Build Coastguard Worker     let ret = unsafe { pipe2(&mut pipe_fds[0], O_CLOEXEC) };
377*bb4ee6a4SAndroid Build Coastguard Worker     if ret == -1 {
378*bb4ee6a4SAndroid Build Coastguard Worker         errno_result()
379*bb4ee6a4SAndroid Build Coastguard Worker     } else {
380*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
381*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because both fds must be valid for pipe2 to have returned sucessfully and we have
382*bb4ee6a4SAndroid Build Coastguard Worker         // exclusive ownership of them.
383*bb4ee6a4SAndroid Build Coastguard Worker         Ok(unsafe {
384*bb4ee6a4SAndroid Build Coastguard Worker             (
385*bb4ee6a4SAndroid Build Coastguard Worker                 File::from_raw_fd(pipe_fds[0]),
386*bb4ee6a4SAndroid Build Coastguard Worker                 File::from_raw_fd(pipe_fds[1]),
387*bb4ee6a4SAndroid Build Coastguard Worker             )
388*bb4ee6a4SAndroid Build Coastguard Worker         })
389*bb4ee6a4SAndroid Build Coastguard Worker     }
390*bb4ee6a4SAndroid Build Coastguard Worker }
391*bb4ee6a4SAndroid Build Coastguard Worker 
392*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the pipe signified with fd to `size`.
393*bb4ee6a4SAndroid Build Coastguard Worker ///
394*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the new size of the pipe or an error if the OS fails to set the pipe size.
395*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_pipe_size(fd: RawFd, size: usize) -> Result<usize> {
396*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
397*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because fcntl with the `F_SETPIPE_SZ` arg doesn't touch memory.
398*bb4ee6a4SAndroid Build Coastguard Worker     syscall!(unsafe { fcntl(fd, libc::F_SETPIPE_SZ, size as c_int) }).map(|ret| ret as usize)
399*bb4ee6a4SAndroid Build Coastguard Worker }
400*bb4ee6a4SAndroid Build Coastguard Worker 
401*bb4ee6a4SAndroid Build Coastguard Worker /// Test-only function used to create a pipe that is full. The pipe is created, has its size set to
402*bb4ee6a4SAndroid Build Coastguard Worker /// the minimum and then has that much data written to it. Use `new_pipe_full` to test handling of
403*bb4ee6a4SAndroid Build Coastguard Worker /// blocking `write` calls in unit tests.
404*bb4ee6a4SAndroid Build Coastguard Worker pub fn new_pipe_full() -> Result<(File, File)> {
405*bb4ee6a4SAndroid Build Coastguard Worker     use std::io::Write;
406*bb4ee6a4SAndroid Build Coastguard Worker 
407*bb4ee6a4SAndroid Build Coastguard Worker     let (rx, mut tx) = pipe()?;
408*bb4ee6a4SAndroid Build Coastguard Worker     // The smallest allowed size of a pipe is the system page size on linux.
409*bb4ee6a4SAndroid Build Coastguard Worker     let page_size = set_pipe_size(tx.as_raw_descriptor(), round_up_to_page_size(1))?;
410*bb4ee6a4SAndroid Build Coastguard Worker 
411*bb4ee6a4SAndroid Build Coastguard Worker     // Fill the pipe with page_size zeros so the next write call will block.
412*bb4ee6a4SAndroid Build Coastguard Worker     let buf = vec![0u8; page_size];
413*bb4ee6a4SAndroid Build Coastguard Worker     tx.write_all(&buf)?;
414*bb4ee6a4SAndroid Build Coastguard Worker 
415*bb4ee6a4SAndroid Build Coastguard Worker     Ok((rx, tx))
416*bb4ee6a4SAndroid Build Coastguard Worker }
417*bb4ee6a4SAndroid Build Coastguard Worker 
418*bb4ee6a4SAndroid Build Coastguard Worker /// Used to attempt to clean up a named pipe after it is no longer used.
419*bb4ee6a4SAndroid Build Coastguard Worker pub struct UnlinkUnixDatagram(pub UnixDatagram);
420*bb4ee6a4SAndroid Build Coastguard Worker impl AsRef<UnixDatagram> for UnlinkUnixDatagram {
421*bb4ee6a4SAndroid Build Coastguard Worker     fn as_ref(&self) -> &UnixDatagram {
422*bb4ee6a4SAndroid Build Coastguard Worker         &self.0
423*bb4ee6a4SAndroid Build Coastguard Worker     }
424*bb4ee6a4SAndroid Build Coastguard Worker }
425*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for UnlinkUnixDatagram {
426*bb4ee6a4SAndroid Build Coastguard Worker     fn drop(&mut self) {
427*bb4ee6a4SAndroid Build Coastguard Worker         if let Ok(addr) = self.0.local_addr() {
428*bb4ee6a4SAndroid Build Coastguard Worker             if let Some(path) = addr.as_pathname() {
429*bb4ee6a4SAndroid Build Coastguard Worker                 if let Err(e) = remove_file(path) {
430*bb4ee6a4SAndroid Build Coastguard Worker                     warn!("failed to remove control socket file: {}", e);
431*bb4ee6a4SAndroid Build Coastguard Worker                 }
432*bb4ee6a4SAndroid Build Coastguard Worker             }
433*bb4ee6a4SAndroid Build Coastguard Worker         }
434*bb4ee6a4SAndroid Build Coastguard Worker     }
435*bb4ee6a4SAndroid Build Coastguard Worker }
436*bb4ee6a4SAndroid Build Coastguard Worker 
437*bb4ee6a4SAndroid Build Coastguard Worker /// Used to attempt to clean up a named pipe after it is no longer used.
438*bb4ee6a4SAndroid Build Coastguard Worker pub struct UnlinkUnixListener(pub UnixListener);
439*bb4ee6a4SAndroid Build Coastguard Worker 
440*bb4ee6a4SAndroid Build Coastguard Worker impl AsRef<UnixListener> for UnlinkUnixListener {
441*bb4ee6a4SAndroid Build Coastguard Worker     fn as_ref(&self) -> &UnixListener {
442*bb4ee6a4SAndroid Build Coastguard Worker         &self.0
443*bb4ee6a4SAndroid Build Coastguard Worker     }
444*bb4ee6a4SAndroid Build Coastguard Worker }
445*bb4ee6a4SAndroid Build Coastguard Worker 
446*bb4ee6a4SAndroid Build Coastguard Worker impl Deref for UnlinkUnixListener {
447*bb4ee6a4SAndroid Build Coastguard Worker     type Target = UnixListener;
448*bb4ee6a4SAndroid Build Coastguard Worker 
449*bb4ee6a4SAndroid Build Coastguard Worker     fn deref(&self) -> &UnixListener {
450*bb4ee6a4SAndroid Build Coastguard Worker         &self.0
451*bb4ee6a4SAndroid Build Coastguard Worker     }
452*bb4ee6a4SAndroid Build Coastguard Worker }
453*bb4ee6a4SAndroid Build Coastguard Worker 
454*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for UnlinkUnixListener {
455*bb4ee6a4SAndroid Build Coastguard Worker     fn drop(&mut self) {
456*bb4ee6a4SAndroid Build Coastguard Worker         if let Ok(addr) = self.0.local_addr() {
457*bb4ee6a4SAndroid Build Coastguard Worker             if let Some(path) = addr.as_pathname() {
458*bb4ee6a4SAndroid Build Coastguard Worker                 if let Err(e) = remove_file(path) {
459*bb4ee6a4SAndroid Build Coastguard Worker                     warn!("failed to remove control socket file: {}", e);
460*bb4ee6a4SAndroid Build Coastguard Worker                 }
461*bb4ee6a4SAndroid Build Coastguard Worker             }
462*bb4ee6a4SAndroid Build Coastguard Worker         }
463*bb4ee6a4SAndroid Build Coastguard Worker     }
464*bb4ee6a4SAndroid Build Coastguard Worker }
465*bb4ee6a4SAndroid Build Coastguard Worker 
466*bb4ee6a4SAndroid Build Coastguard Worker /// Verifies that |raw_descriptor| is actually owned by this process and duplicates it
467*bb4ee6a4SAndroid Build Coastguard Worker /// to ensure that we have a unique handle to it.
468*bb4ee6a4SAndroid Build Coastguard Worker pub fn validate_raw_descriptor(raw_descriptor: RawDescriptor) -> Result<RawDescriptor> {
469*bb4ee6a4SAndroid Build Coastguard Worker     validate_raw_fd(&raw_descriptor)
470*bb4ee6a4SAndroid Build Coastguard Worker }
471*bb4ee6a4SAndroid Build Coastguard Worker 
472*bb4ee6a4SAndroid Build Coastguard Worker /// Verifies that |raw_fd| is actually owned by this process and duplicates it to ensure that
473*bb4ee6a4SAndroid Build Coastguard Worker /// we have a unique handle to it.
474*bb4ee6a4SAndroid Build Coastguard Worker pub fn validate_raw_fd(raw_fd: &RawFd) -> Result<RawFd> {
475*bb4ee6a4SAndroid Build Coastguard Worker     // Checking that close-on-exec isn't set helps filter out FDs that were opened by
476*bb4ee6a4SAndroid Build Coastguard Worker     // crosvm as all crosvm FDs are close on exec.
477*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
478*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because this doesn't modify any memory and we check the return value.
479*bb4ee6a4SAndroid Build Coastguard Worker     let flags = unsafe { libc::fcntl(*raw_fd, libc::F_GETFD) };
480*bb4ee6a4SAndroid Build Coastguard Worker     if flags < 0 || (flags & libc::FD_CLOEXEC) != 0 {
481*bb4ee6a4SAndroid Build Coastguard Worker         return Err(Error::new(libc::EBADF));
482*bb4ee6a4SAndroid Build Coastguard Worker     }
483*bb4ee6a4SAndroid Build Coastguard Worker 
484*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
485*bb4ee6a4SAndroid Build Coastguard Worker     // Duplicate the fd to ensure that we don't accidentally close an fd previously
486*bb4ee6a4SAndroid Build Coastguard Worker     // opened by another subsystem.  Safe because this doesn't modify any memory and
487*bb4ee6a4SAndroid Build Coastguard Worker     // we check the return value.
488*bb4ee6a4SAndroid Build Coastguard Worker     let dup_fd = unsafe { libc::fcntl(*raw_fd, libc::F_DUPFD_CLOEXEC, 0) };
489*bb4ee6a4SAndroid Build Coastguard Worker     if dup_fd < 0 {
490*bb4ee6a4SAndroid Build Coastguard Worker         return Err(Error::last());
491*bb4ee6a4SAndroid Build Coastguard Worker     }
492*bb4ee6a4SAndroid Build Coastguard Worker     Ok(dup_fd as RawFd)
493*bb4ee6a4SAndroid Build Coastguard Worker }
494*bb4ee6a4SAndroid Build Coastguard Worker 
495*bb4ee6a4SAndroid Build Coastguard Worker /// Utility function that returns true if the given FD is readable without blocking.
496*bb4ee6a4SAndroid Build Coastguard Worker ///
497*bb4ee6a4SAndroid Build Coastguard Worker /// On an error, such as an invalid or incompatible FD, this will return false, which can not be
498*bb4ee6a4SAndroid Build Coastguard Worker /// distinguished from a non-ready to read FD.
499*bb4ee6a4SAndroid Build Coastguard Worker pub fn poll_in<F: AsRawDescriptor>(fd: &F) -> bool {
500*bb4ee6a4SAndroid Build Coastguard Worker     let mut fds = libc::pollfd {
501*bb4ee6a4SAndroid Build Coastguard Worker         fd: fd.as_raw_descriptor(),
502*bb4ee6a4SAndroid Build Coastguard Worker         events: libc::POLLIN,
503*bb4ee6a4SAndroid Build Coastguard Worker         revents: 0,
504*bb4ee6a4SAndroid Build Coastguard Worker     };
505*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
506*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because we give a valid pointer to a list (of 1) FD and check the return value.
507*bb4ee6a4SAndroid Build Coastguard Worker     let ret = unsafe { libc::poll(&mut fds, 1, 0) };
508*bb4ee6a4SAndroid Build Coastguard Worker     // An error probably indicates an invalid FD, or an FD that can't be polled. Returning false in
509*bb4ee6a4SAndroid Build Coastguard Worker     // that case is probably correct as such an FD is unlikely to be readable, although there are
510*bb4ee6a4SAndroid Build Coastguard Worker     // probably corner cases in which that is wrong.
511*bb4ee6a4SAndroid Build Coastguard Worker     if ret == -1 {
512*bb4ee6a4SAndroid Build Coastguard Worker         return false;
513*bb4ee6a4SAndroid Build Coastguard Worker     }
514*bb4ee6a4SAndroid Build Coastguard Worker     fds.revents & libc::POLLIN != 0
515*bb4ee6a4SAndroid Build Coastguard Worker }
516*bb4ee6a4SAndroid Build Coastguard Worker 
517*bb4ee6a4SAndroid Build Coastguard Worker /// Return the maximum Duration that can be used with libc::timespec.
518*bb4ee6a4SAndroid Build Coastguard Worker pub fn max_timeout() -> Duration {
519*bb4ee6a4SAndroid Build Coastguard Worker     Duration::new(libc::time_t::MAX as u64, 999999999)
520*bb4ee6a4SAndroid Build Coastguard Worker }
521*bb4ee6a4SAndroid Build Coastguard Worker 
522*bb4ee6a4SAndroid Build Coastguard Worker /// If the given path is of the form /proc/self/fd/N for some N, returns `Ok(Some(N))`. Otherwise
523*bb4ee6a4SAndroid Build Coastguard Worker /// returns `Ok(None)`.
524*bb4ee6a4SAndroid Build Coastguard Worker pub fn safe_descriptor_from_path<P: AsRef<Path>>(path: P) -> Result<Option<SafeDescriptor>> {
525*bb4ee6a4SAndroid Build Coastguard Worker     let path = path.as_ref();
526*bb4ee6a4SAndroid Build Coastguard Worker     if path.parent() == Some(Path::new("/proc/self/fd")) {
527*bb4ee6a4SAndroid Build Coastguard Worker         let raw_descriptor = path
528*bb4ee6a4SAndroid Build Coastguard Worker             .file_name()
529*bb4ee6a4SAndroid Build Coastguard Worker             .and_then(|fd_osstr| fd_osstr.to_str())
530*bb4ee6a4SAndroid Build Coastguard Worker             .and_then(|fd_str| fd_str.parse::<RawFd>().ok())
531*bb4ee6a4SAndroid Build Coastguard Worker             .ok_or_else(|| Error::new(EINVAL))?;
532*bb4ee6a4SAndroid Build Coastguard Worker         let validated_fd = validate_raw_fd(&raw_descriptor)?;
533*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Some(
534*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY:
535*bb4ee6a4SAndroid Build Coastguard Worker             // Safe because nothing else has access to validated_fd after this call.
536*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { SafeDescriptor::from_raw_descriptor(validated_fd) },
537*bb4ee6a4SAndroid Build Coastguard Worker         ))
538*bb4ee6a4SAndroid Build Coastguard Worker     } else {
539*bb4ee6a4SAndroid Build Coastguard Worker         Ok(None)
540*bb4ee6a4SAndroid Build Coastguard Worker     }
541*bb4ee6a4SAndroid Build Coastguard Worker }
542*bb4ee6a4SAndroid Build Coastguard Worker 
543*bb4ee6a4SAndroid Build Coastguard Worker /// Check FD is not opened by crosvm and returns a FD that is freshly DUPFD_CLOEXEC's.
544*bb4ee6a4SAndroid Build Coastguard Worker /// A SafeDescriptor is created from the duplicated fd. It does not take ownership of
545*bb4ee6a4SAndroid Build Coastguard Worker /// fd passed by argument.
546*bb4ee6a4SAndroid Build Coastguard Worker pub fn safe_descriptor_from_cmdline_fd(fd: &RawFd) -> Result<SafeDescriptor> {
547*bb4ee6a4SAndroid Build Coastguard Worker     let validated_fd = validate_raw_fd(fd)?;
548*bb4ee6a4SAndroid Build Coastguard Worker     Ok(
549*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
550*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because nothing else has access to validated_fd after this call.
551*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { SafeDescriptor::from_raw_descriptor(validated_fd) },
552*bb4ee6a4SAndroid Build Coastguard Worker     )
553*bb4ee6a4SAndroid Build Coastguard Worker }
554*bb4ee6a4SAndroid Build Coastguard Worker 
555*bb4ee6a4SAndroid Build Coastguard Worker /// Open the file with the given path, or if it is of the form `/proc/self/fd/N` then just use the
556*bb4ee6a4SAndroid Build Coastguard Worker /// file descriptor.
557*bb4ee6a4SAndroid Build Coastguard Worker ///
558*bb4ee6a4SAndroid Build Coastguard Worker /// Note that this will not work properly if the same `/proc/self/fd/N` path is used twice in
559*bb4ee6a4SAndroid Build Coastguard Worker /// different places, as the metadata (including the offset) will be shared between both file
560*bb4ee6a4SAndroid Build Coastguard Worker /// descriptors.
561*bb4ee6a4SAndroid Build Coastguard Worker pub fn open_file_or_duplicate<P: AsRef<Path>>(path: P, options: &OpenOptions) -> Result<File> {
562*bb4ee6a4SAndroid Build Coastguard Worker     let path = path.as_ref();
563*bb4ee6a4SAndroid Build Coastguard Worker     // Special case '/proc/self/fd/*' paths. The FD is already open, just use it.
564*bb4ee6a4SAndroid Build Coastguard Worker     Ok(if let Some(fd) = safe_descriptor_from_path(path)? {
565*bb4ee6a4SAndroid Build Coastguard Worker         fd.into()
566*bb4ee6a4SAndroid Build Coastguard Worker     } else {
567*bb4ee6a4SAndroid Build Coastguard Worker         options.open(path)?
568*bb4ee6a4SAndroid Build Coastguard Worker     })
569*bb4ee6a4SAndroid Build Coastguard Worker }
570*bb4ee6a4SAndroid Build Coastguard Worker 
571*bb4ee6a4SAndroid Build Coastguard Worker /// Get the soft and hard limits of max number of open files allowed by the environment.
572*bb4ee6a4SAndroid Build Coastguard Worker pub fn max_open_files() -> Result<libc::rlimit64> {
573*bb4ee6a4SAndroid Build Coastguard Worker     let mut buf = mem::MaybeUninit::<libc::rlimit64>::zeroed();
574*bb4ee6a4SAndroid Build Coastguard Worker 
575*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
576*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because this will only modify `buf` and we check the return value.
577*bb4ee6a4SAndroid Build Coastguard Worker     let res = unsafe { libc::prlimit64(0, libc::RLIMIT_NOFILE, ptr::null(), buf.as_mut_ptr()) };
578*bb4ee6a4SAndroid Build Coastguard Worker     if res == 0 {
579*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
580*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because the kernel guarantees that the struct is fully initialized.
581*bb4ee6a4SAndroid Build Coastguard Worker         let limit = unsafe { buf.assume_init() };
582*bb4ee6a4SAndroid Build Coastguard Worker         Ok(limit)
583*bb4ee6a4SAndroid Build Coastguard Worker     } else {
584*bb4ee6a4SAndroid Build Coastguard Worker         errno_result()
585*bb4ee6a4SAndroid Build Coastguard Worker     }
586*bb4ee6a4SAndroid Build Coastguard Worker }
587*bb4ee6a4SAndroid Build Coastguard Worker 
588*bb4ee6a4SAndroid Build Coastguard Worker /// Executes the given callback with extended soft limit of max number of open files. After the
589*bb4ee6a4SAndroid Build Coastguard Worker /// callback executed, restore the limit.
590*bb4ee6a4SAndroid Build Coastguard Worker pub fn call_with_extended_max_files<T, E>(
591*bb4ee6a4SAndroid Build Coastguard Worker     callback: impl FnOnce() -> std::result::Result<T, E>,
592*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<std::result::Result<T, E>> {
593*bb4ee6a4SAndroid Build Coastguard Worker     let cur_limit = max_open_files()?;
594*bb4ee6a4SAndroid Build Coastguard Worker     let new_limit = libc::rlimit64 {
595*bb4ee6a4SAndroid Build Coastguard Worker         rlim_cur: cur_limit.rlim_max,
596*bb4ee6a4SAndroid Build Coastguard Worker         ..cur_limit
597*bb4ee6a4SAndroid Build Coastguard Worker     };
598*bb4ee6a4SAndroid Build Coastguard Worker     let needs_extension = cur_limit.rlim_cur < new_limit.rlim_cur;
599*bb4ee6a4SAndroid Build Coastguard Worker     if needs_extension {
600*bb4ee6a4SAndroid Build Coastguard Worker         set_max_open_files(new_limit)?;
601*bb4ee6a4SAndroid Build Coastguard Worker     }
602*bb4ee6a4SAndroid Build Coastguard Worker 
603*bb4ee6a4SAndroid Build Coastguard Worker     let r = callback();
604*bb4ee6a4SAndroid Build Coastguard Worker 
605*bb4ee6a4SAndroid Build Coastguard Worker     // Restore the soft limit.
606*bb4ee6a4SAndroid Build Coastguard Worker     if needs_extension {
607*bb4ee6a4SAndroid Build Coastguard Worker         set_max_open_files(cur_limit)?;
608*bb4ee6a4SAndroid Build Coastguard Worker     }
609*bb4ee6a4SAndroid Build Coastguard Worker 
610*bb4ee6a4SAndroid Build Coastguard Worker     Ok(r)
611*bb4ee6a4SAndroid Build Coastguard Worker }
612*bb4ee6a4SAndroid Build Coastguard Worker 
613*bb4ee6a4SAndroid Build Coastguard Worker /// Set the soft and hard limits of max number of open files to the given value.
614*bb4ee6a4SAndroid Build Coastguard Worker fn set_max_open_files(limit: libc::rlimit64) -> Result<()> {
615*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: RLIMIT_NOFILE is known only to read a buffer of size rlimit64, and we have always
616*bb4ee6a4SAndroid Build Coastguard Worker     // rlimit64 allocated.
617*bb4ee6a4SAndroid Build Coastguard Worker     let res = unsafe { libc::setrlimit64(libc::RLIMIT_NOFILE, &limit) };
618*bb4ee6a4SAndroid Build Coastguard Worker     if res == 0 {
619*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
620*bb4ee6a4SAndroid Build Coastguard Worker     } else {
621*bb4ee6a4SAndroid Build Coastguard Worker         errno_result()
622*bb4ee6a4SAndroid Build Coastguard Worker     }
623*bb4ee6a4SAndroid Build Coastguard Worker }
624*bb4ee6a4SAndroid Build Coastguard Worker 
625*bb4ee6a4SAndroid Build Coastguard Worker /// Moves the requested PID/TID to a particular cgroup
626*bb4ee6a4SAndroid Build Coastguard Worker pub fn move_to_cgroup(cgroup_path: PathBuf, id_to_write: Pid, cgroup_file: &str) -> Result<()> {
627*bb4ee6a4SAndroid Build Coastguard Worker     use std::io::Write;
628*bb4ee6a4SAndroid Build Coastguard Worker 
629*bb4ee6a4SAndroid Build Coastguard Worker     let gpu_cgroup_file = cgroup_path.join(cgroup_file);
630*bb4ee6a4SAndroid Build Coastguard Worker     let mut f = File::create(gpu_cgroup_file)?;
631*bb4ee6a4SAndroid Build Coastguard Worker     f.write_all(id_to_write.to_string().as_bytes())?;
632*bb4ee6a4SAndroid Build Coastguard Worker     Ok(())
633*bb4ee6a4SAndroid Build Coastguard Worker }
634*bb4ee6a4SAndroid Build Coastguard Worker 
635*bb4ee6a4SAndroid Build Coastguard Worker pub fn move_task_to_cgroup(cgroup_path: PathBuf, thread_id: Pid) -> Result<()> {
636*bb4ee6a4SAndroid Build Coastguard Worker     move_to_cgroup(cgroup_path, thread_id, "tasks")
637*bb4ee6a4SAndroid Build Coastguard Worker }
638*bb4ee6a4SAndroid Build Coastguard Worker 
639*bb4ee6a4SAndroid Build Coastguard Worker pub fn move_proc_to_cgroup(cgroup_path: PathBuf, process_id: Pid) -> Result<()> {
640*bb4ee6a4SAndroid Build Coastguard Worker     move_to_cgroup(cgroup_path, process_id, "cgroup.procs")
641*bb4ee6a4SAndroid Build Coastguard Worker }
642*bb4ee6a4SAndroid Build Coastguard Worker 
643*bb4ee6a4SAndroid Build Coastguard Worker /// Queries the property of a specified CPU sysfs node.
644*bb4ee6a4SAndroid Build Coastguard Worker fn parse_sysfs_cpu_info_vec(cpu_id: usize, property: &str) -> Result<Vec<u32>> {
645*bb4ee6a4SAndroid Build Coastguard Worker     let path = format!("/sys/devices/system/cpu/cpu{cpu_id}/{property}");
646*bb4ee6a4SAndroid Build Coastguard Worker     let res: Result<Vec<_>> = std::fs::read_to_string(path)?
647*bb4ee6a4SAndroid Build Coastguard Worker         .split_whitespace()
648*bb4ee6a4SAndroid Build Coastguard Worker         .map(|x| x.parse().map_err(|_| Error::new(libc::EINVAL)))
649*bb4ee6a4SAndroid Build Coastguard Worker         .collect();
650*bb4ee6a4SAndroid Build Coastguard Worker     res
651*bb4ee6a4SAndroid Build Coastguard Worker }
652*bb4ee6a4SAndroid Build Coastguard Worker 
653*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a list of supported frequencies in kHz for a given logical core.
654*bb4ee6a4SAndroid Build Coastguard Worker pub fn logical_core_frequencies_khz(cpu_id: usize) -> Result<Vec<u32>> {
655*bb4ee6a4SAndroid Build Coastguard Worker     parse_sysfs_cpu_info_vec(cpu_id, "cpufreq/scaling_available_frequencies")
656*bb4ee6a4SAndroid Build Coastguard Worker }
657*bb4ee6a4SAndroid Build Coastguard Worker 
658*bb4ee6a4SAndroid Build Coastguard Worker fn parse_sysfs_cpu_info(cpu_id: usize, property: &str) -> Result<u32> {
659*bb4ee6a4SAndroid Build Coastguard Worker     let path = format!("/sys/devices/system/cpu/cpu{cpu_id}/{property}");
660*bb4ee6a4SAndroid Build Coastguard Worker     std::fs::read_to_string(path)?
661*bb4ee6a4SAndroid Build Coastguard Worker         .trim()
662*bb4ee6a4SAndroid Build Coastguard Worker         .parse()
663*bb4ee6a4SAndroid Build Coastguard Worker         .map_err(|_| Error::new(libc::EINVAL))
664*bb4ee6a4SAndroid Build Coastguard Worker }
665*bb4ee6a4SAndroid Build Coastguard Worker 
666*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the capacity (measure of performance) of a given logical core.
667*bb4ee6a4SAndroid Build Coastguard Worker pub fn logical_core_capacity(cpu_id: usize) -> Result<u32> {
668*bb4ee6a4SAndroid Build Coastguard Worker     static CPU_MAX_FREQS: OnceCell<Vec<u32>> = OnceCell::new();
669*bb4ee6a4SAndroid Build Coastguard Worker 
670*bb4ee6a4SAndroid Build Coastguard Worker     let cpu_capacity = parse_sysfs_cpu_info(cpu_id, "cpu_capacity")?;
671*bb4ee6a4SAndroid Build Coastguard Worker 
672*bb4ee6a4SAndroid Build Coastguard Worker     // Collect and cache the maximum frequencies of all cores. We need to know
673*bb4ee6a4SAndroid Build Coastguard Worker     // the largest maximum frequency between all cores to reverse normalization,
674*bb4ee6a4SAndroid Build Coastguard Worker     // so collect all the values once on the first call to this function.
675*bb4ee6a4SAndroid Build Coastguard Worker     let cpu_max_freqs = CPU_MAX_FREQS.get_or_try_init(|| {
676*bb4ee6a4SAndroid Build Coastguard Worker         (0..number_of_logical_cores()?)
677*bb4ee6a4SAndroid Build Coastguard Worker             .map(logical_core_max_freq_khz)
678*bb4ee6a4SAndroid Build Coastguard Worker             .collect()
679*bb4ee6a4SAndroid Build Coastguard Worker     });
680*bb4ee6a4SAndroid Build Coastguard Worker 
681*bb4ee6a4SAndroid Build Coastguard Worker     if let Ok(cpu_max_freqs) = cpu_max_freqs {
682*bb4ee6a4SAndroid Build Coastguard Worker         let largest_max_freq = *cpu_max_freqs.iter().max().ok_or(Error::new(EINVAL))?;
683*bb4ee6a4SAndroid Build Coastguard Worker         let cpu_max_freq = *cpu_max_freqs.get(cpu_id).ok_or(Error::new(EINVAL))?;
684*bb4ee6a4SAndroid Build Coastguard Worker         let normalized_cpu_capacity = (u64::from(cpu_capacity) * u64::from(largest_max_freq))
685*bb4ee6a4SAndroid Build Coastguard Worker             .checked_div(u64::from(cpu_max_freq))
686*bb4ee6a4SAndroid Build Coastguard Worker             .ok_or(Error::new(EINVAL))?;
687*bb4ee6a4SAndroid Build Coastguard Worker         normalized_cpu_capacity
688*bb4ee6a4SAndroid Build Coastguard Worker             .try_into()
689*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(|_| Error::new(EINVAL))
690*bb4ee6a4SAndroid Build Coastguard Worker     } else {
691*bb4ee6a4SAndroid Build Coastguard Worker         // cpu-freq is not enabled. Fall back to using the normalized capacity.
692*bb4ee6a4SAndroid Build Coastguard Worker         Ok(cpu_capacity)
693*bb4ee6a4SAndroid Build Coastguard Worker     }
694*bb4ee6a4SAndroid Build Coastguard Worker }
695*bb4ee6a4SAndroid Build Coastguard Worker 
696*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the cluster ID of a given logical core.
697*bb4ee6a4SAndroid Build Coastguard Worker pub fn logical_core_cluster_id(cpu_id: usize) -> Result<u32> {
698*bb4ee6a4SAndroid Build Coastguard Worker     parse_sysfs_cpu_info(cpu_id, "topology/physical_package_id")
699*bb4ee6a4SAndroid Build Coastguard Worker }
700*bb4ee6a4SAndroid Build Coastguard Worker 
701*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the maximum frequency (in kHz) of a given logical core.
702*bb4ee6a4SAndroid Build Coastguard Worker pub fn logical_core_max_freq_khz(cpu_id: usize) -> Result<u32> {
703*bb4ee6a4SAndroid Build Coastguard Worker     parse_sysfs_cpu_info(cpu_id, "cpufreq/cpuinfo_max_freq")
704*bb4ee6a4SAndroid Build Coastguard Worker }
705*bb4ee6a4SAndroid Build Coastguard Worker 
706*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
707*bb4ee6a4SAndroid Build Coastguard Worker pub struct sched_attr {
708*bb4ee6a4SAndroid Build Coastguard Worker     pub size: u32,
709*bb4ee6a4SAndroid Build Coastguard Worker 
710*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_policy: u32,
711*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_flags: u64,
712*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_nice: i32,
713*bb4ee6a4SAndroid Build Coastguard Worker 
714*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_priority: u32,
715*bb4ee6a4SAndroid Build Coastguard Worker 
716*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_runtime: u64,
717*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_deadline: u64,
718*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_period: u64,
719*bb4ee6a4SAndroid Build Coastguard Worker 
720*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_util_min: u32,
721*bb4ee6a4SAndroid Build Coastguard Worker     pub sched_util_max: u32,
722*bb4ee6a4SAndroid Build Coastguard Worker }
723*bb4ee6a4SAndroid Build Coastguard Worker 
724*bb4ee6a4SAndroid Build Coastguard Worker impl sched_attr {
725*bb4ee6a4SAndroid Build Coastguard Worker     pub fn default() -> Self {
726*bb4ee6a4SAndroid Build Coastguard Worker         Self {
727*bb4ee6a4SAndroid Build Coastguard Worker             size: std::mem::size_of::<sched_attr>() as u32,
728*bb4ee6a4SAndroid Build Coastguard Worker             sched_policy: 0,
729*bb4ee6a4SAndroid Build Coastguard Worker             sched_flags: 0,
730*bb4ee6a4SAndroid Build Coastguard Worker             sched_nice: 0,
731*bb4ee6a4SAndroid Build Coastguard Worker             sched_priority: 0,
732*bb4ee6a4SAndroid Build Coastguard Worker             sched_runtime: 0,
733*bb4ee6a4SAndroid Build Coastguard Worker             sched_deadline: 0,
734*bb4ee6a4SAndroid Build Coastguard Worker             sched_period: 0,
735*bb4ee6a4SAndroid Build Coastguard Worker             sched_util_min: 0,
736*bb4ee6a4SAndroid Build Coastguard Worker             sched_util_max: 0,
737*bb4ee6a4SAndroid Build Coastguard Worker         }
738*bb4ee6a4SAndroid Build Coastguard Worker     }
739*bb4ee6a4SAndroid Build Coastguard Worker }
740*bb4ee6a4SAndroid Build Coastguard Worker 
741*bb4ee6a4SAndroid Build Coastguard Worker pub fn sched_setattr(pid: Pid, attr: &mut sched_attr, flags: u32) -> Result<()> {
742*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: Safe becuase all the args are valid and the return valud is checked.
743*bb4ee6a4SAndroid Build Coastguard Worker     let ret = unsafe {
744*bb4ee6a4SAndroid Build Coastguard Worker         libc::syscall(
745*bb4ee6a4SAndroid Build Coastguard Worker             libc::SYS_sched_setattr,
746*bb4ee6a4SAndroid Build Coastguard Worker             pid as usize,
747*bb4ee6a4SAndroid Build Coastguard Worker             attr as *mut sched_attr as usize,
748*bb4ee6a4SAndroid Build Coastguard Worker             flags as usize,
749*bb4ee6a4SAndroid Build Coastguard Worker         )
750*bb4ee6a4SAndroid Build Coastguard Worker     };
751*bb4ee6a4SAndroid Build Coastguard Worker 
752*bb4ee6a4SAndroid Build Coastguard Worker     if ret < 0 {
753*bb4ee6a4SAndroid Build Coastguard Worker         return Err(Error::last());
754*bb4ee6a4SAndroid Build Coastguard Worker     }
755*bb4ee6a4SAndroid Build Coastguard Worker     Ok(())
756*bb4ee6a4SAndroid Build Coastguard Worker }
757*bb4ee6a4SAndroid Build Coastguard Worker 
758*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
759*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
760*bb4ee6a4SAndroid Build Coastguard Worker     use std::io::Write;
761*bb4ee6a4SAndroid Build Coastguard Worker     use std::os::fd::AsRawFd;
762*bb4ee6a4SAndroid Build Coastguard Worker 
763*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
764*bb4ee6a4SAndroid Build Coastguard Worker     use crate::unix::add_fd_flags;
765*bb4ee6a4SAndroid Build Coastguard Worker 
766*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
767*bb4ee6a4SAndroid Build Coastguard Worker     fn pipe_size_and_fill() {
768*bb4ee6a4SAndroid Build Coastguard Worker         let (_rx, mut tx) = new_pipe_full().expect("Failed to pipe");
769*bb4ee6a4SAndroid Build Coastguard Worker 
770*bb4ee6a4SAndroid Build Coastguard Worker         // To  check that setting the size worked, set the descriptor to non blocking and check that
771*bb4ee6a4SAndroid Build Coastguard Worker         // write returns an error.
772*bb4ee6a4SAndroid Build Coastguard Worker         add_fd_flags(tx.as_raw_fd(), libc::O_NONBLOCK).expect("Failed to set tx non blocking");
773*bb4ee6a4SAndroid Build Coastguard Worker         tx.write(&[0u8; 8])
774*bb4ee6a4SAndroid Build Coastguard Worker             .expect_err("Write after fill didn't fail");
775*bb4ee6a4SAndroid Build Coastguard Worker     }
776*bb4ee6a4SAndroid Build Coastguard Worker }
777