Add telemetry event on container creation (#40704)
* Add telemetry event on container creation * Apply PR feedback * Update test
Blue committed
Jun 7, 2026 at 21:44 UTC
6f8d2e439bf6f9ffd4ce9e15d3016c91998a4c28
6 files changed
+37
-20
src/windows/service/exe/WSLCSessionManager.cpp
+3
-3
@@ -270,7 +270,7 @@ void WSLCSessionManagerImpl::CreateSession(
270
auto factory = wslutil::CreateComServerAsUser<IWSLCSessionFactory>(__uuidof(WSLCSessionFactory), userToken.get());
271
AddSessionProcessToJobObject(factory.get());
272
273
- const auto sessionSettings = CreateSessionSettings(sessionId, creatorPid, Settings, resolvedDisplayName.c_str());
273
+ const auto sessionSettings = CreateSessionSettings(sessionId, callerFileName.c_str(), Settings, resolvedDisplayName.c_str());
274
wil::com_ptr<IWSLCSession> session;
275
wil::com_ptr<IWSLCSessionReference> serviceRef;
276
THROW_IF_FAILED(factory->CreateSession(&sessionSettings, vm.Get(), notifier.Get(), WarningCallback, &session, &serviceRef));
@@ -415,11 +415,11 @@ void WSLCSessionManagerImpl::EnterSession(
415
}
416
417
WSLCSessionInitSettings WSLCSessionManagerImpl::CreateSessionSettings(
418
- _In_ ULONG SessionId, _In_ DWORD CreatorPid, _In_ const WSLCSessionSettings* Settings, _In_ LPCWSTR ResolvedDisplayName)
418
+ _In_ ULONG SessionId, _In_ LPCWSTR CreatorProcessName, _In_ const WSLCSessionSettings* Settings, _In_ LPCWSTR ResolvedDisplayName)
419
{
420
WSLCSessionInitSettings sessionSettings{};
421
sessionSettings.SessionId = SessionId;
422
- sessionSettings.CreatorPid = CreatorPid;
422
+ sessionSettings.CreatorProcessName = CreatorProcessName;
423
sessionSettings.DisplayName = ResolvedDisplayName;
424
sessionSettings.StoragePath = Settings->StoragePath;
425
sessionSettings.MaximumStorageSizeMb = Settings->MaximumStorageSizeMb;
src/windows/service/exe/WSLCSessionManager.h
+1
-1
@@ -165,7 +165,7 @@ private:
165
166
void AddSessionProcessToJobObject(_In_ IWSLCSessionFactory* Factory);
167
WSLCSessionInitSettings CreateSessionSettings(
168
- _In_ ULONG SessionId, _In_ DWORD CreatorPid, _In_ const WSLCSessionSettings* Settings, _In_ LPCWSTR ResolvedDisplayName);
168
+ _In_ ULONG SessionId, _In_ LPCWSTR CreatorProcessName, _In_ const WSLCSessionSettings* Settings, _In_ LPCWSTR ResolvedDisplayName);
169
void EnsureJobObjectCreated();
170
static CallingProcessTokenInfo GetCallingProcessTokenInfo();
171
static HRESULT CheckTokenAccess(const SessionEntry& Entry, const CallingProcessTokenInfo& TokenInfo);
src/windows/service/inc/wslc.idl
+1
-1
@@ -713,7 +713,7 @@ typedef enum _WSLCSessionState
713
typedef struct _WSLCSessionInitSettings
714
{
715
ULONG SessionId;
716
- ULONG CreatorPid;
716
+ [unique] LPCWSTR CreatorProcessName;
717
LPCWSTR DisplayName;
718
LPCWSTR StoragePath;
719
WSLCSessionStorageFlags StorageFlags;
src/windows/wslcsession/WSLCSession.cpp
+26
-14
@@ -273,6 +273,7 @@ try
273
// N.B. No locking is required because Initialize() is always called before the session is returned to the caller.
274
m_id = Settings->SessionId;
275
m_displayName = Settings->DisplayName ? Settings->DisplayName : L"";
276
+ m_creatorProcessName = Settings->CreatorProcessName ? Settings->CreatorProcessName : L"";
277
m_featureFlags = Settings->FeatureFlags;
278
m_pluginNotifier = PluginNotifier;
279
@@ -283,7 +284,7 @@ try
284
"SessionInitialized",
285
TraceLoggingValue(m_id, "SessionId"),
286
TraceLoggingValue(m_displayName.c_str(), "DisplayName"),
286
- TraceLoggingValue(Settings->CreatorPid, "CreatorPid"));
287
+ TraceLoggingValue(m_creatorProcessName.c_str(), "CreatorProcess"));
288
289
// Create the VM.
290
m_virtualMachine.emplace(Vm, Settings, m_sessionTerminatingEvent.get());
@@ -1669,17 +1670,33 @@ HRESULT WSLCSession::CreateContainer(const WSLCContainerOptions* containerOption
1670
try
1671
{
1672
WSLCExecutionContext context(this, WarningCallback);
1673
+ THROW_HR_IF_NULL(E_POINTER, containerOptions);
1674
+ THROW_HR_IF_NULL(E_POINTER, Container);
1675
+ THROW_HR_IF(E_POINTER, containerOptions->Image == nullptr);
1676
1673
- RETURN_HR_IF_NULL(E_POINTER, containerOptions);
1677
+ auto lock = m_lock.lock_shared();
1678
1675
- // Validate that Image is not null.
1676
- RETURN_HR_IF(E_INVALIDARG, containerOptions->Image == nullptr);
1679
+ auto result = wil::ResultFromException([&]() { CreateContainerImpl(containerOptions, Container); });
1680
1678
- auto lock = m_lock.lock_shared();
1681
+ // This telemetry event is used to keep track of the container creation failure rate and surface unexpected errors.
1682
+ WSL_LOG_TELEMETRY(
1683
+ "WSLCCreateContainer",
1684
+ PDT_ProductAndServicePerformance,
1685
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA),
1686
+ TraceLoggingValue(result, "Result"),
1687
+ TraceLoggingValue(containerOptions->Image, "Image"),
1688
+ TraceLoggingValue(m_displayName.c_str(), "SessionName"),
1689
+ TraceLoggingValue(m_creatorProcessName.c_str(), "CreatorProcess"));
1690
+
1691
+ return result;
1692
+}
1693
+CATCH_RETURN();
1694
1680
- RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_virtualMachine);
1681
- RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_eventTracker);
1682
- RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_dockerClient);
1695
+void WSLCSession::CreateContainerImpl(const WSLCContainerOptions* containerOptions, IWSLCContainer** Container)
1696
+{
1697
+ THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_virtualMachine);
1698
+ THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_eventTracker);
1699
+ THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_dockerClient);
1700
1701
// Validate that name & images are valid.
1702
if (containerOptions->Name != nullptr && containerOptions->Name[0] != '\0')
@@ -1687,9 +1704,7 @@ try
1704
ValidateName(containerOptions->Name, WSLC_MAX_CONTAINER_NAME_LENGTH);
1705
}
1706
1690
- RETURN_HR_IF(E_INVALIDARG, strlen(containerOptions->Image) > WSLC_MAX_IMAGE_NAME_LENGTH);
1691
-
1692
- // TODO: Log entrance into the function.
1707
+ THROW_HR_IF(E_INVALIDARG, strlen(containerOptions->Image) > WSLC_MAX_IMAGE_NAME_LENGTH);
1708
1709
try
1710
{
@@ -1741,8 +1756,6 @@ try
1756
WI_ASSERT(inserted);
1757
1758
it->second->CopyTo(Container);
1744
-
1745
- return S_OK;
1759
}
1760
catch (const DockerHTTPException& e)
1761
{
@@ -1757,7 +1770,6 @@ try
1770
THROW_HR_WITH_USER_ERROR(E_FAIL, errorMessage);
1771
}
1772
}
1760
-CATCH_RETURN();
1773
1774
HRESULT WSLCSession::OpenContainer(LPCSTR Id, IWSLCContainer** Container)
1775
try
src/windows/wslcsession/WSLCSession.h
+5
@@ -202,6 +202,10 @@ private:
202
203
__requires_lock_held(m_userHandlesLock) void CancelUserHandleIO();
204
__requires_lock_held(m_userCOMCallbacksLock) void CancelUserCOMCallbacks();
205
+
206
+ _Requires_shared_lock_held_(m_lock)
207
+ void CreateContainerImpl(const WSLCContainerOptions* Options, IWSLCContainer** Container);
208
+
209
void ConfigureStorage(const WSLCSessionInitSettings& Settings, PSID UserSid);
210
void Ext4Format(const std::string& Device);
211
_Requires_shared_lock_held_(m_lock)
@@ -235,6 +239,7 @@ private:
239
std::optional<DockerEventTracker> m_eventTracker;
240
wil::unique_event m_dockerdReadyEvent{wil::EventOptions::ManualReset};
241
std::wstring m_displayName;
242
+ std::wstring m_creatorProcessName;
243
std::filesystem::path m_storageVhdPath;
244
std::filesystem::path m_swapVhdPath;
245
test/windows/WSLCTests.cpp
+1
-1
@@ -5436,7 +5436,7 @@ class WSLCTests
5436
5437
wil::com_ptr<IWSLCContainer> container;
5438
auto hr = m_defaultSession->CreateContainer(&options, nullptr, &container);
5439
- VERIFY_ARE_EQUAL(hr, E_INVALIDARG);
5439
+ VERIFY_ARE_EQUAL(hr, E_POINTER);
5440
}
5441
5442
// Test null container name