vfs: move operations into trait StorageDevice, hold StorageDevices in KERNEL_STATE

This commit is contained in:
TheOddGarlic 2022-08-03 15:45:49 +03:00
parent 9462350de7
commit 31a3feb6a0
8 changed files with 350 additions and 250 deletions

View file

@ -6,4 +6,21 @@
pub enum FsError { pub enum FsError {
UnsupportedOperation, UnsupportedOperation,
InvalidDevice,
}
impl Into<FsError> for ext2::error::Error {
fn into(self) -> FsError {
match self {
ext2::error::Error::Other(_) => todo!(),
ext2::error::Error::BadMagic { magic: _ } => todo!(),
ext2::error::Error::OutOfBounds { index: _ } => todo!(),
ext2::error::Error::AddressOutOfBounds { sector: _, offset: _, size: _ } => todo!(),
ext2::error::Error::BadBlockGroupCount { by_blocks: _, by_inodes: _ } => todo!(),
ext2::error::Error::InodeNotFound { inode: _ } => todo!(),
ext2::error::Error::NotADirectory { inode: _, name: _ } => todo!(),
ext2::error::Error::NotAbsolute { name: _ } => todo!(),
ext2::error::Error::NotFound { name: _ } => todo!(),
}
}
} }

View file

@ -0,0 +1,85 @@
use ext2::fs::Ext2;
use ext2::sector::SectorSize;
use ext2::volume::Volume;
use super::{FsResult as Result, StorageDevice};
pub struct Ext2StorageDevice<S, V>
where
S: SectorSize,
V: Volume<u8, S>,
{
fs: Ext2<S, V>,
}
impl<S, V> Ext2StorageDevice<S, V>
where
S: SectorSize,
V: Volume<u8, S>,
{
pub fn new(volume: V) -> Result<Self> {
Ok(Self {
fs: Ext2::new(volume).map_err(|e| e.into())?,
})
}
}
impl<S, V> StorageDevice for Ext2StorageDevice<S, V>
where
S: SectorSize + Send,
V: Volume<u8, S> + Send,
{
fn open(&self, node: &super::FsNode /* TODO: flags */) -> Result<crate::handle::Handle> {
todo!()
}
fn close(&self, node: &super::FsNode) -> Result<()> {
todo!()
}
fn read(&self, node: &super::FsNode, offset: u32, size: u32) -> Result<Box<[u8]>> {
todo!()
}
fn write(&self, node: &super::FsNode, offset: u32, buffer: Box<[u8]>) -> Result<()> {
todo!()
}
fn read_dir(&self, node: &super::FsNode, index: u32) -> Result<super::DirectoryEntry> {
todo!()
}
fn find_dir(&self, node: &super::FsNode, name: &str) -> Result<super::FsNode> {
todo!()
}
}
// fn load_fs() -> Arc<Mutex<Ext2<Size1024, Vec<u8>>>> {
// let mut volume = Vec::new();
// volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img"));
// Arc::<Ext2<Size1024, _>>::new(volume).unwrap()
// }
// pub fn walk<S: SectorSize, V: Volume<u8, S>>(
// fs: &Synced<Ext2<S, V>>,
// inode: Inode<S, V>,
// name: String,
// ) {
// if let Some(dir) = inode.directory() {
// for entry in dir {
// assert!(entry.is_ok());
// let entry = entry.unwrap();
// let entry_name = String::from_utf8_lossy(&entry.name);
// println!("{}/{} => {}", name, entry_name, entry.inode,);
// if entry_name != "." && entry_name != ".." {
// walk(
// fs,
// fs.inode_nth(entry.inode).unwrap(),
// format!("{}/{}", name, entry_name),
// );
// }
// }
// }
// }

View file

