diff --git a/.gitmodules b/.gitmodules index ab2343fa..641851e7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,3 +9,6 @@ [submodule "deps/sgx_protect_file"] path = deps/sgx_protect_file url = https://github.com/occlum/sgx_protect_file +[submodule "deps/sefs"] + path = deps/sefs + url = https://github.com/occlum/sefs.git diff --git a/deps/sefs b/deps/sefs new file mode 160000 index 00000000..62827eb7 --- /dev/null +++ b/deps/sefs @@ -0,0 +1 @@ +Subproject commit 62827eb7bb979f70fc2dad1d957ba19016214441 diff --git a/src/libos/Cargo.lock b/src/libos/Cargo.lock index 311da8b6..18531d0c 100644 --- a/src/libos/Cargo.lock +++ b/src/libos/Cargo.lock @@ -5,12 +5,24 @@ name = "Occlum" version = "0.0.1" dependencies = [ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rcore-fs 0.1.0", + "rcore-fs-sefs 0.1.0", "sgx_trts 1.0.6", "sgx_tstd 1.0.6", "sgx_types 1.0.6", "xmas-elf 0.6.2", ] +[[package]] +name = "bitvec" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" version = "1.1.0" @@ -20,6 +32,30 @@ dependencies = [ "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "log" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rcore-fs" +version = "0.1.0" + +[[package]] +name = "rcore-fs-sefs" +version = "0.1.0" +dependencies = [ + "bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rcore-fs 0.1.0", + "sgx_tstd 1.0.6", + "spin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sgx_alloc" version = "1.0.6" @@ -83,6 +119,11 @@ name = "spin" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "static_assertions" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "version_check" version = "0.1.4" @@ -101,7 +142,11 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfadef5c4e2c2e64067b9ecc061179f12ac7ec65ba613b1f60f3972bbada1f5b" +"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum spin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "37b5646825922b96b5d7d676b5bb3458a54498e96ed7b0ce09dc43a07038fea4" +"checksum static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "389ce475f424f267dbed6479cbd8f126c5e1afb053b0acdaa019c74305fc65d1" "checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" "checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5" diff --git a/src/libos/Cargo.toml b/src/libos/Cargo.toml index 3861aef7..80551b82 100644 --- a/src/libos/Cargo.toml +++ b/src/libos/Cargo.toml @@ -8,6 +8,8 @@ crate-type = ["staticlib"] [dependencies] lazy_static = { version = "1.1.0", features = ["spin_no_std"] } # Implies nightly +rcore-fs = { path = "../../deps/sefs/rcore-fs" } +rcore-fs-sefs = { path = "../../deps/sefs/rcore-fs-sefs", features = ["sgx"] } [features] default = [] diff --git a/src/libos/src/errno.rs b/src/libos/src/errno.rs index 0c8292a4..9957fd1a 100644 --- a/src/libos/src/errno.rs +++ b/src/libos/src/errno.rs @@ -78,6 +78,8 @@ pub enum Errno { EDEADLK = 35, ENAMETOOLONG = 36, ENOLCK = 37, + ENOSYS = 38, + ENOTEMPTY = 39, } impl Errno { @@ -130,6 +132,8 @@ impl fmt::Display for Errno { Errno::EDEADLK => "Resource deadlock would occur", Errno::ENAMETOOLONG => "File name too long", Errno::ENOLCK => "No record locks available", + Errno::ENOSYS => "Function not implemented", + Errno::ENOTEMPTY => "Directory not empty", _ => "Unknown error", }, ) diff --git a/src/libos/src/fs/inode_file.rs b/src/libos/src/fs/inode_file.rs new file mode 100644 index 00000000..8715bd7c --- /dev/null +++ b/src/libos/src/fs/inode_file.rs @@ -0,0 +1,106 @@ +use super::*; + +use std::fmt; +use rcore_fs::vfs::{INode, FileSystem, FsError}; +use rcore_fs_sefs::{SEFS, dev::sgx_impl::{SgxStorage, SgxTimeProvider}}; + +lazy_static! { + /// The root of file system + pub static ref ROOT_INODE: Arc = { + let device = Box::new(SgxStorage::new("sefs")); + let sefs = SEFS::open(device, &SgxTimeProvider).expect("failed to open SEFS"); + sefs.root_inode() + }; +} + +pub struct INodeFile { + inode: Arc, + offset: SgxMutex, + is_readable: bool, + is_writable: bool, + is_append: bool, +} + +impl File for INodeFile { + fn read(&self, buf: &mut [u8]) -> Result { + if !self.is_readable { + return Err(Error::new(Errno::EBADF, "File not readable")); + } + let mut offset = self.offset.lock().unwrap(); + let len = self.inode.read_at(*offset, buf)?; + *offset += len; + Ok(len) + } + + fn write(&self, buf: &[u8]) -> Result { + if !self.is_writable { + return Err(Error::new(Errno::EBADF, "File not writable")); + } + let mut offset = self.offset.lock().unwrap(); + if self.is_append { + let info = self.inode.metadata()?; + *offset = info.size; + } + let len = self.inode.write_at(*offset, buf)?; + *offset += len; + Ok(len) + } + + fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { + Err(Error::new(Errno::ENOSYS, "Not implemented")) + } + + fn writev(&self, bufs: &[&[u8]]) -> Result { + Err(Error::new(Errno::ENOSYS, "Not implemented")) + } + + fn seek(&self, pos: SeekFrom) -> Result { + let mut offset = self.offset.lock().unwrap(); + *offset = match pos { + SeekFrom::Start(off) => off as usize, + SeekFrom::End(off) => (self.inode.metadata()?.size as i64 + off) as usize, + SeekFrom::Current(off) => (*offset as i64 + off) as usize, + }; + Ok(*offset as i64) + } +} + +impl INodeFile { + pub fn open(path: &str, is_readable: bool, is_writable: bool, is_append: bool) -> Result { + Ok(INodeFile { + inode: ROOT_INODE.lookup(path)?, + offset: SgxMutex::new(0), + is_readable, + is_writable, + is_append, + }) + } +} + +/// Convert VFS Error to libc error code +impl From for Error { + fn from(error: FsError) -> Self { + let errno = match error { + FsError::NotSupported => ENOSYS, + FsError::NotFile => EISDIR, + FsError::IsDir => EISDIR, + FsError::NotDir => ENOTDIR, + FsError::EntryNotFound => ENOENT, + FsError::EntryExist => EEXIST, + FsError::NotSameFs => EXDEV, + FsError::InvalidParam => EINVAL, + FsError::NoDeviceSpace => ENOMEM, + FsError::DirRemoved => ENOENT, + FsError::DirNotEmpty => ENOTEMPTY, + FsError::WrongFs => EINVAL, + FsError::DeviceError => EIO, + }; + Error::new(errno, "") + } +} + +impl Debug for INodeFile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "INodeFile {{ pos: {}, inode: ??? }}", *self.offset.lock().unwrap()) + } +} diff --git a/src/libos/src/fs/mod.rs b/src/libos/src/fs/mod.rs index 871acf8c..7757a107 100644 --- a/src/libos/src/fs/mod.rs +++ b/src/libos/src/fs/mod.rs @@ -6,6 +6,7 @@ use {process, std}; mod file; mod file_table; mod pipe; +mod inode_file; pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile}; pub use self::file_table::{FileDesc, FileTable}; diff --git a/src/libos/src/lib.rs b/src/libos/src/lib.rs index cfcc7770..98a793c4 100644 --- a/src/libos/src/lib.rs +++ b/src/libos/src/lib.rs @@ -17,6 +17,8 @@ extern crate sgx_trts; extern crate xmas_elf; #[macro_use] extern crate lazy_static; +extern crate rcore_fs; +extern crate rcore_fs_sefs; use sgx_trts::libc; use sgx_types::*;