Add getpid and getppid

This commit is contained in:
Tate, Hongliang Tian 2019-01-03 21:20:55 +08:00
parent b717842113
commit 372649f3d6
16 changed files with 141 additions and 52 deletions

@ -22,8 +22,9 @@ extern int occlum_spawn(int* child_pid, const char* path,
const char** argv,
const char** envp);
extern int occlum_wait4(int child_pid, int* status, int options/*, struct rusage* rusage*/);
extern unsigned int occlum_getpid(void);
extern void occlum_exit(int status);
extern unsigned int occlum_getpid(void);
extern unsigned int occlum_getppid(void);
extern void *occlum_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
extern int occlum_munmap(void *addr, size_t length);

@ -7,7 +7,7 @@ pub type FileDesc = u32;
// Invariant 1: fd < max_fd, where fd is any fd in the table
// Invariant 2: max_fd = table.size()
// Invariant 3: num_fds <= table.size()
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
#[repr(C)]
pub struct FileTable {
table: Vec<Option<FileRef>>,
@ -72,10 +72,3 @@ impl FileTable {
del_file
}
}
impl Default for FileTable {
fn default() -> FileTable {
FileTable::new()
}
}

@ -78,7 +78,8 @@ fn do_boot(path_str: &str) -> Result<(), Error> {
let argv = std::vec::Vec::new();
let envp = std::vec::Vec::new();
process::do_spawn(&path_str, &argv, &envp)?;
let parent = &process::IDLE_PROCESS;
process::do_spawn(&path_str, &argv, &envp, parent)?;
Ok(())
}

