mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
Replace the Isle variant with a proper Trait.
The proxy library was moved into an own directory. Then the IsleKind enum was replaced with an Isle trait which is implemented by qemu/multi/uhyve.
This commit is contained in:
parent
66332a1337
commit
abbcee0b46
18 changed files with 247 additions and 184 deletions
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "hermitcore_proxy"
|
||||
name = "hermit_proxy"
|
||||
version = "0.0.1"
|
||||
authors = ["bytesnake <bytesnake@mailbox.org>"]
|
||||
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::io::{Write, Read, BufReader, BufRead};
|
||||
use inotify::{Inotify, watch_mask};
|
||||
|
||||
use hermit_env;
|
||||
use qemu::QEmu;
|
||||
use multi::Multi;
|
||||
use uhyve::Uhyve;
|
||||
use uhyve::vm::VirtualMachine;
|
||||
use error::*;
|
||||
|
||||
pub enum IsleKind {
|
||||
QEMU(QEmu),
|
||||
UHYVE((Uhyve, VirtualMachine)),
|
||||
MULTI(Multi)
|
||||
}
|
||||
|
||||
impl IsleKind {
|
||||
pub fn new(path: &str) -> Result<IsleKind> {
|
||||
let isle = hermit_env::isle_kind();
|
||||
|
||||
debug!("Create a new {} isle", isle);
|
||||
|
||||
let isle = match isle.as_str() {
|
||||
"qemu"=>IsleKind::QEMU(QEmu::new(path)?),
|
||||
"uhyve" => {
|
||||
let uhyve = Uhyve::new();
|
||||
let mut vm = uhyve.create_vm(0x20000000)?;
|
||||
vm.load_kernel(path)?;
|
||||
vm.init()?;
|
||||
|
||||
IsleKind::UHYVE((uhyve, vm))
|
||||
},
|
||||
s => IsleKind::MULTI(Multi::new(s.parse::<u8>().unwrap_or(0), path)?)
|
||||
};
|
||||
|
||||
Ok(isle)
|
||||
}
|
||||
|
||||
fn get_num(&self) -> u8 {
|
||||
match *self {
|
||||
IsleKind::QEMU(_) => 0,
|
||||
IsleKind::UHYVE(_) => 0,
|
||||
IsleKind::MULTI(ref s) => s.get_num()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_available(&self) -> Result<bool> {
|
||||
let mut file = match *self {
|
||||
IsleKind::QEMU(ref q) => File::open(q.tmp_path()),
|
||||
_ => File::open(format!("/sys/hermit/isle{}/log", self.get_num()))
|
||||
};
|
||||
|
||||
let mut file = file.map_err(|x| Error::InvalidFile(format!("{:?}",x)))?;
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
//let mut result = String::new();
|
||||
//file.read_to_string(&mut result).map_err(|_| Error::InvalidFile)?;
|
||||
|
||||
for line in reader.lines() {
|
||||
if line.unwrap().contains("TCP server is listening.") {
|
||||
debug!("Found key token, continue");
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub fn wait_available(&mut self) -> Result<()> {
|
||||
debug!("HERMIT - wait to be available");
|
||||
|
||||
let mut ino = Inotify::init().unwrap();
|
||||
|
||||
match *self {
|
||||
IsleKind::QEMU(_) => ino.add_watch(Path::new("/tmp"), watch_mask::MODIFY | watch_mask::CREATE).unwrap(),
|
||||
IsleKind::MULTI(_) => ino.add_watch(Path::new("/sys/hermit"), watch_mask::MODIFY | watch_mask::CREATE).unwrap(),
|
||||
IsleKind::UHYVE(_) => return Ok(())
|
||||
};
|
||||
|
||||
let mut buffer = [0; 1024];
|
||||
loop {
|
||||
//debug!("Wait ... ");
|
||||
if let Some(_) = ino.read_events(&mut buffer).unwrap().next() {
|
||||
if self.is_available()? {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
if let IsleKind::QEMU(ref mut obj) = *self {
|
||||
let (stdout,stderr) = obj.output();
|
||||
|
||||
if stderr != "" {
|
||||
return Err(Error::QEmu((stdout, stderr)));
|
||||
}
|
||||
|
||||
if stdout != "" {
|
||||
debug!("stdout: {}", stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop(&self) -> Result<()> {
|
||||
let cpu_path = format!("/sys/hermit/isle{}/cpus", self.get_num());
|
||||
|
||||
let mut cpus_file = File::create(&cpu_path)
|
||||
.map_err(|_| Error::InvalidFile(cpu_path.clone()))?;
|
||||
|
||||
cpus_file.write("-1".as_bytes())
|
||||
.map_err(|_| Error::InvalidFile(cpu_path));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run(mut self) -> Result<()> {
|
||||
match self {
|
||||
IsleKind::UHYVE((_, mut vm)) => vm.run()?,
|
||||
IsleKind::QEMU(qemu) => qemu.run(),
|
||||
IsleKind::MULTI(multi) => multi.run()
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
105
tools/hermit_proxy/src/hermit/mod.rs
Normal file
105
tools/hermit_proxy/src/hermit/mod.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
pub mod error;
|
||||
mod utils;
|
||||
mod hermit_env;
|
||||
mod qemu;
|
||||
mod multi;
|
||||
mod proto;
|
||||
mod socket;
|
||||
mod uhyve;
|
||||
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::io::{Write, Read, BufReader, BufRead};
|
||||
use inotify::{Inotify, watch_mask};
|
||||
|
||||
use hermit::qemu::QEmu;
|
||||
use hermit::multi::Multi;
|
||||
use hermit::uhyve::uhyve::Uhyve;
|
||||
|
||||
use hermit::error::*;
|
||||
|
||||
pub fn new_isle(path: &str) -> Result<Box<Isle>> {
|
||||
let isle = hermit_env::isle_kind();
|
||||
|
||||
debug!("Create a new {} isle", isle);
|
||||
|
||||
match isle.as_str() {
|
||||
"qemu"=> Ok(Box::new(QEmu::new(path)?)),
|
||||
"uhyve" => Ok(Box::new(Uhyve::new(path)?)),
|
||||
s => Ok(Box::new(Multi::new(s.parse::<u8>().unwrap_or(0), path)?))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Isle {
|
||||
fn num(&self) -> u8;
|
||||
fn log_file(&self) -> Result<String>;
|
||||
fn log_path(&self) -> Result<String>;
|
||||
fn cpu_path(&self) -> Result<String>;
|
||||
|
||||
fn run(&mut self) -> Result<()>;
|
||||
|
||||
fn is_available(&self) -> Result<bool> {
|
||||
let log = self.log_file()?;
|
||||
|
||||
// open the log file
|
||||
let mut file = File::open(log)
|
||||
.map_err(|x| Error::InvalidFile(format!("{:?}",x)))?;
|
||||
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
for line in reader.lines() {
|
||||
if line.unwrap().contains("TCP server is listening.") {
|
||||
debug!("Found key token, continue");
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn wait_until_available(&self) -> Result<()> {
|
||||
debug!("Wait for the HermitIsle to be available");
|
||||
|
||||
let mut ino = Inotify::init().unwrap();
|
||||
|
||||
// watch on the log path
|
||||
let log_path = self.log_path()?;
|
||||
ino.add_watch(Path::new(&log_path), watch_mask::MODIFY | watch_mask::CREATE).unwrap();
|
||||
|
||||
let mut buffer = [0; 1024];
|
||||
loop {
|
||||
if let Some(_) = ino.read_events(&mut buffer).unwrap().next() {
|
||||
if self.is_available()? {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if let IsleKind::QEMU(ref mut obj) = *self {
|
||||
let (stdout,stderr) = obj.output();
|
||||
|
||||
if stderr != "" {
|
||||
return Err(Error::QEmu((stdout, stderr)));
|
||||
}
|
||||
|
||||
if stdout != "" {
|
||||
debug!("stdout: {}", stdout);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
fn stop(&self) -> Result<()> {
|
||||
debug!("Stop the HermitIsle");
|
||||
|
||||
let cpu_path = self.cpu_path()?;
|
||||
|
||||
let mut cpus_file = File::create(&cpu_path)
|
||||
.map_err(|_| Error::InvalidFile(cpu_path.clone()))?;
|
||||
|
||||
cpus_file.write("-1".as_bytes())
|
||||
.map_err(|_| Error::InvalidFile(cpu_path));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -2,10 +2,10 @@ use std::fs::File;
|
|||
use std::env;
|
||||
use std::io::{Write, Read};
|
||||
|
||||
use error::*;
|
||||
|
||||
use hermit_env;
|
||||
use socket::Socket;
|
||||
use hermit::Isle;
|
||||
use hermit::error::*;
|
||||
use hermit::hermit_env;
|
||||
use hermit::socket::Socket;
|
||||
|
||||
pub struct Multi {
|
||||
num: u8,
|
||||
|
@ -49,12 +49,28 @@ impl Multi {
|
|||
|
||||
Ok(Multi { num: num, socket: Socket::new_multi(num) })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_num(&self) -> u8 {
|
||||
impl Isle for Multi {
|
||||
fn num(&self) -> u8 {
|
||||
self.num
|
||||
}
|
||||
|
||||
pub fn run(&self) {
|
||||
fn log_file(&self) -> Result<String> {
|
||||
Ok(format!("/sys/hermit/isle{}/log", self.num))
|
||||
}
|
||||
|
||||
fn log_path(&self) -> Result<String> {
|
||||
Ok("/sys/hermit/".into())
|
||||
}
|
||||
|
||||
fn cpu_path(&self) -> Result<String> {
|
||||
Ok(format!("/sys/hermit/isle{}/cpus", self.num))
|
||||
}
|
||||
|
||||
fn run(&mut self) -> Result<()> {
|
||||
self.socket.connect().run();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,14 +1,15 @@
|
|||
use std::env;
|
||||
use utils;
|
||||
use error::*;
|
||||
use std::process::{Stdio, Child, Command};
|
||||
use libc;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::process::{ChildStdout, ChildStderr};
|
||||
|
||||
use hermit_env;
|
||||
use socket::Socket;
|
||||
use hermit::Isle;
|
||||
use hermit::utils;
|
||||
use hermit::error::*;
|
||||
use hermit::hermit_env;
|
||||
use hermit::socket::Socket;
|
||||
|
||||
const PIDNAME: &'static str = "/tmp/hpid-XXXXXX";
|
||||
const TMPNAME: &'static str = "/tmp/hermit-XXXXXX";
|
||||
|
@ -42,14 +43,6 @@ impl QEmu {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn run(&self) {
|
||||
self.socket.connect().run();
|
||||
}
|
||||
|
||||
pub fn tmp_path(&self) -> &str {
|
||||
&self.tmp_file
|
||||
}
|
||||
|
||||
pub fn start_with(path: &str, tmp_file: &str, pid_file: &str) -> Result<Command> {
|
||||
let hostfwd = format!("user,hostfwd=tcp:127.0.0.1:{}-:{}", hermit_env::port(), hermit_env::port());
|
||||
let monitor_str = format!("telnet:127.0.0.1:{},server,nowait", (hermit_env::port().parse::<u32>().unwrap()+1).to_string());
|
||||
|
@ -132,6 +125,25 @@ impl QEmu {
|
|||
}
|
||||
}
|
||||
|
||||
impl Isle for QEmu {
|
||||
fn num(&self) -> u8 { 0 }
|
||||
fn log_file(&self) -> Result<String> {
|
||||
Ok(self.tmp_file.clone())
|
||||
}
|
||||
fn log_path(&self) -> Result<String> {
|
||||
Ok("/tmp".into())
|
||||
}
|
||||
fn cpu_path(&self) -> Result<String> {
|
||||
Err(Error::InternalError)
|
||||
}
|
||||
|
||||
fn run(&mut self) -> Result<()> {
|
||||
self.socket.connect().run();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for QEmu {
|
||||
fn drop(&mut self) {
|
||||
let mut id_str = String::new();
|
|
@ -6,8 +6,8 @@ use std::ffi::CString;
|
|||
use std::process;
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
|
||||
|
||||
use proto;
|
||||
use proto::Packet;
|
||||
use hermit::proto;
|
||||
use hermit::proto::Packet;
|
||||
|
||||
use libc;
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
//! GDT. The Global Descriptor Table contains information about the memory structure used by the
|
||||
//! X86 family.
|
||||
|
||||
use uhyve::kvm_header::kvm_segment;
|
||||
use super::kvm_header::kvm_segment;
|
||||
|
||||
/// Used segments in order
|
||||
pub const BOOT_NULL: isize = 0;
|
|
@ -1,6 +1,6 @@
|
|||
//gdt.rs kvm_header.rs kvm.rs mod.rs vcpu.rs vm.rs
|
||||
mod gdt;
|
||||
mod kvm_header;
|
||||
pub mod kvm_header;
|
||||
pub mod uhyve;
|
||||
pub mod vcpu;
|
||||
pub mod vm;
|
||||
|
@ -8,5 +8,6 @@ pub mod proto;
|
|||
|
||||
// reexport Uhyve to show up in the root namespace of our module
|
||||
pub use self::uhyve::*;
|
||||
|
||||
// reexport the Error enum and Result type
|
||||
pub use error::*;
|
||||
pub use hermit::error::*;
|
|
@ -1,5 +1,5 @@
|
|||
use libc::{write, read, lseek, exit, open, close, c_int, c_void};
|
||||
use uhyve::kvm_header::{kvm_run, KVM_EXIT_IO, KVM_EXIT_HLT, KVM_EXIT_MMIO,KVM_EXIT_FAIL_ENTRY, KVM_EXIT_INTERNAL_ERROR, KVM_EXIT_SHUTDOWN };
|
||||
use super::kvm_header::{kvm_run, KVM_EXIT_IO, KVM_EXIT_HLT, KVM_EXIT_MMIO,KVM_EXIT_FAIL_ENTRY, KVM_EXIT_INTERNAL_ERROR, KVM_EXIT_SHUTDOWN };
|
||||
use std::ffi::CStr;
|
||||
|
||||
|
|
@ -7,15 +7,16 @@ use std::os::unix::fs::OpenOptionsExt;
|
|||
use std::os::unix::io::AsRawFd;
|
||||
use libc;
|
||||
|
||||
use uhyve::{Error, Result, NameIOCTL};
|
||||
use uhyve::vm::VirtualMachine;
|
||||
use hermit::Isle;
|
||||
use super::{Error, Result, NameIOCTL};
|
||||
use super::vm::VirtualMachine;
|
||||
|
||||
/// The normal way of defining a IOCTL interface is provided by C macros. In Rust we have our own
|
||||
/// flawed macro system. The module below wraps a bunch of functions which are generated by the
|
||||
/// ioctl! macro and need to be wrapped further to provide a safe interface.
|
||||
pub mod ioctl {
|
||||
use std::mem;
|
||||
use uhyve::kvm_header::{KVMIO, kvm_msr_list, kvm_cpuid2_header, kvm_memory_region, kvm_dirty_log, kvm_memory_alias, kvm_userspace_memory_region, kvm_regs,kvm_sregs};
|
||||
use hermit::uhyve::kvm_header::{KVMIO, kvm_msr_list, kvm_cpuid2_header, kvm_memory_region, kvm_dirty_log, kvm_memory_alias, kvm_userspace_memory_region, kvm_regs,kvm_sregs};
|
||||
|
||||
ioctl!(get_version with io!(KVMIO, 0x00));
|
||||
ioctl!(create_vm with io!(KVMIO, 0x01));
|
||||
|
@ -55,13 +56,13 @@ pub enum Version{
|
|||
|
||||
/// This is the entry point of our module, it connects to the KVM device and wraps the functions
|
||||
/// which accept the global file descriptor.
|
||||
pub struct Uhyve {
|
||||
pub struct KVM {
|
||||
file: File
|
||||
}
|
||||
|
||||
impl Uhyve {
|
||||
impl KVM {
|
||||
// Connects to the KVM hypervisor, by opening the virtual device /dev/kvm
|
||||
pub fn new() -> Uhyve {
|
||||
pub fn new() -> KVM {
|
||||
|
||||
let kvm_file = OpenOptions::new()
|
||||
.read(true)
|
||||
|
@ -71,7 +72,7 @@ impl Uhyve {
|
|||
|
||||
debug!("UHYVE - The connection to KVM was established.");
|
||||
|
||||
Uhyve { file: kvm_file }
|
||||
KVM { file: kvm_file }
|
||||
}
|
||||
|
||||
// Acquires the KVM version to seperate ancient systems
|
||||
|
@ -97,3 +98,46 @@ impl Uhyve {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Uhyve {
|
||||
kvm: KVM,
|
||||
vm: VirtualMachine
|
||||
}
|
||||
|
||||
impl Uhyve {
|
||||
pub fn new(path: &str) -> Result<Uhyve> {
|
||||
let kvm = KVM::new();
|
||||
let mut vm = kvm.create_vm(0x20000000)?;
|
||||
vm.load_kernel(path)?;
|
||||
vm.init()?;
|
||||
|
||||
Ok(Uhyve {
|
||||
kvm: kvm,
|
||||
vm: vm
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Isle for Uhyve {
|
||||
fn num(&self) -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
fn log_file(&self) -> Result<String> {
|
||||
Err(Error::InternalError)
|
||||
}
|
||||
|
||||
fn log_path(&self) -> Result<String> {
|
||||
Err(Error::InternalError)
|
||||
}
|
||||
|
||||
fn cpu_path(&self) -> Result<String> {
|
||||
Err(Error::InternalError)
|
||||
}
|
||||
|
||||
fn run(&mut self) -> Result<()> {
|
||||
self.vm.run();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -6,11 +6,11 @@ use std::os::unix::io::FromRawFd;
|
|||
use memmap::{Mmap, Protection};
|
||||
use errno::errno;
|
||||
|
||||
use uhyve;
|
||||
use uhyve::kvm_header::{kvm_sregs, kvm_regs, kvm_segment, kvm_cpuid2,kvm_cpuid2_header};
|
||||
use uhyve::{Result, Error, NameIOCTL};
|
||||
use uhyve::gdt;
|
||||
use uhyve::proto;
|
||||
use hermit::uhyve;
|
||||
use super::kvm_header::{kvm_sregs, kvm_regs, kvm_segment, kvm_cpuid2,kvm_cpuid2_header};
|
||||
use super::{Result, Error, NameIOCTL};
|
||||
use super::gdt;
|
||||
use super::proto;
|
||||
|
||||
pub const GUEST_OFFSET: usize = 0x0;
|
||||
pub const CPUID_FUNC_PERFMON: usize = 0x0A;
|
|
@ -8,12 +8,13 @@ use std::io::{Read, Cursor};
|
|||
use memmap::{Mmap, Protection};
|
||||
use elf;
|
||||
use elf::types::{ELFCLASS64, OSABI, PT_LOAD};
|
||||
use std::ffi::CStr;
|
||||
|
||||
use utils;
|
||||
use uhyve;
|
||||
use uhyve::kvm_header::{kvm_userspace_memory_region };
|
||||
use uhyve::{Result, Error, NameIOCTL};
|
||||
use uhyve::vcpu::VirtualCPU;
|
||||
use hermit::utils;
|
||||
use hermit::uhyve;
|
||||
use super::kvm_header::{kvm_userspace_memory_region };
|
||||
use super::{Result, Error, NameIOCTL};
|
||||
use super::vcpu::VirtualCPU;
|
||||
|
||||
//use byteorder::ByteOrder;
|
||||
// guest offset?
|
||||
|
@ -23,7 +24,8 @@ pub struct VirtualMachine {
|
|||
kvm_fd: libc::c_int,
|
||||
vm_fd: libc::c_int,
|
||||
mem: Mmap,
|
||||
elf_entry: Option<u64>,
|
||||
elf_header: Option<elf::types::FileHeader>,
|
||||
klog: Option<*const i8>,
|
||||
vcpus: Vec<VirtualCPU>,
|
||||
size: usize
|
||||
}
|
||||
|
@ -35,7 +37,7 @@ impl VirtualMachine {
|
|||
// create a new memory region to map the memory of our guest
|
||||
Mmap::anonymous(size, Protection::ReadWrite)
|
||||
.map_err(|_| Error::NotEnoughMemory)
|
||||
.map(|mem| VirtualMachine { kvm_fd: kvm_fd, vm_fd: fd, mem: mem, elf_entry: None, vcpus: Vec::new(), size: size })
|
||||
.map(|mem| VirtualMachine { kvm_fd: kvm_fd, vm_fd: fd, mem: mem, elf_header: None, klog: None, vcpus: Vec::new(), size: size })
|
||||
}
|
||||
|
||||
/// Loads a kernel from path and initialite mem and elf_entry
|
||||
|
@ -56,7 +58,7 @@ impl VirtualMachine {
|
|||
return Err(Error::InvalidFile(path.into()));
|
||||
}
|
||||
|
||||
self.elf_entry = Some(file_efi.ehdr.entry);
|
||||
self.elf_header = Some(file_efi.ehdr);
|
||||
|
||||
// acquire the slices of the user memory and kernel file
|
||||
let vm_mem_length = self.mem.len() as u64;
|
||||
|
@ -93,6 +95,8 @@ impl VirtualMachine {
|
|||
*(ptr.offset(0x38) as *mut u64) = header.memsz; //
|
||||
*(ptr.offset(0x60) as *mut u32) = 1; // NUMA nodes
|
||||
*(ptr.offset(0x94) as *mut u32) = 1; // announce uhyve
|
||||
|
||||
self.klog = Some(vm_mem.as_ptr().offset(header.paddr as isize + 0x5000) as *const i8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,13 +136,20 @@ impl VirtualMachine {
|
|||
}
|
||||
|
||||
pub fn create_vcpu(&mut self, id: u8) -> Result<VirtualCPU> {
|
||||
let entry = self.elf_entry.ok_or(Error::KernelNotLoaded)?;
|
||||
let entry = self.elf_header.ok_or(Error::KernelNotLoaded)?.entry;
|
||||
|
||||
let cpu = VirtualCPU::new(self.kvm_fd, self.vm_fd, id, entry, &mut self.mem)?;
|
||||
|
||||
Ok(cpu)
|
||||
}
|
||||
|
||||
pub fn output(&self) -> Result<String> {
|
||||
let paddr = self.klog.ok_or(Error::KernelNotLoaded)?;
|
||||
let c_str = unsafe { CStr::from_ptr(paddr).to_str().map_err(|_| Error::KernelNotLoaded)? };
|
||||
|
||||
Ok(c_str.into())
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> Result<()> {
|
||||
let mut guest_mem = unsafe { self.mem.as_mut_slice() };
|
||||
|
||||
|
@ -149,3 +160,11 @@ impl VirtualMachine {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for VirtualMachine {
|
||||
fn drop(&mut self) {
|
||||
if let Ok(output) = self.output() {
|
||||
debug!("{}", output);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ use std::os::unix::io::FromRawFd;
|
|||
use std::ffi::CString;
|
||||
use std::io::Read;
|
||||
|
||||
use error::*;
|
||||
use hermit::error::*;
|
||||
|
||||
use libc;
|
||||
|
|
@ -17,18 +17,11 @@ extern crate byteorder;
|
|||
#[macro_use]
|
||||
extern crate nix;
|
||||
|
||||
mod error;
|
||||
mod utils;
|
||||
mod hermit;
|
||||
mod uhyve;
|
||||
mod hermit_env;
|
||||
mod qemu;
|
||||
mod multi;
|
||||
mod proto;
|
||||
mod socket;
|
||||
|
||||
use nix::sys::signal;
|
||||
use std::{env, process};
|
||||
use hermit::error;
|
||||
|
||||
extern fn exit(_:i32) {
|
||||
panic!("Aborting ..");
|
||||
|
@ -46,9 +39,9 @@ fn main() {
|
|||
|
||||
// create the isle, wait to be available and start it
|
||||
env::args().skip(1).next().ok_or(error::Error::MissingBinary)
|
||||
.and_then(|path| hermit::IsleKind::new(&path))
|
||||
.and_then(|path| hermit::new_isle(&path))
|
||||
.and_then(|mut isle| {
|
||||
isle.wait_available()?;
|
||||
isle.wait_until_available()?;
|
||||
isle.run()?;
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Reference in a new issue