@ -5,34 +5,29 @@
*/ */
pub mod errors; pub mod errors;
pub mod ext2;
use alloc::rc::Weak; use alloc::rc::Weak;
use bitflags::bitflags; use bitflags::bitflags;
use ext2::{
fs::{
sync::{Inode, Synced},
Ext2,
},
sector::{SectorSize, Size1024},
volume::Volume,
};
use spin::Lazy;
use crate::handle::Handle; use crate::{handle::Handle, KERNEL_STATE};
use self::errors::FsError; use self::errors::FsError;
use FsResult as Result; use FsResult as Result;
pub type FsResult<T> = core::result::Result<T, FsError>; pub type FsResult<T> = core::result::Result<T, FsError>;
pub type FsOpenOperation = fn(node: &FsNode /* TODO: flags */) -> Result<Handle>; pub trait StorageDevice
pub type FsCloseOperation = fn(node: &FsNode) -> Result<()>; where
pub type FsReadOperation = fn(node: &FsNode, offset: u32, size: u32) Self: Send,
-> Result<Box<[u8]>>; {
pub type FsWriteOperation = fn(node: &FsNode, offset: u32, buffer: Box<[u8]>) fn open(&self, node: &FsNode /* TODO: flags */) -> Result<Handle>;
-> Result<()>; fn close(&self, node: &FsNode) -> Result<()>;
pub type FsReaddirOperation = fn(node: &FsNode, index: u32) -> Result<DirectoryEntry>; fn read(&self, node: &FsNode, offset: u32, size: u32) -> Result<Box<[u8]>>;
pub type FsFinddirOperation = fn(node: &FsNode, name: &str) -> Result<FsNode>; fn write(&self, node: &FsNode, offset: u32, buffer: Box<[u8]>) -> Result<()>;
fn read_dir(&self, node: &FsNode, index: u32) -> Result<DirectoryEntry>;
fn find_dir(&self, node: &FsNode, name: &str) -> Result<FsNode>;
}
/// A VFS node, that can either be a file or a directory. /// A VFS node, that can either be a file or a directory.
pub struct FsNode { pub struct FsNode {
@ -44,12 +39,6 @@ pub struct FsNode {
inode: u32, // implementation specific identifier for the node inode: u32, // implementation specific identifier for the node
device_handle: Handle, // uniquely assigned device handle device_handle: Handle, // uniquely assigned device handle
ptr: Weak<FsNode>, // used by mountpoints and symlinks ptr: Weak<FsNode>, // used by mountpoints and symlinks
open: Option<FsOpenOperation>,
close: Option<FsCloseOperation>,
read: Option<FsReadOperation>,
write: Option<FsWriteOperation>,
readdir: Option<FsReaddirOperation>,
finddir: Option<FsFinddirOperation>,
// todo: permissions mask // todo: permissions mask
// todo: owning user/group // todo: owning user/group
} }
@ -57,51 +46,57 @@ pub struct FsNode {
impl FsNode { impl FsNode {
// TODO: make this take flags // TODO: make this take flags
fn open(&self) -> Result<Handle> { fn open(&self) -> Result<Handle> {
if let Some(open) = self.open { let state = KERNEL_STATE.lock();
open(self) let device = state
} else { .get_storage_device(self.device_handle)
Err(FsError::UnsupportedOperation) .ok_or_else(|| FsError::InvalidDevice)?;
}
device.open(self)
} }
fn close(&self) -> Result<()> { fn close(&self) -> Result<()> {
if let Some(close) = self.close { let state = KERNEL_STATE.lock();
close(self) let device = state
} else { .get_storage_device(self.device_handle)
Err(FsError::UnsupportedOperation) .ok_or_else(|| FsError::InvalidDevice)?;
}
device.close(self)
} }
fn read(&self, offset: u32, size: u32) -> Result<Box<[u8]>> { fn read(&self, offset: u32, size: u32) -> Result<Box<[u8]>> {
if let Some(read) = self.read { let state = KERNEL_STATE.lock();
read(self, offset, size) let device = state
} else { .get_storage_device(self.device_handle)
Err(FsError::UnsupportedOperation) .ok_or_else(|| FsError::InvalidDevice)?;
}
device.read(self, offset, size)
} }
fn write(&self, offset: u32, buffer: Box<[u8]>) -> Result<()> { fn write(&self, offset: u32, buffer: Box<[u8]>) -> Result<()> {
if let Some(write) = self.write { let state = KERNEL_STATE.lock();
write(self, offset, buffer) let device = state
} else { .get_storage_device(self.device_handle)
Err(FsError::UnsupportedOperation) .ok_or_else(|| FsError::InvalidDevice)?;
}
device.write(self, offset, buffer)
} }
fn readdir(&self, index: u32) -> Result<DirectoryEntry> { fn read_dir(&self, index: u32) -> Result<DirectoryEntry> {
if let Some(readdir) = self.readdir { let state = KERNEL_STATE.lock();
readdir(self, index) let device = state
} else { .get_storage_device(self.device_handle)
Err(FsError::UnsupportedOperation) .ok_or_else(|| FsError::InvalidDevice)?;
}
device.read_dir(self, index)
} }
fn finddir(&self, name: &str) -> Result<FsNode> { fn find_dir(&self, name: &str) -> Result<FsNode> {
if let Some(finddir) = self.finddir { let state = KERNEL_STATE.lock();
finddir(self, name) let device = state
} else { .get_storage_device(self.device_handle)
Err(FsError::UnsupportedOperation) .ok_or_else(|| FsError::InvalidDevice)?;
}
device.find_dir(self, name)
} }
} }
@ -124,36 +119,3 @@ pub struct DirectoryEntry {
name: String, name: String,
inode: u32, inode: u32,
} }
pub static FILE_SYSTEM: Lazy<spin::Mutex<Synced<Ext2<Size1024, Vec<u8>>>>> =
Lazy::new(|| spin::Mutex::new(load_fs()));
pub fn walk<S: SectorSize, V: Volume<u8, S>>(
fs: &Synced<Ext2<S, V>>,
inode: Inode<S, V>,
name: String,
) {
if let Some(dir) = inode.directory() {
for entry in dir {
assert!(entry.is_ok());
let entry = entry.unwrap();
let entry_name = String::from_utf8_lossy(&entry.name);
println!("{}/{} => {}", name, entry_name, entry.inode,);
if entry_name != "." && entry_name != ".." {
walk(
fs,
fs.inode_nth(entry.inode).unwrap(),
format!("{}/{}", name, entry_name),
);
}
}
}
}
fn load_fs() -> Synced<Ext2<Size1024, Vec<u8>>> {
let mut volume = Vec::new();
volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img"));
Synced::<Ext2<Size1024, _>>::new(volume).unwrap()
}

View file

@ -1,10 +1,14 @@
use hashbrown::HashMap;
use spin::Lazy; use spin::Lazy;
use crate::{handle::{Handle, HandleResource}, filesystem::StorageDevice};
pub static KERNEL_STATE: Lazy<spin::Mutex<KernelInternalState>> = pub static KERNEL_STATE: Lazy<spin::Mutex<KernelInternalState>> =
Lazy::new(|| spin::Mutex::new(KernelInternalState::new())); Lazy::new(|| spin::Mutex::new(KernelInternalState::new()));
pub struct KernelInternalState { pub struct KernelInternalState {
pub hostname: String, pub hostname: String,
storage_devices: HashMap<Handle, Box<dyn StorageDevice>>,
should_shutdown: bool, should_shutdown: bool,
} }
@ -12,6 +16,7 @@ impl KernelInternalState {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
should_shutdown: false, should_shutdown: false,
storage_devices: HashMap::new(),
hostname: "".to_string(), hostname: "".to_string(),
} }
} }
@ -19,9 +24,19 @@ impl KernelInternalState {
pub fn set_hostname(&mut self, hostname: String) { pub fn set_hostname(&mut self, hostname: String) {
self.hostname = hostname; self.hostname = hostname;
} }
pub fn add_storage_device(&mut self, device: impl StorageDevice + Send + 'static) {
self.storage_devices.insert(Handle::new(HandleResource::StorageDevice), Box::new(device));
}
pub fn get_storage_device(&self, handle: Handle) -> Option<&dyn StorageDevice> {
self.storage_devices.get(&handle).map(|d| &**d)
}
pub fn shutdown(&mut self) { pub fn shutdown(&mut self) {
self.should_shutdown = true; self.should_shutdown = true;
} }
pub fn update_state(&mut self) { pub fn update_state(&mut self) {
if self.should_shutdown { if self.should_shutdown {
crate::arch::shutdown(); crate::arch::shutdown();

View file

@ -1,7 +1,7 @@
use crate::arch::drivers::sysinfo::master; use crate::arch::drivers::sysinfo::master;
use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE}; use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
use crate::{filesystem::FILE_SYSTEM, time::fetch_time, KERNEL_STATE}; use crate::{time::fetch_time, KERNEL_STATE};
use genfs::{Fs, OpenOptions}; // use genfs::{Fs, OpenOptions};
use kernel::allocator::ALLOCATOR; use kernel::allocator::ALLOCATOR;
// use rhai::Engine; // use rhai::Engine;
use spin::Lazy; use spin::Lazy;
@ -103,23 +103,23 @@ pub fn poke_memory(ptr: i64, val: i64) {
} }
} }
pub fn ls() { // pub fn ls() {
let current_dir = CURRENT_DIR.lock(); // let current_dir = CURRENT_DIR.lock();
let fs = &*FILE_SYSTEM.lock(); // let fs = &*FILE_SYSTEM.lock();
let file = fs // let file = fs
.open(current_dir.as_bytes(), OpenOptions::new().read(true)) // .open(current_dir.as_bytes(), OpenOptions::new().read(true))
.unwrap(); // .unwrap();
let mut files = file.directory().unwrap(); // let mut files = file.directory().unwrap();
println!("current dir: {}", *current_dir); // println!("current dir: {}", *current_dir);
while let Some(Ok(entry)) = files.next() { // while let Some(Ok(entry)) = files.next() {
let inode_name = entry.name; // let inode_name = entry.name;
let s = String::from_utf8_lossy(&inode_name); // let s = String::from_utf8_lossy(&inode_name);
println!("{}", s); // println!("{}", s);
} // }
} // }
pub fn log_dump() { pub fn log_dump() {
use crate::network::socket::SimpleSock; use crate::network::socket::SimpleSock;
@ -144,55 +144,55 @@ pub fn log_dump() {
} }
} }
pub fn echo_file(path: String) { // pub fn echo_file(path: String) {
let mut current_dir = CURRENT_DIR.lock(); // let mut current_dir = CURRENT_DIR.lock();
let fs = &*FILE_SYSTEM.lock(); // let fs = &*FILE_SYSTEM.lock();
current_dir.push_str(&path); // current_dir.push_str(&path);
let file = fs // let file = fs
.open(current_dir.as_bytes(), OpenOptions::new().read(true)) // .open(current_dir.as_bytes(), OpenOptions::new().read(true))
.unwrap(); // .unwrap();
if file.is_dir() { // if file.is_dir() {
println!("{} is a directory", path); // println!("{} is a directory", path);
} else { // } else {
let mut file_contents = Vec::new(); // let mut file_contents = Vec::new();
let _ret = file.read_to_end(&mut file_contents).unwrap(); // let _ret = file.read_to_end(&mut file_contents).unwrap();
let file_contents_str = String::from_utf8_lossy(&file_contents); // let file_contents_str = String::from_utf8_lossy(&file_contents);
println!("{}", file_contents_str); // println!("{}", file_contents_str);
} // }
} // }
pub fn change_directory(path: String) { // pub fn change_directory(path: String) {
let mut current_dir = CURRENT_DIR.lock(); // let mut current_dir = CURRENT_DIR.lock();
let _fs = &*FILE_SYSTEM.lock(); // let _fs = &*FILE_SYSTEM.lock();
if path == "." || path == ".." { // if path == "." || path == ".." {
let mut split_dir = current_dir.split('/').collect::<Vec<&str>>(); // let mut split_dir = current_dir.split('/').collect::<Vec<&str>>();
let mut new_dir = String::new(); // let mut new_dir = String::new();
split_dir.remove(split_dir.len() - 1); // split_dir.remove(split_dir.len() - 1);
println!("{:?}", split_dir); // println!("{:?}", split_dir);
if split_dir.is_empty() { // if split_dir.is_empty() {
new_dir = "/".to_string(); // new_dir = "/".to_string();
} else { // } else {
for x in split_dir { // for x in split_dir {
new_dir.push_str(x); // new_dir.push_str(x);
new_dir.push('/'); // new_dir.push('/');
} // }
} // }
*current_dir = new_dir; // *current_dir = new_dir;
} else { // } else {
if !current_dir.ends_with('/') { // if !current_dir.ends_with('/') {
current_dir.push('/'); // current_dir.push('/');
} // }
current_dir.push_str(&path); // current_dir.push_str(&path);
} // }
} // }
// fn engine_construction() -> Engine { // fn engine_construction() -> Engine {
// let mut engine = rhai::Engine::new(); // let mut engine = rhai::Engine::new();

