Add getpid and getppid
This commit is contained in:
parent
b717842113
commit
372649f3d6
@ -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 ¤t.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
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
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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user