Skip to content

Commit 61e6b9a

Browse files
chemwolf6922Feng WangCopilot
authored
Fix wsl stuck when misconfigured cifs mount presents (#14466)
* detach terminal before running mount -a * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * use _exit on error before execv in child process to avoid unintentional resource release * Add regression test * Fix clang format issue * fix all clang format issue * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * resolve ai comments * move test to unit test * Fix string literal * Overwrite fstab to resolve pipeline missing file issue --------- Co-authored-by: Feng Wang <wangfen@microsoft.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent d7ff5b9 commit 61e6b9a

4 files changed

Lines changed: 45 additions & 5 deletions

File tree

src/linux/init/config.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2137,7 +2137,7 @@ Return Value:
21372137
//
21382138

21392139
const char* const Argv[] = {MOUNT_COMMAND, MOUNT_FSTAB_ARG, nullptr};
2140-
if (UtilCreateProcessAndWait(Argv[0], Argv, nullptr, {{WSL_DRVFS_ELEVATED_ENV, Elevated ? "1" : "0"}}) < 0)
2140+
if (UtilCreateProcessAndWait(Argv[0], Argv, nullptr, {{WSL_DRVFS_ELEVATED_ENV, Elevated ? "1" : "0"}}, true) < 0)
21412141
{
21422142
auto message = wsl::shared::Localization::MessageFstabMountFailed();
21432143
LOG_ERROR("{}", message.c_str());

src/linux/init/util.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ Return Value:
613613
return SocketFd;
614614
}
615615

616-
int UtilCreateProcessAndWait(const char* const File, const char* const Argv[], int* Status, const std::map<std::string, std::string>& Env)
616+
int UtilCreateProcessAndWait(const char* const File, const char* const Argv[], int* Status, const std::map<std::string, std::string>& Env, bool DetachTerminal)
617617

618618
/*++
619619
@@ -630,6 +630,9 @@ Routine Description:
630630
Status - Supplies an optional pointer that receives the exit status of the
631631
process.
632632
633+
DetachTerminal - Supplies a boolean that, when true, calls setsid() in the
634+
child process to detach it from the controlling terminal.
635+
633636
Return Value:
634637
635638
0 on success, -1 on failure.
@@ -664,7 +667,7 @@ Return Value:
664667

665668
if (UtilSetSignalHandlers(g_SavedSignalActions, false) < 0 || UtilRestoreBlockedSignals() < 0)
666669
{
667-
exit(-1);
670+
_exit(-1);
668671
}
669672

670673
//
@@ -676,6 +679,19 @@ Return Value:
676679
setenv(e.first.c_str(), e.second.c_str(), 1);
677680
}
678681

682+
//
683+
// Detach from the controlling terminal if requested.
684+
//
685+
686+
if (DetachTerminal)
687+
{
688+
if (setsid() == -1)
689+
{
690+
LOG_ERROR("setsid failed {}", errno);
691+
_exit(-1);
692+
}
693+
}
694+
679695
//
680696
// Invoke the executable.
681697
//
@@ -686,7 +702,7 @@ Return Value:
686702
// with std::string anyway.
687703
execv(File, const_cast<char* const*>(Argv));
688704
LOG_ERROR("execv({}) failed with {}", File, errno);
689-
exit(-1);
705+
_exit(-1);
690706
}
691707

692708
if (Status == nullptr)

src/linux/init/util.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ Return Value:
191191
_exit(1);
192192
}
193193

194-
int UtilCreateProcessAndWait(const char* File, const char* const Argv[], int* Status = nullptr, const std::map<std::string, std::string>& Env = {});
194+
int UtilCreateProcessAndWait(
195+
const char* File, const char* const Argv[], int* Status = nullptr, const std::map<std::string, std::string>& Env = {}, bool DetachTerminal = false);
195196

196197
template <typename TMethod>
197198
void UtilCreateWorkerThread(const char* Name, TMethod&& ThreadFunction)

test/windows/UnitTests.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6539,5 +6539,28 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
65396539
VERIFY_ARE_EQUAL(err, L"");
65406540
}
65416541

6542+
TEST_METHOD(InteractiveMount)
6543+
{
6544+
WSL2_TEST_ONLY();
6545+
6546+
// Add a fake interactive mount helper.
6547+
DistroFileChange mountHelper(L"/sbin/mount.hang", false);
6548+
mountHelper.SetContent(
6549+
L"#!/bin/sh\n"
6550+
L"read pass < /dev/tty\n");
6551+
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"chmod +x /sbin/mount.hang"), (DWORD)0);
6552+
6553+
// Don't keep the original fstab as it can be missing on the pipeline.
6554+
DistroFileChange fstab(L"/etc/fstab", false);
6555+
fstab.SetContent(L"none /mnt/ttytest hang 0 0\n");
6556+
6557+
// Restart the distro with this mount.
6558+
WslShutdown();
6559+
wsl::windows::common::SubProcess process(nullptr, LxssGenerateWslCommandLine(L"echo booted").c_str());
6560+
auto result = process.RunAndCaptureOutput(60 * 1000);
6561+
VERIFY_ARE_EQUAL(result.Stdout, L"booted\n");
6562+
VERIFY_ARE_EQUAL(result.ExitCode, 0);
6563+
}
6564+
65426565
}; // namespace UnitTests
65436566
} // namespace UnitTests

0 commit comments

Comments
 (0)