pub struct Task {Show 15 fields
pub weak_self: WeakRef<Self>,
pub tid: tid_t,
pub thread_group_key: ThreadGroupKey,
pub kernel: Arc<Kernel>,
pub thread_group: Arc<ThreadGroup>,
pub thread: RwLock<Option<Arc<Thread>>>,
pub files: FdTable,
pub mm: RcuOptionArc<MemoryManager>,
pub abstract_socket_namespace: Arc<AbstractUnixSocketNamespace>,
pub abstract_vsock_namespace: Arc<AbstractVsockSocketNamespace>,
pub persistent_info: TaskPersistentInfo,
pub seccomp_filter_state: SeccompState,
pub trace_syscalls: AtomicBool,
pub proc_pid_directory_cache: Mutex<Option<FsNodeHandle>>,
pub security_state: TaskState,
/* private fields */
}Expand description
A unit of execution.
A task is the primary unit of execution in the Starnix kernel. Most tasks are user tasks, which have an associated Zircon thread. The Zircon thread switches between restricted mode, in which the thread runs userspace code, and normal mode, in which the thread runs Starnix code.
Tasks track the resources used by userspace by referencing various objects, such as an
FdTable, a MemoryManager, and an FsContext. Many tasks can share references to these
objects. In principle, which objects are shared between which tasks can be largely arbitrary,
but there are common patterns of sharing. For example, tasks created with pthread_create
will share the FdTable, MemoryManager, and FsContext and are often called “threads” by
userspace programmers. Tasks created by posix_spawn do not share these objects and are often
called “processes” by userspace programmers. However, inside the kernel, there is no clear
definition of a “thread” or a “process”.
During boot, the kernel creates the first task, often called init. The vast majority of other
tasks are created as transitive clones (e.g., using clone(2)) of that task. Sometimes, the
kernel will create new tasks from whole cloth, either with a corresponding userspace component
or to represent some background work inside the kernel.
See also CurrentTask, which represents the task corresponding to the thread that is currently
executing.
Fields§
§weak_self: WeakRef<Self>Weak reference to the OwnedRef of this Task. This allows to retrieve the
TempRef from a raw Task.
tid: tid_tA unique identifier for this task.
This value can be read in userspace using gettid(2). In general, this value
is different from the value return by getpid(2), which returns the id of the leader
of the thread_group.
thread_group_key: ThreadGroupKeyThe process key of this task.
kernel: Arc<Kernel>The kernel to which this thread group belongs.
thread_group: Arc<ThreadGroup>The thread group to which this task belongs.
The group of tasks in a thread group roughly corresponds to the userspace notion of a process.
thread: RwLock<Option<Arc<Thread>>>A handle to the underlying Zircon thread object.
Some tasks lack an underlying Zircon thread. These tasks are used internally by the
Starnix kernel to track background work, typically on a kthread.
files: FdTableThe file descriptor table for this task.
This table can be share by many tasks.
mm: RcuOptionArc<MemoryManager>The memory manager for this task. This is None only for system tasks.
abstract_socket_namespace: Arc<AbstractUnixSocketNamespace>The namespace for abstract AF_UNIX sockets for this task.
abstract_vsock_namespace: Arc<AbstractVsockSocketNamespace>The namespace for AF_VSOCK for this task.
persistent_info: TaskPersistentInfoThe information of the task that needs to be available to the ThreadGroup while computing
which process a wait can target.
Contains the command line, the task credentials and the exit signal.
See TaskPersistentInfo for more information.
seccomp_filter_state: SeccompStateVariable that can tell you whether there are currently seccomp filters without holding a lock
trace_syscalls: AtomicBoolTell you whether you are tracing syscall entry / exit without a lock.
proc_pid_directory_cache: Mutex<Option<FsNodeHandle>>§security_state: TaskStateThe Linux Security Modules state for this thread group. This should be the last member of this struct.
Implementations§
Source§impl Task
impl Task
pub fn kernel(&self) -> &Arc<Kernel>
pub fn thread_group(&self) -> &Arc<ThreadGroup>
pub fn has_same_address_space(&self, other: Option<&Arc<MemoryManager>>) -> bool
pub fn flags(&self) -> TaskFlags
Sourcepub fn set_ptrace_zombie(&self, pids: &mut PidTable)
pub fn set_ptrace_zombie(&self, pids: &mut PidTable)
When the task exits, if there is a notification that needs to propagate to a ptracer, make sure it will propagate.
Sourcepub fn ptrace_disconnect(&mut self, pids: &PidTable)
pub fn ptrace_disconnect(&mut self, pids: &PidTable)
Disconnects this task from the tracer, if the tracer is still running.
pub fn exit_status(&self) -> Option<ExitStatus>
pub fn is_exitted(&self) -> bool
pub fn load_stopped(&self) -> StopState
Sourcepub fn from_weak(weak: &WeakRef<Task>) -> Result<TempRef<'_, Task>, Errno>
pub fn from_weak(weak: &WeakRef<Task>) -> Result<TempRef<'_, Task>, Errno>
Upgrade a Reference to a Task, returning a ESRCH errno if the reference cannot be borrowed.
Sourcepub fn new(
tid: tid_t,
command: TaskCommand,
thread_group: Arc<ThreadGroup>,
thread: Option<Thread>,
files: FdTable,
mm: Option<Arc<MemoryManager>>,
fs: Arc<FsContext>,
creds: Credentials,
abstract_socket_namespace: Arc<AbstractUnixSocketNamespace>,
abstract_vsock_namespace: Arc<AbstractVsockSocketNamespace>,
signal_mask: SigSet,
kernel_signals: VecDeque<KernelSignal>,
vfork_event: Option<Arc<Event>>,
scheduler_state: SchedulerState,
uts_ns: UtsNamespaceHandle,
no_new_privs: bool,
seccomp_filter_state: SeccompState,
seccomp_filters: SeccompFilterContainer,
robust_list_head: RobustListHeadPtr,
timerslack_ns: u64,
security_state: TaskState,
) -> OwnedRef<Self>
pub fn new( tid: tid_t, command: TaskCommand, thread_group: Arc<ThreadGroup>, thread: Option<Thread>, files: FdTable, mm: Option<Arc<MemoryManager>>, fs: Arc<FsContext>, creds: Credentials, abstract_socket_namespace: Arc<AbstractUnixSocketNamespace>, abstract_vsock_namespace: Arc<AbstractVsockSocketNamespace>, signal_mask: SigSet, kernel_signals: VecDeque<KernelSignal>, vfork_event: Option<Arc<Event>>, scheduler_state: SchedulerState, uts_ns: UtsNamespaceHandle, no_new_privs: bool, seccomp_filter_state: SeccompState, seccomp_filters: SeccompFilterContainer, robust_list_head: RobustListHeadPtr, timerslack_ns: u64, security_state: TaskState, ) -> OwnedRef<Self>
Internal function for creating a Task object. Useful when you need to specify the value of every field. create_process and create_thread are more likely to be what you want.
Any fields that should be initialized fresh for every task, even if the task was created with fork, are initialized to their defaults inside this function. All other fields are passed as parameters.
pub fn read<'a>(self: &'a Task) -> TaskReadGuard<'a>
pub fn write<'a>(self: &'a Task) -> TaskWriteGuard<'a>
pub fn add_file<L>(
&self,
locked: &mut Locked<L>,
file: FileHandle,
flags: FdFlags,
) -> Result<FdNumber, Errno>where
L: LockEqualOrBefore<FileOpsCore>,
Sourcepub fn real_creds(&self) -> Credentials
pub fn real_creds(&self) -> Credentials
Returns the real credentials of the task. These credentials are used to check permissions
for actions performed on the task. If the task itself is performing an action, use
CurrentTask::current_creds instead.
pub fn with_real_creds<B, F>(&self, f: F) -> Bwhere
F: FnOnce(&Credentials) -> B,
pub fn ptracer_task(&self) -> WeakRef<Task>
pub fn fs(&self) -> Arc<FsContext>
pub fn mm(&self) -> Result<Arc<MemoryManager>, Errno>
Sourcepub fn set_scheduler_state(
&self,
scheduler_state: SchedulerState,
) -> Result<(), Errno>
pub fn set_scheduler_state( &self, scheduler_state: SchedulerState, ) -> Result<(), Errno>
Overwrite the existing scheduler state with a new one and update the task’s thread’s role.
Sourcepub fn sync_scheduler_state_to_role(&self) -> Result<(), Errno>
pub fn sync_scheduler_state_to_role(&self) -> Result<(), Errno>
Update the task’s thread’s role based on its current scheduler state without making any changes to the state.
This should be called on tasks that have newly created threads, e.g. after cloning.
Sourcepub fn signal_vfork(&self)
pub fn signal_vfork(&self)
Signals the vfork event, if any, to unblock waiters.
Sourcepub fn wait_for_execve(&self, task_to_wait: WeakRef<Task>) -> Result<(), Errno>
pub fn wait_for_execve(&self, task_to_wait: WeakRef<Task>) -> Result<(), Errno>
Blocks the caller until the task has exited or executed execve(). This is used to implement vfork() and clone(… CLONE_VFORK, …). The task must have created with CLONE_EXECVE.
Sourcepub fn clear_child_tid_if_needed<L>(
&self,
locked: &mut Locked<L>,
) -> Result<(), Errno>where
L: LockBefore<TerminalLock>,
pub fn clear_child_tid_if_needed<L>(
&self,
locked: &mut Locked<L>,
) -> Result<(), Errno>where
L: LockBefore<TerminalLock>,
If needed, clear the child tid for this task.
Userspace can ask us to clear the child tid and issue a futex wake at the child tid address when we tear down a task. For example, bionic uses this mechanism to implement pthread_join. The thread that calls pthread_join sleeps using FUTEX_WAIT on the child tid address. We wake them up here to let them know the thread is done.
pub fn get_task(&self, tid: tid_t) -> WeakRef<Task>
pub fn get_pid(&self) -> pid_t
pub fn get_tid(&self) -> tid_t
pub fn is_leader(&self) -> bool
pub fn read_argv(&self, max_len: usize) -> Result<Vec<FsString>, Errno>
pub fn read_argv0(&self) -> Result<FsString, Errno>
pub fn read_env(&self, max_len: usize) -> Result<Vec<FsString>, Errno>
pub fn thread_runtime_info(&self) -> Result<TaskRuntimeInfo, Errno>
pub fn real_fscred(&self) -> FsCred
Sourcepub fn interrupt(&self)
pub fn interrupt(&self)
Interrupts the current task.
This will interrupt any blocking syscalls if the task is blocked on one. The signal_state of the task must not be locked.
pub fn command(&self) -> TaskCommand
pub fn set_command_name(&self, new_name: TaskCommand)
pub fn set_seccomp_state(&self, state: SeccompStateValue) -> Result<(), Errno>
pub fn state_code(&self) -> TaskStateCode
pub fn time_stats(&self) -> TaskTimeStats
pub fn get_signal_action(&self, signal: Signal) -> sigaction_t
pub fn record_pid_koid_mapping(&self)
Trait Implementations§
Source§impl MemoryAccessor for Task
impl MemoryAccessor for Task
Source§fn read_memory<'a>(
&self,
addr: UserAddress,
bytes: &'a mut [MaybeUninit<u8>],
) -> Result<&'a mut [u8], Errno>
fn read_memory<'a>( &self, addr: UserAddress, bytes: &'a mut [MaybeUninit<u8>], ) -> Result<&'a mut [u8], Errno>
Source§fn read_memory_partial_until_null_byte<'a>(
&self,
addr: UserAddress,
bytes: &'a mut [MaybeUninit<u8>],
) -> Result<&'a mut [u8], Errno>
fn read_memory_partial_until_null_byte<'a>( &self, addr: UserAddress, bytes: &'a mut [MaybeUninit<u8>], ) -> Result<&'a mut [u8], Errno>
addr, continuing until either a null byte is read, bytes.len()
bytes have been read or no more bytes can be read from the target. Read moreSource§fn read_memory_partial<'a>(
&self,
addr: UserAddress,
bytes: &'a mut [MaybeUninit<u8>],
) -> Result<&'a mut [u8], Errno>
fn read_memory_partial<'a>( &self, addr: UserAddress, bytes: &'a mut [MaybeUninit<u8>], ) -> Result<&'a mut [u8], Errno>
addr, continuing until either bytes.len() bytes have been read
or no more bytes can be read from the target. Read moreSource§fn write_memory(&self, addr: UserAddress, bytes: &[u8]) -> Result<usize, Errno>
fn write_memory(&self, addr: UserAddress, bytes: &[u8]) -> Result<usize, Errno>
addr. Read moreSource§fn write_memory_partial(
&self,
addr: UserAddress,
bytes: &[u8],
) -> Result<usize, Errno>
fn write_memory_partial( &self, addr: UserAddress, bytes: &[u8], ) -> Result<usize, Errno>
addr, continuing until either bytes.len() bytes have been
written or no more bytes can be written. Read moreSource§impl Releasable for Task
impl Releasable for Task
type Context<'a> = (Box<ThreadState>, &'a mut Locked<TaskRelease>, RwLockWriteGuard<'a, RawSyncRwLock, PidTable>)
fn release<'a>(self, context: Self::Context<'a>)
Source§impl TaskMemoryAccessor for Task
impl TaskMemoryAccessor for Task
Source§fn maximum_valid_address(&self) -> Option<UserAddress>
fn maximum_valid_address(&self) -> Option<UserAddress>
impl Eq for Task
Auto Trait Implementations§
impl !Freeze for Task
impl !RefUnwindSafe for Task
impl Send for Task
impl Sync for Task
impl Unpin for Task
impl !UnwindSafe for Task
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T, D> Encode<Ambiguous1, D> for Twhere
D: ResourceDialect,
impl<T, D> Encode<Ambiguous1, D> for Twhere
D: ResourceDialect,
Source§impl<T, D> Encode<Ambiguous2, D> for Twhere
D: ResourceDialect,
impl<T, D> Encode<Ambiguous2, D> for Twhere
D: ResourceDialect,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<T> InstanceFromServiceTransport<T> for T
impl<T> InstanceFromServiceTransport<T> for T
§fn from_service_transport(handle: T) -> T
fn from_service_transport(handle: T) -> T
T to [Self]Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> MemoryAccessorExt for Twhere
T: MemoryAccessor,
impl<T> MemoryAccessorExt for Twhere
T: MemoryAccessor,
Source§fn read_memory_to_slice(
&self,
addr: UserAddress,
bytes: &mut [u8],
) -> Result<(), Errno>
fn read_memory_to_slice( &self, addr: UserAddress, bytes: &mut [u8], ) -> Result<(), Errno>
Source§fn read_memory_to_vec(
&self,
addr: UserAddress,
len: usize,
) -> Result<Vec<u8>, Errno>
fn read_memory_to_vec( &self, addr: UserAddress, len: usize, ) -> Result<Vec<u8>, Errno>
len bytes of memory, returning them as a a Vec.Source§fn read_memory_partial_to_vec(
&self,
addr: UserAddress,
max_len: usize,
) -> Result<Vec<u8>, Errno>
fn read_memory_partial_to_vec( &self, addr: UserAddress, max_len: usize, ) -> Result<Vec<u8>, Errno>
max_len bytes from addr, returning them as a Vec.Source§fn read_memory_to_array<const N: usize>(
&self,
addr: UserAddress,
) -> Result<[u8; N], Errno>
fn read_memory_to_array<const N: usize>( &self, addr: UserAddress, ) -> Result<[u8; N], Errno>
N bytes from addr, returning them as an array.Source§fn read_buffer(&self, buffer: &UserBuffer) -> Result<Vec<u8>, Errno>
fn read_buffer(&self, buffer: &UserBuffer) -> Result<Vec<u8>, Errno>
buffer, returning them as a Vec.Source§fn read_object<T: FromBytes>(&self, user: UserRef<T>) -> Result<T, Errno>
fn read_object<T: FromBytes>(&self, user: UserRef<T>) -> Result<T, Errno>
user.fn read_multi_arch_ptr<T64, T32>( &self, user: MultiArchUserRef<MultiArchUserRef<T64, T32>, MultiArchUserRef<T64, T32>>, ) -> Result<MultiArchUserRef<T64, T32>, Errno>
Source§fn read_multi_arch_object<T, T64: FromBytes + TryInto<T>, T32: FromBytes + TryInto<T>>(
&self,
user: MappingMultiArchUserRef<T, T64, T32>,
) -> Result<T, Errno>
fn read_multi_arch_object<T, T64: FromBytes + TryInto<T>, T32: FromBytes + TryInto<T>>( &self, user: MappingMultiArchUserRef<T, T64, T32>, ) -> Result<T, Errno>
user where the object has a different representation in 32
and 64 bits.Source§fn read_multi_arch_objects_to_vec<T, T64: FromBytes + TryInto<T>, T32: FromBytes + TryInto<T>>(
&self,
user: MappingMultiArchUserRef<T, T64, T32>,
len: usize,
) -> Result<Vec<T>, Errno>
fn read_multi_arch_objects_to_vec<T, T64: FromBytes + TryInto<T>, T32: FromBytes + TryInto<T>>( &self, user: MappingMultiArchUserRef<T, T64, T32>, len: usize, ) -> Result<Vec<T>, Errno>
len objects from user, returning them as a Vec.Source§fn read_object_partial<T: FromBytes>(
&self,
user: UserRef<T>,
partial_size: usize,
) -> Result<T, Errno>
fn read_object_partial<T: FromBytes>( &self, user: UserRef<T>, partial_size: usize, ) -> Result<T, Errno>
partial bytes of an object, leaving any remainder 0-filled. Read moreSource§fn read_objects<'a, T: FromBytes>(
&self,
user: UserRef<T>,
objects: &'a mut [MaybeUninit<T>],
) -> Result<&'a mut [T], Errno>
fn read_objects<'a, T: FromBytes>( &self, user: UserRef<T>, objects: &'a mut [MaybeUninit<T>], ) -> Result<&'a mut [T], Errno>
objects.len() objects into objects from user.Source§fn read_objects_to_slice<T: FromBytes>(
&self,
user: UserRef<T>,
objects: &mut [T],
) -> Result<(), Errno>
fn read_objects_to_slice<T: FromBytes>( &self, user: UserRef<T>, objects: &mut [T], ) -> Result<(), Errno>
objects.len() objects into objects from user.Source§fn read_objects_to_vec<T: FromBytes>(
&self,
user: UserRef<T>,
len: usize,
) -> Result<Vec<T>, Errno>
fn read_objects_to_vec<T: FromBytes>( &self, user: UserRef<T>, len: usize, ) -> Result<Vec<T>, Errno>
len objects from user, returning them as a Vec.Source§fn read_objects_to_smallvec<T: Clone + FromBytes, const N: usize>(
&self,
user: UserRef<T>,
len: usize,
) -> Result<SmallVec<[T; N]>, Errno>
fn read_objects_to_smallvec<T: Clone + FromBytes, const N: usize>( &self, user: UserRef<T>, len: usize, ) -> Result<SmallVec<[T; N]>, Errno>
len objects from user, returning them as a SmallVec.Source§fn read_objects_to_array<T: Copy + FromBytes, const N: usize>(
&self,
user: UserRef<T>,
) -> Result<[T; N], Errno>
fn read_objects_to_array<T: Copy + FromBytes, const N: usize>( &self, user: UserRef<T>, ) -> Result<[T; N], Errno>
N objects from user, returning them as an array.Source§fn read_iovec<T: Copy + Eq + IntoBytes + FromBytes + Immutable + TryInto<usize>>(
&self,
iovec_addr: IOVecPtr,
iovec_count: UserValue<T>,
) -> Result<UserBuffers, Errno>
fn read_iovec<T: Copy + Eq + IntoBytes + FromBytes + Immutable + TryInto<usize>>( &self, iovec_addr: IOVecPtr, iovec_count: UserValue<T>, ) -> Result<UserBuffers, Errno>
Source§fn read_c_string_to_vec(
&self,
string: UserCString,
max_size: usize,
) -> Result<FsString, Errno>
fn read_c_string_to_vec( &self, string: UserCString, max_size: usize, ) -> Result<FsString, Errno>
max_size bytes from string, stopping at the first discovered null byte and
returning the results as a Vec.Source§fn read_path_if_non_null(&self, path: UserCString) -> Result<FsString, Errno>
fn read_path_if_non_null(&self, path: UserCString) -> Result<FsString, Errno>
Source§fn read_nul_delimited_c_string_list(
&self,
start: UserAddress,
len: usize,
) -> Result<Vec<FsString>, Errno>
fn read_nul_delimited_c_string_list( &self, start: UserAddress, len: usize, ) -> Result<Vec<FsString>, Errno>
len bytes from start and parse the region as null-delimited CStrings, for example
how argv is stored. Read moreSource§fn read_c_string<'a>(
&self,
string: UserCString,
buffer: &'a mut [MaybeUninit<u8>],
) -> Result<&'a FsStr, Errno>
fn read_c_string<'a>( &self, string: UserCString, buffer: &'a mut [MaybeUninit<u8>], ) -> Result<&'a FsStr, Errno>
buffer.len() bytes from string, stopping at the first discovered null byte
and returning the result as a slice that ends before that null. Read moreSource§fn read_c_string_if_non_null<'a>(
&self,
addr: UserCString,
buffer: &'a mut [MaybeUninit<u8>],
) -> Result<&'a FsStr, Errno>
fn read_c_string_if_non_null<'a>( &self, addr: UserCString, buffer: &'a mut [MaybeUninit<u8>], ) -> Result<&'a FsStr, Errno>
addr is null, otherwise
behaves as read_c_string.