diff --git a/tools/hermit_proxy/src/daemon.rs b/tools/hermit_proxy/src/daemon.rs index fe3e38eb4..a0e37e47e 100644 --- a/tools/hermit_proxy/src/daemon.rs +++ b/tools/hermit_proxy/src/daemon.rs @@ -89,6 +89,7 @@ impl Connection { loop { match self.socket.read(&mut tmp) { + Ok(0) => break, Ok(nread) => buf.extend_from_slice(&tmp[0..nread]), Err(err) => { if buf.len() > 0 { @@ -141,7 +142,7 @@ pub enum ActionResult { CreateIsle(Result), StopIsle(Result), RemoveIsle(Result), - Connect, + Connect(Result<()>), Log(Vec), IsleLog(Result), List(Vec<(Result, IsleParameter)>), @@ -251,6 +252,9 @@ impl State { } } +fn exit_daemon_handler() { +} + pub fn daemon_handler() { let mut state = State::new(); let mut buf = vec![0; 256]; @@ -261,8 +265,6 @@ pub fn daemon_handler() { for stream in listener.incoming() { match stream { Ok(mut stream) => { - //let mut stream = Arc::new(Mutex::new(stream)); - loop { let nread = stream.read(&mut buf); @@ -275,6 +277,11 @@ pub fn daemon_handler() { let ret = match action { Action::KillDaemon => { fs::remove_file("/tmp/hermit_daemon").unwrap(); + + let buf: Vec = serialize(&ActionResult::KillDaemon(Ok(())), Infinite).unwrap(); + stream.write(&buf); + + process::exit(0); break; }, Action::CreateIsle(path, specs) => { @@ -289,7 +296,7 @@ pub fn daemon_handler() { }, Action::List => ActionResult::List(state.list()), Action::Connect(id) => { - let buf: Vec = serialize(&ActionResult::Connect, Infinite).unwrap(); + let buf: Vec = serialize(&ActionResult::Connect(state.exist_isle(id)), Infinite).unwrap(); stream.write(&buf); state.add_endpoint(id, stream); diff --git a/tools/hermit_proxy/src/hermit/multi.rs b/tools/hermit_proxy/src/hermit/multi.rs index 1beb81eca..6e6acfde9 100644 --- a/tools/hermit_proxy/src/hermit/multi.rs +++ b/tools/hermit_proxy/src/hermit/multi.rs @@ -51,7 +51,7 @@ impl Multi { return Err(Error::MultiIsleFailed); } - Ok(Multi { num: num, socket: Some(Socket::new()) }) + Ok(Multi { num: num, socket: Some(Socket::new(18766)) }) } } diff --git a/tools/hermit_proxy/src/hermit/proto.rs b/tools/hermit_proxy/src/hermit/proto.rs index 3adc6fff9..d3426a193 100644 --- a/tools/hermit_proxy/src/hermit/proto.rs +++ b/tools/hermit_proxy/src/hermit/proto.rs @@ -65,6 +65,10 @@ pub enum Packet { impl Packet { pub fn from_buf(obj: &PartialPacket, buf: &mut Cursor>) -> Packet { + + //println!("{:?}", *obj); + + match *obj { PartialPacket::Write { fd, len } => { debug!("Read write packet with length {}", len); diff --git a/tools/hermit_proxy/src/hermit/qemu.rs b/tools/hermit_proxy/src/hermit/qemu.rs index 3f1dad545..56ad06019 100644 --- a/tools/hermit_proxy/src/hermit/qemu.rs +++ b/tools/hermit_proxy/src/hermit/qemu.rs @@ -19,6 +19,26 @@ use hermit::socket::{Socket, Console}; const PIDNAME: &'static str = "/tmp/hpid-XXXXXX"; const TMPNAME: &'static str = "/tmp/hermit-XXXXXX"; +const BASE_PORT: u16 = 18766; +static mut FREE_PORT: u64 = 0u64; + +// there are 64 ports free +fn get_free_port() -> Result { + // assume single threading + unsafe { + if FREE_PORT == u64::max_value() { + return Err(Error::InternalError); + } + + // find first bit set to zero + let pos = (!FREE_PORT).trailing_zeros(); + + FREE_PORT |= (1 << pos); + + Ok(BASE_PORT + pos as u16) + } +} + #[derive(Debug)] pub struct QEmu { socket: Option, @@ -34,12 +54,15 @@ impl QEmu { pub fn new(path: &str, mem_size: u64, num_cpus: u32, additional: IsleParameterQEmu) -> Result { let tmpf = utils::create_tmp_file(TMPNAME)?; let pidf = utils::create_tmp_file(PIDNAME)?; + // get a new port number + let port = get_free_port()?; - let mut child = QEmu::start_with(path, mem_size, num_cpus, additional, &tmpf, &pidf)?.spawn().expect("Couldn't find qemu binary!"); + debug!("new port number: {}", port); + + let mut child = QEmu::start_with(path, port, mem_size, num_cpus, additional, &tmpf, &pidf)?.spawn().expect("Couldn't find qemu binary!"); let stdout = child.stdout.take().unwrap(); let stderr = child.stderr.take().unwrap(); - println!("{}", pidf); - let socket = Socket::new(); + let socket = Socket::new(port); let console = socket.console(); Ok(QEmu { @@ -53,8 +76,8 @@ impl QEmu { }) } - pub fn start_with(path: &str, mem_size: u64, num_cpus: u32, add: IsleParameterQEmu, tmp_file: &str, pid_file: &str) -> Result { - let hostfwd = format!("user,hostfwd=tcp:127.0.0.1:{}-:{}", add.port, add.port); + pub fn start_with(path: &str, port: u16, mem_size: u64, num_cpus: u32, add: IsleParameterQEmu, tmp_file: &str, pid_file: &str) -> Result { + let hostfwd = format!("user,hostfwd=tcp:127.0.0.1:{}-:{}", port, 18766); let monitor_str = format!("unix:{}_monitor,server,nowait", pid_file); let chardev = format!("file,id=gnc0,path={}",&tmp_file); let freq = format!("\"-freq{} -proxy\"",(utils::cpufreq().unwrap()/1000).to_string()); diff --git a/tools/hermit_proxy/src/hermit/socket.rs b/tools/hermit_proxy/src/hermit/socket.rs index b87b2ecc6..c1d3ee607 100644 --- a/tools/hermit_proxy/src/hermit/socket.rs +++ b/tools/hermit_proxy/src/hermit/socket.rs @@ -26,17 +26,18 @@ pub type Console = Arc>>; #[derive(Debug)] pub struct Socket { stream: Option, + port: u16, console: Console } impl Socket { - pub fn new() -> Socket { - Socket { stream: None, console: Arc::new(Mutex::new(Vec::new())) } + pub fn new(port: u16) -> Socket { + Socket { stream: None, port: port, console: Arc::new(Mutex::new(Vec::new())) } } pub fn connect(&mut self) -> Result<()> { // prepare the initializing struct - let length: usize = 4 + env::args().skip(2).map(|x| 4+x.len()).sum::() + + let length: usize = 4 + 4 + env::args().skip(2).map(|x| 4+x.len()+1).sum::() + 4 + env::vars().map(|(x,y)| 5 + x.len()+ y.len()).sum::(); let mut buf = Cursor::new(vec![0u8;length]); @@ -46,8 +47,9 @@ impl Socket { // send all arguments (skip first) buf.write_u32::(env::args().count() as u32 - 2); for key in env::args().skip(2) { - buf.write_u32::(key.len() as u32); + buf.write_u32::(key.len() as u32 + 1); buf.write(key.as_bytes()); + buf.write_u8(b'\0'); } // send the environment @@ -60,7 +62,7 @@ impl Socket { let mut stream; loop { - match TcpStream::connect(("127.0.0.1", 0x494E)) { + match TcpStream::connect(("127.0.0.1", self.port)) { Ok(mut s) => { match s.write(buf.get_ref()) { Ok(_) => { stream = s; break; }, @@ -120,7 +122,7 @@ impl Socket { Packet::Write { fd, 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()); + buf_ret = transmute(libc::write(fd, buf.as_ptr() as *const libc::c_void, buf.len()).to_le()); } else { let res = match fd { 1 => ActionResult::Output(String::from_utf8_unchecked(buf)), @@ -129,9 +131,10 @@ impl Socket { }; let buf: Vec = serialize(&res, Infinite).unwrap(); - for stream in self.console.lock().unwrap().iter_mut() { - stream.write(&buf).unwrap(); - } + + // try to send the new console log to each endpoint and retain only + // the successfully ones. + self.console.lock().unwrap().retain(|mut x| x.write(&buf).is_ok()); buf_ret = transmute(buf.len()); } @@ -139,24 +142,19 @@ impl Socket { 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()); - debug!("got {:?}", buf); - + let mut buf: [u8; 4] = transmute(libc::open(name.as_ptr(), flags as i32, mode as i32).to_le()); let written = stream.write(&buf).unwrap(); - debug!("Written {}", written); }, Packet::Close { fd } => { - let buf: [u8; 4] = transmute(libc::close(fd as i32).to_le()); + let buf: [u8; 4] = transmute(libc::close(fd).to_le()); stream.write(&buf); }, Packet::Read { fd, len } => { let mut tmp: Vec = vec![0; len as usize]; - let got = libc::read(fd as i32, tmp.as_mut_ptr() as *mut libc::c_void, len as usize); + let got = libc::read(fd, tmp.as_mut_ptr() as *mut libc::c_void, len as usize); let buf: [u8; 8] = transmute(got.to_le()); - debug!("Read size {:?}", buf); - stream.write(&buf); if got > 0 { @@ -164,7 +162,7 @@ impl Socket { } }, Packet::LSeek { fd, offset, whence } => { - let buf: [u8; 8] = transmute(libc::lseek(fd as i32, offset, whence as i32).to_le()); + let buf: [u8; 8] = transmute(libc::lseek(fd, offset, whence as i32).to_le()); stream.write(&buf); } }; diff --git a/tools/hermit_proxy/src/hermit/uhyve/proto.rs b/tools/hermit_proxy/src/hermit/uhyve/proto.rs index 62df90606..159ad5731 100644 --- a/tools/hermit_proxy/src/hermit/uhyve/proto.rs +++ b/tools/hermit_proxy/src/hermit/uhyve/proto.rs @@ -96,8 +96,6 @@ impl Syscall { } pub unsafe fn run(&self, guest_mem: *mut u8, console: Console) -> Result { - println!("{:?}", *self); - match *self { Syscall::Write(obj) => { use std::io::Write; @@ -116,9 +114,7 @@ impl Syscall { let buf: Vec = serialize(&ret, Infinite).unwrap(); - for stream in console.lock().unwrap().iter_mut() { - stream.write(&buf).unwrap(); - } + console.lock().unwrap().retain(|mut x| x.write(&buf).is_ok()); } }, Syscall::Read(obj) => { diff --git a/tools/hermit_proxy/src/hermit/uhyve/vcpu.rs b/tools/hermit_proxy/src/hermit/uhyve/vcpu.rs index 54120cda8..f6c0b89a4 100644 --- a/tools/hermit_proxy/src/hermit/uhyve/vcpu.rs +++ b/tools/hermit_proxy/src/hermit/uhyve/vcpu.rs @@ -237,20 +237,14 @@ impl VirtualCPU { 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"); - } + _ => {} } } diff --git a/tools/hermit_proxy/src/main.rs b/tools/hermit_proxy/src/main.rs index 5c36a40e5..1f86e48f2 100644 --- a/tools/hermit_proxy/src/main.rs +++ b/tools/hermit_proxy/src/main.rs @@ -178,8 +178,10 @@ fn main() { Ok(id) => { let res = daemon.send(Action::Connect(id)); - if let ActionResult::Connect = res { + if let ActionResult::Connect(Ok(())) = res { daemon.output(); + } else { + println!("Invalid number!"); } }, Err(_) => {