master
h 666 lines 15.5 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 hcs_schema.h
8
9 Abstract:
10
11 This file contains the host compute service schema definitions.
12
13 --*/
14
15 #pragma once
16
17 #include "JsonUtils.h"
18
19 #define OMIT_IF_EMPTY(Json, Object, Value) \
20 if ((Object).Value.has_value()) \
21 { \
22 Json[#Value] = (Object).Value.value(); \
23 }
24
25 #define ASSIGN_IF_PRESENT(Json, Object, Value) \
26 if (Json.contains(#Value)) \
27 { \
28 (Object).Value = Json.at(#Value).get_to((Object).Value); \
29 }
30
31 namespace wsl::windows::common::hcs {
32
33 enum class ModifyRequestType
34 {
35 Add,
36 Update,
37 Remove
38 };
39
40 NLOHMANN_JSON_SERIALIZE_ENUM(
41 ModifyRequestType,
42 {
43 {ModifyRequestType::Add, "Add"},
44 {ModifyRequestType::Update, "Update"},
45 {ModifyRequestType::Remove, "Remove"},
46 })
47
48 enum class AttachmentType
49 {
50 VirtualDisk,
51 PassThru
52 };
53
54 NLOHMANN_JSON_SERIALIZE_ENUM(
55 AttachmentType,
56 {
57 {AttachmentType::VirtualDisk, "VirtualDisk"},
58 {AttachmentType::PassThru, "PassThru"},
59 })
60
61 enum class PropertyType
62 {
63 Basic
64 };
65
66 NLOHMANN_JSON_SERIALIZE_ENUM(PropertyType, {{PropertyType::Basic, "Basic"}})
67
68 struct Attachment
69 {
70 Attachment() = default;
71 AttachmentType Type;
72 std::wstring Path;
73 bool ReadOnly;
74 bool SupportCompressedVolumes;
75 bool AlwaysAllowSparseFiles;
76 bool SupportEncryptedFiles;
77
78 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Attachment, Type, Path, ReadOnly, SupportCompressedVolumes, AlwaysAllowSparseFiles, SupportEncryptedFiles);
79 };
80
81 enum class Plan9ShareFlags
82 {
83 None = 0x00000000,
84 ReadOnly = 0x00000001,
85 LinuxMetadata = 0x00000004,
86 CaseSensitive = 0x00000008,
87 UseShareRootIdentity = 0x00000010,
88 AllowOptions = 0x00000020,
89 AllowSubPaths = 0x00000040
90 };
91
92 DEFINE_ENUM_FLAG_OPERATORS(Plan9ShareFlags);
93
94 struct Plan9Share
95 {
96 std::wstring Name;
97 std::wstring AccessName;
98 std::wstring Path;
99 uint32_t Port;
100 Plan9ShareFlags Flags;
101 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Plan9Share, Name, AccessName, Path, Port, Flags);
102 };
103
104 enum class FlexibleIoDeviceHostingModel
105 {
106 ExternalRestricted
107 };
108
109 NLOHMANN_JSON_SERIALIZE_ENUM(
110 FlexibleIoDeviceHostingModel,
111 {
112 {FlexibleIoDeviceHostingModel::ExternalRestricted, "ExternalRestricted"},
113 })
114
115 struct FlexibleIoDevice
116 {
117 GUID EmulatorId;
118 FlexibleIoDeviceHostingModel HostingModel;
119
120 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(FlexibleIoDevice, EmulatorId, HostingModel);
121 };
122
123 struct NetworkAdapter
124 {
125 GUID EndpointId;
126 wsl::shared::string::MacAddress MacAddress;
127 std::optional<GUID> InstanceId;
128 std::optional<bool> IsConnected;
129 std::optional<GUID> SwitchId;
130 std::optional<GUID> PortId;
131 };
132
133 inline void to_json(nlohmann::json& j, const NetworkAdapter& adapter)
134 {
135 j = nlohmann::json{{"EndpointId", adapter.EndpointId}, {"MacAddress", adapter.MacAddress}};
136
137 OMIT_IF_EMPTY(j, adapter, InstanceId);
138 OMIT_IF_EMPTY(j, adapter, IsConnected);
139 OMIT_IF_EMPTY(j, adapter, SwitchId);
140 OMIT_IF_EMPTY(j, adapter, PortId);
141 }
142
143 enum class GpuAssignmentMode
144 {
145 Mirror
146 };
147
148 NLOHMANN_JSON_SERIALIZE_ENUM(
149 GpuAssignmentMode,
150 {
151 {GpuAssignmentMode::Mirror, "Mirror"},
152 })
153
154 struct GpuConfiguration
155 {
156 GpuAssignmentMode AssignmentMode;
157 bool AllowVendorExtension;
158 std::optional<bool> DisableGdiAcceleration;
159 std::optional<bool> DisablePresentation;
160 };
161
162 inline void to_json(nlohmann::json& j, const GpuConfiguration& configuration)
163 {
164 j = nlohmann::json{{"AssignmentMode", configuration.AssignmentMode}, {"AllowVendorExtension", configuration.AllowVendorExtension}};
165
166 OMIT_IF_EMPTY(j, configuration, DisableGdiAcceleration);
167 OMIT_IF_EMPTY(j, configuration, DisablePresentation);
168 }
169
170 template <typename TSettings>
171 struct ModifySettingRequest
172 {
173 std::wstring ResourcePath;
174 ModifyRequestType RequestType;
175 TSettings Settings;
176 };
177
178 template <>
179 struct ModifySettingRequest<void>
180 {
181 ModifySettingRequest() = default;
182 std::wstring ResourcePath;
183 ModifyRequestType RequestType;
184 };
185
186 template <typename TSettings>
187 inline void to_json(nlohmann::json& j, const ModifySettingRequest<TSettings>& request)
188 {
189 j = nlohmann::json{{"ResourcePath", request.ResourcePath}, {"RequestType", request.RequestType}};
190
191 if constexpr (!std::is_same_v<TSettings, void>)
192 {
193 j["Settings"] = request.Settings;
194 }
195 }
196
197 struct PropertyQuery
198 {
199 std::vector<PropertyType> PropertyTypes;
200
201 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(PropertyQuery, PropertyTypes);
202 };
203
204 enum ProcessorFeature
205 {
206 NestedVirt = 70
207 };
208
209 struct _Error // Renamed from 'Error' to make the macro happy.
210 {
211 int32_t Error;
212 std::string ErrorMessage;
213
214 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(_Error, Error, ErrorMessage);
215 };
216
217 struct ProcessorCapabilitiesInfo
218 {
219 std::vector<std::string> ProcessorFeatures;
220
221 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ProcessorCapabilitiesInfo, ProcessorFeatures);
222 };
223
224 struct Version
225 {
226 uint32_t Major;
227 uint32_t Minor;
228
229 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Version, Major, Minor);
230 };
231
232 struct BasicInformation
233 {
234 std::vector<Version> SupportedSchemaVersions;
235
236 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(BasicInformation, SupportedSchemaVersions);
237 };
238
239 template <typename TResponse>
240 struct PropertyResponse
241 {
242 std::optional<_Error> Error;
243 TResponse Response;
244
245 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(PropertyResponse<ProcessorCapabilitiesInfo>, Error, Response);
246 };
247
248 template <typename TResponse>
249 struct ServicePropertiesResponse
250 {
251 std::map<std::string, TResponse> PropertyResponses;
252
253 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ServicePropertiesResponse<PropertyResponse<ProcessorCapabilitiesInfo>>, PropertyResponses);
254 };
255
256 template <typename TResponse>
257 struct ServiceProperties
258 {
259 std::vector<TResponse> Properties;
260
261 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ServiceProperties<BasicInformation>, Properties);
262 };
263
264 enum class SystemType
265 {
266 VirtualMachine = 1
267 };
268
269 NLOHMANN_JSON_SERIALIZE_ENUM(
270 SystemType,
271 {
272 {SystemType::VirtualMachine, "VirtualMachine"},
273 })
274
275 struct Properties
276 {
277 GUID RuntimeId;
278 SystemType SystemType;
279
280 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Properties, RuntimeId, SystemType);
281 };
282
283 enum class MemoryBackingPageSize
284 {
285 Small = 0
286 };
287
288 NLOHMANN_JSON_SERIALIZE_ENUM(
289 MemoryBackingPageSize,
290 {
291 {MemoryBackingPageSize::Small, "Small"},
292 })
293
294 struct Memory
295 {
296 uint64_t SizeInMB;
297 bool AllowOvercommit;
298 bool EnableDeferredCommit;
299 bool EnableColdDiscardHint;
300 std::optional<MemoryBackingPageSize> BackingPageSize;
301 std::optional<uint32_t> FaultClusterSizeShift;
302 std::optional<uint32_t> DirectMapFaultClusterSizeShift;
303 std::optional<uint64_t> HighMmioGapInMB;
304 std::optional<uint64_t> HighMmioBaseInMB;
305 std::optional<std::wstring> HostingProcessNameSuffix;
306 };
307
308 inline void to_json(nlohmann::json& j, const Memory& memory)
309 {
310 j = nlohmann::json{
311 {"SizeInMB", memory.SizeInMB},
312 {"AllowOvercommit", memory.AllowOvercommit},
313 {"EnableDeferredCommit", memory.EnableDeferredCommit},
314 {"EnableColdDiscardHint", memory.EnableColdDiscardHint}};
315
316 OMIT_IF_EMPTY(j, memory, BackingPageSize);
317 OMIT_IF_EMPTY(j, memory, FaultClusterSizeShift);
318 OMIT_IF_EMPTY(j, memory, DirectMapFaultClusterSizeShift);
319 OMIT_IF_EMPTY(j, memory, HighMmioGapInMB);
320 OMIT_IF_EMPTY(j, memory, HighMmioBaseInMB);
321 OMIT_IF_EMPTY(j, memory, HostingProcessNameSuffix);
322 }
323
324 struct Processor
325 {
326 uint32_t Count;
327 std::optional<bool> ExposeVirtualizationExtensions;
328 std::optional<bool> EnablePerfmonPmu;
329 std::optional<bool> EnablePerfmonLbr;
330 };
331
332 inline void to_json(nlohmann::json& j, const Processor& processor)
333 {
334 j = nlohmann::json{{"Count", processor.Count}};
335 OMIT_IF_EMPTY(j, processor, ExposeVirtualizationExtensions)
336 OMIT_IF_EMPTY(j, processor, EnablePerfmonPmu)
337 OMIT_IF_EMPTY(j, processor, EnablePerfmonLbr)
338 }
339
340 struct Topology
341 {
342 Processor Processor;
343 Memory Memory;
344
345 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Topology, Processor, Memory);
346 };
347
348 struct VirtioSerialPort
349 {
350 std::wstring Name;
351 std::wstring NamedPipe;
352 bool ConsoleSupport;
353
354 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(VirtioSerialPort, Name, NamedPipe, ConsoleSupport);
355 };
356
357 struct VirtioSerial
358 {
359 std::map<std::string, VirtioSerialPort> Ports;
360 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(VirtioSerial, Ports);
361 };
362
363 struct ComPort
364 {
365 std::wstring NamedPipe;
366 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(ComPort, NamedPipe);
367 };
368
369 struct LinuxKernelDirect
370 {
371 std::wstring KernelFilePath;
372 std::wstring InitRdPath;
373 std::wstring KernelCmdLine;
374 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(LinuxKernelDirect, KernelFilePath, InitRdPath, KernelCmdLine);
375 };
376
377 enum class UefiBootDevice
378 {
379 VmbFs
380 };
381
382 NLOHMANN_JSON_SERIALIZE_ENUM(
383 UefiBootDevice,
384 {
385 {UefiBootDevice::VmbFs, "VmbFs"},
386 })
387
388 struct UefiBootEntry
389 {
390 UefiBootDevice DeviceType;
391 std::wstring VmbFsRootPath;
392 std::wstring DevicePath;
393 std::wstring OptionalData;
394
395 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(UefiBootEntry, DeviceType, VmbFsRootPath, DevicePath, OptionalData);
396 };
397
398 struct Uefi
399 {
400 UefiBootEntry BootThis;
401 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Uefi, BootThis);
402 };
403
404 struct EmptyObject
405 {
406 };
407
408 inline void to_json(nlohmann::json& j, const EmptyObject& memory)
409 {
410 j = nlohmann::json::object();
411 }
412
413 struct HvSocketSystemConfig
414 {
415 std::wstring DefaultBindSecurityDescriptor;
416 std::wstring DefaultConnectSecurityDescriptor;
417
418 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(HvSocketSystemConfig, DefaultBindSecurityDescriptor, DefaultConnectSecurityDescriptor);
419 };
420
421 struct HvSocket
422 {
423 HvSocketSystemConfig HvSocketConfig;
424 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(HvSocket, HvSocketConfig);
425 };
426
427 struct Chipset
428 {
429 bool UseUtc;
430 std::optional<LinuxKernelDirect> LinuxKernelDirect;
431 std::optional<Uefi> Uefi;
432 };
433
434 inline void to_json(nlohmann::json& j, const Chipset& chipset)
435 {
436 j = nlohmann::json{{"UseUtc", chipset.UseUtc}};
437
438 OMIT_IF_EMPTY(j, chipset, LinuxKernelDirect)
439 OMIT_IF_EMPTY(j, chipset, Uefi)
440 }
441
442 struct Scsi
443 {
444 std::map<std::string, Attachment> Attachments;
445 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Scsi, Attachments);
446 };
447
448 struct DebugOptions
449 {
450 std::optional<std::wstring> BugcheckSavedStateFileName;
451 std::optional<std::wstring> ShutdownOrResetSavedStateFileName;
452 };
453
454 inline void to_json(nlohmann::json& j, const DebugOptions& d)
455 {
456 j = nlohmann::json::object();
457 OMIT_IF_EMPTY(j, d, BugcheckSavedStateFileName);
458 OMIT_IF_EMPTY(j, d, ShutdownOrResetSavedStateFileName);
459 }
460
461 enum class VirtualPMemImageFormat
462 {
463 Vhdx,
464 Vhd1
465 };
466
467 NLOHMANN_JSON_SERIALIZE_ENUM(
468 VirtualPMemImageFormat,
469 {
470 {VirtualPMemImageFormat::Vhdx, "Vhdx"},
471 {VirtualPMemImageFormat::Vhd1, "Vhd1"},
472 })
473
474 struct VirtualPMemDevice
475 {
476 std::wstring HostPath;
477 bool ReadOnly;
478 VirtualPMemImageFormat ImageFormat;
479 // uint64_t SizeBytes;
480 // std::map<uint64_t, VirtualPMemMapping> Mappings;
481
482 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(VirtualPMemDevice, HostPath, ReadOnly, ImageFormat);
483 };
484
485 enum class VirtualPMemBackingType
486 {
487 Virtual,
488 Physical
489 };
490
491 NLOHMANN_JSON_SERIALIZE_ENUM(
492 VirtualPMemBackingType,
493 {
494 {VirtualPMemBackingType::Virtual, "Virtual"},
495 {VirtualPMemBackingType::Physical, "Physical"},
496 })
497
498 struct VirtualPMemController
499 {
500 std::map<std::string, VirtualPMemDevice> Devices;
501 uint8_t MaximumCount;
502 uint64_t MaximumSizeBytes;
503 VirtualPMemBackingType Backing;
504
505 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(VirtualPMemController, Devices, MaximumCount, MaximumSizeBytes, Backing);
506 };
507
508 struct Devices
509 {
510 std::optional<VirtioSerial> VirtioSerial;
511 std::map<std::string, ComPort> ComPorts;
512 EmptyObject Plan9;
513 EmptyObject Battery;
514 HvSocket HvSocket;
515 std::map<std::string, Scsi> Scsi;
516 std::optional<VirtualPMemController> VirtualPMem;
517 };
518
519 inline void to_json(nlohmann::json& j, const Devices& devices)
520 {
521 j = nlohmann::json{
522 {"ComPorts", devices.ComPorts},
523 {"Plan9", devices.Plan9},
524 {"Battery", devices.Battery},
525 {"HvSocket", devices.HvSocket},
526 {"Scsi", devices.Scsi}};
527
528 OMIT_IF_EMPTY(j, devices, VirtioSerial);
529 OMIT_IF_EMPTY(j, devices, VirtualPMem);
530 }
531
532 struct VirtualMachine
533 {
534 bool StopOnReset;
535 Chipset Chipset;
536 Topology ComputeTopology;
537 Devices Devices;
538 DebugOptions DebugOptions;
539
540 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(VirtualMachine, StopOnReset, Chipset, ComputeTopology, Devices, DebugOptions);
541 };
542
543 struct ComputeSystem
544 {
545 std::wstring Owner;
546 bool ShouldTerminateOnLastHandleClosed;
547 Version SchemaVersion;
548 VirtualMachine VirtualMachine;
549
550 NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(ComputeSystem, Owner, ShouldTerminateOnLastHandleClosed, SchemaVersion, VirtualMachine)
551 };
552
553 struct GuestErrorSaveReport
554 {
555 std::optional<std::wstring> SaveStateFile;
556 std::optional<long> Status;
557 };
558
559 inline void to_json(nlohmann::json& j, const GuestErrorSaveReport& g)
560 {
561 j = nlohmann::json::object();
562 OMIT_IF_EMPTY(j, g, SaveStateFile);
563 OMIT_IF_EMPTY(j, g, Status);
564 }
565
566 inline void from_json(const nlohmann::json& j, GuestErrorSaveReport& r)
567 {
568 ASSIGN_IF_PRESENT(j, r, SaveStateFile);
569 ASSIGN_IF_PRESENT(j, r, Status);
570 }
571
572 struct CrashReport
573 {
574 std::wstring CrashLog;
575 std::optional<GuestErrorSaveReport> GuestCrashSaveInfo;
576 };
577
578 inline void to_json(nlohmann::json& j, const CrashReport& c)
579 {
580 j = nlohmann::json::object();
581 j.at("CrashLog") = c.CrashLog;
582 OMIT_IF_EMPTY(j, c, GuestCrashSaveInfo);
583 }
584
585 inline void from_json(const nlohmann::json& j, CrashReport& c)
586 {
587 ASSIGN_IF_PRESENT(j, c, CrashLog);
588 ASSIGN_IF_PRESENT(j, c, GuestCrashSaveInfo);
589 }
590
591 enum class NotificationType
592 {
593 None,
594 GracefulExit,
595 ForcedExit,
596 UnexpectedExit,
597 Unknown
598 };
599
600 NLOHMANN_JSON_SERIALIZE_ENUM(
601 NotificationType,
602 {
603 {NotificationType::None, "None"},
604 {NotificationType::GracefulExit, "GracefulExit"},
605 {NotificationType::ForcedExit, "ForcedExit"},
606 {NotificationType::UnexpectedExit, "UnexpectedExit"},
607 {NotificationType::Unknown, "Unknown"},
608 })
609
610 struct GuestCrashAttribution
611 {
612 std::optional<std::vector<uint64_t>> CrashParameters;
613 };
614
615 inline void to_json(nlohmann::json& j, const GuestCrashAttribution& g)
616 {
617 j = nlohmann::json::object();
618 OMIT_IF_EMPTY(j, g, CrashParameters)
619 }
620
621 inline void from_json(const nlohmann::json& j, GuestCrashAttribution& g)
622 {
623 ASSIGN_IF_PRESENT(j, g, CrashParameters);
624 }
625
626 // Attribution record (trimmed to GuestCrash only for now)
627 struct AttributionRecord
628 {
629 std::optional<GuestCrashAttribution> GuestCrash;
630 };
631
632 inline void to_json(nlohmann::json& j, const AttributionRecord& a)
633 {
634 j = nlohmann::json::object();
635 OMIT_IF_EMPTY(j, a, GuestCrash)
636 }
637
638 inline void from_json(const nlohmann::json& j, AttributionRecord& a)
639 {
640 ASSIGN_IF_PRESENT(j, a, GuestCrash);
641 }
642
643 struct SystemExitStatus
644 {
645 int32_t Status;
646 std::optional<NotificationType> ExitType;
647 std::optional<std::vector<AttributionRecord>> Attribution;
648 };
649
650 inline void to_json(nlohmann::json& j, const SystemExitStatus& s)
651 {
652 j = nlohmann::json{{"Status", s.Status}};
653 OMIT_IF_EMPTY(j, s, ExitType);
654 OMIT_IF_EMPTY(j, s, Attribution);
655 }
656
657 inline void from_json(const nlohmann::json& j, SystemExitStatus& s)
658 {
659 s.Status = j.at("Status").get<int32_t>();
660 ASSIGN_IF_PRESENT(j, s, ExitType);
661 ASSIGN_IF_PRESENT(j, s, Attribution);
662 }
663
664 } // namespace wsl::windows::common::hcs
665
666 #undef OMIT_IF_EMPTY