Skip to content

Commit 05d6129

Browse files
benhillisBen Hillis
andauthored
Implement clean instance terminate when using systemd (#13552)
* Implement clean instance terminate when using systemd * pr feedback * more pr feedback --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
1 parent 491d8d5 commit 05d6129

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

src/linux/init/init.cpp

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ void InitEntryUtilityVm(wsl::linux::WslDistributionConfig& Config);
129129

130130
void InitTerminateInstance(gsl::span<gsl::byte> Buffer, wsl::shared::SocketChannel& Channel, wsl::linux::WslDistributionConfig& Config);
131131

132+
void InitTerminateInstanceInternal(const wsl::linux::WslDistributionConfig& Config);
133+
132134
void InstallSystemdUnit(const char* Path, const std::string& Name, const char* Content);
133135

134136
int GenerateSystemdUnits(int Argc, char** Argv);
@@ -2507,18 +2509,7 @@ Return Value:
25072509
}
25082510
}
25092511

2510-
//
2511-
// If the distro init process was booted, use the shutdown command to terminate the instance.
2512-
//
2513-
2514-
if (Config.BootInit && !Config.BootStartWriteSocket)
2515-
{
2516-
UtilExecCommandLine("systemctl reboot", nullptr);
2517-
}
2518-
2519-
reboot(RB_POWER_OFF);
2520-
FATAL_ERROR("reboot(RB_POWER_OFF) failed {}", errno);
2521-
2512+
InitTerminateInstanceInternal(Config);
25222513
return;
25232514
}
25242515

@@ -2661,10 +2652,56 @@ try
26612652
}
26622653

26632654
//
2664-
// Respond to the instance termination request.
2655+
// Attempt to stop the plan9 server, if it is not able to be stopped because of an
2656+
// in-use file, reply to the service that the instance could not be terminated.
26652657
//
26662658

2667-
Channel.SendResultMessage<bool>(StopPlan9Server(Message->Force, Config));
2659+
if (!StopPlan9Server(Message->Force, Config))
2660+
{
2661+
Channel.SendResultMessage<bool>(false);
2662+
return;
2663+
}
2664+
2665+
InitTerminateInstanceInternal(Config);
2666+
}
2667+
CATCH_LOG();
2668+
2669+
void InitTerminateInstanceInternal(const wsl::linux::WslDistributionConfig& Config)
2670+
2671+
/*++
2672+
2673+
Routine Description:
2674+
2675+
This routine attempts to cleanly terminate the instance.
2676+
2677+
Arguments:
2678+
2679+
Config - Supplies the distribution config.
2680+
2681+
Return Value:
2682+
2683+
None.
2684+
2685+
--*/
2686+
try
2687+
{
2688+
//
2689+
// If systemd is enabled, attempt to poweroff the instance via systemctl.
2690+
//
2691+
2692+
if (Config.BootInit && !Config.BootStartWriteSocket)
2693+
{
2694+
THROW_LAST_ERROR_IF(UtilSetSignalHandlers(g_SavedSignalActions, false) < 0);
2695+
2696+
if (UtilExecCommandLine("systemctl poweroff", nullptr) == 0)
2697+
{
2698+
std::this_thread::sleep_for(std::chrono::milliseconds(Config.BootInitTimeout));
2699+
LOG_ERROR("systemctl poweroff did not terminate the instance in {} ms, calling reboot(RB_POWER_OFF)", Config.BootInitTimeout);
2700+
}
2701+
}
2702+
2703+
reboot(RB_POWER_OFF);
2704+
FATAL_ERROR("reboot(RB_POWER_OFF) failed {}", errno);
26682705
}
26692706
CATCH_LOG();
26702707

src/windows/service/exe/WslCoreInstance.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,12 @@ bool WslCoreInstance::RequestStop(_In_ bool Force)
477477
terminateMessage.Header.MessageSize = sizeof(terminateMessage);
478478
terminateMessage.Force = Force;
479479

480-
const auto& terminateResponse = m_initChannel->GetChannel().Transaction(terminateMessage, nullptr, m_socketTimeout);
481-
shutdown = terminateResponse.Result;
480+
m_initChannel->GetChannel().SendMessage(terminateMessage);
481+
auto [message, span] = m_initChannel->GetChannel().ReceiveMessageOrClosed<RESULT_MESSAGE<bool>>(m_socketTimeout);
482+
if (message)
483+
{
484+
shutdown = message->Result;
485+
}
482486
}
483487
CATCH_LOG()
484488

0 commit comments

Comments
 (0)