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>
Ben Hillis committed
Oct 7, 2025 at 15:37 UTC
05d6129c4fca74b29132fb7c78fe7e4d3b4d37c1
2 files changed
+57
-16
src/linux/init/init.cpp
+51
-14
@@ -129,6 +129,8 @@ void InitEntryUtilityVm(wsl::linux::WslDistributionConfig& Config);
129
130
void InitTerminateInstance(gsl::span<gsl::byte> Buffer, wsl::shared::SocketChannel& Channel, wsl::linux::WslDistributionConfig& Config);
131
132
+void InitTerminateInstanceInternal(const wsl::linux::WslDistributionConfig& Config);
133
+
134
void InstallSystemdUnit(const char* Path, const std::string& Name, const char* Content);
135
136
int GenerateSystemdUnits(int Argc, char** Argv);
@@ -2507,18 +2509,7 @@ Return Value:
2509
}
2510
}
2511
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);
2513
return;
2514
}
2515
@@ -2661,10 +2652,56 @@ try
2652
}
2653
2654
//
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.
2657
//
2658
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);
2705
}
2706
CATCH_LOG();
2707
src/windows/service/exe/WslCoreInstance.cpp
+6
-2
@@ -477,8 +477,12 @@ bool WslCoreInstance::RequestStop(_In_ bool Force)
477
terminateMessage.Header.MessageSize = sizeof(terminateMessage);
478
terminateMessage.Force = Force;
479
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
+ }
486
}
487
CATCH_LOG()
488