reformat code using cargo fmt

This commit is contained in:
WangRunji 2019-04-26 21:25:55 +08:00
parent dd3de96b8e
commit 6e871f7948
30 changed files with 362 additions and 250 deletions

@ -68,7 +68,7 @@ fn parse_arguments(
// TODO: make sure do_boot can only be called once // TODO: make sure do_boot can only be called once
fn do_boot(path_str: &str, argv: &Vec<CString>) -> Result<(), Error> { fn do_boot(path_str: &str, argv: &Vec<CString>) -> Result<(), Error> {
// info!("boot: path: {:?}, argv: {:?}", path_str, argv); // info!("boot: path: {:?}, argv: {:?}", path_str, argv);
util::mpx_util::mpx_enable()?; util::mpx_util::mpx_enable()?;
let envp = std::vec::Vec::new(); let envp = std::vec::Vec::new();

@ -24,7 +24,10 @@ impl convert::From<(Errno, &'static str)> for Error {
impl convert::From<std::io::Error> for Error { impl convert::From<std::io::Error> for Error {
fn from(info: std::io::Error) -> Error { fn from(info: std::io::Error) -> Error {
Error::new(Errno::from_errno(info.raw_os_error().unwrap()), "std::io::Error") Error::new(
Errno::from_errno(info.raw_os_error().unwrap()),
"std::io::Error",
)
} }
} }

@ -17,7 +17,6 @@ impl AccessModes {
} }
} }
bitflags! { bitflags! {
pub struct AccessFlags : u32 { pub struct AccessFlags : u32 {
const AT_SYMLINK_NOFOLLOW = 0x100; const AT_SYMLINK_NOFOLLOW = 0x100;
@ -31,11 +30,18 @@ impl AccessFlags {
} }
} }
pub const AT_FDCWD: i32 = -100;
pub const AT_FDCWD : i32 = -100; pub fn do_faccessat(
dirfd: Option<FileDesc>,
pub fn do_faccessat(dirfd: Option<FileDesc>, path: &str, mode: AccessModes, flags: AccessFlags) -> Result<(), Error> { path: &str,
info!("faccessat: dirfd: {:?}, path: {:?}, mode: {:?}, flags: {:?}", dirfd, path, mode, flags); mode: AccessModes,
flags: AccessFlags,
) -> Result<(), Error> {
info!(
"faccessat: dirfd: {:?}, path: {:?}, mode: {:?}, flags: {:?}",
dirfd, path, mode, flags
);
match dirfd { match dirfd {
// TODO: handle dirfd // TODO: handle dirfd
Some(dirfd) => errno!(ENOSYS, "cannot accept dirfd"), Some(dirfd) => errno!(ENOSYS, "cannot accept dirfd"),

@ -377,7 +377,7 @@ impl File for StdoutFile {
mode: 0, mode: 0,
nlinks: 0, nlinks: 0,
uid: 0, uid: 0,
gid: 0 gid: 0,
}) })
} }
@ -493,7 +493,7 @@ impl File for StdinFile {
mode: 0, mode: 0,
nlinks: 0, nlinks: 0,
uid: 0, uid: 0,
gid: 0 gid: 0,
}) })
} }

@ -19,7 +19,12 @@ impl FileTable {
} }
} }
pub fn dup(&mut self, fd: FileDesc, min_fd: FileDesc, close_on_spawn: bool) -> Result<FileDesc, Error> { pub fn dup(
&mut self,
fd: FileDesc,
min_fd: FileDesc,
close_on_spawn: bool,
) -> Result<FileDesc, Error> {
let file_ref = self.get(fd)?; let file_ref = self.get(fd)?;
let min_fd = min_fd as usize; let min_fd = min_fd as usize;
@ -34,11 +39,13 @@ impl FileTable {
} }
} }
table.iter() table
.iter()
.enumerate() .enumerate()
.skip(min_fd as usize) .skip(min_fd as usize)
.find(|&(idx, opt)| opt.is_none()) .find(|&(idx, opt)| opt.is_none())
.unwrap().0 .unwrap()
.0
} as FileDesc; } as FileDesc;
self.put_at(min_free_fd, file_ref, close_on_spawn); self.put_at(min_free_fd, file_ref, close_on_spawn);
@ -50,7 +57,8 @@ impl FileTable {
let mut table = &mut self.table; let mut table = &mut self.table;
let min_free_fd = if self.num_fds < table.len() { let min_free_fd = if self.num_fds < table.len() {
table.iter() table
.iter()
.enumerate() .enumerate()
.find(|&(idx, opt)| opt.is_none()) .find(|&(idx, opt)| opt.is_none())
.unwrap() .unwrap()

@ -2,8 +2,8 @@ use rcore_fs::vfs::{FileSystem, FsError, INode};
use rcore_fs_sefs::SEFS; use rcore_fs_sefs::SEFS;
use std::fmt; use std::fmt;
use super::*;
use super::sgx_impl::SgxStorage; use super::sgx_impl::SgxStorage;
use super::*;
lazy_static! { lazy_static! {
/// The root of file system /// The root of file system

@ -2,8 +2,8 @@ use super::*;
use std::any::Any; use std::any::Any;
use std::collections::btree_map::BTreeMap; use std::collections::btree_map::BTreeMap;
use std::fmt; use std::fmt;
use std::vec::Vec;
use std::sync::atomic::spin_loop_hint; use std::sync::atomic::spin_loop_hint;
use std::vec::Vec;
/// Forward to host `poll` /// Forward to host `poll`
/// (sgx_libc doesn't have `select`) /// (sgx_libc doesn't have `select`)
@ -81,7 +81,11 @@ pub fn do_select(
Some(tv) => (tv.tv_sec * 1000 + tv.tv_usec / 1000) as i32, Some(tv) => (tv.tv_sec * 1000 + tv.tv_usec / 1000) as i32,
}; };
let ret = try_libc!(libc::ocall::poll(polls.as_mut_ptr(), polls.len() as u64, timeout)); let ret = try_libc!(libc::ocall::poll(
polls.as_mut_ptr(),
polls.len() as u64,
timeout
));
// convert fd back and write fdset // convert fd back and write fdset
readfds.clear(); readfds.clear();
@ -105,7 +109,11 @@ pub fn do_select(
} }
pub fn do_poll(polls: &mut [libc::pollfd], timeout: c_int) -> Result<usize, Error> { pub fn do_poll(polls: &mut [libc::pollfd], timeout: c_int) -> Result<usize, Error> {
info!("poll: {:?}, timeout: {}", polls.iter().map(|p| p.fd).collect::<Vec<_>>(), timeout); info!(
"poll: {:?}, timeout: {}",
polls.iter().map(|p| p.fd).collect::<Vec<_>>(),
timeout
);
let current_ref = process::get_current(); let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap(); let mut proc = current_ref.lock().unwrap();
@ -138,7 +146,11 @@ pub fn do_poll(polls: &mut [libc::pollfd], timeout: c_int) -> Result<usize, Erro
return errno!(EBADF, "not a socket"); return errno!(EBADF, "not a socket");
} }
} }
let ret = try_libc!(libc::ocall::poll(polls.as_mut_ptr(), polls.len() as u64, timeout)); let ret = try_libc!(libc::ocall::poll(
polls.as_mut_ptr(),
polls.len() as u64,
timeout
));
// recover fd ? // recover fd ?
Ok(ret as usize) Ok(ret as usize)
} }
@ -258,8 +270,12 @@ impl EpollFileInner {
host_fd: FileDesc, host_fd: FileDesc,
event: *const libc::epoll_event, event: *const libc::epoll_event,
) -> Result<(), Error> { ) -> Result<(), Error> {
let ret = let ret = try_libc!(libc::ocall::epoll_ctl(
try_libc!(libc::ocall::epoll_ctl(self.epoll_fd, op, host_fd as c_int, event as *mut _)); self.epoll_fd,
op,
host_fd as c_int,
event as *mut _
));
Ok(()) Ok(())
} }
@ -270,14 +286,12 @@ impl EpollFileInner {
events: &mut [libc::epoll_event], events: &mut [libc::epoll_event],
timeout: c_int, timeout: c_int,
) -> Result<usize, Error> { ) -> Result<usize, Error> {
let ret = try_libc!( let ret = try_libc!(libc::ocall::epoll_wait(
libc::ocall::epoll_wait( self.epoll_fd,
self.epoll_fd, events.as_mut_ptr(),
events.as_mut_ptr(), events.len() as c_int,
events.len() as c_int, timeout,
timeout, ));
)
);
Ok(ret as usize) Ok(ret as usize)
} }
} }