View file

@ -11,8 +11,8 @@ use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
use crate::time::fetch_time; use crate::time::fetch_time;
use crate::KERNEL_STATE; use crate::KERNEL_STATE;
use crate::{ use crate::{
arch::shutdown, filesystem::FILE_SYSTEM, rhai_shell::KEYBUFF, vterm::VTerm, arch::shutdown, rhai_shell::KEYBUFF, vterm::Term,
wasm_jumploader::run_program, // wasm_jumploader::run_program,
}; };
use acpi::{AcpiTables, PlatformInfo}; use acpi::{AcpiTables, PlatformInfo};
@ -193,7 +193,7 @@ pub fn real_shell() {
} }
pub fn command_parser(user: String, command: String) { pub fn command_parser(user: String, command: String) {
let fs = &*FILE_SYSTEM.lock(); // let fs = &*FILE_SYSTEM.lock();
let mut iter = command.split_whitespace(); let mut iter = command.split_whitespace();
// TODO: update the open() function to take either a ableOS path or a b"/" type path // TODO: update the open() function to take either a ableOS path or a b"/" type path
@ -225,41 +225,48 @@ pub fn command_parser(user: String, command: String) {
// drop(fs); // drop(fs);
// shell(); // shell();
// } // }
"list" | "ls" => { // "list" | "ls" => {
for dir_entry in list_files_in_dir(fs, current_path) { // for dir_entry in list_files_in_dir(fs, current_path) {
println!("{}", dir_entry.file_name_string()); // println!("{}", dir_entry.file_name_string());
} // }
} // }
<<<<<<< HEAD
"echo" => match conf_args.1.arguments.get("p") { "echo" => match conf_args.1.arguments.get("p") {
Some(path) => echo_file(path.to_string(), fs), Some(path) => echo_file(path.to_string(), fs),
None => println!("No path provided"), None => println!("No path provided"),
}, },
"test" => {} "test" => {}
=======
// "echo" => {
// echo_file(iter.next().unwrap().to_string(), fs);
// }
>>>>>>> 5149f26... vfs: move operations into trait StorageDevice, hold StorageDevices in KERNEL_STATE
"quit" => shutdown(), "quit" => shutdown(),
_ => { _ => {
let mut options = OpenOptions::new(); // let mut options = OpenOptions::new();
options.read(true); // options.read(true);
let file = { // let file = {
let path = format!("/home/{user}/bins/{bin_name}.wasm"); // let path = format!("/home/{user}/bins/{bin_name}.wasm");
if let Ok(file) = fs.open(&path.as_bytes(), &options) { // if let Ok(file) = fs.open(&path.as_bytes(), &options) {
file // file
} else { // } else {
let path = format!("/shared/bins/{bin_name}.wasm"); // let path = format!("/shared/bins/{bin_name}.wasm");
if let Ok(file) = fs.open(&path.as_bytes(), &options) { // if let Ok(file) = fs.open(&path.as_bytes(), &options) {
file // file
} else { // } else {
let path = format!("/system/bins/{bin_name}.wasm"); // let path = format!("/system/bins/{bin_name}.wasm");
match fs.open(&path.as_bytes(), &options) { // match fs.open(&path.as_bytes(), &options) {
Ok(file) => file, // Ok(file) => file,
Err(error) => { // Err(error) => {
trace!("{:?}", error); // trace!("{:?}", error);
println!("No such binary: {}", bin_name); println!("No such binary: {}", bin_name);
error!("No such binary: {}", bin_name); error!("No such binary: {}", bin_name);
return; return;
<<<<<<< HEAD
} }
} }
} }
@ -272,6 +279,20 @@ pub fn command_parser(user: String, command: String) {
// let args = iter.collect::<Vec<&str>>(); // let args = iter.collect::<Vec<&str>>();
// println!("{:?}", args); // println!("{:?}", args);
run_program(&binary); run_program(&binary);
=======
// }
// }
// }
// }
// };
// let mut binary = vec![];
// file.read_to_end(&mut binary).unwrap();
// let args = iter.collect::<Vec<&str>>();
// println!("{:?}", args);
// run_program(&binary);
>>>>>>> 5149f26... vfs: move operations into trait StorageDevice, hold StorageDevices in KERNEL_STATE
} }
} }
} }

