mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-03 12:21:37 +00:00
Most important differences from the old version: - strip global process information from the thread struct into a dedicated one, - a parent is informed about the child death when the whole process (the last thread) dies (not on each thread exit), - all threads have the same parent (spawning thread is NOT the parent of the spawned thread), - a thread is able to wait on children created by another thread, - a process is able to wait for exited children after execve, - rewritten `waitid` implementation (no more gotos, supports __WCLONE and friends flags), - added option for syscall restarting, for now used only in `waitid`. Additionally various bugfixes, cleanups and missing locks added.
83 lines
2.5 KiB
C
83 lines
2.5 KiB
C
/* SPDX-License-Identifier: LGPL-3.0-or-later */
|
|
/* Copyright (C) 2020 Intel Corporation
|
|
* Borys Popławski <borysp@invisiblethingslab.com>
|
|
*/
|
|
#ifndef _SHIM_PROCESS_H
|
|
#define _SHIM_PROCESS_H
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include "list.h"
|
|
#include "pal.h"
|
|
#include "shim_fs.h"
|
|
#include "shim_handle.h"
|
|
#include "shim_lock.h"
|
|
#include "shim_types.h"
|
|
|
|
DEFINE_LIST(shim_child_process);
|
|
DEFINE_LISTP(shim_child_process);
|
|
struct shim_child_process {
|
|
IDTYPE pid;
|
|
IDTYPE vmid;
|
|
|
|
/* Signal sent to the parent process (us) on this child termination. */
|
|
int child_termination_signal;
|
|
|
|
/* These 3 fields are set when the child terminates. */
|
|
int exit_code;
|
|
int term_signal;
|
|
IDTYPE uid;
|
|
|
|
LIST_TYPE(shim_child_process) list;
|
|
};
|
|
|
|
struct shim_process {
|
|
/* These 2 fields are constant and can safely be read without any locks held. */
|
|
IDTYPE pid;
|
|
IDTYPE ppid;
|
|
|
|
/* This field should be accessed atomically, so no lock needed. */
|
|
IDTYPE pgid;
|
|
|
|
/* Currently all threads share filesystem information. For more info check `CLONE_FS` flag in
|
|
* `clone.c`. Protected by `fs_lock`. */
|
|
struct shim_dentry* root;
|
|
struct shim_dentry* cwd;
|
|
mode_t umask;
|
|
|
|
/* Handle to the executable file. Protected by `fs_lock`. */
|
|
struct shim_handle* exec;
|
|
|
|
/* Threads waiting for some child to exit. Protected by `children_lock`. */
|
|
struct shim_thread_queue* wait_queue;
|
|
|
|
/* List of child processes that are still running. Protected by `children_lock`. */
|
|
LISTP_TYPE(shim_child_process) children;
|
|
/* List of already exited children. Protected by `children_lock`. */
|
|
LISTP_TYPE(shim_child_process) zombies;
|
|
|
|
struct shim_lock children_lock;
|
|
struct shim_lock fs_lock;
|
|
};
|
|
|
|
extern struct shim_process g_process;
|
|
|
|
int init_process(void);
|
|
|
|
/* Allocates a new child process structure, initializing all fields. */
|
|
struct shim_child_process* create_child_process(void);
|
|
/* Frees `child` with all accompanying resources. */
|
|
void destroy_child_process(struct shim_child_process* child);
|
|
/* Adds `child` to `g_process` children list. */
|
|
void add_child_process(struct shim_child_process* child);
|
|
|
|
/*
|
|
* These 2 functions mark a child as exited, moving it from `children` list to `zombies` list
|
|
* and generate a child-termination signal (if needed).
|
|
* Return `true` if the child was found, `false` otherwise.
|
|
*/
|
|
bool mark_child_exited_by_vmid(IDTYPE vmid, IDTYPE child_uid, int exit_code, int signal);
|
|
bool mark_child_exited_by_pid(IDTYPE pid, IDTYPE child_uid, int exit_code, int signal);
|
|
|
|
#endif // _SHIM_PROCESS_H
|