@samitouri / QOSAMI-WSL / commits / b3a7b7d3

Add logic to handle partial hvsocket writes and additional logging (#13602)

Blue committed Oct 16, 2025 at 10:53 UTC b3a7b7d395bc843ef706709df1d6e31f1be82c39
4 files changed +64 -15
src/linux/init/common.h
+5 -3
@@ -54,9 +54,6 @@ Abstract:
54 #include <cstdarg>
55 #include "lxinitshared.h"
56 #include "defs.h"
57 -#include "retryshared.h"
58 -#include "socketshared.h"
59 -#include "stringshared.h"
57
58 #define ETC_FOLDER "/etc/"
59 #define NAME_ENV "NAME"
@@ -151,6 +148,11 @@ auto LogImpl(int fd, const std::format_string<Args...>& format, Args&&... args)
148
149 #define FATAL_ERROR(str, ...) FATAL_ERROR_EX(1, str, ##__VA_ARGS__)
150
151 +// Some of these files need the LOG_* macros.
152 +#include "retryshared.h"
153 +#include "socketshared.h"
154 +#include "stringshared.h"
155 +
156 int InitializeLogging(bool SetStderr, wil::LogFunction* ExceptionCallback = nullptr) noexcept;
157
158 void LogException(const char* Message, const char* Description) noexcept;
src/shared/inc/SocketChannel.h
+5 -4
@@ -112,12 +112,13 @@ public:
112
113 #ifdef WIN32
114
115 + auto sentBytes = wsl::windows::common::socket::Send(m_socket.get(), span, m_exitEvent);
116 +
117 WSL_LOG(
118 "SentMessage",
119 TraceLoggingValue(m_name, "Name"),
118 - TraceLoggingValue(reinterpret_cast<const TMessage*>(span.data())->PrettyPrint().c_str(), "Content"));
119 -
120 - wsl::windows::common::socket::Send(m_socket.get(), span, m_exitEvent);
120 + TraceLoggingValue(reinterpret_cast<const TMessage*>(span.data())->PrettyPrint().c_str(), "Content"),
121 + TraceLoggingValue(sentBytes, "SentBytes"));
122
123 #else
124
@@ -130,7 +131,7 @@ public:
131 {
132 LOG_ERROR("Failed to write message {}. Channel: {}", header->MessageType, m_name);
133 THROW_LAST_ERROR();
133 - };
134 + }
135
136 #endif
137 }
src/shared/inc/socketshared.h
+21
@@ -80,6 +80,27 @@ try
80 #endif
81 if (BytesRead <= 0)
82 {
83 + const auto* Header = reinterpret_cast<const MESSAGE_HEADER*>(Buffer.data());
84 +
85 +#if defined(_MSC_VER)
86 +
87 + LOG_HR_MSG(
88 + E_UNEXPECTED,
89 + "Socket closed while reading message. Size: %u, type: %i, sequence: %u",
90 + Header->MessageSize,
91 + Header->MessageType,
92 + Header->SequenceNumber);
93 +
94 +#elif defined(__GNUC__)
95 +
96 + LOG_ERROR(
97 + "Socket closed while reading message. Size: {}, type: {}, sequence: {}",
98 + Header->MessageSize,
99 + Header->MessageType,
100 + Header->SequenceNumber);
101 +
102 +#endif
103 +
104 return {};
105 }
106
src/windows/common/socket.cpp
+33 -8
@@ -138,18 +138,43 @@ std::vector<gsl::byte> wsl::windows::common::socket::Receive(
138 int wsl::windows::common::socket::Send(
139 _In_ SOCKET Socket, _In_ gsl::span<const gsl::byte> Buffer, _In_opt_ HANDLE ExitHandle, _In_ const std::source_location& Location)
140 {
141 - OVERLAPPED Overlapped{};
141 const wil::unique_event OverlappedEvent(wil::EventOptions::ManualReset);
143 - WSABUF VectorBuffer = {gsl::narrow_cast<ULONG>(Buffer.size()), const_cast<CHAR*>(reinterpret_cast<const CHAR*>(Buffer.data()))};
142 + OVERLAPPED Overlapped{};
143 Overlapped.hEvent = OverlappedEvent.get();
145 - DWORD BytesWritten{};
146 - if (WSASend(Socket, &VectorBuffer, 1, &BytesWritten, 0, &Overlapped, nullptr) != 0)
144 +
145 + DWORD Offset = 0;
146 + while (Offset < Buffer.size())
147 {
148 - DWORD Flags;
149 - std::tie(BytesWritten, Flags) = GetResult(Socket, Overlapped, INFINITE, ExitHandle, Location);
148 + OverlappedEvent.ResetEvent();
149 +
150 + WSABUF VectorBuffer = {
151 + gsl::narrow_cast<ULONG>(Buffer.size() - Offset), const_cast<CHAR*>(reinterpret_cast<const CHAR*>(Buffer.data() + Offset))};
152 +
153 + DWORD BytesWritten{};
154 + if (WSASend(Socket, &VectorBuffer, 1, &BytesWritten, 0, &Overlapped, nullptr) != 0)
155 + {
156 + // If WSASend returns non-zero, expect WSA_IO_PENDING.
157 + if (auto error = WSAGetLastError(); error != WSA_IO_PENDING)
158 + {
159 + THROW_WIN32_MSG(error, "WSASend failed. From: %hs", std::format("{}", Location).c_str());
160 + }
161 +
162 + DWORD Flags;
163 + std::tie(BytesWritten, Flags) = GetResult(Socket, Overlapped, INFINITE, ExitHandle, Location);
164 + if (BytesWritten == 0)
165 + {
166 + THROW_WIN32_MSG(ERROR_CONNECTION_ABORTED, "Socket closed during WSASend(). From: %hs", std::format("{}", Location).c_str());
167 + }
168 + }
169 +
170 + Offset += BytesWritten;
171 + if (Offset < Buffer.size())
172 + {
173 + WSL_LOG("PartialSocketWrite", TraceLoggingValue(Buffer.size(), "MessagSize"), TraceLoggingValue(Offset, "Offset"));
174 + }
175 }
176
152 - WI_ASSERT(BytesWritten == gsl::narrow_cast<DWORD>(Buffer.size()));
177 + WI_ASSERT(Offset == gsl::narrow_cast<DWORD>(Buffer.size()));
178
154 - return BytesWritten;
179 + return Offset;
180 }