mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-10 00:44:55 -06:00
Merge merge into feature/wsl-for-apps
This commit is contained in:
parent
f2bd6d60bc
commit
9d505519ea
@ -34,8 +34,8 @@ FetchContent_GetProperties(GSL SOURCE_DIR GSL_SOURCE_DIR)
|
||||
|
||||
|
||||
FetchContent_Declare(nlohmannjson
|
||||
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz
|
||||
URL_HASH SHA256=d6c65aca6b1ed68e7a182f4757257b107ae403032760ed6ef121c9d55e81757d)
|
||||
URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz
|
||||
URL_HASH SHA256=42f6e95cad6ec532fd372391373363b62a14af6d771056dbfc86160e6dfff7aa )
|
||||
|
||||
FetchContent_MakeAvailable(nlohmannjson)
|
||||
FetchContent_GetProperties(nlohmannjson SOURCE_DIR NLOHMAN_JSON_SOURCE_DIR)
|
||||
|
||||
186
NOTICE.txt
186
NOTICE.txt
@ -1762,192 +1762,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
---------------------------------------------------------
|
||||
|
||||
---------------------------------------------------------
|
||||
|
||||
Microsoft.NETCore.App.Runtime.win-arm64 9.0.8 - MIT
|
||||
|
||||
|
||||
Copyright (c) 2021
|
||||
Copyright (c) Six Labors
|
||||
(c) Microsoft Corporation
|
||||
Copyright (c) 2022 FormatJS
|
||||
Copyright (c) Andrew Arnott
|
||||
Copyright 2019 LLVM Project
|
||||
Copyright (c) 1998 Microsoft
|
||||
Copyright 2018 Daniel Lemire
|
||||
Copyright (c) .NET Foundation
|
||||
Copyright 1995-2022 Mark Adler
|
||||
Copyright 1995-2024 Mark Adler
|
||||
Copyright (c) 2011, Google Inc.
|
||||
Copyright (c) 2020 Dan Shechter
|
||||
(c) 1997-2005 Sean Eron Anderson
|
||||
Copyright (c) 2015 Andrew Gallant
|
||||
Copyright (c) 2022, Wojciech Mula
|
||||
Copyright (c) 2017 Yoshifumi Kawai
|
||||
Copyright (c) 2022, Geoff Langdale
|
||||
Copyright (c) 2005-2020 Rich Felker
|
||||
Copyright (c) 2012-2021 Yann Collet
|
||||
Copyright (c) Microsoft Corporation
|
||||
Copyright (c) 2007 James Newton-King
|
||||
Copyright (c) 1991-2022 Unicode, Inc.
|
||||
Copyright (c) 2013-2017, Alfred Klomp
|
||||
Copyright (c) 2018 Nemanja Mijailovic
|
||||
Copyright 2012 the V8 project authors
|
||||
Copyright (c) 1999 Lucent Technologies
|
||||
Copyright (c) 2008-2016, Wojciech Mula
|
||||
Copyright (c) 2011-2020 Microsoft Corp
|
||||
Copyright (c) 2015-2017, Wojciech Mula
|
||||
Copyright (c) 2015-2018, Wojciech Mula
|
||||
Copyright (c) 2005-2007, Nick Galbreath
|
||||
Copyright (c) 2015 The Chromium Authors
|
||||
Copyright (c) 2018 Alexander Chermyanin
|
||||
Copyright (c) The Internet Society 1997
|
||||
Copyright (c) 2004-2006 Intel Corporation
|
||||
Copyright (c) 2011-2015 Intel Corporation
|
||||
Copyright (c) 2013-2017, Milosz Krajewski
|
||||
Copyright (c) 2016-2017, Matthieu Darbois
|
||||
Copyright (c) The Internet Society (2003)
|
||||
Copyright (c) .NET Foundation Contributors
|
||||
(c) 1995-2024 Jean-loup Gailly and Mark Adler
|
||||
Copyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>
|
||||
Copyright (c) .NET Foundation and Contributors
|
||||
Copyright (c) 2012 - present, Victor Zverovich
|
||||
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
|
||||
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
|
||||
Copyright (c) 2019 Microsoft Corporation, Daan Leijen
|
||||
Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
||||
Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
|
||||
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
|
||||
Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
|
||||
Copyright 1995-2024 Jean-loup Gailly and Mark Adler Qkkbal
|
||||
Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
||||
Portions (c) International Organization for Standardization 1986
|
||||
Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
|
||||
Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
|
||||
Copyright (c) 1980, 1986, 1993 The Regents of the University of California
|
||||
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
|
||||
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) .NET Foundation and Contributors
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
---------------------------------------------------------
|
||||
|
||||
---------------------------------------------------------
|
||||
|
||||
Microsoft.NETCore.App.Runtime.win-x64 9.0.8 - MIT
|
||||
|
||||
|
||||
Copyright (c) 2021
|
||||
Copyright (c) Six Labors
|
||||
(c) Microsoft Corporation
|
||||
Copyright (c) 2022 FormatJS
|
||||
Copyright (c) Andrew Arnott
|
||||
Copyright 2019 LLVM Project
|
||||
Copyright (c) 1998 Microsoft
|
||||
Copyright 2018 Daniel Lemire
|
||||
Copyright (c) .NET Foundation
|
||||
Copyright 1995-2022 Mark Adler
|
||||
Copyright 1995-2024 Mark Adler
|
||||
Copyright (c) 2011, Google Inc.
|
||||
Copyright (c) 2020 Dan Shechter
|
||||
(c) 1997-2005 Sean Eron Anderson
|
||||
Copyright (c) 2015 Andrew Gallant
|
||||
Copyright (c) 2022, Wojciech Mula
|
||||
Copyright (c) 2017 Yoshifumi Kawai
|
||||
Copyright (c) 2022, Geoff Langdale
|
||||
Copyright (c) 2005-2020 Rich Felker
|
||||
Copyright (c) 2012-2021 Yann Collet
|
||||
Copyright (c) Microsoft Corporation
|
||||
Copyright (c) 2007 James Newton-King
|
||||
Copyright (c) 1991-2022 Unicode, Inc.
|
||||
Copyright (c) 2013-2017, Alfred Klomp
|
||||
Copyright (c) 2018 Nemanja Mijailovic
|
||||
Copyright 2012 the V8 project authors
|
||||
Copyright (c) 1999 Lucent Technologies
|
||||
Copyright (c) 2008-2016, Wojciech Mula
|
||||
Copyright (c) 2011-2020 Microsoft Corp
|
||||
Copyright (c) 2015-2017, Wojciech Mula
|
||||
Copyright (c) 2015-2018, Wojciech Mula
|
||||
Copyright (c) 2005-2007, Nick Galbreath
|
||||
Copyright (c) 2015 The Chromium Authors
|
||||
Copyright (c) 2018 Alexander Chermyanin
|
||||
Copyright (c) The Internet Society 1997
|
||||
Copyright (c) 2004-2006 Intel Corporation
|
||||
Copyright (c) 2011-2015 Intel Corporation
|
||||
Copyright (c) 2013-2017, Milosz Krajewski
|
||||
Copyright (c) 2016-2017, Matthieu Darbois
|
||||
Copyright (c) The Internet Society (2003)
|
||||
Copyright (c) .NET Foundation Contributors
|
||||
(c) 1995-2024 Jean-loup Gailly and Mark Adler
|
||||
Copyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>
|
||||
Copyright (c) .NET Foundation and Contributors
|
||||
Copyright (c) 2012 - present, Victor Zverovich
|
||||
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
|
||||
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
|
||||
Copyright (c) 2019 Microsoft Corporation, Daan Leijen
|
||||
Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
||||
Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
|
||||
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
|
||||
Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
|
||||
Copyright 1995-2024 Jean-loup Gailly and Mark Adler Qkkbal
|
||||
Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
||||
Portions (c) International Organization for Standardization 1986
|
||||
Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
|
||||
Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
|
||||
Copyright (c) 1980, 1986, 1993 The Regents of the University of California
|
||||
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
|
||||
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) .NET Foundation and Contributors
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
---------------------------------------------------------
|
||||
|
||||
---------------------------------------------------------
|
||||
|
||||
@ -21,6 +21,10 @@ if ($LogProfile -eq $null -Or ![System.IO.File]::Exists($LogProfile))
|
||||
{
|
||||
$url = "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/wsl_storage.wprp"
|
||||
}
|
||||
elseif ($LogProfile -eq "hvsocket")
|
||||
{
|
||||
$url = "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/wsl_hvsocket.wprp"
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Error "Unknown log profile: $LogProfile"
|
||||
@ -52,6 +56,8 @@ if (Test-Path $wslconfig)
|
||||
Copy-Item $wslconfig $folder | Out-Null
|
||||
}
|
||||
|
||||
Copy-Item "C:\Windows\temp\wsl-install-log.txt" $folder -ErrorAction ignore
|
||||
|
||||
get-appxpackage MicrosoftCorporationII.WindowsSubsystemforLinux -ErrorAction Ignore > $folder/appxpackage.txt
|
||||
get-acl "C:\ProgramData\Microsoft\Windows\WindowsApps" -ErrorAction Ignore | Format-List > $folder/acl.txt
|
||||
Get-WindowsOptionalFeature -Online > $folder/optional-components.txt
|
||||
|
||||
172
diagnostics/wsl_hvsocket.wprp
Normal file
172
diagnostics/wsl_hvsocket.wprp
Normal file
@ -0,0 +1,172 @@
|
||||
<?xml version="1.0"?>
|
||||
<WindowsPerformanceRecorder Version="1">
|
||||
<Profiles>
|
||||
<EventCollector Id="Collector" Name="Collector">
|
||||
<BufferSize Value="512" />
|
||||
<Buffers Value="10" PercentageOfTotalMemory="true"/>
|
||||
</EventCollector>
|
||||
|
||||
<EventProvider Id="EventProvider_HvSocketTraceProvider" Name="B2ED3BDB-CD74-5B2C-F660-85079CA074B3" NonPagedMemory="true">
|
||||
<Keywords>
|
||||
<Keyword Value="0x0"/>
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
|
||||
<EventProvider Id="lxcore_kernel" Name="0CD1C309-0878-4515-83DB-749843B3F5C9"/>
|
||||
<EventProvider Id="lxcore_user" Name="D90B9468-67F0-5B3B-42CC-82AC81FFD960"/>
|
||||
<EventProvider Id="lxcore_service" Name="B99CDB5A-039C-5046-E672-1A0DE0A40211"/>
|
||||
<EventProvider Id="wsl_devicehost" Name="9d6c7b9e-2581-4d8a-b8c5-b90b4a17094a"/>
|
||||
<EventProvider Id="wslclient" Name="8cbb7724-7223-5d6f-8137-564dac45104d"/>
|
||||
<EventProvider Id="wslapi" Name="beb94edf-1a7b-5058-0696-ff9e6b1798d1"/>
|
||||
<EventProvider Id="vm_chipset" Name="de9ba731-7f33-4f44-98c9-6cac856b9f83"/>
|
||||
<EventProvider Id="vmcompute_dll" Name="AF7FD3A7-B248-460C-A9F5-FEC39EF8468C"/>
|
||||
<EventProvider Id="vmcompute" Name="17103E3F-3C6E-4677-BB17-3B267EB5BE57"/>
|
||||
<EventProvider Id="vmmm" Name="6066F867-7CA1-4418-85FD-36E3F9C0600C"/>
|
||||
<EventProvider Id="vmwp" Name="51DDFA29-D5C8-4803-BE4B-2ECB715570FE"/>
|
||||
<EventProvider Id="9p" Name="e13c8d52-b153-571f-78c5-1d4098af2a1e"/>
|
||||
<EventProvider Id="9p_errors" Name="06C601B3-6957-4F8C-A15F-74875B24429D" />
|
||||
<EventProvider Id="p9rdr" Name="bb1d36f0-e0e0-48cc-9493-fef0e3d0b28c" />
|
||||
<EventProvider Id="mup" Name="20c46239-d059-4214-a11e-7d6769cbe020" />
|
||||
<EventProvider Id="rfsmon" Name="51734B23-5B7E-4892-BA8E-45BC110B735C" />
|
||||
<EventProvider Id="hyperv_storage" Name="c7ad62c6-5c99-5a1b-bbc4-0821ae5b765e" />
|
||||
<EventProvider Id="hns" Name="0c885e0d-6eb6-476c-a048-2457eed3a5c1" />
|
||||
<EventProvider Id="netmgmt" Name="93f693dc-9163-4dee-af64-d855218af242" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Mobile.Provisioning.AppDownload" Name="0BBE6221-EF09-4A3F-82EE-BE00DBB6A98A" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Mobile.Provisioning.Datastore" Name="42C60CEA-0FE7-4541-A86B-9E11F95BD9BF" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Mobile.Provisioning.PhoneProvisioner" Name="B876B1FC-C7F1-443E-9012-86677F7DE580" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Mobile.Provisioning.PPOEM" Name="7EDBED09-1FF7-4FEE-B8C3-5DB694420830" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.API" Name="82ADD491-01D7-4B85-9EAD-192C3CAACA23" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.CSP" Name="16E12400-A2D8-44B7-9479-004568EC7819" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Engine" Name="A6A847B7-4429-49AA-BBA6-2AD8C191AC8C" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Handlers" Name="0383D92C-2337-4F25-A0B5-A51767F04746" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Migration" Name="A0AF985E-83F9-4E1A-B658-338DCFE27893" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Operations" Name="7F99598F-B2C1-4371-9911-63DEE13B9EB1" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Platform" Name="B1F30020-8BC3-4888-BB1B-4DD681F24209" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Plugin.Engine" Name="55239D60-0EB6-495B-874E-15DE5D5F9A70" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Plugin.RemovableMedia" Name="B55883E6-6C45-45C2-AB9D-800BB7B66B13" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.ProvTool" Name="2BF4B6BA-556E-4D05-8534-CAFEDF19FED8" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.CommandCsp" Name="00BB69FC-60BC-4502-9438-25608F375CCB" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.ProvLaunch" Name="08FACCFA-125D-4ED6-B0B7-B4A1A912E693" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.EMPS.Enrollment" Name="E74EFD1A-B62D-4B83-AB00-66F4A166A2D3" />
|
||||
<EventProvider Id="EventProvider_Microsoft.Windows.EnterpriseManagement.Enrollment" Name="F9E3B648-9AF1-4DC3-9A8E-BF42C0FBCE9A" />
|
||||
<EventProvider Id="Microsoft.Windows.HyperV.Vid" Name="1111450B-DACC-40A3-84AB-F7DBA4A6E63A" NonPagedMemory="true"/>
|
||||
<EventProvider Id="Microsoft-Windows-HyperV-Vid" Name="5931D877-4860-4ee7-A95C-610A5F0D1407" NonPagedMemory="true" />
|
||||
<EventProvider Id="virtdisk_wpp" Name="e14dcdd9-d1ec-4dc3-8395-a606df8ef115" Level="4">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFF" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<EventProvider Id="virtdisk" Name="4D20DF22-E177-4514-A369-F1759FEEDEB3" Level="4">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFF" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<EventProvider Id="vhdmp" Name="E2816346-87F4-4F85-95C3-0C79409AA89D" NonPagedMemory="true" Level="4">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFD" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<EventProvider Id="vhdmp_wpp" Name="3c70c3b0-2fae-41d3-b68d-8f7fcaf79adb" NonPagedMemory="true" Level="5">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFF" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<EventProvider Id="storvsp" Name="10b3d268-9782-49a4-aacc-a93c5482cb6f" NonPagedMemory="true" Level="4">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFF" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<EventProvider Id="HyperV_SyntheticStorage" Name="EDACD782-2564-4497-ADE6-7199377850F2" Level="6">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFF" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<EventProvider Id="HyperV_EmulatedStorage" Name="86E15E01-EDF1-4AC7-89CF-B19563FD6894" Level="6">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFF" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<EventProvider Id="EventProvider_Telemetry_StorVSP" Name="544d0787-9f6d-432e-8414-e035a8b0541d">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFF" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<EventProvider Id="EventProvider_Trace_Vhdmp" Name="dc284fb3-1eab-4854-828a-b25417280280" Level="3">
|
||||
<Keywords>
|
||||
<Keyword Value="0xFFFFFFFFFFFFFFFF" />
|
||||
</Keywords>
|
||||
</EventProvider>
|
||||
|
||||
<Profile
|
||||
Id="WSL.Verbose.File"
|
||||
Name="WSL"
|
||||
Description="Traces for all WSL components"
|
||||
LoggingMode="File"
|
||||
DetailLevel="Verbose"
|
||||
>
|
||||
<Collectors>
|
||||
<EventCollectorId Value="Collector">
|
||||
<EventProviders>
|
||||
<EventProviderId Value="lxcore_kernel"/>
|
||||
<EventProviderId Value="lxcore_user"/>
|
||||
<EventProviderId Value="lxcore_service"/>
|
||||
<EventProviderId Value="wsl_devicehost"/>
|
||||
<EventProviderId Value="wslclient"/>
|
||||
<EventProviderId Value="wslapi"/>
|
||||
<EventProviderId Value="vm_chipset"/>
|
||||
<EventProviderId Value="vmcompute_dll"/>
|
||||
<EventProviderId Value="vmcompute"/>
|
||||
<EventProviderId Value="vmmm"/>
|
||||
<EventProviderId Value="vmwp"/>
|
||||
<EventProviderId Value="9p"/>
|
||||
<EventProviderId Value="9p_errors"/>
|
||||
<EventProviderId Value="p9rdr"/>
|
||||
<EventProviderId Value="mup"/>
|
||||
<EventProviderId Value="rfsmon"/>
|
||||
<EventProviderId Value="hyperv_storage"/>
|
||||
<EventProviderId Value="hns"/>
|
||||
<EventProviderId Value="netmgmt"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Mobile.Provisioning.AppDownload"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Mobile.Provisioning.Datastore"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Mobile.Provisioning.PhoneProvisioner"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Mobile.Provisioning.PPOEM"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.CSP"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Engine"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Migration"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Platform"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Operations"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Plugin.Engine"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Plugin.RemovableMedia"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.ProvTool"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Operations"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.CommandCsp"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.ProvLaunch"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.EMPS.Enrollment"/>
|
||||
<EventProviderId Value="EventProvider_Microsoft.Windows.EnterpriseManagement.Enrollment"/>
|
||||
<EventProviderId Value="Microsoft.Windows.HyperV.Vid"/>
|
||||
<EventProviderId Value="Microsoft-Windows-HyperV-Vid"/>
|
||||
<EventProviderId Value="virtdisk"/>
|
||||
<EventProviderId Value="virtdisk_wpp"/>
|
||||
<EventProviderId Value="vhdmp"/>
|
||||
<EventProviderId Value="vhdmp_wpp"/>
|
||||
<EventProviderId Value="storvsp"/>
|
||||
<EventProviderId Value="HyperV_SyntheticStorage"/>
|
||||
<EventProviderId Value="HyperV_EmulatedStorage"/>
|
||||
<EventProviderId Value="EventProvider_Telemetry_StorVSP"/>
|
||||
<EventProviderId Value="EventProvider_Trace_Vhdmp"/>
|
||||
<EventProviderId Value="EventProvider_HvSocketTraceProvider" />
|
||||
</EventProviders>
|
||||
</EventCollectorId>
|
||||
</Collectors>
|
||||
</Profile>
|
||||
</Profiles>
|
||||
</WindowsPerformanceRecorder>
|
||||
@ -43,16 +43,16 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "openSUSE-Leap-15.6",
|
||||
"FriendlyName": "openSUSE Leap 15.6",
|
||||
"Name": "openSUSE-Leap-16.0",
|
||||
"FriendlyName": "openSUSE Leap 16.0",
|
||||
"Default": false,
|
||||
"Amd64Url": {
|
||||
"Url": "https://github.com/openSUSE/WSL-instarball/releases/download/v20250320.0/openSUSE-Leap-15.6-15.6.x86_64-15.2-Build15.2.wsl",
|
||||
"Sha256": "0x63ea1828168026c86522743d551b2c88f0f4f94d813d2adc5881164d176b0ea1"
|
||||
"Url": "https://github.com/openSUSE/WSL-instarball/releases/download/v20251001.0/openSUSE-Leap-16.0-16.0.x86_64-22.57-Build22.57.wsl",
|
||||
"Sha256": "0x0d1faa095153beee0a9b5089b0f9aa3d2aec95e2cdcffdeeff84dd54c48b8393"
|
||||
},
|
||||
"Arm64Url": {
|
||||
"Url": "https://github.com/openSUSE/WSL-instarball/releases/download/v20250320.0/openSUSE-Leap-15.6-15.6.aarch64-15.2-Build15.2.wsl",
|
||||
"Sha256": "0x0a3c646f69bb83889c4264e41030076104a2f3d71ae6a1e14a1e0653dfd2e3d4"
|
||||
"Url": "https://github.com/openSUSE/WSL-instarball/releases/download/v20251001.0/openSUSE-Leap-16.0-16.0.aarch64-22.57-Build22.57.wsl",
|
||||
"Sha256": "0x91bcdc7e9f42d7a60a4464ad867d91243aaaecab7b3a057039f77a989daac51e"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -166,8 +166,8 @@
|
||||
"FriendlyName": "Arch Linux",
|
||||
"Default": true,
|
||||
"Amd64Url": {
|
||||
"Url": "https://geo.mirror.pkgbuild.com/wsl/2025.09.01.145298/archlinux-2025.09.01.145298.wsl",
|
||||
"Sha256": "9b011093c7ad5d0dccd0be785c9d968c30b4fce3957f3f1868f2c1c4415ae841"
|
||||
"Url": "https://geo.mirror.pkgbuild.com/wsl/2025.10.01.148042/archlinux-2025.10.01.148042.wsl",
|
||||
"Sha256": "98a5792935c46476f471854bc93344b2b1d63f7947905ce4dd75d20a546db7ea"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@ -33,7 +33,8 @@ DISCOURAGED_SYSTEM_UNITS = ['systemd-resolved.service',
|
||||
'systemd-tmpfiles-setup-dev.service',
|
||||
'tmp.mount',
|
||||
'NetworkManager.service',
|
||||
'networking.service']
|
||||
'networking.service',
|
||||
'hypervkvpd.service']
|
||||
|
||||
WSL1_UNSUPPORTED_XATTRS = ['security.selinux', 'security.ima', 'security.evm']
|
||||
|
||||
|
||||
@ -1108,7 +1108,7 @@ Error code: {}</value>
|
||||
<data name="MessageSparseVhdDisabled" xml:space="preserve">
|
||||
<value>Sparse VHD support is currently disabled due to potential data corruption.
|
||||
To force a distribution to use a sparse vhd, please run:
|
||||
wsl.exe --manage <DistributionName> --set-sparse --allow-unsafe</value>
|
||||
wsl.exe --manage <DistributionName> --set-sparse true --allow-unsafe</value>
|
||||
<comment>{Locked="--manage "}{Locked="--set-sparse "}{Locked="--allow-unsafe"}Command line arguments, file names and string inserts should not be translated</comment>
|
||||
</data>
|
||||
<data name="MessageDrvfsMountFailed" xml:space="preserve">
|
||||
|
||||
@ -430,6 +430,14 @@
|
||||
Execute="deferred"
|
||||
/>
|
||||
|
||||
<CustomAction Id="FinalizeInstall"
|
||||
Impersonate="no"
|
||||
BinaryRef="wslinstall.dll"
|
||||
DllEntry="WslFinalizeInstallation"
|
||||
Return="check"
|
||||
Execute="deferred"
|
||||
/>
|
||||
|
||||
<CustomAction Id="DeprovisionMsix"
|
||||
Impersonate="no"
|
||||
BinaryRef="wslinstall.dll"
|
||||
@ -566,6 +574,8 @@
|
||||
<Custom Action="CalculateWslSettingsProtocolIds" Before="WriteRegistryValues" Condition='(not REMOVE~="ALL")' />
|
||||
<?endif?>
|
||||
|
||||
<Custom Action="FinalizeInstall" After="PublishFeatures"/>
|
||||
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<!-- Don't show a 'Modify' button in settings since there is nothing to modify -->
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
<package id="Microsoft.DXCore.Linux.arm64fre" version="10.0.26100.1-240331-1435.ge-release" targetFramework="native" />
|
||||
<package id="Microsoft.Extensions.Hosting" version="9.0.8" />
|
||||
<package id="Microsoft.Identity.MSAL.WSL.Proxy" version="0.1.1" />
|
||||
<package id="Microsoft.NETCore.App.Runtime.win-arm64" version="9.0.8" />
|
||||
<package id="Microsoft.NETCore.App.Runtime.win-x64" version="9.0.8" />
|
||||
<package id="Microsoft.NETCore.App.Runtime.win-arm64" version="9.0.10" />
|
||||
<package id="Microsoft.NETCore.App.Runtime.win-x64" version="9.0.10" />
|
||||
<package id="Microsoft.RemoteDesktop.Client.MSRDC.SessionHost" version="1.2.6353" />
|
||||
<package id="Microsoft.Taef" version="10.97.250317001" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.250325.1" targetFramework="native" />
|
||||
@ -18,13 +18,13 @@
|
||||
<package id="Microsoft.WSL.bsdtar" version="0.0.2-2" />
|
||||
<package id="Microsoft.WSL.Dependencies.amd64fre" version="10.0.27820.1000-250318-1700.rs-base2-hyp" targetFramework="native" />
|
||||
<package id="Microsoft.WSL.Dependencies.arm64fre" version="10.0.27820.1000-250318-1700.rs-base2-hyp" targetFramework="native" />
|
||||
<package id="Microsoft.WSL.DeviceHost" version="1.0.0-20241009.4" />
|
||||
<package id="Microsoft.WSL.DeviceHost" version="1.0.0-20251015.1" />
|
||||
<package id="Microsoft.WSL.Kernel" version="6.6.87.2-1" targetFramework="native" />
|
||||
<package id="Microsoft.WSL.LinuxSdk" version="1.20.0" targetFramework="native" />
|
||||
<package id="Microsoft.WSL.LxUtil.amd64fre" version="10.0.26100.1-240331-1435.ge-release" />
|
||||
<package id="Microsoft.WSL.LxUtil.arm64fre" version="10.0.26100.1-240331-1435.ge-release" />
|
||||
<package id="Microsoft.WSL.TestDistro" version="2.5.7-47" />
|
||||
<package id="Microsoft.WSLg" version="1.0.69" />
|
||||
<package id="Microsoft.WSLg" version="1.0.71" />
|
||||
<package id="Microsoft.Xaml.Behaviors.WinUI.Managed" version="3.0.0" />
|
||||
<package id="StrawberryPerl" version="5.28.0.1" />
|
||||
<package id="vswhere" version="3.1.7" />
|
||||
|
||||
@ -28,6 +28,7 @@ WslDistributionConfig::WslDistributionConfig(const char* configFilePath)
|
||||
ConfigKey("automount.options", DrvFsOptions),
|
||||
ConfigKey(c_ConfigMountFsTabOption, MountFsTab),
|
||||
ConfigKey(c_ConfigLinkOsLibsOption, LinkOsLibs),
|
||||
ConfigKey("automount.cgroups", {{"v1", CGroupVersion::v1}, {"v2", CGroupVersion::v2}}, CGroup, nullptr),
|
||||
|
||||
ConfigKey("filesystem.umask", Umask),
|
||||
|
||||
|
||||
@ -48,6 +48,12 @@ struct WslDistributionConfig
|
||||
WslDistributionConfig(WslDistributionConfig&&) = default;
|
||||
WslDistributionConfig& operator=(WslDistributionConfig&&) = default;
|
||||
|
||||
enum class CGroupVersion
|
||||
{
|
||||
v1 = 0,
|
||||
v2 = 1
|
||||
};
|
||||
|
||||
bool AutoMount = true;
|
||||
bool AutoUpdateTimezone = true;
|
||||
std::optional<std::string> BootCommand;
|
||||
@ -71,6 +77,7 @@ struct WslDistributionConfig
|
||||
bool AppendGpuLibPath = true;
|
||||
bool GpuEnabled = true;
|
||||
bool LinkOsLibs = true;
|
||||
CGroupVersion CGroup = CGroupVersion::v2;
|
||||
|
||||
//
|
||||
// Values not set by /etc/wsl.conf.
|
||||
|
||||
@ -54,9 +54,6 @@ Abstract:
|
||||
#include <cstdarg>
|
||||
#include "lxinitshared.h"
|
||||
#include "defs.h"
|
||||
#include "retryshared.h"
|
||||
#include "socketshared.h"
|
||||
#include "stringshared.h"
|
||||
|
||||
#define ETC_FOLDER "/etc/"
|
||||
#define NAME_ENV "NAME"
|
||||
@ -151,6 +148,11 @@ auto LogImpl(int fd, const std::format_string<Args...>& format, Args&&... args)
|
||||
|
||||
#define FATAL_ERROR(str, ...) FATAL_ERROR_EX(1, str, ##__VA_ARGS__)
|
||||
|
||||
// Some of these files need the LOG_* macros.
|
||||
#include "retryshared.h"
|
||||
#include "socketshared.h"
|
||||
#include "stringshared.h"
|
||||
|
||||
int InitializeLogging(bool SetStderr, wil::LogFunction* ExceptionCallback = nullptr) noexcept;
|
||||
|
||||
void LogException(const char* Message, const char* Description) noexcept;
|
||||
|
||||
@ -73,6 +73,8 @@ Abstract:
|
||||
#define MOUNTS_DEVICE_FIELD 0
|
||||
#define MOUNTS_FSTYPE_FIELD 2
|
||||
|
||||
using wsl::linux::WslDistributionConfig;
|
||||
|
||||
static void ConfigApplyWindowsLibPath(const wsl::linux::WslDistributionConfig& Config);
|
||||
|
||||
static bool CreateLoginSession(const wsl::linux::WslDistributionConfig& Config, const char* Username, uid_t Uid);
|
||||
@ -567,7 +569,7 @@ Return Value:
|
||||
// Initialize cgroups based on what the kernel supports.
|
||||
//
|
||||
|
||||
ConfigInitializeCgroups();
|
||||
ConfigInitializeCgroups(Config);
|
||||
|
||||
//
|
||||
// Attempt to register the NT interop binfmt extension.
|
||||
@ -1783,7 +1785,7 @@ Return Value:
|
||||
{LX_WSL2_GUI_APP_SUPPORT_ENV, "1"}};
|
||||
}
|
||||
|
||||
void ConfigInitializeCgroups(void)
|
||||
void ConfigInitializeCgroups(wsl::linux::WslDistributionConfig& Config)
|
||||
|
||||
/*++
|
||||
|
||||
@ -1795,7 +1797,7 @@ Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
Config - Supplies the distribution configuration.
|
||||
|
||||
Return Value:
|
||||
|
||||
@ -1805,30 +1807,61 @@ Return Value:
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
//
|
||||
// For WSL2 mount cgroup v2.
|
||||
//
|
||||
// N.B. Cgroup v2 is not implemented for WSL1.
|
||||
//
|
||||
std::vector<std::string> DisabledControllers;
|
||||
|
||||
if (UtilIsUtilityVm())
|
||||
{
|
||||
const auto Target = CGROUP_MOUNTPOINT;
|
||||
THROW_LAST_ERROR_IF(
|
||||
UtilMount(CGROUP2_DEVICE, Target, CGROUP2_DEVICE, (MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME), "nsdelegate") < 0);
|
||||
if (Config.CGroup == WslDistributionConfig::CGroupVersion::v1)
|
||||
{
|
||||
auto commandLine = UtilReadFileContent("/proc/cmdline");
|
||||
auto position = commandLine.find(CGROUPS_NO_V1);
|
||||
if (position != std::string::npos)
|
||||
{
|
||||
auto list = commandLine.substr(position + sizeof(CGROUPS_NO_V1) - 1);
|
||||
auto end = list.find_first_of(" \n");
|
||||
if (end != std::string::npos)
|
||||
{
|
||||
list = list.substr(0, end);
|
||||
}
|
||||
|
||||
if (list == "all")
|
||||
{
|
||||
LOG_WARNING("Distribution has cgroupv1 enabled, but kernel command line has {}all. Falling back to cgroupv2", CGROUPS_NO_V1);
|
||||
Config.CGroup = WslDistributionConfig::CGroupVersion::v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisabledControllers = wsl::shared::string::Split(list, ',');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.CGroup == WslDistributionConfig::CGroupVersion::v1)
|
||||
{
|
||||
THROW_LAST_ERROR_IF(mount("tmpfs", CGROUP_MOUNTPOINT, "tmpfs", (MS_NOSUID | MS_NODEV | MS_NOEXEC), "mode=755") < 0);
|
||||
}
|
||||
|
||||
const auto Target = Config.CGroup == WslDistributionConfig::CGroupVersion::v1 ? CGROUP_MOUNTPOINT "/unified" : CGROUP_MOUNTPOINT;
|
||||
THROW_LAST_ERROR_IF(
|
||||
UtilMount(CGROUP2_DEVICE, Target, CGROUP2_DEVICE, (MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME), "nsdelegate") < 0);
|
||||
|
||||
if (Config.CGroup == WslDistributionConfig::CGroupVersion::v2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_LAST_ERROR_IF(mount("tmpfs", CGROUP_MOUNTPOINT, "tmpfs", (MS_NOSUID | MS_NODEV | MS_NOEXEC), "mode=755") < 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Mount cgroup v1 when running in WSL1 mode.
|
||||
// Mount cgroup v1 when running in WSL1 mode or when a WSL2 distro has automount.cgroups=v1 specified.
|
||||
//
|
||||
// Open the /proc/cgroups file and parse each line, ignoring malformed
|
||||
// lines and disabled controllers.
|
||||
//
|
||||
|
||||
THROW_LAST_ERROR_IF(mount("tmpfs", CGROUP_MOUNTPOINT, "tmpfs", (MS_NOSUID | MS_NODEV | MS_NOEXEC), "mode=755") < 0);
|
||||
|
||||
wil::unique_file Cgroups{fopen(CGROUPS_FILE, "r")};
|
||||
THROW_LAST_ERROR_IF(!Cgroups);
|
||||
|
||||
@ -1840,7 +1873,9 @@ try
|
||||
{
|
||||
char* Subsystem = nullptr;
|
||||
bool Enabled = false;
|
||||
if ((UtilParseCgroupsLine(Line, &Subsystem, &Enabled) < 0) || (Enabled == false))
|
||||
if ((UtilParseCgroupsLine(Line, &Subsystem, &Enabled) < 0) || (Enabled == false) ||
|
||||
std::find(DisabledControllers.begin(), DisabledControllers.end(), Subsystem) != DisabledControllers.end())
|
||||
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1849,7 +1884,6 @@ try
|
||||
THROW_LAST_ERROR_IF(
|
||||
UtilMount(CGROUP_DEVICE, Target.c_str(), CGROUP_DEVICE, (MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME), Subsystem) < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
CATCH_LOG()
|
||||
|
||||
|
||||
@ -406,7 +406,7 @@ void ConfigHandleInteropMessage(
|
||||
const MESSAGE_HEADER* Header,
|
||||
const wsl::linux::WslDistributionConfig& Config);
|
||||
|
||||
void ConfigInitializeCgroups(void);
|
||||
void ConfigInitializeCgroups(wsl::linux::WslDistributionConfig& Config);
|
||||
|
||||
int ConfigInitializeInstance(wsl::shared::SocketChannel& Channel, gsl::span<gsl::byte> Buffer, wsl::linux::WslDistributionConfig& Config);
|
||||
|
||||
|
||||
@ -129,6 +129,8 @@ void InitEntryUtilityVm(wsl::linux::WslDistributionConfig& Config);
|
||||
|
||||
void InitTerminateInstance(gsl::span<gsl::byte> Buffer, wsl::shared::SocketChannel& Channel, wsl::linux::WslDistributionConfig& Config);
|
||||
|
||||
void InitTerminateInstanceInternal(const wsl::linux::WslDistributionConfig& Config);
|
||||
|
||||
void InstallSystemdUnit(const char* Path, const std::string& Name, const char* Content);
|
||||
|
||||
int GenerateSystemdUnits(int Argc, char** Argv);
|
||||
@ -2507,18 +2509,7 @@ Return Value:
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If the distro init process was booted, use the shutdown command to terminate the instance.
|
||||
//
|
||||
|
||||
if (Config.BootInit && !Config.BootStartWriteSocket)
|
||||
{
|
||||
UtilExecCommandLine("systemctl reboot", nullptr);
|
||||
}
|
||||
|
||||
reboot(RB_POWER_OFF);
|
||||
FATAL_ERROR("reboot(RB_POWER_OFF) failed {}", errno);
|
||||
|
||||
InitTerminateInstanceInternal(Config);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2661,10 +2652,56 @@ try
|
||||
}
|
||||
|
||||
//
|
||||
// Respond to the instance termination request.
|
||||
// Attempt to stop the plan9 server, if it is not able to be stopped because of an
|
||||
// in-use file, reply to the service that the instance could not be terminated.
|
||||
//
|
||||
|
||||
Channel.SendResultMessage<bool>(StopPlan9Server(Message->Force, Config));
|
||||
if (!StopPlan9Server(Message->Force, Config))
|
||||
{
|
||||
Channel.SendResultMessage<bool>(false);
|
||||
return;
|
||||
}
|
||||
|
||||
InitTerminateInstanceInternal(Config);
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
void InitTerminateInstanceInternal(const wsl::linux::WslDistributionConfig& Config)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine attempts to cleanly terminate the instance.
|
||||
|
||||
Arguments:
|
||||
|
||||
Config - Supplies the distribution config.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
try
|
||||
{
|
||||
//
|
||||
// If systemd is enabled, attempt to poweroff the instance via systemctl.
|
||||
//
|
||||
|
||||
if (Config.BootInit && !Config.BootStartWriteSocket)
|
||||
{
|
||||
THROW_LAST_ERROR_IF(UtilSetSignalHandlers(g_SavedSignalActions, false) < 0);
|
||||
|
||||
if (UtilExecCommandLine("systemctl poweroff", nullptr) == 0)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(Config.BootInitTimeout));
|
||||
LOG_ERROR("systemctl poweroff did not terminate the instance in {} ms, calling reboot(RB_POWER_OFF)", Config.BootInitTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
reboot(RB_POWER_OFF);
|
||||
FATAL_ERROR("reboot(RB_POWER_OFF) failed {}", errno);
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
|
||||
@ -857,10 +857,10 @@ Return Value:
|
||||
|
||||
if (WI_IsFlagSet(Flags, LxMiniInitMessageFlagVerbose))
|
||||
{
|
||||
compressionArguments += "v";
|
||||
compressionArguments += "vv";
|
||||
}
|
||||
|
||||
const char* arguments[] = {
|
||||
std::vector<const char*> arguments{
|
||||
BSDTAR_PATH,
|
||||
"-C",
|
||||
Source,
|
||||
@ -872,7 +872,13 @@ Return Value:
|
||||
"-",
|
||||
".",
|
||||
nullptr};
|
||||
execv(BSDTAR_PATH, const_cast<char**>(arguments));
|
||||
|
||||
if (WI_IsFlagSet(Flags, LxMiniInitMessageFlagVerbose))
|
||||
{
|
||||
arguments.emplace(arguments.begin() + 3, "--totals");
|
||||
}
|
||||
|
||||
execv(BSDTAR_PATH, const_cast<char**>(arguments.data()));
|
||||
LOG_ERROR("execl failed, {}", errno);
|
||||
});
|
||||
|
||||
@ -1158,7 +1164,7 @@ Return Value:
|
||||
"-C",
|
||||
Destination,
|
||||
"-x",
|
||||
WI_IsFlagSet(Flags, LxMiniInitMessageFlagVerbose) ? "-vp" : "-p",
|
||||
WI_IsFlagSet(Flags, LxMiniInitMessageFlagVerbose) ? "-vvp" : "-p",
|
||||
"--xattrs",
|
||||
"--numeric-owner",
|
||||
"-f",
|
||||
@ -3877,6 +3883,63 @@ int WslEntryPoint(int Argc, char* Argv[]);
|
||||
|
||||
extern int WSLAEntryPoint(int Argc, char* Argv[]);
|
||||
|
||||
void EnableDebugMode(const std::string& Mode)
|
||||
{
|
||||
if (Mode == "hvsocket")
|
||||
{
|
||||
// Mount the debugfs.
|
||||
THROW_LAST_ERROR_IF(UtilMount("none", "/sys/kernel/debug", "debugfs", 0, nullptr) < 0);
|
||||
|
||||
// Enable hvsocket events.
|
||||
std::vector<const char*> files{
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_on_msg_dpc/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_on_message/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_onoffer/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_onoffer_rescind/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_onopen_result/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_ongpadl_created/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_ongpadl_torndown/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_open/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_close_internal/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_establish_gpadl_header/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_establish_gpadl_body/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_teardown_gpadl/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_release_relid/enable",
|
||||
"/sys/kernel/debug/tracing/events/hyperv/vmbus_send_tl_connect_request/enable"};
|
||||
|
||||
for (auto* e : files)
|
||||
{
|
||||
WriteToFile(e, "1");
|
||||
}
|
||||
|
||||
// Relay logs to the host.
|
||||
std::thread relayThread{[]() {
|
||||
constexpr auto path = "/sys/kernel/debug/tracing/trace_pipe";
|
||||
std::ifstream file(path);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
LOG_ERROR("Failed to open {}, {}", path, errno);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
LOG_INFO("{}", line);
|
||||
}
|
||||
|
||||
LOG_ERROR("{}: closed", path);
|
||||
}};
|
||||
|
||||
relayThread.detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unknown debugging mode: '{}'", Mode);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int Argc, char* Argv[])
|
||||
{
|
||||
std::vector<gsl::byte> Buffer;
|
||||
@ -4009,6 +4072,37 @@ int main(int Argc, char* Argv[])
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Create the etc directory and mount procfs and sysfs.
|
||||
//
|
||||
|
||||
if (UtilMkdir(ETC_PATH, 0755) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (UtilMount(nullptr, PROCFS_PATH, "proc", 0, nullptr) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (UtilMount(nullptr, SYSFS_PATH, "sysfs", 0, nullptr) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Enable debug mode, if specified.
|
||||
//
|
||||
|
||||
if (const auto* debugMode = getenv(WSL_DEBUG_ENV))
|
||||
{
|
||||
LOG_ERROR("Running in debug mode: '{}'", debugMode);
|
||||
EnableDebugMode(debugMode);
|
||||
|
||||
unsetenv(WSL_DEBUG_ENV);
|
||||
}
|
||||
|
||||
//
|
||||
// Establish the message channel with the service via hvsocket.
|
||||
//
|
||||
@ -4036,25 +4130,6 @@ int main(int Argc, char* Argv[])
|
||||
goto ErrorExit;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the etc directory and mount procfs and sysfs.
|
||||
//
|
||||
|
||||
if (UtilMkdir(ETC_PATH, 0755) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (UtilMount(nullptr, PROCFS_PATH, "proc", 0, nullptr) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (UtilMount(nullptr, SYSFS_PATH, "sysfs", 0, nullptr) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getenv(WSL_ENABLE_CRASH_DUMP_ENV))
|
||||
{
|
||||
Config.EnableCrashDumpCollection = true;
|
||||
|
||||
@ -537,7 +537,7 @@ Return Value:
|
||||
return Socket;
|
||||
}
|
||||
|
||||
wil::unique_fd UtilConnectVsock(unsigned int Port, bool CloseOnExec, std::optional<int> SocketBuffer) noexcept
|
||||
wil::unique_fd UtilConnectVsock(unsigned int Port, bool CloseOnExec, std::optional<int> SocketBuffer, const std::source_location& Source) noexcept
|
||||
|
||||
/*++
|
||||
|
||||
@ -553,6 +553,8 @@ Arguments:
|
||||
|
||||
SocketBuffer - Optionally supplies the size to use for the socket send and receive buffers.
|
||||
|
||||
Source - Supplies the caller location.
|
||||
|
||||
Return Value:
|
||||
|
||||
A file descriptor representing the connected socket, -1 on failure.
|
||||
@ -565,7 +567,7 @@ Return Value:
|
||||
wil::unique_fd SocketFd{socket(AF_VSOCK, Type, 0)};
|
||||
if (!SocketFd)
|
||||
{
|
||||
LOG_ERROR("socket failed {}", errno);
|
||||
LOG_ERROR("socket failed {} (from: {})", errno, Source);
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -577,7 +579,7 @@ Return Value:
|
||||
Timeout.tv_sec = LX_INIT_HVSOCKET_TIMEOUT_SECONDS;
|
||||
if (setsockopt(SocketFd.get(), AF_VSOCK, SO_VM_SOCKETS_CONNECT_TIMEOUT, &Timeout, sizeof(Timeout)) < 0)
|
||||
{
|
||||
LOG_ERROR("setsockopt SO_VM_SOCKETS_CONNECT_TIMEOUT failed {}", errno);
|
||||
LOG_ERROR("setsockopt SO_VM_SOCKETS_CONNECT_TIMEOUT failed {}, (from: {})", errno, Source);
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -586,13 +588,13 @@ Return Value:
|
||||
int BufferSize = *SocketBuffer;
|
||||
if (setsockopt(SocketFd.get(), SOL_SOCKET, SO_SNDBUF, &BufferSize, sizeof(BufferSize)) < 0)
|
||||
{
|
||||
LOG_ERROR("setsockopt(SO_SNDBUF, {}) failed {}", BufferSize, errno);
|
||||
LOG_ERROR("setsockopt(SO_SNDBUF, {}) failed {}, (from: {})", BufferSize, errno, Source);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (setsockopt(SocketFd.get(), SOL_SOCKET, SO_RCVBUF, &BufferSize, sizeof(BufferSize)) < 0)
|
||||
{
|
||||
LOG_ERROR("setsockopt(SO_RCVBUF, {}) failed {}", BufferSize, errno);
|
||||
LOG_ERROR("setsockopt(SO_RCVBUF, {}) failed {}, (from: {})", BufferSize, errno, Source);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@ -603,7 +605,7 @@ Return Value:
|
||||
SocketAddress.svm_port = Port;
|
||||
if (connect(SocketFd.get(), (const struct sockaddr*)&SocketAddress, sizeof(SocketAddress)) < 0)
|
||||
{
|
||||
LOG_ERROR("connect port {} failed {}", Port, errno);
|
||||
LOG_ERROR("connect port {} failed {} (from: {})", Port, errno, Source);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ Abstract:
|
||||
#include <future>
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
#include <source_location>
|
||||
#include "lxinitshared.h"
|
||||
#include "lxdef.h"
|
||||
#include "common.h"
|
||||
@ -128,7 +129,8 @@ wil::unique_fd UtilConnectToInteropServer(std::optional<pid_t> Pid = {});
|
||||
|
||||
wil::unique_fd UtilConnectUnix(const char* Path);
|
||||
|
||||
wil::unique_fd UtilConnectVsock(unsigned int Port, bool CloseOnExec, std::optional<int> SocketBuffer = {}) noexcept;
|
||||
wil::unique_fd UtilConnectVsock(
|
||||
unsigned int Port, bool CloseOnExec, std::optional<int> SocketBuffer = {}, const std::source_location& Source = std::source_location::current()) noexcept;
|
||||
|
||||
// Needs to be declared before UtilCreateChildProcess().
|
||||
void UtilSetThreadName(const char* Name);
|
||||
|
||||
@ -46,18 +46,18 @@ std::wstring ToJsonW(const T& Value)
|
||||
return wsl::shared::string::MultiByteToWide(ToJson(Value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename T, typename TJson = nlohmann::json>
|
||||
T FromJson(const char* Value)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto json = nlohmann::json::parse(Value);
|
||||
auto json = TJson::parse(Value);
|
||||
T object{};
|
||||
from_json(json, object);
|
||||
|
||||
return object;
|
||||
}
|
||||
catch (const nlohmann::json::exception& e)
|
||||
catch (const TJson::exception& e)
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
@ -72,10 +72,10 @@ T FromJson(const char* Value)
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename T, typename TJson = nlohmann::json>
|
||||
T FromJson(const wchar_t* Value)
|
||||
{
|
||||
return FromJson<T>(wsl::shared::string::WideToMultiByte(Value).c_str());
|
||||
return FromJson<T, TJson>(wsl::shared::string::WideToMultiByte(Value).c_str());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
@ -111,12 +111,13 @@ public:
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
auto sentBytes = wsl::windows::common::socket::Send(m_socket.get(), span, m_exitEvent);
|
||||
|
||||
WSL_LOG(
|
||||
"SentMessage",
|
||||
TraceLoggingValue(m_name.c_str(), "Name"),
|
||||
TraceLoggingValue(reinterpret_cast<const TMessage*>(span.data())->PrettyPrint().c_str(), "Content"));
|
||||
|
||||
wsl::windows::common::socket::Send(m_socket.get(), span, m_exitEvent);
|
||||
TraceLoggingValue(reinterpret_cast<const TMessage*>(span.data())->PrettyPrint().c_str(), "Content"),
|
||||
TraceLoggingValue(sentBytes, "SentBytes"));
|
||||
|
||||
#else
|
||||
|
||||
@ -129,7 +130,7 @@ public:
|
||||
{
|
||||
LOG_ERROR("Failed to write message {}. Channel: {}", header->MessageType, m_name);
|
||||
THROW_LAST_ERROR();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -193,6 +193,8 @@ Abstract:
|
||||
|
||||
#define WSL_ENABLE_CRASH_DUMP_ENV "WSL_ENABLE_CRASH_DUMP"
|
||||
|
||||
#define WSL_DEBUG_ENV "WSL_DEBUG"
|
||||
|
||||
#define WSL_DISTRIBUTION_CONF "/etc/wsl-distribution.conf"
|
||||
|
||||
//
|
||||
|
||||
@ -80,6 +80,27 @@ try
|
||||
#endif
|
||||
if (BytesRead <= 0)
|
||||
{
|
||||
const auto* Header = reinterpret_cast<const MESSAGE_HEADER*>(Buffer.data());
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
LOG_HR_MSG(
|
||||
E_UNEXPECTED,
|
||||
"Socket closed while reading message. Size: %u, type: %i, sequence: %u",
|
||||
Header->MessageSize,
|
||||
Header->MessageType,
|
||||
Header->SequenceNumber);
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
LOG_ERROR(
|
||||
"Socket closed while reading message. Size: {}, type: {}, sequence: {}",
|
||||
Header->MessageSize,
|
||||
Header->MessageType,
|
||||
Header->SequenceNumber);
|
||||
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ Abstract:
|
||||
#include <fstream>
|
||||
#include <gsl/gsl>
|
||||
#include <format>
|
||||
#include <source_location>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <string.h>
|
||||
@ -861,6 +862,22 @@ struct std::formatter<wchar_t[N], char>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::formatter<std::source_location, char>
|
||||
{
|
||||
template <typename TCtx>
|
||||
static constexpr auto parse(TCtx& ctx)
|
||||
{
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename TCtx>
|
||||
auto format(const std::source_location& location, TCtx& ctx) const
|
||||
{
|
||||
return std::format_to(ctx.out(), "{}[{}:{}]", location.function_name(), location.file_name(), location.line());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::formatter<char*, wchar_t>
|
||||
{
|
||||
|
||||
@ -112,7 +112,7 @@ DistributionList ReadFromManifest(const std::wstring& url)
|
||||
content = response.Content().ReadAsStringAsync().get();
|
||||
}
|
||||
|
||||
auto distros = wsl::shared::FromJson<DistributionList>(content.c_str());
|
||||
auto distros = wsl::shared::FromJson<DistributionList, nlohmann::ordered_json>(content.c_str());
|
||||
|
||||
if (distros.Distributions.has_value())
|
||||
{
|
||||
|
||||
@ -58,10 +58,28 @@ struct Distribution
|
||||
struct DistributionList
|
||||
{
|
||||
std::optional<std::vector<Distribution>> Distributions;
|
||||
std::optional<std::map<std::string, std::vector<ModernDistributionVersion>>> ModernDistributions;
|
||||
std::optional<nlohmann::ordered_map<std::string, std::vector<ModernDistributionVersion>>> ModernDistributions;
|
||||
std::optional<std::wstring> Default;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(DistributionList, Distributions, ModernDistributions, Default)
|
||||
friend void from_json(const nlohmann::ordered_json& nlohmann_json_j, DistributionList& nlohmann_json_t)
|
||||
{
|
||||
const DistributionList nlohmann_json_default_obj{};
|
||||
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, Distributions, Default));
|
||||
|
||||
auto modernDistributions = nlohmann_json_j.find("ModernDistributions");
|
||||
if (modernDistributions != nlohmann_json_j.end())
|
||||
{
|
||||
nlohmann_json_t.ModernDistributions.emplace();
|
||||
|
||||
for (const auto& e : modernDistributions->items())
|
||||
{
|
||||
std::vector<ModernDistributionVersion> distros;
|
||||
from_json(e.value(), distros);
|
||||
|
||||
nlohmann_json_t.ModernDistributions->emplace_back(e.key(), std::move(distros));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
constexpr inline auto c_distroUrlRegistryValue = L"DistributionListUrl";
|
||||
|
||||
@ -19,7 +19,6 @@ Abstract:
|
||||
// Defines.
|
||||
|
||||
#define LAUNCH_PROCESS_DEFAULT_BUFFER_SIZE 1024
|
||||
#define LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS 30000
|
||||
|
||||
LxssMessagePort::LxssMessagePort(_In_ HANDLE MessagePort) : m_messagePort(MessagePort), m_messageEvent(wil::EventOptions::None)
|
||||
{
|
||||
@ -52,7 +51,7 @@ std::shared_ptr<LxssPort> LxssMessagePort::CreateSessionLeader(_In_ HANDLE Clien
|
||||
LX_INIT_CREATE_SESSION Message{{LxInitMessageCreateSession, sizeof(Message)}, MarshalId};
|
||||
|
||||
Send(&Message, sizeof(Message));
|
||||
auto LocalMessagePort = m_serverPort->WaitForConnection(LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS);
|
||||
auto LocalMessagePort = m_serverPort->WaitForConnection(c_defaultMessageTimeout);
|
||||
ReleaseConsole.release();
|
||||
return LocalMessagePort;
|
||||
}
|
||||
@ -156,7 +155,7 @@ void LxssMessagePort::Receive(_Out_writes_bytes_(Length) PVOID Buffer, _In_ ULON
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<gsl::byte> LxssMessagePort::Receive()
|
||||
std::vector<gsl::byte> LxssMessagePort::Receive(DWORD Timeout)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
std::vector<gsl::byte> Message;
|
||||
@ -170,7 +169,7 @@ std::vector<gsl::byte> LxssMessagePort::Receive()
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
WaitForMessage(&IoStatus);
|
||||
WaitForMessage(&IoStatus, Timeout);
|
||||
Status = IoStatus.Status;
|
||||
SizeReceived = static_cast<ULONG>(IoStatus.Information);
|
||||
}
|
||||
@ -274,7 +273,7 @@ wil::unique_handle LxssMessagePort::UnmarshalVfsFile(_In_ LXBUS_IPC_HANDLE_ID Vf
|
||||
|
||||
void LxssMessagePort::WaitForMessage(_In_ PIO_STATUS_BLOCK IoStatus, _In_ DWORD Timeout) const
|
||||
{
|
||||
const DWORD WaitStatus = WaitForSingleObject(m_messageEvent.get(), LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS);
|
||||
const DWORD WaitStatus = WaitForSingleObject(m_messageEvent.get(), Timeout);
|
||||
if (WaitStatus == WAIT_TIMEOUT)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusCancel;
|
||||
|
||||
@ -21,6 +21,8 @@ class LxssServerPort;
|
||||
class LxssMessagePort : public LxssPort
|
||||
{
|
||||
public:
|
||||
static inline DWORD c_defaultMessageTimeout = 30000;
|
||||
|
||||
LxssMessagePort(_In_ HANDLE MessagePort);
|
||||
LxssMessagePort(_In_ LxssMessagePort&& Source);
|
||||
LxssMessagePort(_In_ std::unique_ptr<LxssMessagePort>&& SourcePointer);
|
||||
@ -46,7 +48,7 @@ public:
|
||||
LXBUS_IPC_PROCESS_ID
|
||||
MarshalProcess(_In_ HANDLE ProcessHandle, _In_ bool TerminateOnClose) const;
|
||||
|
||||
std::vector<gsl::byte> Receive();
|
||||
std::vector<gsl::byte> Receive(DWORD Timeout = c_defaultMessageTimeout);
|
||||
|
||||
void ReleaseConsole(_In_ LXBUS_IPC_CONSOLE_ID ConsoleId) const;
|
||||
|
||||
|
||||
@ -37,15 +37,17 @@ void InitializeWildcardSocketAddress(_Out_ PSOCKADDR_HV Address)
|
||||
}
|
||||
} // namespace
|
||||
|
||||
wil::unique_socket wsl::windows::common::hvsocket::Accept(_In_ SOCKET ListenSocket, _In_ int Timeout, _In_opt_ HANDLE ExitHandle)
|
||||
wil::unique_socket wsl::windows::common::hvsocket::Accept(
|
||||
_In_ SOCKET ListenSocket, _In_ int Timeout, _In_opt_ HANDLE ExitHandle, _In_ const std::source_location& Location)
|
||||
{
|
||||
wil::unique_socket Socket = Create();
|
||||
wsl::windows::common::socket::Accept(ListenSocket, Socket.get(), Timeout, ExitHandle);
|
||||
wsl::windows::common::socket::Accept(ListenSocket, Socket.get(), Timeout, ExitHandle, Location);
|
||||
|
||||
return Socket;
|
||||
}
|
||||
|
||||
wil::unique_socket wsl::windows::common::hvsocket::Connect(_In_ const GUID& VmId, _In_ unsigned long Port, _In_opt_ HANDLE ExitHandle, _In_opt_ ULONG Timeout)
|
||||
wil::unique_socket wsl::windows::common::hvsocket::Connect(
|
||||
_In_ const GUID& VmId, _In_ unsigned long Port, _In_opt_ HANDLE ExitHandle, _In_opt_ ULONG Timeout, _In_ const std::source_location& Location)
|
||||
{
|
||||
OVERLAPPED Overlapped{};
|
||||
const wil::unique_event OverlappedEvent(wil::EventOptions::ManualReset);
|
||||
@ -69,7 +71,7 @@ wil::unique_socket wsl::windows::common::hvsocket::Connect(_In_ const GUID& VmId
|
||||
|
||||
if (Result != 0)
|
||||
{
|
||||
socket::GetResult(Socket.get(), Overlapped, INFINITE, ExitHandle);
|
||||
socket::GetResult(Socket.get(), Overlapped, INFINITE, ExitHandle, Location);
|
||||
}
|
||||
|
||||
THROW_LAST_ERROR_IF_MSG(
|
||||
@ -85,7 +87,7 @@ wil::unique_socket wsl::windows::common::hvsocket::Connect(_In_ const GUID& VmId
|
||||
const BOOL Success = ConnectFn(Socket.get(), reinterpret_cast<sockaddr*>(&Addr), sizeof(Addr), nullptr, 0, nullptr, &Overlapped);
|
||||
if (Success == FALSE)
|
||||
{
|
||||
socket::GetResult(Socket.get(), Overlapped, INFINITE, ExitHandle);
|
||||
socket::GetResult(Socket.get(), Overlapped, INFINITE, ExitHandle, Location);
|
||||
}
|
||||
|
||||
return Socket;
|
||||
|
||||
@ -19,10 +19,18 @@ Abstract:
|
||||
|
||||
namespace wsl::windows::common::hvsocket {
|
||||
|
||||
constexpr ULONG c_connectTimeoutMs = 30 * 1000;
|
||||
wil::unique_socket Accept(_In_ SOCKET ListenSocket, _In_ int Timeout, _In_opt_ HANDLE ExitHandle = nullptr);
|
||||
wil::unique_socket Accept(
|
||||
_In_ SOCKET ListenSocket,
|
||||
_In_ int Timeout,
|
||||
_In_opt_ HANDLE ExitHandle = nullptr,
|
||||
const std::source_location& Location = std::source_location::current());
|
||||
|
||||
wil::unique_socket Connect(_In_ const GUID& VmId, _In_ unsigned long Port, _In_opt_ HANDLE ExitHandle = nullptr, ULONG Timeout = c_connectTimeoutMs);
|
||||
wil::unique_socket Connect(
|
||||
_In_ const GUID& VmId,
|
||||
_In_ unsigned long Port,
|
||||
_In_opt_ HANDLE ExitHandle = nullptr,
|
||||
ULONG Timeout = 30000, // TODO: Fix
|
||||
const std::source_location& Location = std::source_location::current());
|
||||
|
||||
wil::unique_socket Create();
|
||||
|
||||
|
||||
@ -17,7 +17,8 @@ Abstract:
|
||||
#include "socket.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
void wsl::windows::common::socket::Accept(_In_ SOCKET ListenSocket, _In_ SOCKET Socket, _In_ int Timeout, _In_opt_ HANDLE ExitHandle)
|
||||
void wsl::windows::common::socket::Accept(
|
||||
_In_ SOCKET ListenSocket, _In_ SOCKET Socket, _In_ int Timeout, _In_opt_ HANDLE ExitHandle, _In_ const std::source_location& Location)
|
||||
{
|
||||
CHAR AcceptBuffer[2 * sizeof(SOCKADDR_STORAGE)]{};
|
||||
DWORD BytesReturned;
|
||||
@ -29,17 +30,20 @@ void wsl::windows::common::socket::Accept(_In_ SOCKET ListenSocket, _In_ SOCKET
|
||||
|
||||
if (!Success)
|
||||
{
|
||||
GetResult(ListenSocket, Overlapped, Timeout, ExitHandle);
|
||||
GetResult(ListenSocket, Overlapped, Timeout, ExitHandle, Location);
|
||||
}
|
||||
|
||||
// Set the accept context to mark the socket as connected.
|
||||
THROW_LAST_ERROR_IF(
|
||||
setsockopt(Socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, reinterpret_cast<char*>(&ListenSocket), sizeof(ListenSocket)) == SOCKET_ERROR);
|
||||
THROW_LAST_ERROR_IF_MSG(
|
||||
setsockopt(Socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, reinterpret_cast<char*>(&ListenSocket), sizeof(ListenSocket)) == SOCKET_ERROR,
|
||||
"From: %hs",
|
||||
std::format("{}", Location).c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<DWORD, DWORD> wsl::windows::common::socket::GetResult(_In_ SOCKET Socket, _In_ OVERLAPPED& Overlapped, _In_ DWORD Timeout, _In_ HANDLE ExitHandle)
|
||||
std::pair<DWORD, DWORD> wsl::windows::common::socket::GetResult(
|
||||
_In_ SOCKET Socket, _In_ OVERLAPPED& Overlapped, _In_ DWORD Timeout, _In_ HANDLE ExitHandle, _In_ const std::source_location& Location)
|
||||
{
|
||||
const int error = WSAGetLastError();
|
||||
THROW_HR_IF(HRESULT_FROM_WIN32(error), error != WSA_IO_PENDING);
|
||||
@ -64,7 +68,7 @@ std::pair<DWORD, DWORD> wsl::windows::common::socket::GetResult(_In_ SOCKET Sock
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
THROW_HR_IF(HCS_E_CONNECTION_TIMEOUT, (waitStatus != WAIT_OBJECT_0));
|
||||
THROW_HR_IF_MSG(HCS_E_CONNECTION_TIMEOUT, (waitStatus != WAIT_OBJECT_0), "From: %hs", std::format("{}", Location).c_str());
|
||||
|
||||
cancelFunction.release();
|
||||
const bool result = WSAGetOverlappedResult(Socket, &Overlapped, &bytesProcessed, FALSE, &flagsReturned);
|
||||
@ -83,16 +87,17 @@ std::pair<DWORD, DWORD> wsl::windows::common::socket::GetResult(_In_ SOCKET Sock
|
||||
return {bytesProcessed, flagsReturned};
|
||||
}
|
||||
|
||||
int wsl::windows::common::socket::Receive(_In_ SOCKET Socket, _In_ gsl::span<gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle, _In_ DWORD Flags, _In_ DWORD Timeout)
|
||||
int wsl::windows::common::socket::Receive(
|
||||
_In_ SOCKET Socket, _In_ gsl::span<gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle, _In_ DWORD Flags, _In_ DWORD Timeout, _In_ const std::source_location& Location)
|
||||
{
|
||||
const int BytesRead = ReceiveNoThrow(Socket, Buffer, ExitHandle, Flags, Timeout);
|
||||
const int BytesRead = ReceiveNoThrow(Socket, Buffer, ExitHandle, Flags, Timeout, Location);
|
||||
THROW_LAST_ERROR_IF(BytesRead == SOCKET_ERROR);
|
||||
|
||||
return BytesRead;
|
||||
}
|
||||
|
||||
int wsl::windows::common::socket::ReceiveNoThrow(
|
||||
_In_ SOCKET Socket, _In_ gsl::span<gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle, _In_ DWORD Flags, _In_ DWORD Timeout)
|
||||
_In_ SOCKET Socket, _In_ gsl::span<gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle, _In_ DWORD Flags, _In_ DWORD Timeout, _In_ const std::source_location& Location)
|
||||
{
|
||||
OVERLAPPED Overlapped{};
|
||||
const wil::unique_event OverlappedEvent(wil::EventOptions::ManualReset);
|
||||
@ -103,7 +108,7 @@ int wsl::windows::common::socket::ReceiveNoThrow(
|
||||
try
|
||||
{
|
||||
BytesReturned = SOCKET_ERROR;
|
||||
auto [innerBytes, Flags] = GetResult(Socket, Overlapped, Timeout, ExitHandle);
|
||||
auto [innerBytes, Flags] = GetResult(Socket, Overlapped, Timeout, ExitHandle, Location);
|
||||
BytesReturned = innerBytes;
|
||||
}
|
||||
catch (...)
|
||||
@ -116,33 +121,60 @@ int wsl::windows::common::socket::ReceiveNoThrow(
|
||||
return BytesReturned;
|
||||
}
|
||||
|
||||
std::vector<gsl::byte> wsl::windows::common::socket::Receive(_In_ SOCKET Socket, _In_opt_ HANDLE ExitHandle, _In_ DWORD Timeout)
|
||||
std::vector<gsl::byte> wsl::windows::common::socket::Receive(
|
||||
_In_ SOCKET Socket, _In_opt_ HANDLE ExitHandle, _In_ DWORD Timeout, _In_ const std::source_location& Location)
|
||||
{
|
||||
Receive(Socket, {}, ExitHandle, MSG_PEEK);
|
||||
Receive(Socket, {}, ExitHandle, MSG_PEEK, Timeout, Location);
|
||||
|
||||
ULONG Size = 0;
|
||||
THROW_LAST_ERROR_IF(ioctlsocket(Socket, FIONREAD, &Size) == SOCKET_ERROR);
|
||||
|
||||
std::vector<gsl::byte> Buffer(Size);
|
||||
WI_VERIFY(Receive(Socket, gsl::make_span(Buffer), ExitHandle, Timeout) == static_cast<int>(Size));
|
||||
WI_VERIFY(Receive(Socket, gsl::make_span(Buffer), ExitHandle, MSG_WAITALL, Timeout, Location) == static_cast<int>(Size));
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
int wsl::windows::common::socket::Send(_In_ SOCKET Socket, _In_ gsl::span<const gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle)
|
||||
int wsl::windows::common::socket::Send(
|
||||
_In_ SOCKET Socket, _In_ gsl::span<const gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle, _In_ const std::source_location& Location)
|
||||
{
|
||||
OVERLAPPED Overlapped{};
|
||||
const wil::unique_event OverlappedEvent(wil::EventOptions::ManualReset);
|
||||
WSABUF VectorBuffer = {gsl::narrow_cast<ULONG>(Buffer.size()), const_cast<CHAR*>(reinterpret_cast<const CHAR*>(Buffer.data()))};
|
||||
OVERLAPPED Overlapped{};
|
||||
Overlapped.hEvent = OverlappedEvent.get();
|
||||
|
||||
DWORD Offset = 0;
|
||||
while (Offset < Buffer.size())
|
||||
{
|
||||
OverlappedEvent.ResetEvent();
|
||||
|
||||
WSABUF VectorBuffer = {
|
||||
gsl::narrow_cast<ULONG>(Buffer.size() - Offset), const_cast<CHAR*>(reinterpret_cast<const CHAR*>(Buffer.data() + Offset))};
|
||||
|
||||
DWORD BytesWritten{};
|
||||
if (WSASend(Socket, &VectorBuffer, 1, &BytesWritten, 0, &Overlapped, nullptr) != 0)
|
||||
{
|
||||
DWORD Flags;
|
||||
std::tie(BytesWritten, Flags) = GetResult(Socket, Overlapped, INFINITE, ExitHandle);
|
||||
// If WSASend returns non-zero, expect WSA_IO_PENDING.
|
||||
if (auto error = WSAGetLastError(); error != WSA_IO_PENDING)
|
||||
{
|
||||
THROW_WIN32_MSG(error, "WSASend failed. From: %hs", std::format("{}", Location).c_str());
|
||||
}
|
||||
|
||||
WI_ASSERT(BytesWritten == gsl::narrow_cast<DWORD>(Buffer.size()));
|
||||
DWORD Flags;
|
||||
std::tie(BytesWritten, Flags) = GetResult(Socket, Overlapped, INFINITE, ExitHandle, Location);
|
||||
if (BytesWritten == 0)
|
||||
{
|
||||
THROW_WIN32_MSG(ERROR_CONNECTION_ABORTED, "Socket closed during WSASend(). From: %hs", std::format("{}", Location).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return BytesWritten;
|
||||
Offset += BytesWritten;
|
||||
if (Offset < Buffer.size())
|
||||
{
|
||||
WSL_LOG("PartialSocketWrite", TraceLoggingValue(Buffer.size(), "MessagSize"), TraceLoggingValue(Offset, "Offset"));
|
||||
}
|
||||
}
|
||||
|
||||
WI_ASSERT(Offset == gsl::narrow_cast<DWORD>(Buffer.size()));
|
||||
|
||||
return Offset;
|
||||
}
|
||||
|
||||
@ -18,16 +18,42 @@ Abstract:
|
||||
|
||||
namespace wsl::windows::common::socket {
|
||||
|
||||
void Accept(_In_ SOCKET ListenSocket, _In_ SOCKET Socket, _In_ int Timeout, _In_opt_ HANDLE ExitHandle);
|
||||
void Accept(
|
||||
_In_ SOCKET ListenSocket,
|
||||
_In_ SOCKET Socket,
|
||||
_In_ int Timeout,
|
||||
_In_opt_ HANDLE ExitHandle,
|
||||
_In_ const std::source_location& Location = std::source_location::current());
|
||||
|
||||
std::pair<DWORD, DWORD> GetResult(_In_ SOCKET Socket, _In_ OVERLAPPED& Overlapped, _In_ DWORD Timeout, _In_ HANDLE ExitHandle);
|
||||
std::pair<DWORD, DWORD> GetResult(
|
||||
_In_ SOCKET Socket, _In_ OVERLAPPED& Overlapped, _In_ DWORD Timeout, _In_ HANDLE ExitHandle, _In_ const std::source_location& Location);
|
||||
|
||||
int Receive(_In_ SOCKET Socket, _In_ gsl::span<gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle = nullptr, _In_ DWORD Flags = MSG_WAITALL, _In_ DWORD Timeout = INFINITE);
|
||||
int Receive(
|
||||
_In_ SOCKET Socket,
|
||||
_In_ gsl::span<gsl::byte> Buffer,
|
||||
_In_opt_ HANDLE ExitHandle = nullptr,
|
||||
_In_ DWORD Flags = MSG_WAITALL,
|
||||
_In_ DWORD Timeout = INFINITE,
|
||||
_In_ const std::source_location& Location = std::source_location::current());
|
||||
|
||||
std::vector<gsl::byte> Receive(_In_ SOCKET Socket, _In_opt_ HANDLE ExitHandle = nullptr, _In_ DWORD Timeout = INFINITE);
|
||||
std::vector<gsl::byte> Receive(
|
||||
_In_ SOCKET Socket,
|
||||
_In_opt_ HANDLE ExitHandle = nullptr,
|
||||
_In_ DWORD Timeout = INFINITE,
|
||||
_In_ const std::source_location& Location = std::source_location::current());
|
||||
|
||||
int ReceiveNoThrow(_In_ SOCKET Socket, _In_ gsl::span<gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle = nullptr, _In_ DWORD Flags = MSG_WAITALL, _In_ DWORD Timeout = INFINITE);
|
||||
int ReceiveNoThrow(
|
||||
_In_ SOCKET Socket,
|
||||
_In_ gsl::span<gsl::byte> Buffer,
|
||||
_In_opt_ HANDLE ExitHandle = nullptr,
|
||||
_In_ DWORD Flags = MSG_WAITALL,
|
||||
_In_ DWORD Timeout = INFINITE,
|
||||
_In_ const std::source_location& Location = std::source_location::current());
|
||||
|
||||
int Send(_In_ SOCKET Socket, _In_ gsl::span<const gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle = nullptr);
|
||||
int Send(
|
||||
_In_ SOCKET Socket,
|
||||
_In_ gsl::span<const gsl::byte> Buffer,
|
||||
_In_opt_ HANDLE ExitHandle = nullptr,
|
||||
_In_ const std::source_location& Location = std::source_location::current());
|
||||
|
||||
} // namespace wsl::windows::common::socket
|
||||
|
||||
@ -141,7 +141,9 @@ static const std::map<HRESULT, LPCWSTR> g_commonErrors{
|
||||
X_WIN32(ERROR_NO_DATA),
|
||||
X_WIN32(WSAETIMEDOUT),
|
||||
X_WIN32(ERROR_OPERATION_ABORTED),
|
||||
X_WIN32(WSAECONNREFUSED)};
|
||||
X_WIN32(WSAECONNREFUSED),
|
||||
X_WIN32(ERROR_BAD_PATHNAME),
|
||||
X(WININET_E_TIMEOUT)};
|
||||
|
||||
#undef X
|
||||
|
||||
@ -1392,10 +1394,17 @@ int WINAPI InstallRecordHandler(void* context, UINT messageType, LPCWSTR message
|
||||
try
|
||||
{
|
||||
WSL_LOG("MSIMessage", TraceLoggingValue(messageType, "type"), TraceLoggingValue(message, "message"));
|
||||
auto type = (INSTALLMESSAGE)(0xFF000000 & (UINT)messageType);
|
||||
|
||||
if (type == INSTALLMESSAGE_ERROR || type == INSTALLMESSAGE_FATALEXIT || type == INSTALLMESSAGE_WARNING)
|
||||
{
|
||||
WriteInstallLog(std::format("MSI message: {}", message));
|
||||
}
|
||||
|
||||
auto* callback = reinterpret_cast<const std::function<void(UINT, LPCWSTR)>*>(context);
|
||||
if (callback != nullptr)
|
||||
{
|
||||
(*callback)((INSTALLMESSAGE)(0xFF000000 & (UINT)messageType), message);
|
||||
(*callback)(type, message);
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
@ -1449,6 +1458,8 @@ int wsl::windows::common::wslutil::UpdatePackage(bool PreRelease, bool Repair)
|
||||
UINT wsl::windows::common::wslutil::UpgradeViaMsi(
|
||||
_In_ LPCWSTR PackageLocation, _In_opt_ LPCWSTR ExtraArgs, _In_opt_ LPCWSTR LogFile, _In_ const std::function<void(INSTALLMESSAGE, LPCWSTR)>& Callback)
|
||||
{
|
||||
WriteInstallLog(std::format("Upgrading via MSI package: {}. Args: {}", PackageLocation, ExtraArgs != nullptr ? ExtraArgs : L""));
|
||||
|
||||
ConfigureMsiLogging(LogFile, Callback);
|
||||
|
||||
auto result = MsiInstallProduct(PackageLocation, ExtraArgs);
|
||||
@ -1457,6 +1468,8 @@ UINT wsl::windows::common::wslutil::UpgradeViaMsi(
|
||||
TraceLoggingValue(result, "result"),
|
||||
TraceLoggingValue(ExtraArgs != nullptr ? ExtraArgs : L"", "ExtraArgs"));
|
||||
|
||||
WriteInstallLog(std::format("MSI upgrade result: {}", result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1465,10 +1478,15 @@ UINT wsl::windows::common::wslutil::UninstallViaMsi(_In_opt_ LPCWSTR LogFile, _I
|
||||
const auto key = OpenLxssMachineKey(KEY_READ);
|
||||
const auto productCode = ReadString(key.get(), L"Msi", L"ProductCode", nullptr);
|
||||
|
||||
WriteInstallLog(std::format("Uninstalling MSI package: {}", productCode));
|
||||
|
||||
ConfigureMsiLogging(LogFile, Callback);
|
||||
|
||||
auto result = MsiConfigureProduct(productCode.c_str(), 0, INSTALLSTATE_ABSENT);
|
||||
WSL_LOG("MsiUninstallResult", TraceLoggingValue(result, "result"));
|
||||
|
||||
WriteInstallLog(std::format("MSI package uninstall result: {}", result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1499,6 +1517,43 @@ wil::unique_hfile wsl::windows::common::wslutil::ValidateFileSignature(LPCWSTR P
|
||||
return fileHandle;
|
||||
}
|
||||
|
||||
void wsl::windows::common::wslutil::WriteInstallLog(const std::string& Content)
|
||||
try
|
||||
{
|
||||
static std::wstring path = wil::GetWindowsDirectoryW<std::wstring>() + L"\\temp\\wsl-install-log.txt";
|
||||
|
||||
// Wait up to 10 seconds for the log file mutex
|
||||
wil::unique_handle mutex{CreateMutex(nullptr, true, L"Global\\WslInstallLog")};
|
||||
THROW_LAST_ERROR_IF(!mutex);
|
||||
|
||||
THROW_LAST_ERROR_IF(WaitForSingleObject(mutex.get(), 10 * 1000) != WAIT_OBJECT_0);
|
||||
|
||||
wil::unique_handle file{CreateFile(
|
||||
path.c_str(), GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_ALWAYS, 0, nullptr)};
|
||||
|
||||
THROW_LAST_ERROR_IF(!file);
|
||||
|
||||
LARGE_INTEGER size{};
|
||||
THROW_IF_WIN32_BOOL_FALSE(GetFileSizeEx(file.get(), &size));
|
||||
|
||||
// Append to the file if its size is below 10MB, otherwise truncate.
|
||||
if (size.QuadPart < 10 * _1MB)
|
||||
{
|
||||
THROW_LAST_ERROR_IF(SetFilePointer(file.get(), 0, nullptr, FILE_END) == INVALID_SET_FILE_POINTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_IF_WIN32_BOOL_FALSE(SetEndOfFile(file.get()));
|
||||
}
|
||||
|
||||
static auto processName = wil::GetModuleFileNameW<std::wstring>();
|
||||
auto logLine = std::format("{:%FT%TZ} {}[{}]: {}\n", std::chrono::system_clock::now(), processName, WSL_PACKAGE_VERSION, Content);
|
||||
|
||||
DWORD bytesWritten{};
|
||||
THROW_IF_WIN32_BOOL_FALSE(WriteFile(file.get(), logLine.c_str(), static_cast<DWORD>(logLine.size()), &bytesWritten, nullptr));
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
winrt::Windows::Management::Deployment::PackageVolume wsl::windows::common::wslutil::GetSystemVolume()
|
||||
try
|
||||
{
|
||||
|
||||
@ -187,6 +187,8 @@ UINT UpgradeViaMsi(_In_ LPCWSTR PackageLocation, _In_opt_ LPCWSTR ExtraArgs, _In
|
||||
|
||||
UINT UninstallViaMsi(_In_opt_ LPCWSTR LogFile, _In_ const std::function<void(INSTALLMESSAGE, LPCWSTR)>& callback);
|
||||
|
||||
void WriteInstallLog(const std::string& Content);
|
||||
|
||||
winrt::Windows::Management::Deployment::PackageVolume GetSystemVolume();
|
||||
|
||||
} // namespace wsl::windows::common::wslutil
|
||||
|
||||
@ -551,7 +551,9 @@ wil::unique_handle LxssInstance::_CreateLxProcess(
|
||||
m_oobeThread = std::thread([this, OobeMessagePort = std::move(OobeMessagePort), registration = std::move(registration)]() mutable {
|
||||
try
|
||||
{
|
||||
auto Message = OobeMessagePort->Receive();
|
||||
// N.B. The LX_INIT_OOBE_RESULT message is only sent once the OOBE process completes, which might be waiting on user input.
|
||||
// Do no set a timeout here otherwise the OOBE flow will fail if the OOBE process takes longer than expected.
|
||||
auto Message = OobeMessagePort->Receive(INFINITE);
|
||||
auto* OobeResult = gslhelpers::try_get_struct<LX_INIT_OOBE_RESULT>(gsl::make_span(Message));
|
||||
THROW_HR_IF(E_INVALIDARG, !OobeResult || (OobeResult->Header.MessageType != LxInitOobeResult));
|
||||
|
||||
|
||||
@ -510,7 +510,7 @@ try
|
||||
const auto session = m_session.lock();
|
||||
RETURN_HR_IF(RPC_E_DISCONNECTED, !session);
|
||||
|
||||
return session->Shutdown(false, Force);
|
||||
return session->Shutdown(false, Force ? ShutdownBehavior::Force : ShutdownBehavior::Wait);
|
||||
}
|
||||
CATCH_RETURN()
|
||||
|
||||
@ -1926,7 +1926,7 @@ HRESULT LxssUserSessionImpl::SetVersion(_In_ LPCGUID DistroGuid, _In_ ULONG Vers
|
||||
|
||||
if (m_utilityVm->GetConfig().SetVersionDebug)
|
||||
{
|
||||
commandLine += " -v";
|
||||
commandLine += " -vv --totals";
|
||||
}
|
||||
|
||||
// Run the bsdtar elf binary expand the tar file using the socket as stdin.
|
||||
@ -1991,7 +1991,7 @@ HRESULT LxssUserSessionImpl::SetVersion(_In_ LPCGUID DistroGuid, _In_ ULONG Vers
|
||||
|
||||
if (m_utilityVm->GetConfig().SetVersionDebug)
|
||||
{
|
||||
commandLine += " -v";
|
||||
commandLine += " -vv --totals";
|
||||
}
|
||||
|
||||
// Run the bsdtar elf binary to create the tar file using the socket as stdout.
|
||||
@ -2052,13 +2052,11 @@ HRESULT LxssUserSessionImpl::SetVersion(_In_ LPCGUID DistroGuid, _In_ ULONG Vers
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT LxssUserSessionImpl::Shutdown(_In_ bool PreventNewInstances, bool ForceTerminate)
|
||||
HRESULT LxssUserSessionImpl::Shutdown(_In_ bool PreventNewInstances, ShutdownBehavior Behavior)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If the user asks for a forced termination, kill the VM
|
||||
if (ForceTerminate)
|
||||
{
|
||||
auto forceTerminate = [this]() {
|
||||
auto vmId = m_vmId.load();
|
||||
if (!IsEqualGUID(vmId, GUID_NULL))
|
||||
{
|
||||
@ -2071,11 +2069,43 @@ HRESULT LxssUserSessionImpl::Shutdown(_In_ bool PreventNewInstances, bool ForceT
|
||||
|
||||
WSL_LOG("ForceTerminateVm", TraceLoggingValue(result, "Result"));
|
||||
}
|
||||
};
|
||||
|
||||
// If the user asks for a forced termination, kill the VM
|
||||
if (Behavior == ShutdownBehavior::Force)
|
||||
{
|
||||
forceTerminate();
|
||||
}
|
||||
|
||||
{
|
||||
bool locked = false;
|
||||
auto unlock = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [this, &locked]() {
|
||||
if (locked)
|
||||
{
|
||||
m_instanceLock.unlock();
|
||||
}
|
||||
});
|
||||
|
||||
if (Behavior == ShutdownBehavior::ForceAfter30Seconds)
|
||||
{
|
||||
if (m_instanceLock.try_lock_for(std::chrono::seconds(30)))
|
||||
{
|
||||
locked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
WSL_LOG("VmShutdownLockTimedOut");
|
||||
forceTerminate();
|
||||
}
|
||||
}
|
||||
|
||||
if (!locked)
|
||||
{
|
||||
m_instanceLock.lock();
|
||||
locked = true;
|
||||
}
|
||||
|
||||
// Stop each instance with the lock held.
|
||||
std::lock_guard lock(m_instanceLock);
|
||||
while (!m_runningInstances.empty())
|
||||
{
|
||||
_TerminateInstanceInternal(&m_runningInstances.begin()->first, false);
|
||||
@ -2776,8 +2806,6 @@ void LxssUserSessionImpl::_CreateVm()
|
||||
// Create the utility VM and register for callbacks.
|
||||
m_utilityVm = WslCoreVm::Create(m_userToken, std::move(config), vmId);
|
||||
|
||||
m_utilityVm->GetRuntimeId();
|
||||
|
||||
if (m_httpProxyStateTracker)
|
||||
{
|
||||
// this needs to be done after the VM has finished in case we fell back to NAT mode
|
||||
@ -2786,30 +2814,6 @@ void LxssUserSessionImpl::_CreateVm()
|
||||
|
||||
try
|
||||
{
|
||||
auto callback = [this](auto Pid) {
|
||||
// If the vm is currently being destroyed, the instance lock might be held
|
||||
// while WslCoreVm's destructor is waiting on this thread.
|
||||
// Cancel the call if the vm destruction is signaled.
|
||||
// Note: This is safe because m_instanceLock is always initialized
|
||||
// and because WslCoreVm's destructor waits for this thread, the session can't be gone
|
||||
// until this callback completes.
|
||||
|
||||
auto lock = m_instanceLock.try_lock();
|
||||
while (!lock)
|
||||
{
|
||||
if (m_vmTerminating.wait(100))
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock = m_instanceLock.try_lock();
|
||||
}
|
||||
|
||||
auto unlock = wil::scope_exit([&]() { m_instanceLock.unlock(); });
|
||||
TerminateByClientIdLockHeld(Pid);
|
||||
};
|
||||
|
||||
m_utilityVm->RegisterCallbacks(std::bind(callback, _1), std::bind(s_VmTerminated, this, _1));
|
||||
|
||||
// Mount disks after the system distro vhd is mounted in case filesystem detection is needed.
|
||||
_LoadDiskMounts();
|
||||
|
||||
@ -2841,6 +2845,34 @@ void LxssUserSessionImpl::_CreateVm()
|
||||
_VmTerminate();
|
||||
throw;
|
||||
}
|
||||
|
||||
auto callback = [this](auto Pid) {
|
||||
// If the vm is currently being destroyed, the instance lock might be held
|
||||
// while WslCoreVm's destructor is waiting on this thread.
|
||||
// Cancel the call if the vm destruction is signaled.
|
||||
// Note: This is safe because m_instanceLock is always initialized
|
||||
// and because WslCoreVm's destructor waits for this thread, the session can't be gone
|
||||
// until this callback completes.
|
||||
|
||||
auto lock = m_instanceLock.try_lock();
|
||||
while (!lock)
|
||||
{
|
||||
if (m_vmTerminating.wait(100))
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock = m_instanceLock.try_lock();
|
||||
}
|
||||
|
||||
auto unlock = wil::scope_exit([&]() { m_instanceLock.unlock(); });
|
||||
TerminateByClientIdLockHeld(Pid);
|
||||
};
|
||||
|
||||
// N.B. The callbacks must be registered outside of the above try/catch.
|
||||
// Otherwise if an exception is thrown, calling _VmTerminate() will trigger the 's_VmTerminated' termination callback
|
||||
// Which can deadlock since this thread holds the instance lock and HCS can block until the VM termination callback returns before deleting the VM.
|
||||
|
||||
m_utilityVm->RegisterCallbacks(std::bind(callback, _1), std::bind(s_VmTerminated, this, _1));
|
||||
}
|
||||
|
||||
_VmCheckIdle();
|
||||
|
||||
@ -54,6 +54,13 @@ typedef struct _LXSS_VM_MODE_SETUP_CONTEXT
|
||||
std::shared_ptr<LxssRunningInstance> instance;
|
||||
} LXSS_VM_MODE_SETUP_CONTEXT, *PLXSS_VM_MODE_SETUP_CONTEXT;
|
||||
|
||||
enum class ShutdownBehavior
|
||||
{
|
||||
Wait,
|
||||
Force,
|
||||
ForceAfter30Seconds
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Each COM client gets a unique LxssUserSession object which contains a std::weak_ptr to a LxssUserSessionImpl for that user.
|
||||
/// </summary>
|
||||
@ -491,7 +498,7 @@ public:
|
||||
/// <summary>
|
||||
/// Terminates all running instances and the Linux utility vm.
|
||||
/// </summary>
|
||||
HRESULT Shutdown(_In_ bool PreventNewInstances = false, _In_ bool ForceTerminate = false);
|
||||
HRESULT Shutdown(_In_ bool PreventNewInstances = false, ShutdownBehavior Behavior = ShutdownBehavior::Wait);
|
||||
|
||||
/// <summary>
|
||||
/// Worker thread for logging telemetry about processes running inside of WSL.
|
||||
@ -784,7 +791,7 @@ private:
|
||||
/// <summary>
|
||||
/// Lock for protecting various lists.
|
||||
/// </summary>
|
||||
std::recursive_mutex m_instanceLock;
|
||||
std::recursive_timed_mutex m_instanceLock;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the currently running utility VM's.
|
||||
|
||||
@ -49,7 +49,7 @@ void ClearSessionsAndBlockNewInstancesLockHeld(std::optional<std::vector<std::sh
|
||||
// since that could lead to a deadlock if FindSessionByCookie is called since that would try to lock g_sessionLock
|
||||
// while holding the session inner lock
|
||||
|
||||
session->Shutdown(true);
|
||||
session->Shutdown(true, ShutdownBehavior::ForceAfter30Seconds);
|
||||
}
|
||||
|
||||
sessions.reset();
|
||||
|
||||
@ -375,13 +375,6 @@ void WslCoreInstance::Initialize()
|
||||
drvfsMount = m_initializeDrvFs(m_userToken.get());
|
||||
}
|
||||
|
||||
// If not using the WSL init, initialization is complete.
|
||||
if (WI_IsFlagSet(m_configuration.Flags, LXSS_DISTRO_FLAGS_WSLCORE_MODE))
|
||||
{
|
||||
m_initialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a console manager that will be used to manage session leaders.
|
||||
m_consoleManager = ConsoleManager::CreateConsoleManager(m_initChannel);
|
||||
|
||||
@ -477,8 +470,12 @@ bool WslCoreInstance::RequestStop(_In_ bool Force)
|
||||
terminateMessage.Header.MessageSize = sizeof(terminateMessage);
|
||||
terminateMessage.Force = Force;
|
||||
|
||||
const auto& terminateResponse = m_initChannel->GetChannel().Transaction(terminateMessage, nullptr, m_socketTimeout);
|
||||
shutdown = terminateResponse.Result;
|
||||
m_initChannel->GetChannel().SendMessage(terminateMessage);
|
||||
auto [message, span] = m_initChannel->GetChannel().ReceiveMessageOrClosed<RESULT_MESSAGE<bool>>(m_socketTimeout);
|
||||
if (message)
|
||||
{
|
||||
shutdown = message->Result;
|
||||
}
|
||||
}
|
||||
CATCH_LOG()
|
||||
|
||||
|
||||
@ -872,9 +872,10 @@ WslCoreVm::~WslCoreVm() noexcept
|
||||
WSL_LOG("TerminateVmStop");
|
||||
}
|
||||
|
||||
wil::unique_socket WslCoreVm::AcceptConnection(_In_ DWORD ReceiveTimeout) const
|
||||
wil::unique_socket WslCoreVm::AcceptConnection(_In_ DWORD ReceiveTimeout, _In_ const std::source_location& Location) const
|
||||
{
|
||||
auto socket = wsl::windows::common::hvsocket::Accept(m_listenSocket.get(), m_vmConfig.KernelBootTimeout, m_terminatingEvent.get());
|
||||
auto socket =
|
||||
wsl::windows::common::hvsocket::Accept(m_listenSocket.get(), m_vmConfig.KernelBootTimeout, m_terminatingEvent.get(), Location);
|
||||
if (ReceiveTimeout != 0)
|
||||
{
|
||||
THROW_LAST_ERROR_IF(setsockopt(socket.get(), SOL_SOCKET, SO_RCVTIMEO, (const char*)&ReceiveTimeout, sizeof(ReceiveTimeout)) == SOCKET_ERROR);
|
||||
|
||||
@ -61,7 +61,7 @@ public:
|
||||
|
||||
~WslCoreVm() noexcept;
|
||||
|
||||
wil::unique_socket AcceptConnection(_In_ DWORD ReceiveTimeout = 0) const;
|
||||
wil::unique_socket AcceptConnection(_In_ DWORD ReceiveTimeout = 0, _In_ const std::source_location& Location = std::source_location::current()) const;
|
||||
|
||||
enum class DiskType
|
||||
{
|
||||
|
||||
@ -103,9 +103,8 @@ cpp_quote("#define LXSS_DISTRO_FLAGS_ENABLE_INTEROP 0x1")
|
||||
cpp_quote("#define LXSS_DISTRO_FLAGS_APPEND_NT_PATH 0x2")
|
||||
cpp_quote("#define LXSS_DISTRO_FLAGS_ENABLE_DRIVE_MOUNTING 0x4")
|
||||
cpp_quote("#define LXSS_DISTRO_FLAGS_VM_MODE 0x8")
|
||||
cpp_quote("#define LXSS_DISTRO_FLAGS_WSLCORE_MODE 0x10")
|
||||
cpp_quote("#define LXSS_DISTRO_FLAGS_UNCHANGED 0xFFFFFFFE") // Not using ~0 since the inbox tests use that value to validate that invalid flags return an error.
|
||||
cpp_quote("#define LXSS_DISTRO_FLAGS_ALL (LXSS_DISTRO_FLAGS_ENABLE_INTEROP | LXSS_DISTRO_FLAGS_APPEND_NT_PATH | LXSS_DISTRO_FLAGS_ENABLE_DRIVE_MOUNTING | LXSS_DISTRO_FLAGS_VM_MODE| LXSS_DISTRO_FLAGS_WSLCORE_MODE)")
|
||||
cpp_quote("#define LXSS_DISTRO_FLAGS_ALL (LXSS_DISTRO_FLAGS_ENABLE_INTEROP | LXSS_DISTRO_FLAGS_APPEND_NT_PATH | LXSS_DISTRO_FLAGS_ENABLE_DRIVE_MOUNTING | LXSS_DISTRO_FLAGS_VM_MODE)")
|
||||
cpp_quote("#define LXSS_DISTRO_FLAGS_DEFAULT (LXSS_DISTRO_FLAGS_ENABLE_INTEROP | LXSS_DISTRO_FLAGS_APPEND_NT_PATH | LXSS_DISTRO_FLAGS_ENABLE_DRIVE_MOUNTING)")
|
||||
|
||||
cpp_quote("#define LXSS_ENUMERATE_FLAGS_DEFAULT 0x1")
|
||||
|
||||
@ -23,6 +23,7 @@ Abstract:
|
||||
using unique_msi_handle = wil::unique_any<MSIHANDLE, decltype(MsiCloseHandle), &MsiCloseHandle>;
|
||||
|
||||
using namespace wsl::windows::common::registry;
|
||||
using namespace wsl::windows::common::wslutil;
|
||||
|
||||
static constexpr auto c_progIdPrefix{L"App."};
|
||||
static constexpr auto c_protocolProgIdSuffix{L".Protocol"};
|
||||
@ -519,6 +520,7 @@ extern "C" UINT __stdcall DeprovisionMsix(MSIHANDLE install)
|
||||
try
|
||||
{
|
||||
WSL_LOG("DeprovisionMsix");
|
||||
WriteInstallLog("MSI install: DeprovisionMsix");
|
||||
|
||||
const winrt::Windows::Management::Deployment::PackageManager packageManager;
|
||||
const auto result = packageManager.DeprovisionPackageForAllUsersAsync(wsl::windows::common::wslutil::c_msixPackageFamilyName).get();
|
||||
@ -542,6 +544,7 @@ extern "C" UINT __stdcall RemoveMsixAsSystem(MSIHANDLE install)
|
||||
try
|
||||
{
|
||||
WSL_LOG("RemoveMsixAsSystem");
|
||||
WriteInstallLog("MSI install: RemoveMsixAsSystem");
|
||||
|
||||
const winrt::Windows::Management::Deployment::PackageManager packageManager;
|
||||
|
||||
@ -571,6 +574,7 @@ extern "C" UINT __stdcall RemoveMsixAsUser(MSIHANDLE install)
|
||||
try
|
||||
{
|
||||
WSL_LOG("RemoveMsixAsUser");
|
||||
WriteInstallLog("MSI install: RemoveMsixAsUser");
|
||||
|
||||
const winrt::Windows::Management::Deployment::PackageManager packageManager;
|
||||
|
||||
@ -640,6 +644,7 @@ extern "C" UINT __stdcall InstallMsixAsUser(MSIHANDLE install)
|
||||
try
|
||||
{
|
||||
WSL_LOG("InstallMsixAsUser");
|
||||
WriteInstallLog("MSI install: InstallMsixAsUser");
|
||||
|
||||
// RegisterPackageByFamilyNameAsync() cannot be run as SYSTEM.
|
||||
// If this thread runs as SYSTEM, simply skip this step.
|
||||
@ -683,6 +688,7 @@ try
|
||||
msixFile.Handle.reset();
|
||||
|
||||
WSL_LOG("InstallMsix", TraceLoggingValue(msixFile.Path.c_str(), "Path"));
|
||||
WriteInstallLog("MSI install: InstallMsix");
|
||||
|
||||
winrt::Windows::Management::Deployment::PackageManager packageManager;
|
||||
|
||||
@ -780,11 +786,25 @@ catch (...)
|
||||
return ERROR_INSTALL_FAILURE;
|
||||
}
|
||||
|
||||
extern "C" UINT __stdcall WslFinalizeInstallation(MSIHANDLE install)
|
||||
{
|
||||
try
|
||||
{
|
||||
WSL_LOG("WslFinalizeInstallation");
|
||||
WriteInstallLog(std::format("MSI install: WslFinalizeInstallation"));
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
extern "C" UINT __stdcall WslValidateInstallation(MSIHANDLE install)
|
||||
try
|
||||
{
|
||||
WSL_LOG("WslValidateInstallation");
|
||||
|
||||
WriteInstallLog(std::format("MSI install: WslValidateInstallation"));
|
||||
|
||||
// TODO: Use a more precise version check so we don't install if the Windows build doesn't support lifted.
|
||||
|
||||
if (wsl::windows::common::helpers::GetWindowsVersion().BuildNumber < wsl::windows::common::helpers::Vibranium)
|
||||
|
||||
@ -5,6 +5,7 @@ EXPORTS
|
||||
CleanMsixState
|
||||
DeprovisionMsix
|
||||
WslValidateInstallation
|
||||
WslFinalizeInstallation
|
||||
InstallMsix
|
||||
InstallMsixAsUser
|
||||
RegisterLspCategories
|
||||
|
||||
@ -102,7 +102,7 @@ DWORD WINAPI InstallMsiPackage(LPVOID Context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsUpdateNeeded()
|
||||
std::pair<bool, std::wstring> IsUpdateNeeded()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -115,13 +115,15 @@ bool IsUpdateNeeded()
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_INFO),
|
||||
TraceLoggingValue(installedVersion.c_str(), "InstalledVersion"));
|
||||
|
||||
return installedVersion.empty() || wsl::windows::common::wslutil::ParseWslPackageVersion(installedVersion) < wsl::shared::PackageVersion;
|
||||
return std::make_pair(
|
||||
installedVersion.empty() || wsl::windows::common::wslutil::ParseWslPackageVersion(installedVersion) < wsl::shared::PackageVersion,
|
||||
installedVersion);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
|
||||
return false;
|
||||
return std::make_pair(false, L"");
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,11 +134,14 @@ std::shared_ptr<InstallContext> LaunchInstall()
|
||||
|
||||
auto lock = mutex.lock_exclusive();
|
||||
|
||||
if (!IsUpdateNeeded())
|
||||
auto [updateNeeded, existingVersion] = IsUpdateNeeded();
|
||||
if (!updateNeeded)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
wsl::windows::common::wslutil::WriteInstallLog(std::format("Starting upgrade via WslInstaller. Previous version: {}", existingVersion));
|
||||
|
||||
// Return an existing install if any
|
||||
if (auto ptr = weak_context.lock(); ptr != nullptr)
|
||||
{
|
||||
|
||||
@ -110,7 +110,7 @@ class SimpleTests
|
||||
L"The operation completed successfully. \r\n",
|
||||
L"wsl: Sparse VHD support is currently disabled due to potential data corruption.\r\n"
|
||||
L"To force a distribution to use a sparse vhd, please run:\r\n"
|
||||
L"wsl.exe --manage <DistributionName> --set-sparse --allow-unsafe\r\n",
|
||||
L"wsl.exe --manage <DistributionName> --set-sparse true --allow-unsafe\r\n",
|
||||
0);
|
||||
|
||||
std::filesystem::path vhdPath = vhdDir / LXSS_VM_MODE_VHD_NAME;
|
||||
@ -123,7 +123,7 @@ class SimpleTests
|
||||
std::format(L"{} {} {} {}", WSL_MANAGE_ARG, tempDistro, WSL_MANAGE_ARG_SET_SPARSE_OPTION_LONG, L"true").c_str(),
|
||||
L"Sparse VHD support is currently disabled due to potential data corruption.\r\n"
|
||||
L"To force a distribution to use a sparse vhd, please run:\r\n"
|
||||
L"wsl.exe --manage <DistributionName> --set-sparse --allow-unsafe\r\nError code: Wsl/Service/E_INVALIDARG\r\n",
|
||||
L"wsl.exe --manage <DistributionName> --set-sparse true --allow-unsafe\r\nError code: Wsl/Service/E_INVALIDARG\r\n",
|
||||
L"",
|
||||
-1);
|
||||
|
||||
|
||||
@ -5326,6 +5326,76 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
|
||||
|
||||
VERIFY_ARE_EQUAL(error, L"");
|
||||
}
|
||||
|
||||
// Validate that manifest distribution ordering is preserved.
|
||||
{
|
||||
auto validateOrder = [](const std::vector<LPCWSTR>& expected) {
|
||||
auto [out, _] = LxsstuLaunchWslAndCaptureOutput(L"--list --online");
|
||||
|
||||
auto lines = wsl::shared::string::Split<wchar_t>(out, '\n');
|
||||
|
||||
for (size_t i = 0; i < expected.size(); i++)
|
||||
{
|
||||
auto end = lines[i + 4].find_first_of(L" \t");
|
||||
VERIFY_ARE_NOT_EQUAL(end, std::wstring::npos);
|
||||
|
||||
auto distro = lines[i + 4].substr(0, end);
|
||||
|
||||
VERIFY_ARE_EQUAL(expected[i], distro);
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
auto manifest =
|
||||
R"({
|
||||
"ModernDistributions": {
|
||||
"distro1": [
|
||||
{
|
||||
"Name": "distro1",
|
||||
"FriendlyName": "distro1Name",
|
||||
"Amd64Url": {"Url": "","Sha256": ""}
|
||||
}
|
||||
],
|
||||
"distro2": [
|
||||
{
|
||||
"Name": "distro2",
|
||||
"FriendlyName": "distro2Name",
|
||||
"Amd64Url": {"Url": "","Sha256": ""}
|
||||
}
|
||||
]
|
||||
}
|
||||
})";
|
||||
|
||||
auto restore = SetManifest(manifest);
|
||||
validateOrder({L"distro1", L"distro2"});
|
||||
}
|
||||
|
||||
{
|
||||
auto manifest =
|
||||
R"({
|
||||
"ModernDistributions": {
|
||||
"distro2": [
|
||||
{
|
||||
"Name": "distro2",
|
||||
"FriendlyName": "distro2Name",
|
||||
"Amd64Url": {"Url": "","Sha256": ""}
|
||||
}
|
||||
],
|
||||
"distro1": [
|
||||
{
|
||||
"Name": "distro1",
|
||||
"FriendlyName": "distro1Name",
|
||||
"Amd64Url": {"Url": "","Sha256": ""}
|
||||
}
|
||||
]
|
||||
}
|
||||
})";
|
||||
|
||||
auto restore = SetManifest(manifest);
|
||||
|
||||
validateOrder({L"distro2", L"distro1"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(ModernInstallEndToEnd)
|
||||
@ -6080,6 +6150,9 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
|
||||
auto cleanup =
|
||||
wil::scope_exit_log(WI_DIAGNOSTICS_INFO, []() { LxsstuLaunchWsl(std::format(L"--unregister {}", test_distro)); });
|
||||
|
||||
// The below logline makes it easier to find the bsdtar output when debugging this test case.
|
||||
fprintf(stderr, "Starting ImportExportStdout test case\n");
|
||||
|
||||
auto commandLine = std::format(L"cmd.exe /c wsl --export {} - | wsl --import {} . -", LXSS_DISTRO_NAME_TEST_L, test_distro);
|
||||
|
||||
VERIFY_ARE_EQUAL(LxsstuRunCommand(commandLine.data()), 0L);
|
||||
@ -6147,5 +6220,61 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
|
||||
VERIFY_ARE_EQUAL(err, L"");
|
||||
}
|
||||
|
||||
TEST_METHOD(WslDebug)
|
||||
{
|
||||
WSL2_TEST_ONLY();
|
||||
|
||||
// Verify that hvsocket debug events are logged to dmesg.
|
||||
WslConfigChange config(LxssGenerateTestConfig({.kernelCommandLine = L"WSL_DEBUG=hvsocket"}));
|
||||
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"dmesg | grep -iF 'vmbus_send_tl_connect_request'"), 0L);
|
||||
}
|
||||
|
||||
TEST_METHOD(CGroupv1)
|
||||
{
|
||||
WSL2_TEST_ONLY();
|
||||
|
||||
auto expectedMount = [](const char* path, const wchar_t* expected) {
|
||||
auto [out, _] = LxsstuLaunchWslAndCaptureOutput(std::format(L"findmnt -ln '{}' || true", path));
|
||||
|
||||
VERIFY_ARE_EQUAL(out, expected);
|
||||
};
|
||||
|
||||
// Validate that cgroupv2 is mounted by default.
|
||||
expectedMount("/sys/fs/cgroup", L"/sys/fs/cgroup cgroup2 cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate\n");
|
||||
|
||||
// Validate that setting cgroup=v1 causes unified cgroups to be mounted.
|
||||
DistroFileChange wslConf(L"/etc/wsl.conf", false);
|
||||
wslConf.SetContent(L"[automount]\ncgroups=v1");
|
||||
|
||||
TerminateDistribution();
|
||||
|
||||
expectedMount(
|
||||
"/sys/fs/cgroup/unified", L"/sys/fs/cgroup/unified cgroup2 cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate\n");
|
||||
|
||||
// Validate that the cgroupv1 mounts are present.
|
||||
expectedMount("/sys/fs/cgroup/cpu", L"/sys/fs/cgroup/cpu cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpu\n");
|
||||
|
||||
// Validate that having cgroup_no_v1=all causes the distribution to fall back to v2.
|
||||
WslConfigChange wslConfig(LxssGenerateTestConfig({.kernelCommandLine = L"cgroup_no_v1=all"}));
|
||||
|
||||
expectedMount("/sys/fs/cgroup/unified", L"");
|
||||
expectedMount("/sys/fs/cgroup", L"/sys/fs/cgroup cgroup2 cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate\n");
|
||||
|
||||
auto [dmesg, __] = LxsstuLaunchWslAndCaptureOutput(L"dmesg");
|
||||
VERIFY_ARE_NOT_EQUAL(
|
||||
dmesg.find(
|
||||
L"Distribution has cgroupv1 enabled, but kernel command line has cgroup_no_v1=all. Falling back to cgroupv2"),
|
||||
std::wstring::npos);
|
||||
}
|
||||
|
||||
TEST_METHOD(InitPermissions)
|
||||
{
|
||||
WSL2_TEST_ONLY();
|
||||
|
||||
auto [out, _] = LxsstuLaunchWslAndCaptureOutput(L"stat -c %a /init");
|
||||
|
||||
VERIFY_ARE_EQUAL(out, L"755\n");
|
||||
}
|
||||
|
||||
}; // namespace UnitTests
|
||||
} // namespace UnitTests
|
||||
|
||||
@ -40,7 +40,7 @@ use constant TRAILER => "TRAILER!!!";
|
||||
# like initramfs.
|
||||
#
|
||||
use constant INODE => 0;
|
||||
use constant MODE => oct("100777");
|
||||
use constant MODE => oct("100755");
|
||||
use constant UID => 0;
|
||||
use constant GID => 0;
|
||||
use constant NLINK => 0;
|
||||
|
||||
@ -211,6 +211,15 @@ rules:
|
||||
capture:
|
||||
field1: error
|
||||
|
||||
- logline:
|
||||
provider: Microsoft.Windows.Lxss.Manager
|
||||
task: LinuxCrash
|
||||
set:
|
||||
name: linux-crash
|
||||
capture:
|
||||
field3: linux-crash-path
|
||||
field6: linux-crash-process
|
||||
|
||||
- logline:
|
||||
provider: Microsoft.Windows.Lxss.Manager
|
||||
set: wsl-service-logs
|
||||
@ -256,6 +265,11 @@ actions:
|
||||
debug_message: 'Detected user visible error: $error'
|
||||
skip_similar_issues: false
|
||||
|
||||
- foreach:
|
||||
var: linux-crash
|
||||
debug_message: 'Found evidence of linux crash: $linux-crash-process (dump: $linux-crash-path)'
|
||||
skip_similar_issues: false
|
||||
|
||||
- foreach:
|
||||
var: disk-attach-error
|
||||
debug_message: 'Found evidence of disk failing to attach. Error: $error, Path: $vhdpath'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user