Skip to content

Commit

Permalink
WIP : Stop VM with multiple vCPU
Browse files Browse the repository at this point in the history
The VM should be stopped when threads stop
  • Loading branch information
alexis-langlet committed Mar 21, 2023
1 parent 854dd70 commit 4a1ed13
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
13 changes: 7 additions & 6 deletions src/vmm/src/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,20 +215,23 @@ impl Vcpu {
}

/// vCPU emulation loop.
pub fn run(&mut self, no_console: bool) -> bool {
pub fn run(&mut self, no_console: bool, should_stop: Arc<Mutex<bool>>) {
// 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.
let mut should_stop = false;
println!("Before running vCPU {}...", self.index);
let run = self.vcpu_fd.run();
println!("After running vCPU {}...", self.index);

match self.vcpu_fd.run() {
match run {
Ok(exit_reason) => match exit_reason {
// The VM stopped (Shutdown ot HLT).
VcpuExit::Shutdown | VcpuExit::Hlt => {
println!("Guest shutdown: {:?}. Bye!", exit_reason);

if no_console {
should_stop = true;
println!("Exiting... {:?}", self.index);
*should_stop.lock().unwrap() = true;
} else {
let stdin = io::stdin();
let stdin_lock = stdin.lock();
Expand Down Expand Up @@ -279,7 +282,5 @@ impl Vcpu {
},
Err(e) => eprintln!("Emulation error: {}", e),
}

should_stop
}
}
11 changes: 8 additions & 3 deletions src/vmm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,18 @@ impl VMM {
pub fn run(&mut self, no_console: bool) -> Result<()> {
let mut handlers = Vec::new();

let should_stop = Arc::new(Mutex::new(false));

for mut vcpu in self.vcpus.drain(..) {
println!("Starting vCPU {:?}", vcpu.index);
let handler = thread::Builder::new().spawn(move || loop {
let should_stop = vcpu.run(no_console.clone());
let should_stop_cloned = Arc::clone(&should_stop);

if should_stop {
let handler = thread::Builder::new().spawn(move || loop {
if *should_stop_cloned.lock().unwrap() {
println!("Stopping vCPU {:?}", vcpu.index);
break;
}
vcpu.run(no_console, Arc::clone(&should_stop_cloned));
});

handlers.push(handler);
Expand All @@ -242,6 +246,7 @@ impl VMM {
if no_console {
for handler in handlers {
handler.unwrap().join().unwrap(); // TODO: without unwrap
println!("catching handler");
}

println!("Program finished");
Expand Down

0 comments on commit 4a1ed13

Please sign in to comment.