@ -1,20 +1,57 @@
pub use self::process::{Process, ProcessRef, Status, pid_t};
pub use self::process::{Status, IDLE_PROCESS};
pub use self::task::{get_current, run_task};
pub mod table {
pub use super::process_table::{get};
}
pub use self::spawn::{do_spawn};
#[allow(non_camel_case_types)]
pub type pid_t = u32;
#[derive(Debug)]
pub struct Process {
task: Task,
status: Status,
pid: pid_t,
tgid: pid_t,
exit_status: i32,
exec_path: String,
parent: Option<ProcessRef>,
children: Vec<ProcessRef>,
vm: ProcessVM,
file_table: FileTable,
}
pub type ProcessRef = Arc<SgxMutex<Process>>;
pub fn do_getpid() -> pid_t {
let current_ref = get_current();
let current_process = current_ref.lock().unwrap();
current_process.get_pid()
let current = current_ref.lock().unwrap();
current.get_pid()
}
pub fn do_getppid() -> pid_t {
let current_ref = get_current();
let current = current_ref.lock().unwrap();
let parent_ref = current.get_parent();
let parent = parent_ref.lock().unwrap();
parent.get_pid()
}
pub fn do_exit(exit_status: i32) {
let current_ref = get_current();
let mut current_process = current_ref.lock().unwrap();
current_process.exit(exit_status);
let mut current = current_ref.lock().unwrap();
current.exit_status = exit_status;
current.status = Status::ZOMBIE;
for child_ref in &current.children {
let mut child = child_ref.lock().unwrap();
child.parent = Some(IDLE_PROCESS.clone());
}
current.children.clear();
}
pub fn do_wait4(child_pid: u32) -> Result<i32, Error> {
@ -43,3 +80,6 @@ mod process_table;
mod spawn;
use prelude::*;
use vm::{ProcessVM, VMRangeTrait};
use fs::{FileTable, File, FileRef};
use self::task::{Task};

@ -3,23 +3,24 @@ use super::task::{Task};
use vm::{ProcessVM, VMRangeTrait};
use fs::{FileTable, File, FileRef};
#[allow(non_camel_case_types)]
pub type pid_t = u32;
#[derive(Debug)]
pub struct Process {
task: Task,
status: Status,
pid: pid_t,
tgid: pid_t,
exit_status: i32,
exec_path: String,
vm: ProcessVM,
file_table: FileTable,
lazy_static! {
// Dummy object to make all processes having a parent
pub static ref IDLE_PROCESS: ProcessRef = {
Arc::new(SgxMutex::new(Process {
task: Default::default(),
status: Default::default(),
pid: 0,
tgid: 0,
exit_status: 0,
exec_path: "".to_owned(),
parent: None,
children: Vec::new(),
vm: Default::default(),
file_table: Default::default(),
}))
};
}
pub type ProcessRef = Arc<SgxMutex<Process>>;
impl Process {
pub fn new(exec_path: &str, task: Task, vm: ProcessVM, file_table: FileTable)
-> Result<(pid_t, ProcessRef), Error>
@ -32,6 +33,8 @@ impl Process {
tgid: new_pid,
exec_path: exec_path.to_owned(),
exit_status: 0,
parent: None,
children: Vec::new(),
vm: vm,
file_table: file_table,
}));
@ -49,11 +52,8 @@ impl Process {
pub fn get_vm_mut(&mut self) -> &mut ProcessVM { &mut self.vm }
pub fn get_files(&self) -> &FileTable { &self.file_table }
pub fn get_files_mut(&mut self) -> &mut FileTable { &mut self.file_table }
pub fn exit(&mut self, exit_status: i32) {
self.exit_status = exit_status;
self.status = Status::ZOMBIE;
}
pub fn get_parent(&self) -> &ProcessRef { self.parent.as_ref().unwrap() }
pub fn get_children(&self) -> &[ProcessRef] { &self.children }
}
impl Drop for Process {

@ -27,6 +27,8 @@ pub fn alloc_pid() -> u32 {
}
pub fn free_pid(pid: u32) {
// PID 0 is reserved for idle thread, thus no need to free
if pid == 0 { return; }
// TODO:
}

@ -14,7 +14,8 @@ mod init_vm;
mod elf_helper;
mod segment;
pub fn do_spawn<P: AsRef<Path>>(elf_path: &P, argv: &[CString], envp: &[CString])
pub fn do_spawn<P: AsRef<Path>>(elf_path: &P, argv: &[CString], envp: &[CString],
parent_ref: &ProcessRef)
-> Result<u32, Error>
{
let mut elf_buf = {
@ -58,6 +59,7 @@ pub fn do_spawn<P: AsRef<Path>>(elf_path: &P, argv: &[CString], envp: &[CString]
let exec_path = elf_path.as_ref().to_str().unwrap();
Process::new(exec_path, task, vm, files)?
};
parent_adopts_new_child(&parent_ref, &new_process_ref);
process_table::put(new_pid, new_process_ref.clone());
task::enqueue_task(new_process_ref);
Ok(new_pid)
@ -102,3 +104,11 @@ fn init_stack(stack_top: usize, argv: &[CString], envp: &[CString])
init_stack::do_init(stack_top, 4096, argv, envp, &auxtbl)
}
fn parent_adopts_new_child(parent_ref: &ProcessRef, child_ref: &ProcessRef)
{
let mut parent = parent_ref.lock().unwrap();
let mut child = child_ref.lock().unwrap();
parent.children.push(child_ref.clone());
child.parent = Some(parent_ref.clone());
}

@ -66,18 +66,26 @@ pub fn run_task() -> Result<i32, Error> {
Ok(exit_status)
}
thread_local! {
static _CURRENT_PROCESS_PTR: Cell<*const SgxMutex<Process>> =
Cell::new(0 as *const SgxMutex<Process>);
static _CURRENT_PROCESS_PTR: Cell<*const SgxMutex<Process>> = {
Cell::new(0 as *const SgxMutex<Process>)
};
}
pub fn get_current() -> &'static SgxMutex<Process> {
let mut process_ptr = 0 as *const SgxMutex<Process>;
_CURRENT_PROCESS_PTR.with(|cp| {
process_ptr = cp.get();
});
unsafe { mem::transmute(process_ptr) }
pub fn get_current() -> ProcessRef {
let current_ptr = {
let mut current_ptr = 0 as *const SgxMutex<Process>;
_CURRENT_PROCESS_PTR.with(|cell| {
current_ptr = cell.get();
});
current_ptr
};
let current_ref = unsafe { Arc::from_raw(current_ptr) };
let current_ref_clone = current_ref.clone();
Arc::into_raw(current_ref);
current_ref_clone
}
fn set_current(process: &ProcessRef) {

@ -30,7 +30,7 @@ fn check_mut_array_from_user<T>(user_buf: *mut T, count: usize) -> Result<(), Er
Ok(())
}
fn clone_string_from_user_safely(user_ptr: *const c_char)
fn clone_cstring_from_user_safely(user_ptr: *const c_char)
-> Result<String, Error>
{
check_ptr_from_user(user_ptr)?;
@ -329,6 +329,12 @@ pub extern "C" fn occlum_getpid() -> c_uint
process::do_getpid()
}
#[no_mangle]
pub extern "C" fn occlum_getppid() -> c_uint
{
process::do_getppid()
}
#[no_mangle]
pub extern "C" fn occlum_exit(status: i32)
{
@ -348,11 +354,12 @@ fn do_spawn(child_pid_ptr: *mut c_uint,
-> Result<(), Error>
{
check_mut_ptr_from_user(child_pid_ptr)?;
let path = clone_string_from_user_safely(path)?;
let path = clone_cstring_from_user_safely(path)?;
let argv = clone_cstrings_from_user_safely(argv)?;
let envp = clone_cstrings_from_user_safely(envp)?;
let parent = process::get_current();
let child_pid = process::do_spawn(&path, &argv, &envp)?;
let child_pid = process::do_spawn(&path, &argv, &envp, &parent)?;
unsafe { *child_pid_ptr = child_pid };
Ok(())

@ -80,6 +80,10 @@ long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long
ret = occlum_getpid();
break;
}
case SYS_getppid: {
ret = occlum_getppid();
break;
}
case SYS_mmap: {
DECL_SYSCALL_ARG(void*, addr, arg0);
DECL_SYSCALL_ARG(size_t, length, arg1);

@ -59,12 +59,12 @@ pub struct VMSpace {
guard_type: VMGuardAreaType,
}
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct VMDomain {
range: VMRange,
}
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct VMArea {
range: VMRange,
flags: VMAreaFlags,

@ -22,7 +22,7 @@ extern {
pub fn vm_get_prealloced_data_space(addr: &mut usize, size: &mut usize);
}
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct ProcessVM {
//code_domain: VMDomain,
data_domain: VMDomain,

@ -383,6 +383,16 @@ impl Drop for VMRange {
unsafe impl Send for VMRange {}
unsafe impl Sync for VMRange {}
impl Default for VMRange {
fn default() -> VMRange {
VMRange {
inner: VMRangeInner::new(0, 0, VMGrowthType::Fixed),
parent_range: 0 as *const VMRange,
sub_ranges: None,
}
}
}
#[derive(Clone, Copy)]
pub struct VMRangeInner {

@ -1,7 +1,7 @@
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PROJECT_DIR := $(realpath $(CUR_DIR)/../)
TEST_SUITES := empty hello_world malloc
TEST_SUITES := empty hello_world malloc getpid
BUILD_TEST_SUITES := $(TEST_SUITES:%=%)
RUN_TEST_SUITES := $(TEST_SUITES:%=run-%)
CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%)

4
test/getpid/Makefile Normal file

@ -0,0 +1,4 @@
include ../test_common.mk
EXTRA_C_FLAGS :=
EXTRA_LINK_FLAGS :=

9
test/getpid/main.c Normal file

@ -0,0 +1,9 @@
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void) {
printf("pid = %d\n", getpid());
printf("ppid = %d\n", getppid());
return 0;
}