From b572ebea5985f397f316bbd5050c3ab5ce9bd391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Fri, 28 May 2021 15:57:51 -0300 Subject: [PATCH] [libvirt] Implement forced stop. --- .../libvirt/libvirt_virtual_machine.cpp | 55 ++++++++++++------- .../libvirt/libvirt_virtual_machine.h | 4 +- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/platform/backends/libvirt/libvirt_virtual_machine.cpp b/src/platform/backends/libvirt/libvirt_virtual_machine.cpp index d4bbd5f5bc..e6e330766b 100644 --- a/src/platform/backends/libvirt/libvirt_virtual_machine.cpp +++ b/src/platform/backends/libvirt/libvirt_virtual_machine.cpp @@ -312,38 +312,53 @@ void mp::LibVirtVirtualMachine::start() monitor->on_resume(); } -void mp::LibVirtVirtualMachine::stop() +void mp::LibVirtVirtualMachine::stop(bool force) { - shutdown(); + shutdown(force); } -void mp::LibVirtVirtualMachine::shutdown() +void mp::LibVirtVirtualMachine::shutdown(bool force) { std::unique_lock lock{state_mutex}; auto domain = domain_by_name_for(vm_name, open_libvirt_connection(libvirt_wrapper).get(), libvirt_wrapper); - state = refresh_instance_state_for_domain(domain.get(), state, libvirt_wrapper); - if (state == State::running || state == State::delayed_shutdown || state == State::unknown) - { - if (!domain || libvirt_wrapper->virDomainShutdown(domain.get()) == -1) - { - auto warning_string{ - fmt::format("Cannot shutdown '{}': {}", vm_name, libvirt_wrapper->virGetLastErrorMessage())}; - mpl::log(mpl::Level::warning, vm_name, warning_string); - throw std::runtime_error(warning_string); - } - state = State::off; - update_state(); - } - else if (state == State::starting) + if (force) { + mpl::log(mpl::Level::info, vm_name, "Forced shutdown"); + + auto domain = domain_by_name_for(vm_name, open_libvirt_connection(libvirt_wrapper).get(), libvirt_wrapper); + libvirt_wrapper->virDomainDestroy(domain.get()); - state_wait.wait(lock, [this] { return shutdown_while_starting; }); + + state = State::off; update_state(); } - else if (state == State::suspended) + else { - mpl::log(mpl::Level::info, vm_name, fmt::format("Ignoring shutdown issued while suspended")); + state = refresh_instance_state_for_domain(domain.get(), state, libvirt_wrapper); + if (state == State::running || state == State::delayed_shutdown || state == State::unknown) + { + if (!domain || libvirt_wrapper->virDomainShutdown(domain.get()) == -1) + { + auto warning_string{ + fmt::format("Cannot shutdown '{}': {}", vm_name, libvirt_wrapper->virGetLastErrorMessage())}; + mpl::log(mpl::Level::warning, vm_name, warning_string); + throw std::runtime_error(warning_string); + } + + state = State::off; + update_state(); + } + else if (state == State::starting) + { + libvirt_wrapper->virDomainDestroy(domain.get()); + state_wait.wait(lock, [this] { return shutdown_while_starting; }); + update_state(); + } + else if (state == State::suspended) + { + mpl::log(mpl::Level::info, vm_name, fmt::format("Ignoring shutdown issued while suspended")); + } } lock.unlock(); diff --git a/src/platform/backends/libvirt/libvirt_virtual_machine.h b/src/platform/backends/libvirt/libvirt_virtual_machine.h index ca0bdf38e9..5ee70b4aa2 100644 --- a/src/platform/backends/libvirt/libvirt_virtual_machine.h +++ b/src/platform/backends/libvirt/libvirt_virtual_machine.h @@ -40,8 +40,8 @@ class LibVirtVirtualMachine final : public BaseVirtualMachine ~LibVirtVirtualMachine(); void start() override; - void stop() override; - void shutdown() override; + void stop(bool force = false) override; + void shutdown(bool force = false) override; void suspend() override; State current_state() override; int ssh_port() override;