cleanup: add scsi disks during VM creation (#13939)
* cleanup: add scsi disks during VM creation * pr feedback --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Ben Hillis committed
Dec 18, 2025 at 19:05 UTC
a4f1f7a1478e156861af864d959568824e422704
3 files changed
+33
-22
src/windows/common/hcs_schema.h
+1
-1
@@ -435,7 +435,7 @@ inline void to_json(nlohmann::json& j, const Chipset& chipset)
435
436
struct Scsi
437
{
438
- std::map<std::string, EmptyObject> Attachments;
438
+ std::map<std::string, Attachment> Attachments;
439
NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Scsi, Attachments);
440
};
441
src/windows/service/exe/WslCoreVm.cpp
+30
-20
@@ -451,27 +451,12 @@ void WslCoreVm::Initialize(const GUID& VmId, const wil::shared_handle& UserToken
451
ReadGuestCapabilities();
452
453
// Mount the system distro.
454
+ // N.B. If using SCSI, the system distro is added during VM creation.
455
switch (m_systemDistroDeviceType)
456
{
456
- case LxMiniInitMountDeviceTypeLun:
457
- m_systemDistroDeviceId =
458
- AttachDiskLockHeld(m_vmConfig.SystemDistroPath.c_str(), DiskType::VHD, MountFlags::ReadOnly, {}, false, m_userToken.get());
459
- break;
460
-
457
case LxMiniInitMountDeviceTypePmem:
458
m_systemDistroDeviceId = MountFileAsPersistentMemory(m_vmConfig.SystemDistroPath.c_str(), true);
459
break;
464
-
465
- default:
466
- break;
467
- }
468
-
469
- // Mount the kernel modules VHD.
470
- ULONG modulesLun = ULONG_MAX;
471
- if (!m_vmConfig.KernelModulesPath.empty())
472
- {
473
- modulesLun =
474
- AttachDiskLockHeld(m_vmConfig.KernelModulesPath.c_str(), DiskType::VHD, MountFlags::ReadOnly, {}, false, m_userToken.get());
460
}
461
462
// Attempt to create and mount the swap vhd.
@@ -543,7 +528,7 @@ void WslCoreVm::Initialize(const GUID& VmId, const wil::shared_handle& UserToken
528
message->EnableSafeMode = m_vmConfig.EnableSafeMode;
529
message->EnableDnsTunneling = m_vmConfig.EnableDnsTunneling;
530
message->DefaultKernel = m_defaultKernel;
546
- message->KernelModulesDeviceId = modulesLun;
531
+ message->KernelModulesDeviceId = m_kernelModulesDeviceId;
532
message.WriteString(message->HostnameOffset, wsl::windows::common::filesystem::GetLinuxHostName());
533
message.WriteString(message->KernelModulesListOffset, m_vmConfig.KernelModulesList);
534
message->DnsTunnelingIpAddress = m_vmConfig.DnsTunnelingIpAddress.value_or(0);
@@ -1729,9 +1714,33 @@ std::wstring WslCoreVm::GenerateConfigJson()
1714
vmSettings.Chipset.Uefi = std::move(uefiSettings);
1715
}
1716
1732
- // Initialize other devices.
1733
- vmSettings.Devices.Scsi["0"] = hcs::Scsi{};
1734
- hcs::HvSocket hvSocketConfig{};
1717
+ // Initialize SCSI devices.
1718
+ hcs::Scsi scsiController{};
1719
+ auto attachDisk = [&](PCWSTR path) {
1720
+ auto lun = ReserveLun();
1721
+ hcs::Attachment disk{};
1722
+ disk.Type = hcs::AttachmentType::VirtualDisk;
1723
+ disk.Path = path;
1724
+ disk.ReadOnly = true;
1725
+ disk.SupportCompressedVolumes = true;
1726
+ disk.AlwaysAllowSparseFiles = true;
1727
+ disk.SupportEncryptedFiles = true;
1728
+ scsiController.Attachments[std::to_string(lun)] = std::move(disk);
1729
+ m_attachedDisks.emplace(AttachedDisk{DiskType::VHD, path, false}, DiskState{lun, {}, {}});
1730
+ return lun;
1731
+ };
1732
+
1733
+ if (m_systemDistroDeviceType == LxMiniInitMountDeviceTypeLun)
1734
+ {
1735
+ m_systemDistroDeviceId = attachDisk(m_vmConfig.SystemDistroPath.c_str());
1736
+ }
1737
+
1738
+ if (!m_vmConfig.KernelModulesPath.empty())
1739
+ {
1740
+ m_kernelModulesDeviceId = attachDisk(m_vmConfig.KernelModulesPath.c_str());
1741
+ }
1742
+
1743
+ vmSettings.Devices.Scsi["0"] = std::move(scsiController);
1744
1745
// Construct a security descriptor that allows system and the current user.
1746
wil::unique_hlocal_string userSidString;
@@ -1740,6 +1749,7 @@ std::wstring WslCoreVm::GenerateConfigJson()
1749
std::wstring securityDescriptor{L"D:P(A;;FA;;;SY)(A;;FA;;;"};
1750
securityDescriptor += userSidString.get();
1751
securityDescriptor += L")";
1752
+ hcs::HvSocket hvSocketConfig{};
1753
hvSocketConfig.HvSocketConfig.DefaultBindSecurityDescriptor = securityDescriptor;
1754
hvSocketConfig.HvSocketConfig.DefaultConnectSecurityDescriptor = securityDescriptor;
1755
vmSettings.Devices.HvSocket = std::move(hvSocketConfig);
src/windows/service/exe/WslCoreVm.h
+2
-1
@@ -242,7 +242,7 @@ private:
242
void ReadGuestCapabilities();
243
244
_Requires_lock_held_(m_lock)
245
- ULONG ReserveLun(_In_ std::optional<ULONG> Lun);
245
+ ULONG ReserveLun(_In_ std::optional<ULONG> Lun = {});
246
247
void RestorePassthroughDiskState(_In_ LPCWSTR Disk) const;
248
@@ -296,6 +296,7 @@ private:
296
bool m_defaultKernel = true;
297
LX_MINI_INIT_MOUNT_DEVICE_TYPE m_systemDistroDeviceType = LxMiniInitMountDeviceTypeInvalid;
298
ULONG m_systemDistroDeviceId = ULONG_MAX;
299
+ ULONG m_kernelModulesDeviceId = ULONG_MAX;
300
wsl::windows::common::hcs::unique_hcs_system m_system;
301
wil::unique_socket m_listenSocket;
302
std::function<void(GUID)> m_onExit;