Add DevFS for device files
This commit is contained in:
parent
1514be14fd
commit
d6cd89f03b
@ -162,6 +162,10 @@ Occlum can be configured easily via a configuration file named `Occlum.json`, wh
|
|||||||
"options": {
|
"options": {
|
||||||
"temporary": true
|
"temporary": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/dev",
|
||||||
|
"type": "devfs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,10 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"temporary": true
|
"temporary": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/dev",
|
||||||
|
"type": "devfs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
10
src/libos/Cargo.lock
generated
10
src/libos/Cargo.lock
generated
@ -13,6 +13,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"rcore-fs",
|
"rcore-fs",
|
||||||
|
"rcore-fs-devfs",
|
||||||
"rcore-fs-mountfs",
|
"rcore-fs-mountfs",
|
||||||
"rcore-fs-ramfs",
|
"rcore-fs-ramfs",
|
||||||
"rcore-fs-sefs",
|
"rcore-fs-sefs",
|
||||||
@ -395,6 +396,15 @@ dependencies = [
|
|||||||
"spin",
|
"spin",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rcore-fs-devfs"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"rcore-fs",
|
||||||
|
"spin",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rcore-fs-mountfs"
|
name = "rcore-fs-mountfs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -21,6 +21,7 @@ rcore-fs-sefs = { path = "../../deps/sefs/rcore-fs-sefs" }
|
|||||||
rcore-fs-ramfs = { path = "../../deps/sefs/rcore-fs-ramfs" }
|
rcore-fs-ramfs = { path = "../../deps/sefs/rcore-fs-ramfs" }
|
||||||
rcore-fs-mountfs = { path = "../../deps/sefs/rcore-fs-mountfs" }
|
rcore-fs-mountfs = { path = "../../deps/sefs/rcore-fs-mountfs" }
|
||||||
rcore-fs-unionfs = { path = "../../deps/sefs/rcore-fs-unionfs" }
|
rcore-fs-unionfs = { path = "../../deps/sefs/rcore-fs-unionfs" }
|
||||||
|
rcore-fs-devfs = { path = "../../deps/sefs/rcore-fs-devfs" }
|
||||||
serde = { path = "../../deps/serde-sgx/serde", features = ["derive"] }
|
serde = { path = "../../deps/serde-sgx/serde", features = ["derive"] }
|
||||||
serde_json = { path = "../../deps/serde-json-sgx" }
|
serde_json = { path = "../../deps/serde-json-sgx" }
|
||||||
memoffset = "0.6.1"
|
memoffset = "0.6.1"
|
||||||
|
@ -125,6 +125,7 @@ pub enum ConfigMountFsType {
|
|||||||
TYPE_HOSTFS,
|
TYPE_HOSTFS,
|
||||||
TYPE_RAMFS,
|
TYPE_RAMFS,
|
||||||
TYPE_UNIONFS,
|
TYPE_UNIONFS,
|
||||||
|
TYPE_DEVFS,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -199,13 +200,14 @@ impl ConfigEnv {
|
|||||||
|
|
||||||
impl ConfigMount {
|
impl ConfigMount {
|
||||||
fn from_input(input: &InputConfigMount) -> Result<ConfigMount> {
|
fn from_input(input: &InputConfigMount) -> Result<ConfigMount> {
|
||||||
const ALL_FS_TYPES: [&str; 4] = ["sefs", "hostfs", "ramfs", "unionfs"];
|
const ALL_FS_TYPES: [&str; 5] = ["sefs", "hostfs", "ramfs", "unionfs", "devfs"];
|
||||||
|
|
||||||
let type_ = match input.type_.as_str() {
|
let type_ = match input.type_.as_str() {
|
||||||
"sefs" => ConfigMountFsType::TYPE_SEFS,
|
"sefs" => ConfigMountFsType::TYPE_SEFS,
|
||||||
"hostfs" => ConfigMountFsType::TYPE_HOSTFS,
|
"hostfs" => ConfigMountFsType::TYPE_HOSTFS,
|
||||||
"ramfs" => ConfigMountFsType::TYPE_RAMFS,
|
"ramfs" => ConfigMountFsType::TYPE_RAMFS,
|
||||||
"unionfs" => ConfigMountFsType::TYPE_UNIONFS,
|
"unionfs" => ConfigMountFsType::TYPE_UNIONFS,
|
||||||
|
"devfs" => ConfigMountFsType::TYPE_DEVFS,
|
||||||
_ => {
|
_ => {
|
||||||
return_errno!(EINVAL, "Unsupported file system type");
|
return_errno!(EINVAL, "Unsupported file system type");
|
||||||
}
|
}
|
||||||
|
@ -3,24 +3,43 @@ use super::*;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DevNull;
|
pub struct DevNull;
|
||||||
|
|
||||||
impl File for DevNull {
|
impl INode for DevNull {
|
||||||
fn write(&self, _buf: &[u8]) -> Result<usize> {
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> vfs::Result<usize> {
|
||||||
Ok(_buf.len())
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> {
|
fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result<usize> {
|
||||||
Ok(_buf.len())
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn writev(&self, bufs: &[&[u8]]) -> Result<usize> {
|
fn poll(&self) -> vfs::Result<vfs::PollStatus> {
|
||||||
Ok(bufs.iter().map(|buf| buf.len()).sum())
|
Ok(vfs::PollStatus {
|
||||||
|
read: true,
|
||||||
|
write: true,
|
||||||
|
error: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_new(&self) -> IoEvents {
|
fn metadata(&self) -> vfs::Result<Metadata> {
|
||||||
IoEvents::IN
|
Ok(Metadata {
|
||||||
|
dev: 1,
|
||||||
|
inode: 0,
|
||||||
|
size: 0,
|
||||||
|
blk_size: 0,
|
||||||
|
blocks: 0,
|
||||||
|
atime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
mtime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
ctime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
type_: vfs::FileType::CharDevice,
|
||||||
|
mode: 0o666,
|
||||||
|
nlinks: 1,
|
||||||
|
uid: 0,
|
||||||
|
gid: 0,
|
||||||
|
rdev: 0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,30 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::net::PollEventFlags;
|
|
||||||
use crate::util::random;
|
use crate::util::random;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DevRandom;
|
pub struct DevRandom;
|
||||||
|
|
||||||
impl File for DevRandom {
|
impl INode for DevRandom {
|
||||||
fn read(&self, _buf: &mut [u8]) -> Result<usize> {
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> vfs::Result<usize> {
|
||||||
random::get_random(_buf)?;
|
random::get_random(buf).map_err(|_| FsError::Again)?;
|
||||||
Ok(_buf.len())
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result<usize> {
|
fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result<usize> {
|
||||||
self.read(_buf)
|
Err(FsError::PermError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize> {
|
fn poll(&self) -> vfs::Result<vfs::PollStatus> {
|
||||||
let mut total_nbytes = 0;
|
Ok(vfs::PollStatus {
|
||||||
for buf in bufs {
|
read: true,
|
||||||
match self.read(buf) {
|
write: false,
|
||||||
Ok(this_nbytes) => {
|
error: false,
|
||||||
total_nbytes += this_nbytes;
|
})
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
if total_nbytes > 0 {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(total_nbytes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Result<Metadata> {
|
fn metadata(&self) -> vfs::Result<Metadata> {
|
||||||
Ok(Metadata {
|
Ok(Metadata {
|
||||||
dev: 0,
|
dev: 1,
|
||||||
inode: 0,
|
inode: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
blk_size: 0,
|
blk_size: 0,
|
||||||
@ -44,36 +32,16 @@ impl File for DevRandom {
|
|||||||
atime: Timespec { sec: 0, nsec: 0 },
|
atime: Timespec { sec: 0, nsec: 0 },
|
||||||
mtime: Timespec { sec: 0, nsec: 0 },
|
mtime: Timespec { sec: 0, nsec: 0 },
|
||||||
ctime: Timespec { sec: 0, nsec: 0 },
|
ctime: Timespec { sec: 0, nsec: 0 },
|
||||||
type_: FileType::CharDevice,
|
type_: vfs::FileType::CharDevice,
|
||||||
mode: (FileMode::S_IRUSR | FileMode::S_IRGRP | FileMode::S_IROTH).bits(),
|
mode: 0o444,
|
||||||
nlinks: 0,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
rdev: 0,
|
rdev: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self) -> Result<(PollEventFlags)> {
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
Ok(PollEventFlags::POLLIN)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_new(&self) -> IoEvents {
|
|
||||||
IoEvents::IN
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AsDevRandom {
|
|
||||||
fn as_dev_random(&self) -> Result<&DevRandom>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsDevRandom for FileRef {
|
|
||||||
fn as_dev_random(&self) -> Result<&DevRandom> {
|
|
||||||
self.as_any()
|
|
||||||
.downcast_ref::<DevRandom>()
|
|
||||||
.ok_or_else(|| errno!(EBADF, "not random device"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -15,7 +15,54 @@ extern "C" {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DevSgx;
|
pub struct DevSgx;
|
||||||
|
|
||||||
impl File for DevSgx {
|
impl INode for DevSgx {
|
||||||
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> vfs::Result<usize> {
|
||||||
|
Err(FsError::PermError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result<usize> {
|
||||||
|
Err(FsError::PermError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll(&self) -> vfs::Result<vfs::PollStatus> {
|
||||||
|
Err(FsError::PermError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> vfs::Result<Metadata> {
|
||||||
|
Ok(Metadata {
|
||||||
|
dev: 1,
|
||||||
|
inode: 0,
|
||||||
|
size: 0,
|
||||||
|
blk_size: 0,
|
||||||
|
blocks: 0,
|
||||||
|
atime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
mtime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
ctime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
type_: vfs::FileType::CharDevice,
|
||||||
|
mode: 0o666,
|
||||||
|
nlinks: 1,
|
||||||
|
uid: 0,
|
||||||
|
gid: 0,
|
||||||
|
rdev: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn io_control(&self, _cmd: u32, _data: usize) -> vfs::Result<()> {
|
||||||
|
let mut ioctl_cmd =
|
||||||
|
unsafe { IoctlCmd::new(_cmd, _data as *mut u8).map_err(|_| FsError::InvalidParam)? };
|
||||||
|
self.ioctl(&mut ioctl_cmd).map_err(|e| {
|
||||||
|
error!("{}", e.backtrace());
|
||||||
|
FsError::IOCTLError
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DevSgx {
|
||||||
fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> {
|
fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> {
|
||||||
let nonbuiltin_cmd = match cmd {
|
let nonbuiltin_cmd = match cmd {
|
||||||
IoctlCmd::NonBuiltin(nonbuiltin_cmd) => nonbuiltin_cmd,
|
IoctlCmd::NonBuiltin(nonbuiltin_cmd) => nonbuiltin_cmd,
|
||||||
@ -180,14 +227,6 @@ impl File for DevSgx {
|
|||||||
}
|
}
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_new(&self) -> IoEvents {
|
|
||||||
IoEvents::IN
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -3,31 +3,46 @@ use super::*;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DevZero;
|
pub struct DevZero;
|
||||||
|
|
||||||
impl File for DevZero {
|
impl INode for DevZero {
|
||||||
fn read(&self, _buf: &mut [u8]) -> Result<usize> {
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> vfs::Result<usize> {
|
||||||
for b in _buf.iter_mut() {
|
for b in buf.iter_mut() {
|
||||||
*b = 0;
|
*b = 0;
|
||||||
}
|
}
|
||||||
Ok(_buf.len())
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result<usize> {
|
fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result<usize> {
|
||||||
self.read(_buf)
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize> {
|
fn poll(&self) -> vfs::Result<vfs::PollStatus> {
|
||||||
let mut total_nbytes = 0;
|
Ok(vfs::PollStatus {
|
||||||
for buf in bufs {
|
read: true,
|
||||||
total_nbytes += self.read(buf)?;
|
write: true,
|
||||||
}
|
error: false,
|
||||||
Ok(total_nbytes)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_new(&self) -> IoEvents {
|
fn metadata(&self) -> vfs::Result<Metadata> {
|
||||||
IoEvents::IN
|
Ok(Metadata {
|
||||||
|
dev: 1,
|
||||||
|
inode: 0,
|
||||||
|
size: 0,
|
||||||
|
blk_size: 0,
|
||||||
|
blocks: 0,
|
||||||
|
atime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
mtime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
ctime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
type_: vfs::FileType::CharDevice,
|
||||||
|
mode: 0o666,
|
||||||
|
nlinks: 1,
|
||||||
|
uid: 0,
|
||||||
|
gid: 0,
|
||||||
|
rdev: 0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,30 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use rcore_fs::vfs;
|
||||||
|
use rcore_fs_devfs::DevFS;
|
||||||
|
|
||||||
pub use self::dev_null::DevNull;
|
use self::dev_null::DevNull;
|
||||||
pub use self::dev_random::{AsDevRandom, DevRandom};
|
use self::dev_random::DevRandom;
|
||||||
pub use self::dev_sgx::DevSgx;
|
use self::dev_sgx::DevSgx;
|
||||||
pub use self::dev_zero::DevZero;
|
use self::dev_zero::DevZero;
|
||||||
|
|
||||||
mod dev_null;
|
mod dev_null;
|
||||||
mod dev_random;
|
mod dev_random;
|
||||||
mod dev_sgx;
|
mod dev_sgx;
|
||||||
mod dev_zero;
|
mod dev_zero;
|
||||||
|
|
||||||
|
/// API to initialize the DevFS
|
||||||
|
pub fn init_devfs() -> Result<Arc<DevFS>> {
|
||||||
|
let devfs = DevFS::new();
|
||||||
|
let dev_null = Arc::new(DevNull) as _;
|
||||||
|
devfs.add("null", dev_null)?;
|
||||||
|
let dev_zero = Arc::new(DevZero) as _;
|
||||||
|
devfs.add("zero", dev_zero)?;
|
||||||
|
let dev_random = Arc::new(DevRandom) as _;
|
||||||
|
devfs.add("random", Arc::clone(&dev_random))?;
|
||||||
|
devfs.add("urandom", Arc::clone(&dev_random))?;
|
||||||
|
devfs.add("arandom", Arc::clone(&dev_random))?;
|
||||||
|
let dev_sgx = Arc::new(DevSgx) as _;
|
||||||
|
devfs.add("sgx", dev_sgx)?;
|
||||||
|
// TODO: Add stdio(stdin, stdout, stderr) into DevFS
|
||||||
|
Ok(devfs)
|
||||||
|
}
|
||||||
|
@ -25,6 +25,20 @@ impl IoEvents {
|
|||||||
Self::from_bits_truncate(raw)
|
Self::from_bits_truncate(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_poll_status(poll_status: &crate::rcore_fs::vfs::PollStatus) -> Self {
|
||||||
|
if poll_status.error {
|
||||||
|
return Self::ERR;
|
||||||
|
}
|
||||||
|
let mut events = Self::empty();
|
||||||
|
if poll_status.read {
|
||||||
|
events |= Self::IN
|
||||||
|
}
|
||||||
|
if poll_status.write {
|
||||||
|
events |= Self::OUT
|
||||||
|
}
|
||||||
|
events
|
||||||
|
}
|
||||||
|
|
||||||
fn contains_unrecognizable_bits(raw: u32) -> bool {
|
fn contains_unrecognizable_bits(raw: u32) -> bool {
|
||||||
// Help to detect four valid but mostly useless flags that we do not
|
// Help to detect four valid but mostly useless flags that we do not
|
||||||
// handle, yet: POLLRDNORM, POLLRDBAND, POLLWRNORM, annd POLLWRBAND.
|
// handle, yet: POLLRDNORM, POLLRDBAND, POLLWRNORM, annd POLLWRBAND.
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use super::dev_fs::{DevNull, DevRandom, DevSgx, DevZero};
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use process::Process;
|
use process::Process;
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use super::dev_fs::{DevNull, DevRandom, DevSgx, DevZero};
|
|
||||||
/// Present a per-process view of FS.
|
/// Present a per-process view of FS.
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -40,18 +39,6 @@ impl FsView {
|
|||||||
|
|
||||||
/// Open a file on the process. But DO NOT add it to file table.
|
/// Open a file on the process. But DO NOT add it to file table.
|
||||||
pub fn open_file(&self, path: &str, flags: u32, mode: u32) -> Result<Arc<dyn File>> {
|
pub fn open_file(&self, path: &str, flags: u32, mode: u32) -> Result<Arc<dyn File>> {
|
||||||
if path == "/dev/null" {
|
|
||||||
return Ok(Arc::new(DevNull));
|
|
||||||
}
|
|
||||||
if path == "/dev/zero" {
|
|
||||||
return Ok(Arc::new(DevZero));
|
|
||||||
}
|
|
||||||
if path == "/dev/random" || path == "/dev/urandom" || path == "/dev/arandom" {
|
|
||||||
return Ok(Arc::new(DevRandom));
|
|
||||||
}
|
|
||||||
if path == "/dev/sgx" {
|
|
||||||
return Ok(Arc::new(DevSgx));
|
|
||||||
}
|
|
||||||
let creation_flags = CreationFlags::from_bits_truncate(flags);
|
let creation_flags = CreationFlags::from_bits_truncate(flags);
|
||||||
let inode = if creation_flags.no_follow_symlink() {
|
let inode = if creation_flags.no_follow_symlink() {
|
||||||
match self.lookup_inode_no_follow(path) {
|
match self.lookup_inode_no_follow(path) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::net::PollEventFlags;
|
||||||
use rcore_fs_sefs::dev::SefsMac;
|
use rcore_fs_sefs::dev::SefsMac;
|
||||||
|
|
||||||
pub struct INodeFile {
|
pub struct INodeFile {
|
||||||
@ -196,6 +197,20 @@ impl File for INodeFile {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> {
|
||||||
|
let cmd_num = cmd.cmd_num();
|
||||||
|
let cmd_argp = cmd.arg_ptr() as usize;
|
||||||
|
self.inode.io_control(cmd_num, cmd_argp)?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_new(&self) -> IoEvents {
|
||||||
|
match self.inode.poll() {
|
||||||
|
Ok(poll_status) => IoEvents::from_poll_status(&poll_status),
|
||||||
|
Err(_) => IoEvents::empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ use std::mem::MaybeUninit;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use untrusted::{SliceAsMutPtrAndLen, SliceAsPtrAndLen};
|
use untrusted::{SliceAsMutPtrAndLen, SliceAsPtrAndLen};
|
||||||
|
|
||||||
pub use self::dev_fs::AsDevRandom;
|
|
||||||
pub use self::event_file::{AsEvent, EventCreationFlags, EventFile};
|
pub use self::event_file::{AsEvent, EventCreationFlags, EventFile};
|
||||||
pub use self::events::{AtomicIoEvents, IoEvents, IoNotifier};
|
pub use self::events::{AtomicIoEvents, IoEvents, IoNotifier};
|
||||||
pub use self::file::{File, FileRef};
|
pub use self::file::{File, FileRef};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::dev_fs;
|
||||||
use super::hostfs::HostFS;
|
use super::hostfs::HostFS;
|
||||||
use super::sefs::{SgxStorage, SgxUuidProvider};
|
use super::sefs::{SgxStorage, SgxUuidProvider};
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -144,6 +145,10 @@ fn mount_nonroot_fs_according_to(mount_config: &Vec<ConfigMount>, root: &MNode)
|
|||||||
let ramfs = RamFS::new();
|
let ramfs = RamFS::new();
|
||||||
mount_fs_at(ramfs, root, &mc.target)?;
|
mount_fs_at(ramfs, root, &mc.target)?;
|
||||||
}
|
}
|
||||||
|
TYPE_DEVFS => {
|
||||||
|
let devfs = dev_fs::init_devfs()?;
|
||||||
|
mount_fs_at(devfs, root, &mc.target)?;
|
||||||
|
}
|
||||||
TYPE_UNIONFS => {
|
TYPE_UNIONFS => {
|
||||||
return_errno!(EINVAL, "Cannot mount UnionFS at non-root path");
|
return_errno!(EINVAL, "Cannot mount UnionFS at non-root path");
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ extern crate lazy_static;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate rcore_fs;
|
extern crate rcore_fs;
|
||||||
|
extern crate rcore_fs_devfs;
|
||||||
extern crate rcore_fs_mountfs;
|
extern crate rcore_fs_mountfs;
|
||||||
extern crate rcore_fs_ramfs;
|
extern crate rcore_fs_ramfs;
|
||||||
extern crate rcore_fs_sefs;
|
extern crate rcore_fs_sefs;
|
||||||
|
@ -15,7 +15,7 @@ pub use self::poll::{do_poll, PollEvent, PollEventFlags};
|
|||||||
pub use self::poll_new::{do_poll_new, PollFd};
|
pub use self::poll_new::{do_poll_new, PollFd};
|
||||||
pub use self::select::{do_select, FdSetExt};
|
pub use self::select::{do_select, FdSetExt};
|
||||||
|
|
||||||
use fs::{AsDevRandom, AsEvent, CreationFlags, File, FileDesc, FileRef, HostFd, PipeType};
|
use fs::{AsEvent, AsINodeFile, CreationFlags, File, FileDesc, FileRef, HostFd, PipeType};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -93,7 +93,6 @@ pub fn do_poll(pollfds: &mut [PollEvent], timeout: *mut timeval_t) -> Result<usi
|
|||||||
if file_ref.as_unix_socket().is_ok()
|
if file_ref.as_unix_socket().is_ok()
|
||||||
|| file_ref.as_pipe_reader().is_ok()
|
|| file_ref.as_pipe_reader().is_ok()
|
||||||
|| file_ref.as_pipe_writer().is_ok()
|
|| file_ref.as_pipe_writer().is_ok()
|
||||||
|| file_ref.as_dev_random().is_ok()
|
|
||||||
{
|
{
|
||||||
let events = file_ref.poll()?;
|
let events = file_ref.poll()?;
|
||||||
debug!("polled events are {:?}", events);
|
debug!("polled events are {:?}", events);
|
||||||
|
@ -61,6 +61,10 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"temporary": true
|
"temporary": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/dev",
|
||||||
|
"type": "devfs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,10 @@ fn gen_mount_config(occlum_conf_root_fs_mac: String) -> serde_json::Value {
|
|||||||
"options": {
|
"options": {
|
||||||
"temporary": true
|
"temporary": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/dev",
|
||||||
|
"type": "devfs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -148,6 +148,7 @@ cmd_init() {
|
|||||||
mkdir -p image/root
|
mkdir -p image/root
|
||||||
mkdir -p image/host
|
mkdir -p image/host
|
||||||
mkdir -p image/tmp
|
mkdir -p image/tmp
|
||||||
|
mkdir -p image/dev
|
||||||
local occlum_glibc_lib=/opt/occlum/glibc/lib
|
local occlum_glibc_lib=/opt/occlum/glibc/lib
|
||||||
local cpu_lib=/sys/devices/system/cpu
|
local cpu_lib=/sys/devices/system/cpu
|
||||||
if [ -d "$occlum_glibc_lib" ]; then
|
if [ -d "$occlum_glibc_lib" ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user