View file

@ -1,101 +1,101 @@
pub mod host_functions; pub mod host_functions;
use crate::{filesystem::FILE_SYSTEM, wasm_jumploader::host_functions::HostExternals}; use crate::wasm_jumploader::host_functions::HostExternals;
use genfs::{Fs, OpenOptions}; // use genfs::{Fs, OpenOptions};
use wasmi::{ImportsBuilder, ModuleInstance}; use wasmi::{ImportsBuilder, ModuleInstance};
pub fn interp() { pub fn interp() {
trace!("Interpreting..."); trace!("Interpreting...");
let fs = &*FILE_SYSTEM.lock(); // let fs = &*FILE_SYSTEM.lock();
trace!("Got filesystem"); // trace!("Got filesystem");
let file = fs // let file = fs
.open( // .open(
b"/home/able/bins/aos_test.wasm", // b"/home/able/bins/aos_test.wasm",
OpenOptions::new().read(true), // OpenOptions::new().read(true),
) // )
.unwrap(); // .unwrap();
let mut wasm_binary = Vec::new(); // let mut wasm_binary = Vec::new();
let ret = file.read_to_end(&mut wasm_binary).unwrap(); // let ret = file.read_to_end(&mut wasm_binary).unwrap();
trace!("Binary size {}", ret); // trace!("Binary size {}", ret);
// Load wasm binary and prepare it for instantiation. // // Load wasm binary and prepare it for instantiation.
let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm"); // let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm");
trace!("Loaded wasm binary"); // trace!("Loaded wasm binary");
let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {}); // let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {});
trace!("Created imports"); // trace!("Created imports");
// Instantiate a module with empty imports and // // Instantiate a module with empty imports and
// assert that there is no `start` function. // // assert that there is no `start` function.
let instance = ModuleInstance::new(&module, &imports); // .expect("failed to instantiate wasm module") // let instance = ModuleInstance::new(&module, &imports); // .expect("failed to instantiate wasm module")
match instance { // match instance {
Ok(inst) => { // Ok(inst) => {
let instance = inst.assert_no_start(); // let instance = inst.assert_no_start();
let mut is_driver = false; // let mut is_driver = false;
let _is_program = false; // let _is_program = false;
let mut has_driver_entry = false; // let mut has_driver_entry = false;
let mut has_driver_exit = false; // let mut has_driver_exit = false;
let mut has_start = false; // let mut has_start = false;
if let Some(_val) = instance.export_by_name("driver_entry") { // if let Some(_val) = instance.export_by_name("driver_entry") {
has_driver_entry = true; // has_driver_entry = true;
} // }
if let Some(_val) = instance.export_by_name("driver_exit") { // if let Some(_val) = instance.export_by_name("driver_exit") {
has_driver_exit = true; // has_driver_exit = true;
} // }
match instance.export_by_name("start") { // match instance.export_by_name("start") {
Some(_val) => { // Some(_val) => {
trace!("Program start function found"); // trace!("Program start function found");
has_start = true; // has_start = true;
} // }
None => debug!("No start function found"), // None => debug!("No start function found"),
} // }
match instance.export_by_name("main") { // match instance.export_by_name("main") {
Some(_val) => { // Some(_val) => {
trace!("Program main function found"); // trace!("Program main function found");
has_start = true; // has_start = true;
} // }
None => debug!("No main function found"), // None => debug!("No main function found"),
} // }
match (has_driver_entry, has_driver_exit) { // match (has_driver_entry, has_driver_exit) {
(true, true) => { // (true, true) => {
trace!("Valid driver entry and exit functions found"); // trace!("Valid driver entry and exit functions found");
is_driver = true; // is_driver = true;
} // }
(true, false) => error!("Driver entry function found but no driver exit function"), // (true, false) => error!("Driver entry function found but no driver exit function"),
(false, true) => error!("Driver exit function found but no driver entry function"), // (false, true) => error!("Driver exit function found but no driver entry function"),
(false, false) => { // (false, false) => {
trace!("No driver entry or exit functions found"); // trace!("No driver entry or exit functions found");
} // }
} // }
if has_start && has_driver_entry { // if has_start && has_driver_entry {
error!( // error!(
"A program should not have both a start function and a driver entry function. It Will be treated as a program." // "A program should not have both a start function and a driver entry function. It Will be treated as a program."
); // );
} // }
if has_start { // if has_start {
let ret = instance // let ret = instance
.invoke_export("start", &[], &mut HostExternals {}) // .invoke_export("start", &[], &mut HostExternals {})
.expect("failed to execute export"); // .expect("failed to execute export");
println!("collected wasm return value: {:?}", ret); // println!("collected wasm return value: {:?}", ret);
} else if is_driver { // } else if is_driver {
let ret = instance // let ret = instance
.invoke_export("driver_entry", &[], &mut HostExternals {}) // .invoke_export("driver_entry", &[], &mut HostExternals {})
.expect("failed to execute export"); // .expect("failed to execute export");
println!("collected wasm return value: {:?}", ret); // println!("collected wasm return value: {:?}", ret);
} // }
} // }
Err(err) => error!("{}", err), // Err(err) => error!("{}", err),
} // }
} }
pub fn run_program(program: &[u8]) { pub fn run_program(program: &[u8]) {

View file

@ -62,8 +62,8 @@ pub enum Error {
/// inode name /// inode name
name: String, name: String,
}, },
#[cfg(any(test, not(feature = "no_std")))] // #[cfg(any(test, not(feature = "no_std")))]
Io { inner: io::Error }, // Io { inner: io::Error },
} }
impl Display for Error { impl Display for Error {