xref: /aosp_15_r20/external/crosvm/base/src/descriptor.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 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 use std::fs::File;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::mem;
7*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::ManuallyDrop;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc;
9*bb4ee6a4SAndroid Build Coastguard Worker 
10*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize;
11*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize;
12*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serializer;
13*bb4ee6a4SAndroid Build Coastguard Worker 
14*bb4ee6a4SAndroid Build Coastguard Worker use crate::EventToken;
15*bb4ee6a4SAndroid Build Coastguard Worker use crate::RawDescriptor;
16*bb4ee6a4SAndroid Build Coastguard Worker 
17*bb4ee6a4SAndroid Build Coastguard Worker /// Wraps a RawDescriptor and safely closes it when self falls out of scope.
18*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Serialize, Deserialize, Debug, Eq)]
19*bb4ee6a4SAndroid Build Coastguard Worker #[serde(transparent)]
20*bb4ee6a4SAndroid Build Coastguard Worker pub struct SafeDescriptor {
21*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(with = "super::with_raw_descriptor")]
22*bb4ee6a4SAndroid Build Coastguard Worker     pub(crate) descriptor: RawDescriptor,
23*bb4ee6a4SAndroid Build Coastguard Worker }
24*bb4ee6a4SAndroid Build Coastguard Worker 
25*bb4ee6a4SAndroid Build Coastguard Worker /// Trait for forfeiting ownership of the current raw descriptor, and returning the raw descriptor
26*bb4ee6a4SAndroid Build Coastguard Worker pub trait IntoRawDescriptor {
into_raw_descriptor(self) -> RawDescriptor27*bb4ee6a4SAndroid Build Coastguard Worker     fn into_raw_descriptor(self) -> RawDescriptor;
28*bb4ee6a4SAndroid Build Coastguard Worker }
29*bb4ee6a4SAndroid Build Coastguard Worker 
30*bb4ee6a4SAndroid Build Coastguard Worker /// Trait for returning the underlying raw descriptor, without giving up ownership of the
31*bb4ee6a4SAndroid Build Coastguard Worker /// descriptor.
32*bb4ee6a4SAndroid Build Coastguard Worker pub trait AsRawDescriptor {
33*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns the underlying raw descriptor.
34*bb4ee6a4SAndroid Build Coastguard Worker     ///
35*bb4ee6a4SAndroid Build Coastguard Worker     /// Since the descriptor is still owned by the provider, callers should not assume that it will
36*bb4ee6a4SAndroid Build Coastguard Worker     /// remain open for longer than the immediate call of this method. In particular, it is a
37*bb4ee6a4SAndroid Build Coastguard Worker     /// dangerous practice to store the result of this method for future use: instead, it should be
38*bb4ee6a4SAndroid Build Coastguard Worker     /// used to e.g. obtain a raw descriptor that is immediately passed to a system call.
39*bb4ee6a4SAndroid Build Coastguard Worker     ///
40*bb4ee6a4SAndroid Build Coastguard Worker     /// If you need to use the descriptor for a longer time (and particularly if you cannot reliably
41*bb4ee6a4SAndroid Build Coastguard Worker     /// track the lifetime of the providing object), you should probably consider using
42*bb4ee6a4SAndroid Build Coastguard Worker     /// [`SafeDescriptor`] (possibly along with [`trait@IntoRawDescriptor`]) to get full ownership
43*bb4ee6a4SAndroid Build Coastguard Worker     /// over a descriptor pointing to the same resource.
as_raw_descriptor(&self) -> RawDescriptor44*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor;
45*bb4ee6a4SAndroid Build Coastguard Worker }
46*bb4ee6a4SAndroid Build Coastguard Worker 
47*bb4ee6a4SAndroid Build Coastguard Worker /// A trait similar to `AsRawDescriptor` but supports an arbitrary number of descriptors.
48*bb4ee6a4SAndroid Build Coastguard Worker pub trait AsRawDescriptors {
49*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns the underlying raw descriptors.
50*bb4ee6a4SAndroid Build Coastguard Worker     ///
51*bb4ee6a4SAndroid Build Coastguard Worker     /// Please refer to the documentation of [`AsRawDescriptor::as_raw_descriptor`] for limitations
52*bb4ee6a4SAndroid Build Coastguard Worker     /// and recommended use.
as_raw_descriptors(&self) -> Vec<RawDescriptor>53*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptors(&self) -> Vec<RawDescriptor>;
54*bb4ee6a4SAndroid Build Coastguard Worker }
55*bb4ee6a4SAndroid Build Coastguard Worker 
56*bb4ee6a4SAndroid Build Coastguard Worker pub trait FromRawDescriptor {
57*bb4ee6a4SAndroid Build Coastguard Worker     /// # Safety
58*bb4ee6a4SAndroid Build Coastguard Worker     /// Safe only if the caller ensures nothing has access to the descriptor after passing it to
59*bb4ee6a4SAndroid Build Coastguard Worker     /// `from_raw_descriptor`
from_raw_descriptor(descriptor: RawDescriptor) -> Self60*bb4ee6a4SAndroid Build Coastguard Worker     unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self;
61*bb4ee6a4SAndroid Build Coastguard Worker }
62*bb4ee6a4SAndroid Build Coastguard Worker 
63*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for SafeDescriptor {
as_raw_descriptor(&self) -> RawDescriptor64*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
65*bb4ee6a4SAndroid Build Coastguard Worker         self.descriptor
66*bb4ee6a4SAndroid Build Coastguard Worker     }
67*bb4ee6a4SAndroid Build Coastguard Worker }
68*bb4ee6a4SAndroid Build Coastguard Worker 
69*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsRawDescriptor for Arc<T>
70*bb4ee6a4SAndroid Build Coastguard Worker where
71*bb4ee6a4SAndroid Build Coastguard Worker     T: AsRawDescriptor,
72*bb4ee6a4SAndroid Build Coastguard Worker {
as_raw_descriptor(&self) -> RawDescriptor73*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
74*bb4ee6a4SAndroid Build Coastguard Worker         self.as_ref().as_raw_descriptor()
75*bb4ee6a4SAndroid Build Coastguard Worker     }
76*bb4ee6a4SAndroid Build Coastguard Worker }
77*bb4ee6a4SAndroid Build Coastguard Worker 
78*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsRawDescriptors for T
79*bb4ee6a4SAndroid Build Coastguard Worker where
80*bb4ee6a4SAndroid Build Coastguard Worker     T: AsRawDescriptor,
81*bb4ee6a4SAndroid Build Coastguard Worker {
as_raw_descriptors(&self) -> Vec<RawDescriptor>82*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptors(&self) -> Vec<RawDescriptor> {
83*bb4ee6a4SAndroid Build Coastguard Worker         vec![self.as_raw_descriptor()]
84*bb4ee6a4SAndroid Build Coastguard Worker     }
85*bb4ee6a4SAndroid Build Coastguard Worker }
86*bb4ee6a4SAndroid Build Coastguard Worker 
87*bb4ee6a4SAndroid Build Coastguard Worker impl IntoRawDescriptor for SafeDescriptor {
into_raw_descriptor(self) -> RawDescriptor88*bb4ee6a4SAndroid Build Coastguard Worker     fn into_raw_descriptor(self) -> RawDescriptor {
89*bb4ee6a4SAndroid Build Coastguard Worker         let descriptor = self.descriptor;
90*bb4ee6a4SAndroid Build Coastguard Worker         mem::forget(self);
91*bb4ee6a4SAndroid Build Coastguard Worker         descriptor
92*bb4ee6a4SAndroid Build Coastguard Worker     }
93*bb4ee6a4SAndroid Build Coastguard Worker }
94*bb4ee6a4SAndroid Build Coastguard Worker 
95*bb4ee6a4SAndroid Build Coastguard Worker impl FromRawDescriptor for SafeDescriptor {
from_raw_descriptor(descriptor: RawDescriptor) -> Self96*bb4ee6a4SAndroid Build Coastguard Worker     unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self {
97*bb4ee6a4SAndroid Build Coastguard Worker         SafeDescriptor { descriptor }
98*bb4ee6a4SAndroid Build Coastguard Worker     }
99*bb4ee6a4SAndroid Build Coastguard Worker }
100*bb4ee6a4SAndroid Build Coastguard Worker 
101*bb4ee6a4SAndroid Build Coastguard Worker impl TryFrom<&dyn AsRawDescriptor> for SafeDescriptor {
102*bb4ee6a4SAndroid Build Coastguard Worker     type Error = std::io::Error;
103*bb4ee6a4SAndroid Build Coastguard Worker 
104*bb4ee6a4SAndroid Build Coastguard Worker     /// Clones the underlying descriptor (handle), internally creating a new descriptor.
105*bb4ee6a4SAndroid Build Coastguard Worker     ///
106*bb4ee6a4SAndroid Build Coastguard Worker     /// WARNING: Windows does NOT support cloning/duplicating all types of handles. DO NOT use this
107*bb4ee6a4SAndroid Build Coastguard Worker     /// function on IO completion ports, sockets, or pseudo-handles (except those from
108*bb4ee6a4SAndroid Build Coastguard Worker     /// GetCurrentProcess or GetCurrentThread). See
109*bb4ee6a4SAndroid Build Coastguard Worker     /// <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-duplicatehandle>
110*bb4ee6a4SAndroid Build Coastguard Worker     /// for further details.
111*bb4ee6a4SAndroid Build Coastguard Worker     ///
112*bb4ee6a4SAndroid Build Coastguard Worker     /// TODO(b/191800567): this API has sharp edges on Windows. We should evaluate making some
113*bb4ee6a4SAndroid Build Coastguard Worker     /// adjustments to smooth those edges.
try_from(rd: &dyn AsRawDescriptor) -> std::result::Result<Self, Self::Error>114*bb4ee6a4SAndroid Build Coastguard Worker     fn try_from(rd: &dyn AsRawDescriptor) -> std::result::Result<Self, Self::Error> {
115*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
116*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because the underlying raw descriptor is guaranteed valid by rd's existence.
117*bb4ee6a4SAndroid Build Coastguard Worker         //
118*bb4ee6a4SAndroid Build Coastguard Worker         // Note that we are cloning the underlying raw descriptor since we have no guarantee of
119*bb4ee6a4SAndroid Build Coastguard Worker         // its existence after this function returns.
120*bb4ee6a4SAndroid Build Coastguard Worker         let rd_as_safe_desc = ManuallyDrop::new(unsafe {
121*bb4ee6a4SAndroid Build Coastguard Worker             SafeDescriptor::from_raw_descriptor(rd.as_raw_descriptor())
122*bb4ee6a4SAndroid Build Coastguard Worker         });
123*bb4ee6a4SAndroid Build Coastguard Worker 
124*bb4ee6a4SAndroid Build Coastguard Worker         // We have to clone rd because we have no guarantee ownership was transferred (rd is
125*bb4ee6a4SAndroid Build Coastguard Worker         // borrowed).
126*bb4ee6a4SAndroid Build Coastguard Worker         rd_as_safe_desc
127*bb4ee6a4SAndroid Build Coastguard Worker             .try_clone()
128*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(|e| Self::Error::from_raw_os_error(e.errno()))
129*bb4ee6a4SAndroid Build Coastguard Worker     }
130*bb4ee6a4SAndroid Build Coastguard Worker }
131*bb4ee6a4SAndroid Build Coastguard Worker 
132*bb4ee6a4SAndroid Build Coastguard Worker impl From<File> for SafeDescriptor {
from(f: File) -> SafeDescriptor133*bb4ee6a4SAndroid Build Coastguard Worker     fn from(f: File) -> SafeDescriptor {
134*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
135*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we own the File at this point.
136*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { SafeDescriptor::from_raw_descriptor(f.into_raw_descriptor()) }
137*bb4ee6a4SAndroid Build Coastguard Worker     }
138*bb4ee6a4SAndroid Build Coastguard Worker }
139*bb4ee6a4SAndroid Build Coastguard Worker 
140*bb4ee6a4SAndroid Build Coastguard Worker /// For use cases where a simple wrapper around a [`RawDescriptor`] is needed, in order to e.g.
141*bb4ee6a4SAndroid Build Coastguard Worker /// implement [`trait@AsRawDescriptor`].
142*bb4ee6a4SAndroid Build Coastguard Worker ///
143*bb4ee6a4SAndroid Build Coastguard Worker /// This is a simply a wrapper and does not manage the lifetime of the descriptor. As such it is the
144*bb4ee6a4SAndroid Build Coastguard Worker /// responsibility of the user to ensure that the wrapped descriptor will not be closed for as long
145*bb4ee6a4SAndroid Build Coastguard Worker /// as the `Descriptor` is alive.
146*bb4ee6a4SAndroid Build Coastguard Worker ///
147*bb4ee6a4SAndroid Build Coastguard Worker /// Most use-cases should prefer [`SafeDescriptor`] or implementing and using
148*bb4ee6a4SAndroid Build Coastguard Worker /// [`trait@AsRawDescriptor`] on the type providing the descriptor. Using this wrapper usually means
149*bb4ee6a4SAndroid Build Coastguard Worker /// something can be improved in your code.
150*bb4ee6a4SAndroid Build Coastguard Worker ///
151*bb4ee6a4SAndroid Build Coastguard Worker /// Valid uses of this struct include:
152*bb4ee6a4SAndroid Build Coastguard Worker /// * You only have a valid [`RawDescriptor`] and need to pass something that implements
153*bb4ee6a4SAndroid Build Coastguard Worker ///   [`trait@AsRawDescriptor`] to a function,
154*bb4ee6a4SAndroid Build Coastguard Worker /// * You need to serialize a [`RawDescriptor`],
155*bb4ee6a4SAndroid Build Coastguard Worker /// * You need [`trait@Send`] or [`trait@Sync`] for your descriptor and properly handle the case
156*bb4ee6a4SAndroid Build Coastguard Worker ///   where your descriptor gets closed.
157*bb4ee6a4SAndroid Build Coastguard Worker ///
158*bb4ee6a4SAndroid Build Coastguard Worker /// Note that with the exception of the last use-case (which requires proper error checking against
159*bb4ee6a4SAndroid Build Coastguard Worker /// the descriptor being closed), the `Descriptor` instance would be very short-lived.
160*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
161*bb4ee6a4SAndroid Build Coastguard Worker #[repr(transparent)]
162*bb4ee6a4SAndroid Build Coastguard Worker pub struct Descriptor(pub RawDescriptor);
163*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for Descriptor {
as_raw_descriptor(&self) -> RawDescriptor164*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
165*bb4ee6a4SAndroid Build Coastguard Worker         self.0
166*bb4ee6a4SAndroid Build Coastguard Worker     }
167*bb4ee6a4SAndroid Build Coastguard Worker }
168*bb4ee6a4SAndroid Build Coastguard Worker impl FromRawDescriptor for Descriptor {
from_raw_descriptor(desc: RawDescriptor) -> Self169*bb4ee6a4SAndroid Build Coastguard Worker     unsafe fn from_raw_descriptor(desc: RawDescriptor) -> Self {
170*bb4ee6a4SAndroid Build Coastguard Worker         Descriptor(desc)
171*bb4ee6a4SAndroid Build Coastguard Worker     }
172*bb4ee6a4SAndroid Build Coastguard Worker }
173*bb4ee6a4SAndroid Build Coastguard Worker 
174*bb4ee6a4SAndroid Build Coastguard Worker /// Implement token for implementations that wish to use this struct as such
175*bb4ee6a4SAndroid Build Coastguard Worker impl EventToken for Descriptor {
as_raw_token(&self) -> u64176*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_token(&self) -> u64 {
177*bb4ee6a4SAndroid Build Coastguard Worker         self.0 as u64
178*bb4ee6a4SAndroid Build Coastguard Worker     }
179*bb4ee6a4SAndroid Build Coastguard Worker 
from_raw_token(data: u64) -> Self180*bb4ee6a4SAndroid Build Coastguard Worker     fn from_raw_token(data: u64) -> Self {
181*bb4ee6a4SAndroid Build Coastguard Worker         Descriptor(data as RawDescriptor)
182*bb4ee6a4SAndroid Build Coastguard Worker     }
183*bb4ee6a4SAndroid Build Coastguard Worker }
184*bb4ee6a4SAndroid Build Coastguard Worker 
185*bb4ee6a4SAndroid Build Coastguard Worker impl Serialize for Descriptor {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,186*bb4ee6a4SAndroid Build Coastguard Worker     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
187*bb4ee6a4SAndroid Build Coastguard Worker     where
188*bb4ee6a4SAndroid Build Coastguard Worker         S: Serializer,
189*bb4ee6a4SAndroid Build Coastguard Worker     {
190*bb4ee6a4SAndroid Build Coastguard Worker         serializer.serialize_u64(self.0 as u64)
191*bb4ee6a4SAndroid Build Coastguard Worker     }
192*bb4ee6a4SAndroid Build Coastguard Worker }
193*bb4ee6a4SAndroid Build Coastguard Worker 
194*bb4ee6a4SAndroid Build Coastguard Worker impl<'de> Deserialize<'de> for Descriptor {
deserialize<D>(deserializer: D) -> Result<Descriptor, D::Error> where D: serde::Deserializer<'de>,195*bb4ee6a4SAndroid Build Coastguard Worker     fn deserialize<D>(deserializer: D) -> Result<Descriptor, D::Error>
196*bb4ee6a4SAndroid Build Coastguard Worker     where
197*bb4ee6a4SAndroid Build Coastguard Worker         D: serde::Deserializer<'de>,
198*bb4ee6a4SAndroid Build Coastguard Worker     {
199*bb4ee6a4SAndroid Build Coastguard Worker         u64::deserialize(deserializer).map(|data| Descriptor(data as RawDescriptor))
200*bb4ee6a4SAndroid Build Coastguard Worker     }
201*bb4ee6a4SAndroid Build Coastguard Worker }
202