1313c4281SWedson Almeida Filho // SPDX-License-Identifier: GPL-2.0 2313c4281SWedson Almeida Filho 3313c4281SWedson Almeida Filho //! Tasks (threads and processes). 4313c4281SWedson Almeida Filho //! 5bc2e7d5cSMiguel Ojeda //! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h). 6313c4281SWedson Almeida Filho 7e7572e5dSAlice Ryhl use crate::{ 8e7572e5dSAlice Ryhl bindings, 91dc707e6SLinus Torvalds ffi::{c_int, c_long, c_uint}, 10e0020ba6SChristian Brauner pid_namespace::PidNamespace, 11e0020ba6SChristian Brauner types::{ARef, NotThreadSafe, Opaque}, 12e7572e5dSAlice Ryhl }; 131dc707e6SLinus Torvalds use core::{ 141dc707e6SLinus Torvalds cmp::{Eq, PartialEq}, 151dc707e6SLinus Torvalds ops::Deref, 161dc707e6SLinus Torvalds ptr, 171dc707e6SLinus Torvalds }; 18e7b9b1ffSAlice Ryhl 19e7b9b1ffSAlice Ryhl /// A sentinel value used for infinite timeouts. 20e7b9b1ffSAlice Ryhl pub const MAX_SCHEDULE_TIMEOUT: c_long = c_long::MAX; 218da7a2b7SWedson Almeida Filho 22f090f0d0SAlice Ryhl /// Bitmask for tasks that are sleeping in an interruptible state. 23f090f0d0SAlice Ryhl pub const TASK_INTERRUPTIBLE: c_int = bindings::TASK_INTERRUPTIBLE as c_int; 24f090f0d0SAlice Ryhl /// Bitmask for tasks that are sleeping in an uninterruptible state. 25f090f0d0SAlice Ryhl pub const TASK_UNINTERRUPTIBLE: c_int = bindings::TASK_UNINTERRUPTIBLE as c_int; 26f090f0d0SAlice Ryhl /// Bitmask for tasks that are sleeping in a freezable state. 27f090f0d0SAlice Ryhl pub const TASK_FREEZABLE: c_int = bindings::TASK_FREEZABLE as c_int; 28f090f0d0SAlice Ryhl /// Convenience constant for waking up tasks regardless of whether they are in interruptible or 29f090f0d0SAlice Ryhl /// uninterruptible sleep. 308da7a2b7SWedson Almeida Filho pub const TASK_NORMAL: c_uint = bindings::TASK_NORMAL as c_uint; 318da7a2b7SWedson Almeida Filho 328da7a2b7SWedson Almeida Filho /// Returns the currently running task. 338da7a2b7SWedson Almeida Filho #[macro_export] 348da7a2b7SWedson Almeida Filho macro_rules! current { 358da7a2b7SWedson Almeida Filho () => { 368da7a2b7SWedson Almeida Filho // SAFETY: Deref + addr-of below create a temporary `TaskRef` that cannot outlive the 378da7a2b7SWedson Almeida Filho // caller. 388da7a2b7SWedson Almeida Filho unsafe { &*$crate::task::Task::current() } 39313c4281SWedson Almeida Filho }; 40e0020ba6SChristian Brauner } 41e0020ba6SChristian Brauner 42e0020ba6SChristian Brauner /// Returns the currently running task's pid namespace. 43e0020ba6SChristian Brauner #[macro_export] 44e0020ba6SChristian Brauner macro_rules! current_pid_ns { 45e0020ba6SChristian Brauner () => { 46e0020ba6SChristian Brauner // SAFETY: Deref + addr-of below create a temporary `PidNamespaceRef` that cannot outlive 47e0020ba6SChristian Brauner // the caller. 48e0020ba6SChristian Brauner unsafe { &*$crate::task::Task::current_pid_ns() } 49e0020ba6SChristian Brauner }; 50313c4281SWedson Almeida Filho } 51313c4281SWedson Almeida Filho 52313c4281SWedson Almeida Filho /// Wraps the kernel's `struct task_struct`. 53313c4281SWedson Almeida Filho /// 54313c4281SWedson Almeida Filho /// # Invariants 55313c4281SWedson Almeida Filho /// 56ebf2b8a7SValentin Obst /// All instances are valid tasks created by the C portion of the kernel. 57313c4281SWedson Almeida Filho /// 588da7a2b7SWedson Almeida Filho /// Instances of this type are always refcounted, that is, a call to `get_task_struct` ensures 598da7a2b7SWedson Almeida Filho /// that the allocation remains valid at least until the matching call to `put_task_struct`. 608da7a2b7SWedson Almeida Filho /// 618da7a2b7SWedson Almeida Filho /// # Examples 628da7a2b7SWedson Almeida Filho /// 638da7a2b7SWedson Almeida Filho /// The following is an example of getting the PID of the current thread with zero additional cost 648da7a2b7SWedson Almeida Filho /// when compared to the C version: 658da7a2b7SWedson Almeida Filho /// 668da7a2b7SWedson Almeida Filho /// ``` 678da7a2b7SWedson Almeida Filho /// let pid = current!().pid(); 688da7a2b7SWedson Almeida Filho /// ``` 698da7a2b7SWedson Almeida Filho /// 708da7a2b7SWedson Almeida Filho /// Getting the PID of the current process, also zero additional cost: 718da7a2b7SWedson Almeida Filho /// 728da7a2b7SWedson Almeida Filho /// ``` 738da7a2b7SWedson Almeida Filho /// let pid = current!().group_leader().pid(); 748da7a2b7SWedson Almeida Filho /// ``` 758da7a2b7SWedson Almeida Filho /// 768da7a2b7SWedson Almeida Filho /// Getting the current task and storing it in some struct. The reference count is automatically 778da7a2b7SWedson Almeida Filho /// incremented when creating `State` and decremented when it is dropped: 788da7a2b7SWedson Almeida Filho /// 798da7a2b7SWedson Almeida Filho /// ``` 808da7a2b7SWedson Almeida Filho /// use kernel::{task::Task, types::ARef}; 818da7a2b7SWedson Almeida Filho /// 828da7a2b7SWedson Almeida Filho /// struct State { 838da7a2b7SWedson Almeida Filho /// creator: ARef<Task>, 848da7a2b7SWedson Almeida Filho /// index: u32, 858da7a2b7SWedson Almeida Filho /// } 868da7a2b7SWedson Almeida Filho /// 878da7a2b7SWedson Almeida Filho /// impl State { 888da7a2b7SWedson Almeida Filho /// fn new() -> Self { 898da7a2b7SWedson Almeida Filho /// Self { 908da7a2b7SWedson Almeida Filho /// creator: current!().into(), 918da7a2b7SWedson Almeida Filho /// index: 0, 928da7a2b7SWedson Almeida Filho /// } 938da7a2b7SWedson Almeida Filho /// } 94313c4281SWedson Almeida Filho /// } 95313c4281SWedson Almeida Filho /// ``` 96313c4281SWedson Almeida Filho #[repr(transparent)] 97d09a6102SAlice Ryhl pub struct Task(pub(crate) Opaque<bindings::task_struct>); 98d09a6102SAlice Ryhl 99d09a6102SAlice Ryhl // SAFETY: By design, the only way to access a `Task` is via the `current` function or via an 100d09a6102SAlice Ryhl // `ARef<Task>` obtained through the `AlwaysRefCounted` impl. This means that the only situation in 101d09a6102SAlice Ryhl // which a `Task` can be accessed mutably is when the refcount drops to zero and the destructor 102d09a6102SAlice Ryhl // runs. It is safe for that to happen on any thread, so it is ok for this type to be `Send`. 103d09a6102SAlice Ryhl unsafe impl Send for Task {} 104d09a6102SAlice Ryhl 105313c4281SWedson Almeida Filho // SAFETY: It's OK to access `Task` through shared references from other threads because we're 106313c4281SWedson Almeida Filho // either accessing properties that don't change (e.g., `pid`, `group_leader`) or that are properly 107313c4281SWedson Almeida Filho // synchronised by C code (e.g., `signal_pending`). 108313c4281SWedson Almeida Filho unsafe impl Sync for Task {} 109313c4281SWedson Almeida Filho 110313c4281SWedson Almeida Filho /// The type of process identifiers (PIDs). 1118ad1a41fSAlice Ryhl pub type Pid = bindings::pid_t; 1128ad1a41fSAlice Ryhl 1138ad1a41fSAlice Ryhl /// The type of user identifiers (UIDs). 1148ad1a41fSAlice Ryhl #[derive(Copy, Clone)] 1158ad1a41fSAlice Ryhl pub struct Kuid { 1168ad1a41fSAlice Ryhl kuid: bindings::kuid_t, 117313c4281SWedson Almeida Filho } 118913f8cf4SAlice Ryhl 119913f8cf4SAlice Ryhl impl Task { 120913f8cf4SAlice Ryhl /// Returns a raw pointer to the current task. 121913f8cf4SAlice Ryhl /// 122913f8cf4SAlice Ryhl /// It is up to the user to use the pointer correctly. 123913f8cf4SAlice Ryhl #[inline] current_raw() -> *mut bindings::task_struct124913f8cf4SAlice Ryhl pub fn current_raw() -> *mut bindings::task_struct { 125913f8cf4SAlice Ryhl // SAFETY: Getting the current pointer is always safe. 126913f8cf4SAlice Ryhl unsafe { bindings::get_current() } 1278da7a2b7SWedson Almeida Filho } 1288da7a2b7SWedson Almeida Filho 1298da7a2b7SWedson Almeida Filho /// Returns a task reference for the currently executing task/thread. 130c61bcc27SMiguel Ojeda /// 1318da7a2b7SWedson Almeida Filho /// The recommended way to get the current task/thread is to use the 1328da7a2b7SWedson Almeida Filho /// [`current`] macro because it is safe. 1338da7a2b7SWedson Almeida Filho /// 1348da7a2b7SWedson Almeida Filho /// # Safety 1358da7a2b7SWedson Almeida Filho /// 1368da7a2b7SWedson Almeida Filho /// Callers must ensure that the returned object doesn't outlive the current task/thread. current() -> impl Deref<Target = Task>1378da7a2b7SWedson Almeida Filho pub unsafe fn current() -> impl Deref<Target = Task> { 138e7572e5dSAlice Ryhl struct TaskRef<'a> { 1398da7a2b7SWedson Almeida Filho task: &'a Task, 1408da7a2b7SWedson Almeida Filho _not_send: NotThreadSafe, 1418da7a2b7SWedson Almeida Filho } 1428da7a2b7SWedson Almeida Filho 1438da7a2b7SWedson Almeida Filho impl Deref for TaskRef<'_> { 1448da7a2b7SWedson Almeida Filho type Target = Task; 1458da7a2b7SWedson Almeida Filho 1468da7a2b7SWedson Almeida Filho fn deref(&self) -> &Self::Target { 1478da7a2b7SWedson Almeida Filho self.task 1488da7a2b7SWedson Almeida Filho } 149913f8cf4SAlice Ryhl } 1508da7a2b7SWedson Almeida Filho 1518da7a2b7SWedson Almeida Filho let current = Task::current_raw(); 1528da7a2b7SWedson Almeida Filho TaskRef { 1538da7a2b7SWedson Almeida Filho // SAFETY: If the current thread is still running, the current task is valid. Given 154913f8cf4SAlice Ryhl // that `TaskRef` is not `Send`, we know it cannot be transferred to another thread 155e7572e5dSAlice Ryhl // (where it could potentially outlive the caller). 1568da7a2b7SWedson Almeida Filho task: unsafe { &*current.cast() }, 1578da7a2b7SWedson Almeida Filho _not_send: NotThreadSafe, 1588da7a2b7SWedson Almeida Filho } 159e0020ba6SChristian Brauner } 160e0020ba6SChristian Brauner 161e0020ba6SChristian Brauner /// Returns a PidNamespace reference for the currently executing task's/thread's pid namespace. 162e0020ba6SChristian Brauner /// 163e0020ba6SChristian Brauner /// This function can be used to create an unbounded lifetime by e.g., storing the returned 164e0020ba6SChristian Brauner /// PidNamespace in a global variable which would be a bug. So the recommended way to get the 165e0020ba6SChristian Brauner /// current task's/thread's pid namespace is to use the [`current_pid_ns`] macro because it is 166e0020ba6SChristian Brauner /// safe. 167e0020ba6SChristian Brauner /// 168e0020ba6SChristian Brauner /// # Safety 169e0020ba6SChristian Brauner /// 170e0020ba6SChristian Brauner /// Callers must ensure that the returned object doesn't outlive the current task/thread. current_pid_ns() -> impl Deref<Target = PidNamespace>171e0020ba6SChristian Brauner pub unsafe fn current_pid_ns() -> impl Deref<Target = PidNamespace> { 172e0020ba6SChristian Brauner struct PidNamespaceRef<'a> { 173e0020ba6SChristian Brauner task: &'a PidNamespace, 174e0020ba6SChristian Brauner _not_send: NotThreadSafe, 175e0020ba6SChristian Brauner } 176e0020ba6SChristian Brauner 177e0020ba6SChristian Brauner impl Deref for PidNamespaceRef<'_> { 178e0020ba6SChristian Brauner type Target = PidNamespace; 179e0020ba6SChristian Brauner 180e0020ba6SChristian Brauner fn deref(&self) -> &Self::Target { 181e0020ba6SChristian Brauner self.task 182e0020ba6SChristian Brauner } 183e0020ba6SChristian Brauner } 184e0020ba6SChristian Brauner 185e0020ba6SChristian Brauner // The lifetime of `PidNamespace` is bound to `Task` and `struct pid`. 186e0020ba6SChristian Brauner // 187e0020ba6SChristian Brauner // The `PidNamespace` of a `Task` doesn't ever change once the `Task` is alive. A 188e0020ba6SChristian Brauner // `unshare(CLONE_NEWPID)` or `setns(fd_pidns/pidfd, CLONE_NEWPID)` will not have an effect 189e0020ba6SChristian Brauner // on the calling `Task`'s pid namespace. It will only effect the pid namespace of children 190e0020ba6SChristian Brauner // created by the calling `Task`. This invariant guarantees that after having acquired a 191e0020ba6SChristian Brauner // reference to a `Task`'s pid namespace it will remain unchanged. 192e0020ba6SChristian Brauner // 193e0020ba6SChristian Brauner // When a task has exited and been reaped `release_task()` will be called. This will set 194e0020ba6SChristian Brauner // the `PidNamespace` of the task to `NULL`. So retrieving the `PidNamespace` of a task 195e0020ba6SChristian Brauner // that is dead will return `NULL`. Note, that neither holding the RCU lock nor holding a 196e0020ba6SChristian Brauner // referencing count to 197e0020ba6SChristian Brauner // the `Task` will prevent `release_task()` being called. 198e0020ba6SChristian Brauner // 199e0020ba6SChristian Brauner // In order to retrieve the `PidNamespace` of a `Task` the `task_active_pid_ns()` function 200e0020ba6SChristian Brauner // can be used. There are two cases to consider: 201e0020ba6SChristian Brauner // 202e0020ba6SChristian Brauner // (1) retrieving the `PidNamespace` of the `current` task 203e0020ba6SChristian Brauner // (2) retrieving the `PidNamespace` of a non-`current` task 204e0020ba6SChristian Brauner // 205e0020ba6SChristian Brauner // From system call context retrieving the `PidNamespace` for case (1) is always safe and 206e0020ba6SChristian Brauner // requires neither RCU locking nor a reference count to be held. Retrieving the 207e0020ba6SChristian Brauner // `PidNamespace` after `release_task()` for current will return `NULL` but no codepath 208e0020ba6SChristian Brauner // like that is exposed to Rust. 209e0020ba6SChristian Brauner // 210e0020ba6SChristian Brauner // Retrieving the `PidNamespace` from system call context for (2) requires RCU protection. 211e0020ba6SChristian Brauner // Accessing `PidNamespace` outside of RCU protection requires a reference count that 212e0020ba6SChristian Brauner // must've been acquired while holding the RCU lock. Note that accessing a non-`current` 213e0020ba6SChristian Brauner // task means `NULL` can be returned as the non-`current` task could have already passed 214e0020ba6SChristian Brauner // through `release_task()`. 215e0020ba6SChristian Brauner // 216e0020ba6SChristian Brauner // To retrieve (1) the `current_pid_ns!()` macro should be used which ensure that the 217e0020ba6SChristian Brauner // returned `PidNamespace` cannot outlive the calling scope. The associated 218e0020ba6SChristian Brauner // `current_pid_ns()` function should not be called directly as it could be abused to 219e0020ba6SChristian Brauner // created an unbounded lifetime for `PidNamespace`. The `current_pid_ns!()` macro allows 220e0020ba6SChristian Brauner // Rust to handle the common case of accessing `current`'s `PidNamespace` without RCU 221e0020ba6SChristian Brauner // protection and without having to acquire a reference count. 222e0020ba6SChristian Brauner // 223e0020ba6SChristian Brauner // For (2) the `task_get_pid_ns()` method must be used. This will always acquire a 224e0020ba6SChristian Brauner // reference on `PidNamespace` and will return an `Option` to force the caller to 225e0020ba6SChristian Brauner // explicitly handle the case where `PidNamespace` is `None`, something that tends to be 226e0020ba6SChristian Brauner // forgotten when doing the equivalent operation in `C`. Missing RCU primitives make it 227e0020ba6SChristian Brauner // difficult to perform operations that are otherwise safe without holding a reference 228e0020ba6SChristian Brauner // count as long as RCU protection is guaranteed. But it is not important currently. But we 229e0020ba6SChristian Brauner // do want it in the future. 230e0020ba6SChristian Brauner // 231e0020ba6SChristian Brauner // Note for (2) the required RCU protection around calling `task_active_pid_ns()` 232e0020ba6SChristian Brauner // synchronizes against putting the last reference of the associated `struct pid` of 233e0020ba6SChristian Brauner // `task->thread_pid`. The `struct pid` stored in that field is used to retrieve the 234e0020ba6SChristian Brauner // `PidNamespace` of the caller. When `release_task()` is called `task->thread_pid` will be 235e0020ba6SChristian Brauner // `NULL`ed and `put_pid()` on said `struct pid` will be delayed in `free_pid()` via 236e0020ba6SChristian Brauner // `call_rcu()` allowing everyone with an RCU protected access to the `struct pid` acquired 237e0020ba6SChristian Brauner // from `task->thread_pid` to finish. 238e0020ba6SChristian Brauner // 239e0020ba6SChristian Brauner // SAFETY: The current task's pid namespace is valid as long as the current task is running. 240e0020ba6SChristian Brauner let pidns = unsafe { bindings::task_active_pid_ns(Task::current_raw()) }; 241e0020ba6SChristian Brauner PidNamespaceRef { 242e0020ba6SChristian Brauner // SAFETY: If the current thread is still running, the current task and its associated 243e0020ba6SChristian Brauner // pid namespace are valid. `PidNamespaceRef` is not `Send`, so we know it cannot be 244e0020ba6SChristian Brauner // transferred to another thread (where it could potentially outlive the current 245e0020ba6SChristian Brauner // `Task`). The caller needs to ensure that the PidNamespaceRef doesn't outlive the 246e0020ba6SChristian Brauner // current task/thread. 247e0020ba6SChristian Brauner task: unsafe { PidNamespace::from_ptr(pidns) }, 248e0020ba6SChristian Brauner _not_send: NotThreadSafe, 249e0020ba6SChristian Brauner } 250fe95f583SAlice Ryhl } 251fe95f583SAlice Ryhl 252fe95f583SAlice Ryhl /// Returns a raw pointer to the task. 253fe95f583SAlice Ryhl #[inline] as_ptr(&self) -> *mut bindings::task_struct254fe95f583SAlice Ryhl pub fn as_ptr(&self) -> *mut bindings::task_struct { 255fe95f583SAlice Ryhl self.0.get() 256313c4281SWedson Almeida Filho } 257313c4281SWedson Almeida Filho 258fe95f583SAlice Ryhl /// Returns the group leader of the given task. group_leader(&self) -> &Task259fe95f583SAlice Ryhl pub fn group_leader(&self) -> &Task { 260fe95f583SAlice Ryhl // SAFETY: The group leader of a task never changes after initialization, so reading this 261313c4281SWedson Almeida Filho // field is not a data race. 262313c4281SWedson Almeida Filho let ptr = unsafe { *ptr::addr_of!((*self.as_ptr()).group_leader) }; 263313c4281SWedson Almeida Filho 264313c4281SWedson Almeida Filho // SAFETY: The lifetime of the returned task reference is tied to the lifetime of `self`, 265313c4281SWedson Almeida Filho // and given that a task has a reference to its group leader, we know it must be valid for 266313c4281SWedson Almeida Filho // the lifetime of the returned task reference. 267313c4281SWedson Almeida Filho unsafe { &*ptr.cast() } 268313c4281SWedson Almeida Filho } 269313c4281SWedson Almeida Filho 270fe95f583SAlice Ryhl /// Returns the PID of the given task. pid(&self) -> Pid271fe95f583SAlice Ryhl pub fn pid(&self) -> Pid { 272fe95f583SAlice Ryhl // SAFETY: The pid of a task never changes after initialization, so reading this field is 273313c4281SWedson Almeida Filho // not a data race. 274313c4281SWedson Almeida Filho unsafe { *ptr::addr_of!((*self.as_ptr()).pid) } 2758ad1a41fSAlice Ryhl } 2768ad1a41fSAlice Ryhl 277fe95f583SAlice Ryhl /// Returns the UID of the given task. uid(&self) -> Kuid278fe95f583SAlice Ryhl pub fn uid(&self) -> Kuid { 2798ad1a41fSAlice Ryhl // SAFETY: It's always safe to call `task_uid` on a valid task. 2808ad1a41fSAlice Ryhl Kuid::from_raw(unsafe { bindings::task_uid(self.as_ptr()) }) 2818ad1a41fSAlice Ryhl } 2828ad1a41fSAlice Ryhl 283fe95f583SAlice Ryhl /// Returns the effective UID of the given task. euid(&self) -> Kuid284fe95f583SAlice Ryhl pub fn euid(&self) -> Kuid { 2858ad1a41fSAlice Ryhl // SAFETY: It's always safe to call `task_euid` on a valid task. 2868ad1a41fSAlice Ryhl Kuid::from_raw(unsafe { bindings::task_euid(self.as_ptr()) }) 287313c4281SWedson Almeida Filho } 288313c4281SWedson Almeida Filho 289fe95f583SAlice Ryhl /// Determines whether the given task has pending signals. signal_pending(&self) -> bool290fe95f583SAlice Ryhl pub fn signal_pending(&self) -> bool { 291313c4281SWedson Almeida Filho // SAFETY: It's always safe to call `signal_pending` on a valid task. 292313c4281SWedson Almeida Filho unsafe { bindings::signal_pending(self.as_ptr()) != 0 } 293e0020ba6SChristian Brauner } 294e0020ba6SChristian Brauner 295e0020ba6SChristian Brauner /// Returns task's pid namespace with elevated reference count get_pid_ns(&self) -> Option<ARef<PidNamespace>>2969ad8d22fSLinus Torvalds pub fn get_pid_ns(&self) -> Option<ARef<PidNamespace>> { 297e0020ba6SChristian Brauner // SAFETY: By the type invariant, we know that `self.0` is valid. 298e0020ba6SChristian Brauner let ptr = unsafe { bindings::task_get_pid_ns(self.as_ptr()) }; 299e0020ba6SChristian Brauner if ptr.is_null() { 300e0020ba6SChristian Brauner None 301e0020ba6SChristian Brauner } else { 302e0020ba6SChristian Brauner // SAFETY: `ptr` is valid by the safety requirements of this function. And we own a 303e0020ba6SChristian Brauner // reference count via `task_get_pid_ns()`. 304e0020ba6SChristian Brauner // CAST: `Self` is a `repr(transparent)` wrapper around `bindings::pid_namespace`. 305e0020ba6SChristian Brauner Some(unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(ptr.cast::<PidNamespace>())) }) 306e0020ba6SChristian Brauner } 307e0020ba6SChristian Brauner } 308e0020ba6SChristian Brauner 309e0020ba6SChristian Brauner /// Returns the given task's pid in the provided pid namespace. 310e0020ba6SChristian Brauner #[doc(alias = "task_tgid_nr_ns")] tgid_nr_ns(&self, pidns: Option<&PidNamespace>) -> Pid311e0020ba6SChristian Brauner pub fn tgid_nr_ns(&self, pidns: Option<&PidNamespace>) -> Pid { 312e0020ba6SChristian Brauner let pidns = match pidns { 313e0020ba6SChristian Brauner Some(pidns) => pidns.as_ptr(), 314e0020ba6SChristian Brauner None => core::ptr::null_mut(), 315e0020ba6SChristian Brauner }; 316e0020ba6SChristian Brauner // SAFETY: By the type invariant, we know that `self.0` is valid. We received a valid 317e0020ba6SChristian Brauner // PidNamespace that we can use as a pointer or we received an empty PidNamespace and 3189ad8d22fSLinus Torvalds // thus pass a null pointer. The underlying C function is safe to be used with NULL 3198ad1a41fSAlice Ryhl // pointers. 3208ad1a41fSAlice Ryhl unsafe { bindings::task_tgid_nr_ns(self.as_ptr(), pidns) } 321313c4281SWedson Almeida Filho } 322313c4281SWedson Almeida Filho 323*6fbafe1cSPanagiotis Foliadis /// Wakes up the task. wake_up(&self)324313c4281SWedson Almeida Filho pub fn wake_up(&self) { 325fe95f583SAlice Ryhl // SAFETY: It's always safe to call `wake_up_process` on a valid task, even if the task 326313c4281SWedson Almeida Filho // running. 327313c4281SWedson Almeida Filho unsafe { bindings::wake_up_process(self.as_ptr()) }; 328313c4281SWedson Almeida Filho } 329ebf2b8a7SValentin Obst } 330313c4281SWedson Almeida Filho 331313c4281SWedson Almeida Filho // SAFETY: The type invariants guarantee that `Task` is always refcounted. 332313c4281SWedson Almeida Filho unsafe impl crate::types::AlwaysRefCounted for Task { inc_ref(&self)333fe95f583SAlice Ryhl fn inc_ref(&self) { 334313c4281SWedson Almeida Filho // SAFETY: The existence of a shared reference means that the refcount is nonzero. 335313c4281SWedson Almeida Filho unsafe { bindings::get_task_struct(self.as_ptr()) }; 336313c4281SWedson Almeida Filho } 337313c4281SWedson Almeida Filho dec_ref(obj: ptr::NonNull<Self>)338313c4281SWedson Almeida Filho unsafe fn dec_ref(obj: ptr::NonNull<Self>) { 339313c4281SWedson Almeida Filho // SAFETY: The safety requirements guarantee that the refcount is nonzero. 340313c4281SWedson Almeida Filho unsafe { bindings::put_task_struct(obj.cast().as_ptr()) } 3418ad1a41fSAlice Ryhl } 3428ad1a41fSAlice Ryhl } 3438ad1a41fSAlice Ryhl 3448ad1a41fSAlice Ryhl impl Kuid { 3458ad1a41fSAlice Ryhl /// Get the current euid. 3468ad1a41fSAlice Ryhl #[inline] current_euid() -> Kuid3478ad1a41fSAlice Ryhl pub fn current_euid() -> Kuid { 3488ad1a41fSAlice Ryhl // SAFETY: Just an FFI call. 3498ad1a41fSAlice Ryhl Self::from_raw(unsafe { bindings::current_euid() }) 3508ad1a41fSAlice Ryhl } 3518ad1a41fSAlice Ryhl 3528ad1a41fSAlice Ryhl /// Create a `Kuid` given the raw C type. 3538ad1a41fSAlice Ryhl #[inline] from_raw(kuid: bindings::kuid_t) -> Self3548ad1a41fSAlice Ryhl pub fn from_raw(kuid: bindings::kuid_t) -> Self { 3558ad1a41fSAlice Ryhl Self { kuid } 3568ad1a41fSAlice Ryhl } 3578ad1a41fSAlice Ryhl 3588ad1a41fSAlice Ryhl /// Turn this kuid into the raw C type. 3598ad1a41fSAlice Ryhl #[inline] into_raw(self) -> bindings::kuid_t3608ad1a41fSAlice Ryhl pub fn into_raw(self) -> bindings::kuid_t { 3618ad1a41fSAlice Ryhl self.kuid 3628ad1a41fSAlice Ryhl } 3638ad1a41fSAlice Ryhl 3648ad1a41fSAlice Ryhl /// Converts this kernel UID into a userspace UID. 3658ad1a41fSAlice Ryhl /// 3668ad1a41fSAlice Ryhl /// Uses the namespace of the current task. 3678ad1a41fSAlice Ryhl #[inline] into_uid_in_current_ns(self) -> bindings::uid_t3688ad1a41fSAlice Ryhl pub fn into_uid_in_current_ns(self) -> bindings::uid_t { 3698ad1a41fSAlice Ryhl // SAFETY: Just an FFI call. 3708ad1a41fSAlice Ryhl unsafe { bindings::from_kuid(bindings::current_user_ns(), self.kuid) } 3718ad1a41fSAlice Ryhl } 3728ad1a41fSAlice Ryhl } 3738ad1a41fSAlice Ryhl 3748ad1a41fSAlice Ryhl impl PartialEq for Kuid { 3758ad1a41fSAlice Ryhl #[inline] eq(&self, other: &Kuid) -> bool3768ad1a41fSAlice Ryhl fn eq(&self, other: &Kuid) -> bool { 3778ad1a41fSAlice Ryhl // SAFETY: Just an FFI call. 3788ad1a41fSAlice Ryhl unsafe { bindings::uid_eq(self.kuid, other.kuid) } 3798ad1a41fSAlice Ryhl } 3808ad1a41fSAlice Ryhl } 381 382 impl Eq for Kuid {} 383