@samitouri / QOSAMI-WSL / commits / a4f1f7a1

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;