Skip to content

Commit

Permalink
fix : read from unix socket
Browse files Browse the repository at this point in the history
Signed-off-by: Maxime <[email protected]>
  • Loading branch information
Maxtho8 committed Mar 31, 2023
1 parent ed58c44 commit dd57431
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 36 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 33 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::u32;
use std::{io::Read, os::unix::net::UnixListener, path::Path, thread::sleep, u32};

use clap::Parser;
use vmm::VMM;
use vmm::{devices::Writer, VMM};

#[derive(Parser)]
#[clap(version = "0.1", author = "Polytech Montpellier - DevOps")]
Expand Down Expand Up @@ -37,6 +37,9 @@ struct VMMOpts {
/// no-console
#[clap(long)]
no_console: bool,

#[clap(long)]
socket: bool,
}

#[derive(Debug)]
Expand All @@ -51,6 +54,32 @@ pub enum Error {
fn main() -> Result<(), Error> {
let opts: VMMOpts = VMMOpts::parse();

let console = opts.console.unwrap();
if opts.socket {
let path = Path::new(console.as_str());
if std::fs::metadata(path).is_ok() {
std::fs::remove_file(path).unwrap();
}

println!("Socket path: {}", path.to_str().unwrap());

let unix_listener = UnixListener::bind(path).unwrap();

std::thread::spawn(move || {
// read from socket
let (mut stream, _) = unix_listener.accept().unwrap();
let mut buffer = [0; 1024];
loop {
let n = stream.read(&mut buffer).unwrap();
if n == 0 {
break;
}
let s = String::from_utf8_lossy(&buffer[0..n]).to_string();
print!("{}", s);
}
});
}

// Create a new VMM
let mut vmm = VMM::new().map_err(Error::VmmNew)?;

Expand All @@ -63,21 +92,14 @@ fn main() -> Result<(), Error> {
opts.cpus,
opts.memory,
&opts.kernel,
opts.console,
Some(console),
opts.no_console,
opts.initramfs,
opts.net,
opts.socket,
)
.map_err(Error::VmmConfigure)?;

// To use Writer with serial device :
// * Create mpsc channel :
// let (tx, rx) = std::sync::mpsc::channel();
// * Create a new Writer
// let writer = Writer::new(tx);
// * Add the Writer when configuring the VMM
// * Use the rx receiver to read the data

// Run the VMM
vmm.run(opts.no_console).map_err(Error::VmmRun)?;

Expand Down
2 changes: 0 additions & 2 deletions src/vmm/src/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,7 @@ impl Vcpu {
// Call into KVM to launch (VMLAUNCH) or resume (VMRESUME) the virtual CPU.
// This is a blocking function, it only returns for either an error or a
// VM-Exit. In the latter case, we can inspect the exit reason.
println!("Before running vCPU {}...", self.index);
let run = self.vcpu_fd.run();
println!("After running vCPU {}...", self.index);

match run {
Ok(exit_reason) => match exit_reason {
Expand Down
20 changes: 7 additions & 13 deletions src/vmm/src/devices/mod.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
// SPDX-License-Identifier: Apache-2.0

use std::io::{Result, Write};
use std::sync::mpsc;
use std::os::unix::net::UnixStream;

pub(crate) mod net;
pub(crate) mod serial;

pub struct Writer {
tx: mpsc::Sender<String>,
unix_stream: UnixStream,
}

impl Write for Writer {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
if buf.len() > 0 && (buf[0] != 10 && buf[0] != 13) {
let s = String::from_utf8_lossy(buf).to_string();
self.tx.send(s).map_err(|_| {
std::io::Error::new(
std::io::ErrorKind::Other,
"Error while sending data to channel",
)
})?;
}
let s = String::from_utf8_lossy(buf).to_string();
let _ = &self.unix_stream.write(s.as_bytes()).unwrap();

Ok(buf.len())
}

Expand All @@ -30,7 +24,7 @@ impl Write for Writer {
}

impl Writer {
pub fn new(tx: mpsc::Sender<String>) -> Self {
Writer { tx }
pub fn new(unix_stream: UnixStream) -> Self {
Writer { unix_stream }
}
}
28 changes: 20 additions & 8 deletions src/vmm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::any::Any;
use std::fs::File;
use std::io::stdout;
use std::os::unix::io::AsRawFd;
use std::os::unix::net::UnixStream;
use std::os::unix::prelude::RawFd;
use std::sync::{Arc, Mutex};
use std::thread;
Expand Down Expand Up @@ -268,6 +269,7 @@ impl VMM {
&mut self,
console_path: Option<String>,
disable_console: bool,
is_socket: bool,
) -> Result<()> {
if disable_console {
return Ok(());
Expand All @@ -278,11 +280,23 @@ impl VMM {
.map_err(Error::Cmdline)?;

if let Some(console_path) = console_path {
// We create the file if it does not exist, else we open
let file = File::create(&console_path).map_err(Error::ConsoleError)?;
if is_socket {
println!("Connecting to socket: {}", console_path);
let unix_stream = UnixStream::connect(console_path).unwrap();

let mut serial = self.serial.lock().unwrap();
*serial = LumperSerial::new(Box::new(file)).map_err(Error::SerialCreation)?;
// create writer

let writer = Writer::new(unix_stream);
let mut serial = self.serial.lock().unwrap();

*serial = LumperSerial::new(Box::new(writer)).map_err(Error::SerialCreation)?;
} else {
// We create the file if it does not exist, else we open
let file = File::create(&console_path).map_err(Error::ConsoleError)?;

let mut serial = self.serial.lock().unwrap();
*serial = LumperSerial::new(Box::new(file)).map_err(Error::SerialCreation)?;
}
}

Ok(())
Expand Down Expand Up @@ -429,9 +443,6 @@ impl VMM {
}
}

console: Option<String>,
no_console: bool,

pub fn configure(
&mut self,
num_vcpus: u8,
Expand All @@ -441,8 +452,9 @@ impl VMM {
no_console: bool,
initramfs_path: Option<String>,
if_name: Option<String>,
is_socket: bool,
) -> Result<()> {
self.configure_console(console, no_console)?;
self.configure_console(console, no_console, is_socket)?;
self.configure_memory(mem_size_mb)?;
self.load_default_cmdline()?;

Expand Down

0 comments on commit dd57431

Please sign in to comment.