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