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
}