Skip to content

Commit

Permalink
[libvirt] Implement forced stop.
Browse files Browse the repository at this point in the history
  • Loading branch information
luis4a0 committed Aug 16, 2022
1 parent 528d995 commit 69ebeca
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 22 deletions.
55 changes: 35 additions & 20 deletions src/platform/backends/libvirt/libvirt_virtual_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,38 +328,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<decltype(state_mutex)> 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();
Expand Down
4 changes: 2 additions & 2 deletions src/platform/backends/libvirt/libvirt_virtual_machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 69ebeca

Please sign in to comment.