1 // SPDX-License-Identifier: GPL-2.0 2 3 // Copyright (c) 2024 Christian Brauner <brauner@kernel.org> 4 5 //! Pid namespaces. 6 //! 7 //! C header: [`include/linux/pid_namespace.h`](srctree/include/linux/pid_namespace.h) and 8 //! [`include/linux/pid.h`](srctree/include/linux/pid.h) 9 10 use crate::{bindings, sync::aref::AlwaysRefCounted, types::Opaque}; 11 use core::ptr; 12 13 /// Wraps the kernel's `struct pid_namespace`. Thread safe. 14 /// 15 /// This structure represents the Rust abstraction for a C `struct pid_namespace`. This 16 /// implementation abstracts the usage of an already existing C `struct pid_namespace` within Rust 17 /// code that we get passed from the C side. 18 #[repr(transparent)] 19 pub struct PidNamespace { 20 inner: Opaque<bindings::pid_namespace>, 21 } 22 23 impl PidNamespace { 24 /// Returns a raw pointer to the inner C struct. 25 #[inline] 26 pub fn as_ptr(&self) -> *mut bindings::pid_namespace { 27 self.inner.get() 28 } 29 30 /// Creates a reference to a [`PidNamespace`] from a valid pointer. 31 /// 32 /// # Safety 33 /// 34 /// The caller must ensure that `ptr` is valid and remains valid for the lifetime of the 35 /// returned [`PidNamespace`] reference. 36 pub unsafe fn from_ptr<'a>(ptr: *const bindings::pid_namespace) -> &'a Self { 37 // SAFETY: The safety requirements guarantee the validity of the dereference, while the 38 // `PidNamespace` type being transparent makes the cast ok. 39 unsafe { &*ptr.cast() } 40 } 41 } 42 43 // SAFETY: Instances of `PidNamespace` are always reference-counted. 44 unsafe impl AlwaysRefCounted for PidNamespace { 45 #[inline] 46 fn inc_ref(&self) { 47 // SAFETY: The existence of a shared reference means that the refcount is nonzero. 48 unsafe { bindings::get_pid_ns(self.as_ptr()) }; 49 } 50 51 #[inline] 52 unsafe fn dec_ref(obj: ptr::NonNull<PidNamespace>) { 53 // SAFETY: The safety requirements guarantee that the refcount is non-zero. 54 unsafe { bindings::put_pid_ns(obj.cast().as_ptr()) } 55 } 56 } 57 58 // SAFETY: 59 // - `PidNamespace::dec_ref` can be called from any thread. 60 // - It is okay to send ownership of `PidNamespace` across thread boundaries. 61 unsafe impl Send for PidNamespace {} 62 63 // SAFETY: It's OK to access `PidNamespace` through shared references from other threads because 64 // we're either accessing properties that don't change or that are properly synchronised by C code. 65 unsafe impl Sync for PidNamespace {} 66