1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

Improved the connect command, fixed some bugs.

This commit is contained in:
bytesnake 2017-08-04 00:04:21 +02:00
parent e2e625d847
commit cb20bd1f5c
11 changed files with 132 additions and 110 deletions

View file

@ -17,7 +17,3 @@ serde = "1.*.*"
chrono = { version = "0.4", features = ["serde"] }
bincode = "0.8"
serde_derive = "1.*.*"
[dependencies.env_logger]
version = "0.3"
default-features = false

View file

@ -141,7 +141,7 @@ pub enum ActionResult {
CreateIsle(Result<u32>),
StopIsle(Result<i32>),
RemoveIsle(Result<i32>),
Connect(Result<()>),
Connect,
Log(Vec<Log>),
IsleLog(Result<String>),
List(Vec<(Result<bool>, IsleParameter)>),
@ -220,8 +220,8 @@ impl State {
pub fn remove_isle(&mut self, id: u32) -> Result<i32> {
self.exist_isle(id)?;
if self.isles[id as usize].is_running()? {
self.isles[id as usize].stop()?;
if let Ok(true) = self.isles[id as usize].is_running() {
self.isles[id as usize].stop();
}
self.isles.remove(id as usize);
@ -244,7 +244,7 @@ impl State {
}
}
fn add_endpoint(&mut self, id: u32, stream: Arc<Mutex<UnixStream>>) -> Result<()> {
fn add_endpoint(&mut self, id: u32, stream: UnixStream) -> Result<()> {
self.exist_isle(id)?;
self.isles[id as usize].add_endpoint(stream)
@ -261,51 +261,60 @@ pub fn daemon_handler() {
for stream in listener.incoming() {
match stream {
Ok(mut stream) => {
let mut stream = Arc::new(Mutex::new(stream));
//let mut stream = Arc::new(Mutex::new(stream));
loop {
//println!("READ");
let nread = stream.lock().unwrap().read(&mut buf);
println!("{:?}", nread);
if let Ok(nread) = nread {
if nread > 0 {
let action:Action = deserialize(&buf).unwrap();
state.add_log(action.clone());
let nread = stream.read(&mut buf);
let ret = match action {
Action::KillDaemon => {
fs::remove_file("/tmp/hermit_daemon").unwrap();
break;
},
Action::CreateIsle(path, specs) => ActionResult::CreateIsle(state.create_isle(path,specs)),
Action::List => ActionResult::List(state.list()),
Action::Connect(id) => {
let res = ActionResult::Connect(state.add_endpoint(id, stream.clone()));
let buf: Vec<u8> = serialize(&res, Infinite).unwrap();
stream.lock().unwrap().write(&buf);
break;
},
Action::Log(id) => {
match id {
Some(id) => ActionResult::IsleLog(state.log_isle(id)),
None => ActionResult::Log(state.log())
}
},
Action::StopIsle(id) => ActionResult::StopIsle(state.stop_isle(id)),
Action::RemoveIsle(id) => ActionResult::RemoveIsle(state.remove_isle(id)),
_ => { panic!(""); }
};
if let Ok(nread) = nread {
if nread > 0 {
let action:Action = deserialize(&buf).unwrap();
state.add_log(action.clone());
println!("WRITE");
let buf: Vec<u8> = serialize(&ret, Infinite).unwrap();
stream.lock().unwrap().write(&buf);
let ret = match action {
Action::KillDaemon => {
fs::remove_file("/tmp/hermit_daemon").unwrap();
break;
},
Action::CreateIsle(path, specs) => {
let id = state.create_isle(path,specs);
let buf: Vec<u8> = serialize(&ActionResult::CreateIsle(id.clone()), Infinite).unwrap();
stream.write(&buf);
if let Ok(id) = id {
state.add_endpoint(id, stream);
}
break;
},
Action::List => ActionResult::List(state.list()),
Action::Connect(id) => {
let buf: Vec<u8> = serialize(&ActionResult::Connect, Infinite).unwrap();
stream.write(&buf);
state.add_endpoint(id, stream);
break;
},
Action::Log(id) => {
match id {
Some(id) => ActionResult::IsleLog(state.log_isle(id)),
None => ActionResult::Log(state.log())
}
},
Action::StopIsle(id) => ActionResult::StopIsle(state.stop_isle(id)),
Action::RemoveIsle(id) => ActionResult::RemoveIsle(state.remove_isle(id)),
_ => { panic!(""); }
};
let buf = serialize(&ret, Infinite).unwrap();
stream.write(&buf);
} else {
break;
}
} else {
break;
}
} else {
break;
}
}
},
Err(err) => { println!("ERR: {:?}", err); }

View file

@ -4,7 +4,7 @@ use errno::errno;
pub type Result<T> = result::Result<T, Error>;
#[derive(Deserialize, Serialize)]
#[derive(Deserialize, Serialize, Clone)]
pub enum Error {
InternalError,
NotEnoughMemory,
@ -45,7 +45,7 @@ impl fmt::Debug for Error {
}
}
#[derive(Serialize, Deserialize,Debug)]
#[derive(Serialize, Deserialize,Debug,Clone)]
pub enum NameIOCTL {
GetVersion,
CreateVM,

View file

@ -56,9 +56,21 @@ impl IsleParameter {
let num_cpus: u32 = env::var("HERMIT_CPUS").map(|x| x.parse().unwrap_or(1)).unwrap_or(1);
match isle_kind.as_str() {
"qemu" | "QEmu" | "QEMU" => {
"multi" | "MULTI" | "Multi" => {
IsleParameter::Multi {
mem_size: mem_size,
num_cpus: num_cpus
}
},
"uhyve" | "UHyve" | "UHYVE" => {
IsleParameter::UHyve {
mem_size: mem_size,
num_cpus: num_cpus
}
},
_ => {
let binary = env::var("HERMIT_BINARY").unwrap_or("qemu-system-x86_64".into());
let kvm = env::var("HERMIT_KVM").map(|x| x.parse().unwrap_or(false)).unwrap_or(false);
let kvm = env::var("HERMIT_KVM").map(|x| x.parse().unwrap_or(true)).unwrap_or(true);
let monitor = env::var("HERMIT_MONITOR").map(|x| x.parse().unwrap_or(false)).unwrap_or(false);
let capture_net = env::var("HERMIT_CAPTURE_NET").map(|x| x.parse().unwrap_or(false)).unwrap_or(false);
let port = env::var("HERMIT_PORT").map(|x| x.parse().unwrap_or(18766)).unwrap_or(18766);
@ -78,20 +90,7 @@ impl IsleParameter {
should_debug: debug
}
}
},
"multi" | "MULTI" | "Multi" => {
IsleParameter::Multi {
mem_size: mem_size,
num_cpus: num_cpus
}
},
"uhyve" | "UHyve" | "UHYVE" => {
IsleParameter::UHyve {
mem_size: mem_size,
num_cpus: num_cpus
}
},
_ => { panic!(""); }
}
}
}
}
@ -109,7 +108,7 @@ pub trait Isle {
fn is_running(&mut self) -> Result<bool>;
fn add_endpoint(&mut self, stream: Arc<Mutex<UnixStream>>) -> Result<()>;
fn add_endpoint(&mut self, stream: UnixStream) -> Result<()>;
fn is_available(&self) -> Result<bool> {
let log = match self.log_file() {

View file

@ -108,7 +108,7 @@ impl Isle for Multi {
Ok(true)
}
fn add_endpoint(&mut self, stream: Arc<Mutex<UnixStream>>) -> Result<()> {
fn add_endpoint(&mut self, stream: UnixStream) -> Result<()> {
Ok(())
}
}

View file

@ -61,11 +61,13 @@ impl QEmu {
let num_cpus = num_cpus.to_string();
let mem_size = format!("{}B", mem_size);
let exe = env::current_exe().unwrap();
/*let exe = env::current_exe().unwrap();
let name = exe.to_str().unwrap();
let exe_path = name.split("/").take(name.matches('/').count()).collect::<Vec<&str>>().join("/");
let exe = format!("{}/ldhermit.elf", exe_path);
*/
let exe: String = "/opt/hermit/bin/ldhermit.elf".into();
let mut port_str;
@ -202,7 +204,7 @@ impl Isle for QEmu {
Ok(state == "VM status: running")
}
fn add_endpoint(&mut self, stream: Arc<Mutex<UnixStream>>) -> Result<()> {
fn add_endpoint(&mut self, stream: UnixStream) -> Result<()> {
self.console.lock().unwrap().push(stream);
Ok(())

View file

@ -1,5 +1,5 @@
use std::net::TcpStream;
use std::env;
use std::{env, slice};
use std::mem::transmute;
use std::io::{Write, Read, Cursor};
use std::ffi::CString;
@ -21,7 +21,7 @@ use libc;
const HERMIT_MAGIC: u32 = 0x7E317;
pub type Console = Arc<Mutex<Vec<Arc<Mutex<UnixStream>>>>>;
pub type Console = Arc<Mutex<Vec<UnixStream>>>;
#[derive(Debug)]
pub struct Socket {
@ -118,27 +118,25 @@ impl Socket {
match packet {
Packet::Exit { arg } => break 'main,
Packet::Write { fd, buf } => {
let buf_ret: [u8;8] = transmute(libc::write(fd as i32, buf.as_ptr() as *const libc::c_void, buf.len()).to_le());
if fd == 1 {
let ret = ActionResult::Output(String::from_utf8_unchecked(buf));
let buf: Vec<u8> = serialize(&ret, Infinite).unwrap();
for stream in self.console.lock().unwrap().iter_mut() {
stream.lock().unwrap().write(&buf).unwrap();
}
//stdout.push_str(&String::from_utf8_unchecked(buf));
} else if fd == 2 {
let ret = ActionResult::OutputErr(String::from_utf8_unchecked(buf));
let buf: Vec<u8> = serialize(&ret, Infinite).unwrap();
for stream in self.console.lock().unwrap().iter_mut() {
stream.lock().unwrap().write(&buf).unwrap();
}
//stderr.push_str(&String::from_utf8_unchecked(buf));
let mut buf_ret: [u8; 8];
if fd != 1 && fd != 2 {
buf_ret = transmute(libc::write(fd as i32, buf.as_ptr() as *const libc::c_void, buf.len()).to_le());
} else {
stream.write(&buf_ret);
let res = match fd {
1 => ActionResult::Output(String::from_utf8_unchecked(buf)),
2 => ActionResult::OutputErr(String::from_utf8_unchecked(buf)),
_ => unreachable!()
};
let buf: Vec<u8> = serialize(&res, Infinite).unwrap();
for stream in self.console.lock().unwrap().iter_mut() {
stream.write(&buf).unwrap();
}
buf_ret = transmute(buf.len());
}
stream.write(&buf_ret);
},
Packet::Open { name, mode, flags } => {
let buf: [u8; 4] = transmute(libc::open(name.as_ptr(), flags as i32, mode as i32).to_le());

View file

@ -1,8 +1,8 @@
use libc::{write, read, lseek, exit, open, close, c_int, c_void, c_char};
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;
use std::ffi::CString;
use bincode::{serialize, Infinite};
use std::slice;
use super::{Error, Result};
use hermit::socket::Console;
@ -58,7 +58,7 @@ pub enum Syscall {
Close(*mut Close),
Read(*mut Read),
LSeek(*mut LSeek),
Exit(*mut isize),
Exit(*mut i32),
Other(*const kvm_run)
}
@ -88,7 +88,7 @@ impl Syscall {
PORT_CLOSE => { Syscall::Close(guest_mem.offset(offset) as *mut Close) },
PORT_OPEN => { Syscall::Open (guest_mem.offset(offset) as *mut Open ) },
PORT_LSEEK => { Syscall::LSeek(guest_mem.offset(offset) as *mut LSeek) },
PORT_EXIT => { Syscall::Exit( guest_mem.offset(offset) as *mut isize) },
PORT_EXIT => { Syscall::Exit( guest_mem.offset(offset) as *mut i32) },
_ => { panic!("KVM: unhandled KVM_EXIT_IO at port 0x{}, direction {}", run.__bindgen_anon_1.io.port, run.__bindgen_anon_1.io.direction); }
}
}
@ -96,29 +96,36 @@ impl Syscall {
}
pub unsafe fn run(&self, guest_mem: *mut u8, console: Console) -> Result<Return> {
debug!("{:?}", *self);
println!("{:?}", *self);
match *self {
Syscall::Write(obj) => {
if (*obj).fd == 1 {
use std::io::Write;
let cstr = CString::from_raw((*obj).buf as *mut c_char);
let ret = ActionResult::Output(cstr.into_string().unwrap_or("".into()));
use std::io::Write;
if (*obj).fd != 1 && (*obj).fd != 2 {
(*obj).length = write((*obj).fd, guest_mem.offset((*obj).buf) as *const c_void, (*obj).length as usize);
} else {
let tmp = slice::from_raw_parts(guest_mem.offset((*obj).buf) as *const u8, (*obj).length as usize);
let content = String::from_utf8_unchecked(tmp.into());
let ret = match (*obj).fd {
1 => ActionResult::Output(content),
2 => ActionResult::OutputErr(content),
_ => unreachable!()
};
let buf: Vec<u8> = serialize(&ret, Infinite).unwrap();
for stream in console.lock().unwrap().iter_mut() {
stream.lock().unwrap().write(&buf).unwrap();
stream.write(&buf).unwrap();
}
} else if (*obj).fd == 2 {
}
(*obj).length = write((*obj).fd, guest_mem.offset((*obj).buf) as *const c_void, (*obj).length as usize);
},
Syscall::Read(obj) => {
(*obj).ret = read((*obj).fd, guest_mem.offset((*obj).buf) as *mut c_void, (*obj).len);
},
Syscall::Exit(obj) => {
return Ok(Return::Exit(*((guest_mem as *mut i32).offset((*obj) as isize))));
return Ok(Return::Exit(*(guest_mem.offset((*obj) as isize)) as i32));
},
Syscall::Open(obj) => {
(*obj).ret = open(guest_mem.offset((*obj).name) as *const i8, (*obj).flags, (*obj).mode);

View file

@ -164,7 +164,7 @@ impl Isle for Uhyve {
self.vm.is_running()
}
fn add_endpoint(&mut self, stream: Arc<Mutex<UnixStream>>) -> Result<()> {
fn add_endpoint(&mut self, stream: UnixStream) -> Result<()> {
self.console.lock().unwrap().push(stream);
Ok(())

View file

@ -236,15 +236,21 @@ impl VirtualCPU {
match VirtualCPU::single_run(fd, &state) {
Ok(proto::Return::Exit(code)) => {
state.running_state.store(false, Ordering::Relaxed);
println!("exit {}", code);
return ExitCode::Cause(Ok(code));
},
Err(err) => {
state.running_state.store(false, Ordering::Relaxed);
println!("error {:?}", err);
return ExitCode::Cause(Err(err));
},
_ => {}
_ => {
println!("RUN");
}
}
}

View file

@ -30,7 +30,7 @@ mod hermit;
mod daemon;
use nix::sys::signal;
use std::env;
use std::{env, fs};
use hermit::{IsleParameter, error};
use daemon::{Action, ActionResult};
@ -128,7 +128,7 @@ fn main() {
let mut i = 0;
println!("{0: <10} | {1: <10} | {2: <10}", "number", "time", "action");
for log in logs {
println!("{0: <10} | {1: <10} | {2: <10?}", i, log.time.to_rfc3339(), log.text);
println!("{0: <10} | {1: <10} | {2: <10?}", i, log.time.format("%H:%M:%S"), log.text);
i += 1;
}
} else if let ActionResult::IsleLog(content) = res {
@ -178,10 +178,8 @@ fn main() {
Ok(id) => {
let res = daemon.send(Action::Connect(id));
if let ActionResult::Connect(Ok(_)) = res {
if let ActionResult::Connect = res {
daemon.output();
} else if let ActionResult::Connect(Err(err)) = res {
println!("Connect failed: {:?}", err);
}
},
Err(_) => {
@ -221,11 +219,18 @@ fn main() {
env::set_var("HERMIT_APP_PORT",app_port);
}
let relative_path: String = matches.value_of("file").unwrap().into();
let path = fs::canonicalize(relative_path).unwrap();
let res = daemon.send(Action::CreateIsle(
matches.value_of("file").unwrap().into(),
path.to_str().unwrap().into(),
IsleParameter::from_env()
));
if let ActionResult::CreateIsle(_) = res {
daemon.output();
}
println!("Created Isle with number: {:?}", res);
}
}