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

New commands, QEmu awaits now the TCP connection

This commit is contained in:
bytesnake 2017-06-30 17:48:15 +02:00
parent 192b0c09fe
commit 18a589317f
5 changed files with 95 additions and 35 deletions

View file

@ -1,8 +1,12 @@
use std::os::unix::net::{UnixStream, UnixListener};
use std::path::Path;
use std::result;
use std::thread;
use log;
use log::{LogMetadata, LogRecord, SetLoggerError, LogLevel, LogLevelFilter};
use nix::unistd::{fork, ForkResult};
use hermit::Isle;
use std::sync::RwLock;
use std::io::Write;
use std::io::Read;
use bincode::{serialize, deserialize, Infinite};
@ -11,9 +15,40 @@ use hermit::IsleParameter;
use hermit::qemu::QEmu;
use hermit::multi::Multi;
use hermit::uhyve::Uhyve;
use hermit::error::Result;
use hermit::error::{Result,Error};
use chrono::{DateTime,Local};
thread_local!{
static LOGS: RwLock<Vec<Log>> = RwLock::new(Vec::new());
}
struct LocalLogger;
impl log::Log for LocalLogger {
fn enabled(&self, metadata: &LogMetadata) -> bool {
true
}
fn log(&self, record: &LogRecord) {
LOGS.with(|f| {
let mut writable = f.write().unwrap();
writable.push(Log { time: Local::now(), level: LogCoverage::Intern, text: format!("{}", record.args()) });
});
}
}
impl LocalLogger {
pub fn init() -> result::Result<(), SetLoggerError> {
log::set_logger(|max_level| {
max_level.set(LogLevelFilter::Trace);
Box::new(LocalLogger)
})
}
}
pub struct Connection {
pub socket: UnixStream
}
@ -68,21 +103,28 @@ pub enum ActionResult {
KillDaemon(Result<()>)
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum LogCoverage {
All,
Communication,
Intern
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Log {
pub time: DateTime<Local>,
pub action: Action
pub level: LogCoverage,
pub text: String
}
struct State {
isles: Vec<Box<Isle>>,
specs: Vec<IsleParameter>,
logs: Vec<Log>
specs: Vec<IsleParameter>
}
impl State {
pub fn new() -> State {
State { isles: Vec::new(), logs: Vec::new(), specs: Vec::new() }
State { isles: Vec::new(), specs: Vec::new() }
}
pub fn create_isle(&mut self, path: String, specs: IsleParameter) -> Result<u32> {
@ -94,7 +136,6 @@ impl State {
IsleParameter::Multi{ mem_size, num_cpus } => Box::new(Multi::new(0, &path, mem_size, num_cpus)?)
};
isle.wait_until_available()?;
isle.run()?;
self.isles.push(isle);
@ -107,18 +148,31 @@ impl State {
}
pub fn log(&self) -> Vec<Log> {
self.logs.clone()
let mut logs = Vec::new();
LOGS.with(|f| {
logs = (*f.read().unwrap()).to_vec();
});
logs
}
pub fn add_log(&mut self, action: Action) {
self.logs.push(Log { time: Local::now(), action: action });
LOGS.with(|f| {
let mut writable = f.write().unwrap();
writable.push(Log { time: Local::now(), level: LogCoverage::Communication, text: format!("{:?}",action) });
});
}
pub fn stop_isle(&mut self, id: u32) -> Result<i32> {
self.exist_isle(id)?;
self.isles[id as usize].stop()
}
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()?;
}
@ -128,12 +182,28 @@ impl State {
Ok(0)
}
fn log_isle(&self, id: u32) -> Result<String> {
self.exist_isle(id)?;
self.isles[id as usize].output()
}
fn exist_isle(&self, id: u32) -> Result<()> {
if self.isles.len() > id as usize {
Ok(())
} else {
Err(Error::WrongIsleNumber)
}
}
}
pub fn daemon_handler() {
let mut state = State::new();
let mut buf = vec![0; 256];
LocalLogger::init();
let listener = UnixListener::bind("/tmp/hermit_daemon").unwrap();
//for stream in listener.incoming() {
// match stream {
@ -156,7 +226,7 @@ pub fn daemon_handler() {
Action::List => ActionResult::List(state.list()),
Action::Log(id) => {
match id {
Some(id) => ActionResult::IsleLog(state.isles[id as usize].output()),
Some(id) => ActionResult::IsleLog(state.log_isle(id)),
None => ActionResult::Log(state.log())
}
},

View file

@ -17,7 +17,8 @@ pub enum Error {
QEmu((String, String)),
MissingBinary,
Protocol(String),
ParseMemory
ParseMemory,
WrongIsleNumber
}
impl fmt::Debug for Error {
@ -38,7 +39,8 @@ impl fmt::Debug for Error {
Error::QEmu((_, ref stderr)) => write!(f, "The qemu binary has encountered an error: {}", stderr),
Error::MissingBinary => write!(f, "Please specify a binary."),
Error::Protocol(ref err) => write!(f, "{}", err),
Error::ParseMemory => write!(f, "Couldn't parse the guest memory size from the environment")
Error::ParseMemory => write!(f, "Couldn't parse the guest memory size from the environment"),
Error::WrongIsleNumber => write!(f, "Unknown isle number")
}
}
}

View file

@ -141,7 +141,6 @@ pub trait Isle {
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() {

View file

@ -86,10 +86,10 @@ impl QEmu {
args.push("host");
}
//if add.monitor {
if add.monitor {
args.push("-monitor");
args.push(&monitor_str);
//}
}
if add.should_debug {
args.push("-s");
@ -100,10 +100,7 @@ impl QEmu {
args.push("dump");
}
/*
if hermit_env::verbose() != "0" {
debug!("Execute {} with args {:#?}", hermit_env::qemu_binary(), args);
}*/
debug!("Execute {} with args {:#?}", add.binary, args);
let mut cmd = Command::new(add.binary);

View file

@ -5,10 +5,6 @@
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#[macro_use]
extern crate log;
extern crate env_logger;
#[macro_use]
extern crate clap;
@ -27,6 +23,9 @@ extern crate chrono;
#[macro_use]
extern crate nix;
#[macro_use]
extern crate log;
mod hermit;
mod daemon;
@ -38,18 +37,7 @@ use daemon::{Action, ActionResult};
use std::net::Shutdown;
use chrono::DateTime;
extern fn exit(_:i32) {
panic!("Aborting ..");
}
fn main() {
// register a signal
/*let sig_action = signal::SigAction::new(signal::SigHandler::Handler(exit), signal::SaFlags::empty(), signal::SigSet::empty());
unsafe {
signal::sigaction(signal::SIGINT, &sig_action).unwrap();
signal::sigaction(signal::SIGTERM, &sig_action).unwrap();
}*/
let matches = clap_app!(HermitProxy =>
(version: "0.0.1")
(author: "Lorenz Schmidt <bytesnake@mailbox.org>")
@ -127,7 +115,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_string(), log.action);
println!("{0: <10} | {1: <10} | {2: <10?}", i, log.time.to_rfc3339(), log.text);
i += 1;
}
} else if let ActionResult::IsleLog(content) = res {
@ -160,6 +148,11 @@ fn main() {
Ok(id) => {
let res = daemon.send(Action::RemoveIsle(id));
if let ActionResult::RemoveIsle(Ok(_)) = res {
println!("Isle {} was successfully removed", id);
} else if let ActionResult::RemoveIsle(Err(err)) = res {
println!("Remove failed: {:?}", err);
}
},
Err(_) => {
println!("Invalid number!");
@ -198,7 +191,6 @@ fn main() {
env::set_var("HERMIT_APP_PORT",app_port);
}
env_logger::init().unwrap();
let res = daemon.send(Action::CreateIsle(
matches.value_of("file").unwrap().into(),
IsleParameter::from_env()