@ -1,36 +1,35 @@
use {process, std};
use prelude::*; use prelude::*;
use process::Process; use process::Process;
use rcore_fs::vfs::{FileType, FsError, INode, Metadata, Timespec}; use rcore_fs::vfs::{FileType, FsError, INode, Metadata, Timespec};
use std::sgxfs as fs_impl; use std::sgxfs as fs_impl;
use {process, std};
use super::*; use super::*;
pub use self::access::{do_access, do_faccessat, AccessFlags, AccessModes, AT_FDCWD};
pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile}; pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile};
pub use self::file_table::{FileDesc, FileTable}; pub use self::file_table::{FileDesc, FileTable};
pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE};
pub use self::socket_file::{SocketFile, AsSocket};
pub use self::unix_socket::{UnixSocketFile, AsUnixSocket};
use self::inode_file::OpenOptions; use self::inode_file::OpenOptions;
pub use self::pipe::Pipe; pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE};
pub use self::io_multiplexing::*; pub use self::io_multiplexing::*;
pub use self::access::{AccessModes, AccessFlags, AT_FDCWD, do_access, do_faccessat};
use self::null::NullFile; use self::null::NullFile;
use std::mem::uninitialized; pub use self::pipe::Pipe;
pub use self::socket_file::{AsSocket, SocketFile};
pub use self::unix_socket::{AsUnixSocket, UnixSocketFile};
use std::any::Any; use std::any::Any;
use std::mem::uninitialized;
mod access;
mod file; mod file;
mod file_table; mod file_table;
mod inode_file; mod inode_file;
mod socket_file; mod io_multiplexing;
mod null;
mod pipe; mod pipe;
mod sgx_impl; mod sgx_impl;
mod io_multiplexing; mod socket_file;
mod access;
mod null;
mod unix_socket; mod unix_socket;
pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> { pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> {
let flags = OpenFlags::from_bits_truncate(flags); let flags = OpenFlags::from_bits_truncate(flags);
info!( info!(
@ -46,7 +45,10 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> {
let fd = { let fd = {
let close_on_spawn = flags.contains(OpenFlags::CLOEXEC); let close_on_spawn = flags.contains(OpenFlags::CLOEXEC);
proc.get_files().lock().unwrap().put(file_ref, close_on_spawn) proc.get_files()
.lock()
.unwrap()
.put(file_ref, close_on_spawn)
}; };
Ok(fd) Ok(fd)
} }
@ -353,7 +355,8 @@ pub fn do_sendfile(
in_fd: FileDesc, in_fd: FileDesc,
offset: Option<off_t>, offset: Option<off_t>,
count: usize, count: usize,
) -> Result<(usize, usize), Error> { // (len, offset) ) -> Result<(usize, usize), Error> {
// (len, offset)
info!( info!(
"sendfile: out: {}, in: {}, offset: {:?}, count: {}", "sendfile: out: {}, in: {}, offset: {:?}, count: {}",
out_fd, in_fd, offset, count out_fd, in_fd, offset, count
@ -683,7 +686,6 @@ pub unsafe fn write_cstr(ptr: *mut u8, s: &str) {
ptr.add(s.len()).write(0); ptr.add(s.len()).write(0);
} }
#[derive(Debug)] #[derive(Debug)]
pub enum FcntlCmd { pub enum FcntlCmd {
/// Duplicate the file descriptor fd using the lowest-numbered available /// Duplicate the file descriptor fd using the lowest-numbered available
@ -727,11 +729,11 @@ pub fn do_fcntl(fd: FileDesc, cmd: &FcntlCmd) -> Result<isize, Error> {
FcntlCmd::DupFd(min_fd) => { FcntlCmd::DupFd(min_fd) => {
let dup_fd = files.dup(fd, *min_fd, false)?; let dup_fd = files.dup(fd, *min_fd, false)?;
dup_fd as isize dup_fd as isize
}, }
FcntlCmd::DupFdCloexec(min_fd) => { FcntlCmd::DupFdCloexec(min_fd) => {
let dup_fd = files.dup(fd, *min_fd, true)?; let dup_fd = files.dup(fd, *min_fd, true)?;
dup_fd as isize dup_fd as isize
}, }
FcntlCmd::GetFd() => { FcntlCmd::GetFd() => {
let entry = files.get_entry(fd)?; let entry = files.get_entry(fd)?;
let fd_flags = if entry.is_close_on_spawn() { let fd_flags = if entry.is_close_on_spawn() {
@ -740,12 +742,12 @@ pub fn do_fcntl(fd: FileDesc, cmd: &FcntlCmd) -> Result<isize, Error> {
0 0
}; };
fd_flags as isize fd_flags as isize
}, }
FcntlCmd::SetFd(fd_flags) => { FcntlCmd::SetFd(fd_flags) => {
let entry = files.get_entry_mut(fd)?; let entry = files.get_entry_mut(fd)?;
entry.set_close_on_spawn((fd_flags & libc::FD_CLOEXEC as u32) != 0); entry.set_close_on_spawn((fd_flags & libc::FD_CLOEXEC as u32) != 0);
0 0
}, }
FcntlCmd::GetFl() => { FcntlCmd::GetFl() => {
let file = files.get(fd)?; let file = files.get(fd)?;
if let Ok(socket) = file.as_socket() { if let Ok(socket) = file.as_socket() {

@ -2,12 +2,12 @@ use rcore_fs::dev::TimeProvider;
use rcore_fs::vfs::Timespec; use rcore_fs::vfs::Timespec;
use rcore_fs_sefs::dev::*; use rcore_fs_sefs::dev::*;
use std::boxed::Box; use std::boxed::Box;
use std::collections::BTreeMap;
use std::io::{Read, Seek, SeekFrom, Write}; use std::io::{Read, Seek, SeekFrom, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sgxfs::{remove, OpenOptions, SgxFile}; use std::sgxfs::{remove, OpenOptions, SgxFile};
use std::sync::{SgxMutex as Mutex, Arc}; use std::sync::{Arc, SgxMutex as Mutex};
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use std::collections::BTreeMap;
pub struct SgxStorage { pub struct SgxStorage {
path: PathBuf, path: PathBuf,
@ -19,7 +19,7 @@ impl SgxStorage {
// assert!(path.as_ref().is_dir()); // assert!(path.as_ref().is_dir());
SgxStorage { SgxStorage {
path: path.as_ref().to_path_buf(), path: path.as_ref().to_path_buf(),
file_cache: Mutex::new(BTreeMap::new()) file_cache: Mutex::new(BTreeMap::new()),
} }
} }
/// Get file by `file_id`. /// Get file by `file_id`.

@ -33,19 +33,30 @@ impl Drop for SocketFile {
let ret = unsafe { libc::ocall::close(self.fd) }; let ret = unsafe { libc::ocall::close(self.fd) };
if ret < 0 { if ret < 0 {
let errno = unsafe { libc::errno() }; let errno = unsafe { libc::errno() };
warn!("socket (host fd: {}) close failed: errno = {}", self.fd, errno); warn!(
"socket (host fd: {}) close failed: errno = {}",
self.fd, errno
);
} }
} }
} }
impl File for SocketFile { impl File for SocketFile {
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> { fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
let ret = try_libc!(libc::ocall::read(self.fd, buf.as_mut_ptr() as *mut c_void, buf.len())); let ret = try_libc!(libc::ocall::read(
self.fd,
buf.as_mut_ptr() as *mut c_void,
buf.len()
));
Ok(ret as usize) Ok(ret as usize)
} }
fn write(&self, buf: &[u8]) -> Result<usize, Error> { fn write(&self, buf: &[u8]) -> Result<usize, Error> {
let ret = try_libc!(libc::ocall::write(self.fd, buf.as_ptr() as *const c_void, buf.len())); let ret = try_libc!(libc::ocall::write(
self.fd,
buf.as_ptr() as *const c_void,
buf.len()
));
Ok(ret as usize) Ok(ret as usize)
} }
@ -103,7 +114,7 @@ impl File for SocketFile {
mode: 0, mode: 0,
nlinks: 0, nlinks: 0,
uid: 0, uid: 0,
gid: 0 gid: 0,
}) })
} }

@ -1,13 +1,13 @@
use super::*; use super::*;
use std::collections::btree_map::BTreeMap;
use util::ring_buf::{RingBufReader, RingBufWriter, RingBuf};
use std::sync::SgxMutex as Mutex;
use alloc::prelude::ToString; use alloc::prelude::ToString;
use std::collections::btree_map::BTreeMap;
use std::fmt; use std::fmt;
use std::sync::atomic::spin_loop_hint; use std::sync::atomic::spin_loop_hint;
use std::sync::SgxMutex as Mutex;
use util::ring_buf::{RingBuf, RingBufReader, RingBufWriter};
pub struct UnixSocketFile { pub struct UnixSocketFile {
inner: Mutex<UnixSocket> inner: Mutex<UnixSocket>,
} }
impl File for UnixSocketFile { impl File for UnixSocketFile {
@ -77,7 +77,7 @@ impl File for UnixSocketFile {
mode: 0, mode: 0,
nlinks: 0, nlinks: 0,
uid: 0, uid: 0,
gid: 0 gid: 0,
}) })
} }
@ -105,7 +105,9 @@ impl File for UnixSocketFile {
impl UnixSocketFile { impl UnixSocketFile {
pub fn new(socket_type: c_int, protocol: c_int) -> Result<Self, Error> { pub fn new(socket_type: c_int, protocol: c_int) -> Result<Self, Error> {
let inner = UnixSocket::new(socket_type, protocol)?; let inner = UnixSocket::new(socket_type, protocol)?;
Ok(UnixSocketFile { inner: Mutex::new(inner) }) Ok(UnixSocketFile {
inner: Mutex::new(inner),
})
} }
pub fn bind(&self, path: impl AsRef<str>) -> Result<(), Error> { pub fn bind(&self, path: impl AsRef<str>) -> Result<(), Error> {
@ -121,7 +123,9 @@ impl UnixSocketFile {
pub fn accept(&self) -> Result<UnixSocketFile, Error> { pub fn accept(&self) -> Result<UnixSocketFile, Error> {
let mut inner = self.inner.lock().unwrap(); let mut inner = self.inner.lock().unwrap();
let new_socket = inner.accept()?; let new_socket = inner.accept()?;
Ok(UnixSocketFile { inner: Mutex::new(new_socket) }) Ok(UnixSocketFile {
inner: Mutex::new(new_socket),
})
} }
pub fn connect(&self, path: impl AsRef<str>) -> Result<(), Error> { pub fn connect(&self, path: impl AsRef<str>) -> Result<(), Error> {
@ -146,7 +150,6 @@ impl Debug for UnixSocketFile {
} }
} }
pub trait AsUnixSocket { pub trait AsUnixSocket {
fn as_unix_socket(&self) -> Result<&UnixSocketFile, Error>; fn as_unix_socket(&self) -> Result<&UnixSocketFile, Error>;
} }
@ -159,7 +162,6 @@ impl AsUnixSocket for FileRef {
} }
} }
pub struct UnixSocket { pub struct UnixSocket {
obj: Option<Arc<UnixSocketObject>>, obj: Option<Arc<UnixSocketObject>>,
status: Status, status: Status,
@ -177,7 +179,7 @@ impl UnixSocket {
if socket_type == libc::SOCK_STREAM && protocol == 0 { if socket_type == libc::SOCK_STREAM && protocol == 0 {
Ok(UnixSocket { Ok(UnixSocket {
obj: None, obj: None,
status: Status::None status: Status::None,
}) })
} else { } else {
errno!(ENOSYS, "unimplemented unix socket type") errno!(ENOSYS, "unimplemented unix socket type")
@ -221,8 +223,8 @@ impl UnixSocket {
if let Status::Listening = self.status { if let Status::Listening = self.status {
return errno!(EINVAL, "unix socket is listening?"); return errno!(EINVAL, "unix socket is listening?");
} }
let obj = UnixSocketObject::get(path) let obj =
.ok_or(Error::new(EINVAL, "unix socket path not found"))?; UnixSocketObject::get(path).ok_or(Error::new(EINVAL, "unix socket path not found"))?;
let (channel1, channel2) = Channel::new_pair(); let (channel1, channel2) = Channel::new_pair();
self.status = Status::Connected(channel1); self.status = Status::Connected(channel1);
obj.push(UnixSocket { obj.push(UnixSocket {
@ -240,7 +242,8 @@ impl UnixSocket {
self.channel()?.writer.write(buf) self.channel()?.writer.write(buf)
} }
pub fn poll(&self) -> Result<(bool, bool, bool), Error> { // (read, write, error) pub fn poll(&self) -> Result<(bool, bool, bool), Error> {
// (read, write, error)
let channel = self.channel()?; let channel = self.channel()?;
let r = channel.reader.can_read(); let r = channel.reader.can_read();
let w = channel.writer.can_write(); let w = channel.writer.can_write();
@ -251,7 +254,9 @@ impl UnixSocket {
const FIONREAD: c_int = 0x541B; // Get the number of bytes to read const FIONREAD: c_int = 0x541B; // Get the number of bytes to read
if cmd == FIONREAD { if cmd == FIONREAD {
let bytes_to_read = self.channel()?.reader.bytes_to_read(); let bytes_to_read = self.channel()?.reader.bytes_to_read();
unsafe { argp.write(bytes_to_read as c_int); } unsafe {
argp.write(bytes_to_read as c_int);
}
Ok(()) Ok(())
} else { } else {
warn!("ioctl for unix socket is unimplemented"); warn!("ioctl for unix socket is unimplemented");
@ -302,7 +307,7 @@ impl UnixSocketObject {
} }
let obj = Arc::new(UnixSocketObject { let obj = Arc::new(UnixSocketObject {
path: path.as_ref().to_string(), path: path.as_ref().to_string(),
accepted_sockets: Mutex::new(VecDeque::new()) accepted_sockets: Mutex::new(VecDeque::new()),
}); });
paths.insert(path.as_ref().to_string(), obj.clone()); paths.insert(path.as_ref().to_string(), obj.clone());
Ok(obj) Ok(obj)
@ -315,7 +320,7 @@ impl UnixSocketObject {
struct Channel { struct Channel {
reader: RingBufReader, reader: RingBufReader,
writer: RingBufWriter writer: RingBufWriter,
} }
unsafe impl Send for Channel {} unsafe impl Send for Channel {}
@ -340,6 +345,6 @@ impl Channel {
pub const DEFAULT_BUF_SIZE: usize = 1 * 1024 * 1024; pub const DEFAULT_BUF_SIZE: usize = 1 * 1024 * 1024;
lazy_static! { lazy_static! {
static ref UNIX_SOCKET_OBJS: Mutex<BTreeMap<String, Arc<UnixSocketObject>>> static ref UNIX_SOCKET_OBJS: Mutex<BTreeMap<String, Arc<UnixSocketObject>>> =
= Mutex::new(BTreeMap::new()); Mutex::new(BTreeMap::new());
} }

@ -36,12 +36,12 @@ mod prelude;
mod entry; mod entry;
mod errno; mod errno;
mod fs; mod fs;
mod misc;
mod process; mod process;
mod syscall; mod syscall;
mod time; mod time;
mod util; mod util;
mod vm; mod vm;
mod misc;
use prelude::*; use prelude::*;

@ -1,7 +1,7 @@
use super::*; use super::*;
mod uname;
mod rlimit; mod rlimit;
mod uname;
pub use self::uname::{utsname_t, do_uname}; pub use self::rlimit::{do_prlimit, resource_t, rlimit_t, ResourceLimits, ResourceLimitsRef};
pub use self::rlimit::{rlimit_t, resource_t, ResourceLimits, ResourceLimitsRef, do_prlimit}; pub use self::uname::{do_uname, utsname_t};

@ -1,5 +1,5 @@
use super::*; use super::*;
use process::{pid_t}; use process::pid_t;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct ResourceLimits { pub struct ResourceLimits {
@ -21,13 +21,12 @@ impl Default for ResourceLimits {
fn default() -> ResourceLimits { fn default() -> ResourceLimits {
// TODO: set appropriate limits for resources // TODO: set appropriate limits for resources
let mut rlimits = ResourceLimits { let mut rlimits = ResourceLimits {
rlimits: [ Default::default(); RLIMIT_COUNT ], rlimits: [Default::default(); RLIMIT_COUNT],
}; };
rlimits rlimits
} }
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct rlimit_t { pub struct rlimit_t {
@ -44,41 +43,40 @@ impl Default for rlimit_t {
} }
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub enum resource_t { pub enum resource_t {
RLIMIT_CPU = 0, RLIMIT_CPU = 0,
RLIMIT_FSIZE = 1, RLIMIT_FSIZE = 1,
RLIMIT_DATA = 2, RLIMIT_DATA = 2,
RLIMIT_STACK = 3, RLIMIT_STACK = 3,
RLIMIT_CORE = 4, RLIMIT_CORE = 4,
RLIMIT_RSS = 5, RLIMIT_RSS = 5,
RLIMIT_NPROC = 6, RLIMIT_NPROC = 6,
RLIMIT_NOFILE = 7, RLIMIT_NOFILE = 7,
RLIMIT_MEMLOCK = 8, RLIMIT_MEMLOCK = 8,
RLIMIT_AS = 9, RLIMIT_AS = 9,
RLIMIT_LOCKS = 10, RLIMIT_LOCKS = 10,
RLIMIT_SIGPENDING = 11, RLIMIT_SIGPENDING = 11,
RLIMIT_MSGQUEUE = 12, RLIMIT_MSGQUEUE = 12,
RLIMIT_NICE = 13, RLIMIT_NICE = 13,
RLIMIT_RTPRIO = 14, RLIMIT_RTPRIO = 14,
} }
const RLIMIT_COUNT: usize = 15; const RLIMIT_COUNT: usize = 15;
impl resource_t { impl resource_t {
pub fn from_u32(bits: u32) -> Result<resource_t, Error> { pub fn from_u32(bits: u32) -> Result<resource_t, Error> {
match bits { match bits {
0 => Ok(resource_t::RLIMIT_CPU), 0 => Ok(resource_t::RLIMIT_CPU),
1 => Ok(resource_t::RLIMIT_FSIZE), 1 => Ok(resource_t::RLIMIT_FSIZE),
2 => Ok(resource_t::RLIMIT_DATA), 2 => Ok(resource_t::RLIMIT_DATA),
3 => Ok(resource_t::RLIMIT_STACK), 3 => Ok(resource_t::RLIMIT_STACK),
4 => Ok(resource_t::RLIMIT_CORE), 4 => Ok(resource_t::RLIMIT_CORE),
5 => Ok(resource_t::RLIMIT_RSS), 5 => Ok(resource_t::RLIMIT_RSS),
6 => Ok(resource_t::RLIMIT_NPROC), 6 => Ok(resource_t::RLIMIT_NPROC),
7 => Ok(resource_t::RLIMIT_NOFILE), 7 => Ok(resource_t::RLIMIT_NOFILE),
8 => Ok(resource_t::RLIMIT_MEMLOCK), 8 => Ok(resource_t::RLIMIT_MEMLOCK),
9 => Ok(resource_t::RLIMIT_AS), 9 => Ok(resource_t::RLIMIT_AS),
10 => Ok(resource_t::RLIMIT_LOCKS), 10 => Ok(resource_t::RLIMIT_LOCKS),
11 => Ok(resource_t::RLIMIT_SIGPENDING), 11 => Ok(resource_t::RLIMIT_SIGPENDING),
12 => Ok(resource_t::RLIMIT_MSGQUEUE), 12 => Ok(resource_t::RLIMIT_MSGQUEUE),
@ -89,7 +87,6 @@ impl resource_t {
} }
} }
pub fn do_prlimit( pub fn do_prlimit(
pid: pid_t, pid: pid_t,
resource: resource_t, resource: resource_t,
@ -98,8 +95,7 @@ pub fn do_prlimit(
) -> Result<(), Error> { ) -> Result<(), Error> {
let process_ref = if pid == 0 { let process_ref = if pid == 0 {
process::get_current() process::get_current()
} } else {
else {
process::get(pid)? process::get(pid)?
}; };
let mut process = process_ref.lock().unwrap(); let mut process = process_ref.lock().unwrap();

@ -34,7 +34,7 @@ pub fn do_uname(name: &mut utsname_t) -> Result<(), Error> {
} }
lazy_static! { lazy_static! {
static ref SYSNAME : CString = CString::new("Occlum").unwrap(); static ref SYSNAME: CString = CString::new("Occlum").unwrap();
static ref NODENAME: CString = CString::new("occlum-node").unwrap(); static ref NODENAME: CString = CString::new("occlum-node").unwrap();
static ref RELEASE: CString = CString::new("0.1").unwrap(); static ref RELEASE: CString = CString::new("0.1").unwrap();
static ref VERSION: CString = CString::new("0.1").unwrap(); static ref VERSION: CString = CString::new("0.1").unwrap();
@ -43,9 +43,8 @@ lazy_static! {
} }
fn copy_from_cstr_to_u8_array(src: &CStr, dst: &mut [u8]) { fn copy_from_cstr_to_u8_array(src: &CStr, dst: &mut [u8]) {
let src : &[u8] = src.to_bytes_with_nul(); let src: &[u8] = src.to_bytes_with_nul();
let len = min(dst.len() - 1, src.len()); let len = min(dst.len() - 1, src.len());
dst[..len].copy_from_slice(&src[..len]); dst[..len].copy_from_slice(&src[..len]);
dst[len] = 0; dst[len] = 0;
} }

@ -14,6 +14,7 @@ pub use std::sync::{
//pub use std::borrow::BorrowMut; //pub use std::borrow::BorrowMut;
pub use std::borrow::ToOwned; pub use std::borrow::ToOwned;
pub use std::boxed::Box; pub use std::boxed::Box;
pub use std::cmp::{max, min};
pub use std::cmp::{Ordering, PartialOrd}; pub use std::cmp::{Ordering, PartialOrd};
pub use std::collections::{HashMap, VecDeque}; pub use std::collections::{HashMap, VecDeque};
pub use std::fmt::{Debug, Display}; pub use std::fmt::{Debug, Display};
@ -22,7 +23,6 @@ pub use std::iter::Iterator;
pub use std::rc::Rc; pub use std::rc::Rc;
pub use std::string::String; pub use std::string::String;
pub use std::vec::Vec; pub use std::vec::Vec;
pub use std::cmp::{min, max};
pub use errno::Errno; pub use errno::Errno;
pub use errno::Errno::*; pub use errno::Errno::*;

@ -22,22 +22,28 @@ impl ArchPrctlCode {
} }
pub fn do_arch_prctl(code: ArchPrctlCode, addr: *mut usize) -> Result<(), Error> { pub fn do_arch_prctl(code: ArchPrctlCode, addr: *mut usize) -> Result<(), Error> {
info!("do_arch_prctl: code: {:?}, addr: {:#o}", code, addr as usize); info!(
"do_arch_prctl: code: {:?}, addr: {:#o}",
code, addr as usize
);
match code { match code {
ArchPrctlCode::ARCH_SET_FS => { ArchPrctlCode::ARCH_SET_FS => {
let current_ref = get_current(); let current_ref = get_current();
let mut current = current_ref.lock().unwrap(); let mut current = current_ref.lock().unwrap();
let task = &mut current.task; let task = &mut current.task;
task.user_fsbase_addr = addr as usize; task.user_fsbase_addr = addr as usize;
}, }
ArchPrctlCode::ARCH_GET_FS => { ArchPrctlCode::ARCH_GET_FS => {
let current_ref = get_current(); let current_ref = get_current();
let current = current_ref.lock().unwrap(); let current = current_ref.lock().unwrap();
let task = &current.task; let task = &current.task;
unsafe { *addr = task.user_fsbase_addr; } unsafe {
}, *addr = task.user_fsbase_addr;
ArchPrctlCode::ARCH_SET_GS | ArchPrctlCode::ARCH_GET_GS }
=> return errno!(EINVAL, "GS cannot be accessed from the user space"), }
ArchPrctlCode::ARCH_SET_GS | ArchPrctlCode::ARCH_GET_GS => {
return errno!(EINVAL, "GS cannot be accessed from the user space");
}
} }
Ok(()) Ok(())
} }

@ -28,7 +28,9 @@ pub fn do_exit(exit_status: i32) {
// Notify another process, if any, that waits on ctid (see set_tid_address) // Notify another process, if any, that waits on ctid (see set_tid_address)
if let Some(ctid) = current.clear_child_tid { if let Some(ctid) = current.clear_child_tid {
unsafe { atomic_store(ctid, 0); } unsafe {
atomic_store(ctid, 0);
}
futex_wake(ctid as *const i32, 1); futex_wake(ctid as *const i32, 1);
} }

@ -7,18 +7,18 @@ use std::sync::atomic::{AtomicBool, Ordering};
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub enum FutexOp { pub enum FutexOp {
FUTEX_WAIT = 0, FUTEX_WAIT = 0,
FUTEX_WAKE = 1, FUTEX_WAKE = 1,
FUTEX_FD = 2, FUTEX_FD = 2,
FUTEX_REQUEUE = 3, FUTEX_REQUEUE = 3,
FUTEX_CMP_REQUEUE = 4, FUTEX_CMP_REQUEUE = 4,
FUTEX_WAKE_OP = 5, FUTEX_WAKE_OP = 5,
FUTEX_LOCK_PI = 6, FUTEX_LOCK_PI = 6,
FUTEX_UNLOCK_PI = 7, FUTEX_UNLOCK_PI = 7,
FUTEX_TRYLOCK_PI = 8, FUTEX_TRYLOCK_PI = 8,
FUTEX_WAIT_BITSET = 9, FUTEX_WAIT_BITSET = 9,
} }
const FUTEX_OP_MASK : u32 = 0x0000_000F; const FUTEX_OP_MASK: u32 = 0x0000_000F;
impl FutexOp { impl FutexOp {
pub fn from_u32(bits: u32) -> Result<FutexOp, Error> { pub fn from_u32(bits: u32) -> Result<FutexOp, Error> {
@ -44,12 +44,11 @@ bitflags! {
const FUTEX_CLOCK_REALTIME = 256; const FUTEX_CLOCK_REALTIME = 256;
} }
} }
const FUTEX_FLAGS_MASK : u32 = 0xFFFF_FFF0; const FUTEX_FLAGS_MASK: u32 = 0xFFFF_FFF0;
impl FutexFlags { impl FutexFlags {
pub fn from_u32(bits: u32) -> Result<FutexFlags, Error> { pub fn from_u32(bits: u32) -> Result<FutexFlags, Error> {
FutexFlags::from_bits(bits).ok_or_else(|| FutexFlags::from_bits(bits).ok_or_else(|| Error::new(Errno::EINVAL, "Unknown futex flags"))
Error::new(Errno::EINVAL, "Unknown futex flags"))
} }
} }
@ -65,12 +64,10 @@ pub fn futex_op_and_flags_from_u32(bits: u32) -> Result<(FutexOp, FutexFlags), E
Ok((op, flags)) Ok((op, flags))
} }
/// Do futex wait /// Do futex wait
pub fn futex_wait(futex_addr: *const i32, futex_val: i32) -> Result<(), Error> { pub fn futex_wait(futex_addr: *const i32, futex_val: i32) -> Result<(), Error> {
let futex_key = FutexKey::new(futex_addr); let futex_key = FutexKey::new(futex_addr);
let futex_item = FUTEX_TABLE.lock().unwrap() let futex_item = FUTEX_TABLE.lock().unwrap().get_or_new_item(futex_key);
.get_or_new_item(futex_key);
futex_item.wait(futex_val); futex_item.wait(futex_val);
@ -87,11 +84,8 @@ pub fn futex_wake(futex_addr: *const i32, max_count: usize) -> Result<usize, Err
Ok(count) Ok(count)
} }
lazy_static! { lazy_static! {
static ref FUTEX_TABLE : SgxMutex<FutexTable> = { static ref FUTEX_TABLE: SgxMutex<FutexTable> = { SgxMutex::new(FutexTable::new()) };
SgxMutex::new(FutexTable::new())
};
} }
#[derive(PartialEq, Eq, Hash, Copy, Clone)] #[derive(PartialEq, Eq, Hash, Copy, Clone)]
@ -126,7 +120,9 @@ impl FutexItem {
while count < max_count { while count < max_count {
let waiter = { let waiter = {
let waiter_option = queue.pop_front(); let waiter_option = queue.pop_front();
if waiter_option.is_none() { break; } if waiter_option.is_none() {
break;
}
waiter_option.unwrap() waiter_option.unwrap()
}; };
waiter.wake(); waiter.wake();
@ -165,15 +161,17 @@ impl FutexTable {
pub fn get_or_new_item(&mut self, key: FutexKey) -> FutexItemRef { pub fn get_or_new_item(&mut self, key: FutexKey) -> FutexItemRef {
let table = &mut self.table; let table = &mut self.table;
let item = table.entry(key).or_insert_with(|| { let item = table
Arc::new(FutexItem::new(key)) .entry(key)
}); .or_insert_with(|| Arc::new(FutexItem::new(key)));
item.clone() item.clone()
} }
pub fn get_item(&mut self, key: FutexKey) -> Result<FutexItemRef, Error> { pub fn get_item(&mut self, key: FutexKey) -> Result<FutexItemRef, Error> {
let table = &mut self.table; let table = &mut self.table;
table.get_mut(&key).map(|item| item.clone()) table
.get_mut(&key)
.map(|item| item.clone())
.ok_or_else(|| Error::new(Errno::ENOENT, "futex key cannot be found")) .ok_or_else(|| Error::new(Errno::ENOENT, "futex key cannot be found"))
} }
@ -193,7 +191,6 @@ impl FutexTable {
} }
} }
#[derive(Debug)] #[derive(Debug)]
struct Waiter { struct Waiter {
thread: *const c_void, thread: *const c_void,

@ -1,12 +1,12 @@
pub use self::process::{Status, IDLE_PROCESS}; pub use self::arch_prctl::{do_arch_prctl, ArchPrctlCode};
pub use self::task::{get_current, run_task, current_pid};
pub use self::process_table::{get};
pub use self::exit::{do_exit, do_wait4, ChildProcessFilter}; pub use self::exit::{do_exit, do_wait4, ChildProcessFilter};
pub use self::futex::{futex_op_and_flags_from_u32, futex_wait, futex_wake, FutexFlags, FutexOp};
pub use self::process::{Status, IDLE_PROCESS};
pub use self::process_table::get;
pub use self::spawn::{do_spawn, FileAction}; pub use self::spawn::{do_spawn, FileAction};
pub use self::task::{current_pid, get_current, run_task};
pub use self::thread::{do_clone, do_set_tid_address, CloneFlags, ThreadGroup};
pub use self::wait::{WaitQueue, Waiter}; pub use self::wait::{WaitQueue, Waiter};
pub use self::thread::{do_clone, CloneFlags, ThreadGroup, do_set_tid_address};
pub use self::futex::{FutexOp, FutexFlags, futex_op_and_flags_from_u32, futex_wake, futex_wait};
pub use self::arch_prctl::{ArchPrctlCode, do_arch_prctl};
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub type pid_t = u32; pub type pid_t = u32;
@ -64,18 +64,18 @@ pub fn do_getppid() -> pid_t {
parent.get_pid() parent.get_pid()
} }
mod arch_prctl;
mod exit; mod exit;
mod futex;
mod process; mod process;
mod process_table; mod process_table;
mod spawn; mod spawn;
mod task; mod task;
mod wait;
mod thread; mod thread;
mod futex; mod wait;
mod arch_prctl;
use self::task::Task; use self::task::Task;
use super::*; use super::*;
use fs::{File, FileRef, FileTable}; use fs::{File, FileRef, FileTable};
use misc::ResourceLimitsRef;
use vm::{ProcessVM, VMRangeTrait}; use vm::{ProcessVM, VMRangeTrait};
use misc::{ResourceLimitsRef};

@ -88,7 +88,7 @@ impl Process {
pub fn get_parent(&self) -> &ProcessRef { pub fn get_parent(&self) -> &ProcessRef {
self.parent.as_ref().unwrap() self.parent.as_ref().unwrap()
} }
pub fn get_children_iter(&self) -> impl Iterator<Item=ProcessRef> + '_ { pub fn get_children_iter(&self) -> impl Iterator<Item = ProcessRef> + '_ {
self.children self.children
.iter() .iter()
.filter_map(|child_weak| child_weak.upgrade()) .filter_map(|child_weak| child_weak.upgrade())

@ -15,7 +15,10 @@ pub fn remove(pid: pid_t) {
} }
pub fn get(pid: pid_t) -> Result<ProcessRef, Error> { pub fn get(pid: pid_t) -> Result<ProcessRef, Error> {
PROCESS_TABLE.lock().unwrap().get(&pid) PROCESS_TABLE
.lock()
.unwrap()
.get(&pid)
.map(|pr| pr.clone()) .map(|pr| pr.clone())
.ok_or_else(|| Error::new(Errno::ENOENT, "process not found")) .ok_or_else(|| Error::new(Errno::ENOENT, "process not found"))
} }

@ -1,15 +1,15 @@
use xmas_elf::{ElfFile, header, program, sections};
use xmas_elf::symbol_table::Entry; use xmas_elf::symbol_table::Entry;
use xmas_elf::{header, program, sections, ElfFile};
use fs::{File, FileDesc, FileTable, INodeExt, ROOT_INODE, StdinFile, StdoutFile, OpenFlags}; use fs::{File, FileDesc, FileTable, INodeExt, OpenFlags, StdinFile, StdoutFile, ROOT_INODE};
use misc::ResourceLimitsRef;
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::path::Path; use std::path::Path;
use std::sgxfs::SgxFile; use std::sgxfs::SgxFile;
use vm::{ProcessVM, VMRangeTrait}; use vm::{ProcessVM, VMRangeTrait};
use misc::{ResourceLimitsRef};
use super::*;
use super::task::Task; use super::task::Task;
use super::*;
use self::init_stack::{AuxKey, AuxTable}; use self::init_stack::{AuxKey, AuxTable};
@ -98,7 +98,12 @@ fn init_files(parent_ref: &ProcessRef, file_actions: &[FileAction]) -> Result<Fi
// Perform file actions to modify the cloned file table // Perform file actions to modify the cloned file table
for file_action in file_actions { for file_action in file_actions {
match file_action { match file_action {
&FileAction::Open { ref path, mode, oflag, fd} => { &FileAction::Open {
ref path,
mode,
oflag,
fd,
} => {
let flags = OpenFlags::from_bits_truncate(oflag); let flags = OpenFlags::from_bits_truncate(oflag);
let file = parent.open_file(path.as_str(), flags, mode)?; let file = parent.open_file(path.as_str(), flags, mode)?;
let file_ref: Arc<Box<File>> = Arc::new(file); let file_ref: Arc<Box<File>> = Arc::new(file);
@ -151,7 +156,11 @@ fn init_task(
}) })
} }
fn init_auxtbl(base_addr: usize, program_entry: usize, elf_file: &ElfFile) -> Result<AuxTable, Error> { fn init_auxtbl(
base_addr: usize,
program_entry: usize,
elf_file: &ElfFile,
) -> Result<AuxTable, Error> {
let mut auxtbl = AuxTable::new(); let mut auxtbl = AuxTable::new();
auxtbl.set_val(AuxKey::AT_PAGESZ, 4096)?; auxtbl.set_val(AuxKey::AT_PAGESZ, 4096)?;
auxtbl.set_val(AuxKey::AT_UID, 0)?; auxtbl.set_val(AuxKey::AT_UID, 0)?;

@ -4,7 +4,6 @@ pub struct ThreadGroup {
threads: Vec<ProcessRef>, threads: Vec<ProcessRef>,
} }
bitflags! { bitflags! {
pub struct CloneFlags : u32 { pub struct CloneFlags : u32 {
const CLONE_VM = 0x00000100; const CLONE_VM = 0x00000100;
@ -40,8 +39,10 @@ pub fn do_clone(
ctid: Option<*mut pid_t>, ctid: Option<*mut pid_t>,
new_tls: Option<usize>, new_tls: Option<usize>,
) -> Result<pid_t, Error> { ) -> Result<pid_t, Error> {
info!("clone: flags: {:?}, stack_addr: {:?}, ptid: {:?}, ctid: {:?}, new_tls: {:?}", info!(
flags, stack_addr, ptid, ctid, new_tls); "clone: flags: {:?}, stack_addr: {:?}, ptid: {:?}, ctid: {:?}, new_tls: {:?}",
flags, stack_addr, ptid, ctid, new_tls
);
// TODO: return error for unsupported flags // TODO: return error for unsupported flags
let current_ref = get_current(); let current_ref = get_current();
@ -75,7 +76,9 @@ pub fn do_clone(
process_table::put(new_thread_pid, new_thread_ref.clone()); process_table::put(new_thread_pid, new_thread_ref.clone());
if let Some(ptid) = ptid { if let Some(ptid) = ptid {
unsafe { *ptid = new_thread_pid; } unsafe {
*ptid = new_thread_pid;
}
} }
task::enqueue_task(new_thread_ref); task::enqueue_task(new_thread_ref);

@ -921,10 +921,7 @@ fn do_fcntl(fd: FileDesc, cmd: u32, arg: u64) -> Result<isize, Error> {
} }
fn do_ioctl(fd: FileDesc, cmd: c_int, argp: *mut c_int) -> Result<isize, Error> { fn do_ioctl(fd: FileDesc, cmd: c_int, argp: *mut c_int) -> Result<isize, Error> {
info!( info!("ioctl: fd: {}, cmd: {}, argp: {:?}", fd, cmd, argp);
"ioctl: fd: {}, cmd: {}, argp: {:?}",
fd, cmd, argp
);
let current_ref = process::get_current(); let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap(); let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?; let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
@ -994,7 +991,9 @@ fn do_connect(
} else if let Ok(unix_socket) = file_ref.as_unix_socket() { } else if let Ok(unix_socket) = file_ref.as_unix_socket() {
let addr = addr as *const libc::sockaddr_un; let addr = addr as *const libc::sockaddr_un;
check_ptr(addr)?; // TODO: check addr_len check_ptr(addr)?; // TODO: check addr_len
let path = clone_cstring_safely(unsafe { (&*addr).sun_path.as_ptr() })?.to_string_lossy().into_owned(); let path = clone_cstring_safely(unsafe { (&*addr).sun_path.as_ptr() })?
.to_string_lossy()
.into_owned();
unix_socket.connect(path)?; unix_socket.connect(path)?;
Ok(0) Ok(0)
} else { } else {
@ -1066,7 +1065,9 @@ fn do_bind(
} else if let Ok(unix_socket) = file_ref.as_unix_socket() { } else if let Ok(unix_socket) = file_ref.as_unix_socket() {
let addr = addr as *const libc::sockaddr_un; let addr = addr as *const libc::sockaddr_un;
check_ptr(addr)?; // TODO: check addr_len check_ptr(addr)?; // TODO: check addr_len
let path = clone_cstring_safely(unsafe { (&*addr).sun_path.as_ptr() })?.to_string_lossy().into_owned(); let path = clone_cstring_safely(unsafe { (&*addr).sun_path.as_ptr() })?
.to_string_lossy()
.into_owned();
unix_socket.bind(path)?; unix_socket.bind(path)?;
Ok(0) Ok(0)
} else { } else {
@ -1152,20 +1153,22 @@ fn do_getpeername(
addr: *mut libc::sockaddr, addr: *mut libc::sockaddr,
addr_len: *mut libc::socklen_t, addr_len: *mut libc::socklen_t,
) -> Result<isize, Error> { ) -> Result<isize, Error> {
info!("getpeername: fd: {}, addr: {:?}, addr_len: {:?}", fd, addr, addr_len); info!(
"getpeername: fd: {}, addr: {:?}, addr_len: {:?}",
fd, addr, addr_len
);
let current_ref = process::get_current(); let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap(); let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?; let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() { if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::getpeername( let ret = try_libc!(libc::ocall::getpeername(socket.fd(), addr, addr_len));
socket.fd(),
addr,
addr_len
));
Ok(ret as isize) Ok(ret as isize)
} else if let Ok(unix_socket) = file_ref.as_unix_socket() { } else if let Ok(unix_socket) = file_ref.as_unix_socket() {
warn!("getpeername for unix socket is unimplemented"); warn!("getpeername for unix socket is unimplemented");
errno!(ENOTCONN, "hack for php: Transport endpoint is not connected") errno!(
ENOTCONN,
"hack for php: Transport endpoint is not connected"
)
} else { } else {
errno!(EBADF, "not a socket") errno!(EBADF, "not a socket")
} }
@ -1176,16 +1179,15 @@ fn do_getsockname(
addr: *mut libc::sockaddr, addr: *mut libc::sockaddr,
addr_len: *mut libc::socklen_t, addr_len: *mut libc::socklen_t,
) -> Result<isize, Error> { ) -> Result<isize, Error> {
info!("getsockname: fd: {}, addr: {:?}, addr_len: {:?}", fd, addr, addr_len); info!(
"getsockname: fd: {}, addr: {:?}, addr_len: {:?}",
fd, addr, addr_len
);
let current_ref = process::get_current(); let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap(); let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?; let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() { if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::getsockname( let ret = try_libc!(libc::ocall::getsockname(socket.fd(), addr, addr_len));
socket.fd(),
addr,
addr_len
));
Ok(ret as isize) Ok(ret as isize)
} else if let Ok(unix_socket) = file_ref.as_unix_socket() { } else if let Ok(unix_socket) = file_ref.as_unix_socket() {
warn!("getsockname for unix socket is unimplemented"); warn!("getsockname for unix socket is unimplemented");

@ -2,8 +2,8 @@ use alloc::alloc::{alloc, dealloc, Layout};
use std::cmp::{max, min}; use std::cmp::{max, min};
use std::ptr; use std::ptr;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use super::*; use super::*;

@ -5,18 +5,22 @@ use std::fmt;
#[macro_use] #[macro_use]
mod vm_range; mod vm_range;
mod vm_area;
mod process_vm; mod process_vm;
mod vm_area;
pub use self::vm_range::{VMRange, VMRangeTrait};
pub use self::vm_area::{VMSpace, VMDomain, VMArea, VMAreaFlags, VM_AREA_FLAG_R, VM_AREA_FLAG_W, VM_AREA_FLAG_X};
pub use self::process_vm::ProcessVM; pub use self::process_vm::ProcessVM;
pub use self::vm_area::{
VMArea, VMAreaFlags, VMDomain, VMSpace, VM_AREA_FLAG_R, VM_AREA_FLAG_W, VM_AREA_FLAG_X,
};
pub use self::vm_range::{VMRange, VMRangeTrait};
// TODO: separate proc and flags // TODO: separate proc and flags
// TODO: accept fd and offset // TODO: accept fd and offset
pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Error> { pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Error> {
info!("mmap: addr: {:#x}, size: {:#x}, flags: {:?}", addr, size, flags); info!(
"mmap: addr: {:#x}, size: {:#x}, flags: {:?}",
addr, size, flags
);
let current_ref = get_current(); let current_ref = get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let current_vm_ref = current_process.get_vm(); let current_vm_ref = current_process.get_vm();
@ -68,7 +72,6 @@ pub enum VMGuardAreaType {
Dynamic { size: usize }, Dynamic { size: usize },
} }
#[derive(Clone, PartialEq, Default)] #[derive(Clone, PartialEq, Default)]
pub struct VMAllocOptions { pub struct VMAllocOptions {
size: usize, size: usize,
@ -123,7 +126,6 @@ impl fmt::Debug for VMAllocOptions {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum VMAddrOption { pub enum VMAddrOption {
Any, // Free to choose any address Any, // Free to choose any address
@ -156,7 +158,6 @@ impl VMAddrOption {
} }
} }
/// How VMRange may grow: /// How VMRange may grow:
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum VMGrowthType { pub enum VMGrowthType {
@ -171,7 +172,6 @@ impl Default for VMGrowthType {
} }
} }
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct VMResizeOptions { pub struct VMResizeOptions {
new_size: usize, new_size: usize,

@ -46,24 +46,29 @@ impl ProcessVM {
) -> Result<ProcessVM, Error> { ) -> Result<ProcessVM, Error> {
// Allocate the data domain from the global data space // Allocate the data domain from the global data space
let mut data_domain = { let mut data_domain = {
let data_domain_size = code_size + data_size + heap_size let data_domain_size = code_size + data_size + heap_size + stack_size + mmap_size;
+ stack_size + mmap_size; let data_domain = DATA_SPACE
let data_domain = DATA_SPACE.lock().unwrap().alloc_domain( .lock()
data_domain_size, "data_domain")?; .unwrap()
.alloc_domain(data_domain_size, "data_domain")?;
data_domain data_domain
}; };
// Allocate vmas from the data domain // Allocate vmas from the data domain
let (code_vma, data_vma, heap_vma, stack_vma) = let (code_vma, data_vma, heap_vma, stack_vma) = match ProcessVM::alloc_vmas(
match ProcessVM::alloc_vmas(&mut data_domain, code_size, &mut data_domain,
data_size, heap_size, stack_size) { code_size,
Err(e) => { data_size,
// Note: we need to handle error here so that we can heap_size,
// deallocate the data domain explictly. stack_size,
DATA_SPACE.lock().unwrap().dealloc_domain(data_domain); ) {
return Err(e); Err(e) => {
}, // Note: we need to handle error here so that we can
Ok(vmas) => vmas, // deallocate the data domain explictly.
}; DATA_SPACE.lock().unwrap().dealloc_domain(data_domain);
return Err(e);
}
Ok(vmas) => vmas,
};
// Initial value of the program break // Initial value of the program break
let brk = heap_vma.get_start(); let brk = heap_vma.get_start();
// No mmapped vmas initially // No mmapped vmas initially
@ -92,7 +97,8 @@ impl ProcessVM {
let mut alloc_vma_continuously = let mut alloc_vma_continuously =
|addr: &mut usize, desc, size, flags, growth, fill_zeros| -> Result<_, Error> { |addr: &mut usize, desc, size, flags, growth, fill_zeros| -> Result<_, Error> {
let mut options = VMAllocOptions::new(size)?; let mut options = VMAllocOptions::new(size)?;
options.addr(VMAddrOption::Fixed(*addr))? options
.addr(VMAddrOption::Fixed(*addr))?
.growth(growth)? .growth(growth)?
.description(desc)? .description(desc)?
.fill_zeros(fill_zeros)?; .fill_zeros(fill_zeros)?;
@ -104,17 +110,41 @@ impl ProcessVM {
let rx_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_X); let rx_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_X);
let rw_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_W); let rw_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_W);
let code_vma = alloc_vma_continuously(&mut addr, "code_vma", code_size, let code_vma = alloc_vma_continuously(
rx_flags, VMGrowthType::Fixed, true)?; &mut addr,
let data_vma = alloc_vma_continuously(&mut addr, "data_vma", data_size, "code_vma",
rw_flags, VMGrowthType::Fixed, true)?; code_size,
let heap_vma = alloc_vma_continuously(&mut addr, "heap_vma", 0, rx_flags,
rw_flags, VMGrowthType::Upward, true)?; VMGrowthType::Fixed,
true,
)?;
let data_vma = alloc_vma_continuously(
&mut addr,
"data_vma",
data_size,
rw_flags,
VMGrowthType::Fixed,
true,
)?;
let heap_vma = alloc_vma_continuously(
&mut addr,
"heap_vma",
0,
rw_flags,
VMGrowthType::Upward,
true,
)?;
// Preserve the space for heap // Preserve the space for heap
addr += heap_size; addr += heap_size;
// After the heap is the stack // After the heap is the stack
let stack_vma = alloc_vma_continuously(&mut addr, "stack_vma", stack_size, let stack_vma = alloc_vma_continuously(
rw_flags, VMGrowthType::Downward, false)?; &mut addr,
"stack_vma",
stack_size,
rw_flags,
VMGrowthType::Downward,
false,
)?;
Ok((code_vma, data_vma, heap_vma, stack_vma)) Ok((code_vma, data_vma, heap_vma, stack_vma))
} }
@ -178,7 +208,8 @@ impl ProcessVM {
alloc_options alloc_options
}; };
// TODO: when failed, try to resize data_domain // TODO: when failed, try to resize data_domain
let new_mmap_vma = self.get_data_domain_mut() let new_mmap_vma = self
.get_data_domain_mut()
.alloc_area(&alloc_options, flags)?; .alloc_area(&alloc_options, flags)?;
let addr = new_mmap_vma.get_start(); let addr = new_mmap_vma.get_start();
self.mmap_vmas.push(Box::new(new_mmap_vma)); self.mmap_vmas.push(Box::new(new_mmap_vma));
@ -201,7 +232,8 @@ impl ProcessVM {
}; };
let removed_mmap_vma = self.mmap_vmas.swap_remove(mmap_vma_i); let removed_mmap_vma = self.mmap_vmas.swap_remove(mmap_vma_i);
self.get_data_domain_mut().dealloc_area(unbox(removed_mmap_vma)); self.get_data_domain_mut()
.dealloc_area(unbox(removed_mmap_vma));
Ok(()) Ok(())
} }
@ -229,7 +261,8 @@ impl ProcessVM {
let new_heap_end = align_up(new_brk, PAGE_SIZE); let new_heap_end = align_up(new_brk, PAGE_SIZE);
let new_heap_size = new_heap_end - heap_start; let new_heap_size = new_heap_end - heap_start;
let mut options = VMResizeOptions::new(new_heap_size)?; let mut options = VMResizeOptions::new(new_heap_size)?;
options.addr(VMAddrOption::Fixed(heap_start)) options
.addr(VMAddrOption::Fixed(heap_start))
.fill_zeros(true); .fill_zeros(true);
options options
}; };
@ -261,7 +294,9 @@ impl Drop for ProcessVM {
} }
// Remove the domain from its parent space // Remove the domain from its parent space
DATA_SPACE.lock().unwrap().dealloc_domain( DATA_SPACE
unbox(self.data_domain.take().unwrap())); .lock()
.unwrap()
.dealloc_domain(unbox(self.data_domain.take().unwrap()));
} }
} }

@ -27,8 +27,7 @@ impl VMSpace {
pub fn alloc_domain(&mut self, size: usize, desc: &str) -> Result<VMDomain, Error> { pub fn alloc_domain(&mut self, size: usize, desc: &str) -> Result<VMDomain, Error> {
let mut options = VMAllocOptions::new(size)?; let mut options = VMAllocOptions::new(size)?;
options.growth(VMGrowthType::Upward)? options.growth(VMGrowthType::Upward)?.description(desc)?;
.description(desc)?;
let new_range = self.range.alloc_subrange(&options)?; let new_range = self.range.alloc_subrange(&options)?;
Ok(VMDomain { range: new_range }) Ok(VMDomain { range: new_range })
@ -44,7 +43,6 @@ impl VMSpace {
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct VMDomain { pub struct VMDomain {
range: VMRange, range: VMRange,
@ -78,7 +76,6 @@ impl VMDomain {
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct VMArea { pub struct VMArea {
range: VMRange, range: VMRange,
@ -97,7 +94,6 @@ impl VMArea {
} }
} }
#[derive(Copy, Clone, Debug, Default, PartialEq)] #[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct VMAreaFlags(pub u32); pub struct VMAreaFlags(pub u32);

@ -46,7 +46,12 @@ pub struct VMRange {
impl_vmrange_trait_for!(VMRange, inner); impl_vmrange_trait_for!(VMRange, inner);
impl VMRange { impl VMRange {
pub unsafe fn new(start: usize, end: usize, growth: VMGrowthType, description: &str) -> Result<VMRange, Error> { pub unsafe fn new(
start: usize,
end: usize,
growth: VMGrowthType,
description: &str,
) -> Result<VMRange, Error> {
if start % PAGE_SIZE != 0 || end % PAGE_SIZE != 0 { if start % PAGE_SIZE != 0 || end % PAGE_SIZE != 0 {
return errno!(EINVAL, "Invalid start and/or end"); return errno!(EINVAL, "Invalid start and/or end");
} }
@ -75,8 +80,10 @@ impl VMRange {
debug_assert!(free_space.contains(new_subrange_start)); debug_assert!(free_space.contains(new_subrange_start));
debug_assert!(free_space.contains(new_subrange_end)); debug_assert!(free_space.contains(new_subrange_end));
(free_space.index_in_subranges, VMRangeInner::new( (
new_subrange_start, new_subrange_end, options.growth)) free_space.index_in_subranges,
VMRangeInner::new(new_subrange_start, new_subrange_end, options.growth),
)
}; };
self.get_subranges_mut() self.get_subranges_mut()
.insert(new_subrange_idx, new_subrange_inner); .insert(new_subrange_idx, new_subrange_inner);
@ -186,7 +193,7 @@ impl VMRange {
let pre_range = &range_pair[0]; let pre_range = &range_pair[0];
let next_range = &range_pair[1]; let next_range = &range_pair[1];
let (free_range_start, free_range_end)= { let (free_range_start, free_range_end) = {
let free_range_start = pre_range.get_end(); let free_range_start = pre_range.get_end();
let free_range_end = next_range.get_start(); let free_range_end = next_range.get_start();
@ -209,7 +216,7 @@ impl VMRange {
match addr { match addr {
// Want a minimal free_space // Want a minimal free_space
VMAddrOption::Any => { }, VMAddrOption::Any => {}
// Prefer to have free_space.start == addr // Prefer to have free_space.start == addr
VMAddrOption::Hint(addr) => { VMAddrOption::Hint(addr) => {
if free_space.contains(addr) { if free_space.contains(addr) {
@ -218,7 +225,7 @@ impl VMRange {
return Ok(free_space); return Ok(free_space);
} }
} }
}, }
// Must have free_space.start == addr // Must have free_space.start == addr
VMAddrOption::Fixed(addr) => { VMAddrOption::Fixed(addr) => {
if !free_space.contains(addr) { if !free_space.contains(addr) {
@ -241,20 +248,24 @@ impl VMRange {
continue; continue;
} }
} }
}, }
} }
if min_big_enough_free_space == None || if min_big_enough_free_space == None
free_space < *min_big_enough_free_space.as_ref().unwrap() { || free_space < *min_big_enough_free_space.as_ref().unwrap()
{
min_big_enough_free_space = Some(free_space); min_big_enough_free_space = Some(free_space);
} }
} }
min_big_enough_free_space min_big_enough_free_space.ok_or_else(|| Error::new(Errno::ENOMEM, "not enough space"))
.ok_or_else(|| Error::new(Errno::ENOMEM, "not enough space"))
} }
fn alloc_from_free_space(&self, free_space: &FreeSpace, options: &VMAllocOptions) -> (usize, usize) { fn alloc_from_free_space(
&self,
free_space: &FreeSpace,
options: &VMAllocOptions,
) -> (usize, usize) {
// Get valid parameters from options // Get valid parameters from options
let size = options.size; let size = options.size;
let addr_option = options.addr; let addr_option = options.addr;
@ -262,8 +273,7 @@ impl VMRange {
if let VMAddrOption::Fixed(addr) = addr_option { if let VMAddrOption::Fixed(addr) = addr_option {
return (addr, addr + size); return (addr, addr + size);
} } else if let VMAddrOption::Hint(addr) = addr_option {
else if let VMAddrOption::Hint(addr) = addr_option {
if free_space.start == addr { if free_space.start == addr {
return (addr, addr + size); return (addr, addr + size);
} }
@ -349,7 +359,12 @@ impl VMRange {
Ok(()) Ok(())
} }
fn grow_subrange_to(&mut self, subrange: &mut VMRange, new_size: usize, fill_zeros: bool) -> Result<(), Error> { fn grow_subrange_to(
&mut self,
subrange: &mut VMRange,
new_size: usize,
fill_zeros: bool,
) -> Result<(), Error> {
let subrange_i = self.position_subrange(subrange); let subrange_i = self.position_subrange(subrange);
let subranges = self.get_subranges_mut(); let subranges = self.get_subranges_mut();
@ -379,7 +394,8 @@ impl VMRange {
memset(mem_ptr, 0 as c_int, mem_size); memset(mem_ptr, 0 as c_int, mem_size);
} }
} }
} else { // self.growth == VMGrowthType::Downward } else {
// self.growth == VMGrowthType::Downward
// Can we grow downard? // Can we grow downard?
let max_new_size = { let max_new_size = {
let pre_subrange = &subranges[subrange_i - 1]; let pre_subrange = &subranges[subrange_i - 1];
@ -429,7 +445,6 @@ impl Drop for VMRange {
unsafe impl Send for VMRange {} unsafe impl Send for VMRange {}
unsafe impl Sync for VMRange {} unsafe impl Sync for VMRange {}
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct VMRangeInner { pub struct VMRangeInner {
start: usize, start: usize,