From 4a1ed13e764ce904947ccaf3c5c9962b570ec8e6 Mon Sep 17 00:00:00 2001 From: Alexis Langlet Date: Tue, 21 Mar 2023 13:53:40 +0100 Subject: [PATCH] WIP : Stop VM with multiple vCPU The VM should be stopped when threads stop --- src/vmm/src/cpu/mod.rs | 13 +++++++------ src/vmm/src/lib.rs | 11 ++++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/vmm/src/cpu/mod.rs b/src/vmm/src/cpu/mod.rs index 4310bc8..dcadd67 100644 --- a/src/vmm/src/cpu/mod.rs +++ b/src/vmm/src/cpu/mod.rs @@ -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>) { // 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(); @@ -279,7 +282,5 @@ impl Vcpu { }, Err(e) => eprintln!("Emulation error: {}", e), } - - should_stop } } diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index b84df2d..7a8f2b3 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -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); @@ -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");