From 4c28821fefe1db75664ffa4ecd62d2bf8b2e8284 Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Wed, 1 Apr 2026 20:17:14 -0700 Subject: [PATCH] LinuxContainer: Move memory clamping to VZ code (#630) The memory limit (clamp to system ram) is a VZ limitation so it's weird that we had that logic directly in LinuxContainer. Someone could make a VZVirtualMachineInstance that doesn't have this limitation but we inherit this logic because it's done before passing off the memory amount to the VMM. --- Sources/Containerization/LinuxContainer.swift | 9 ++------- Sources/Containerization/VZVirtualMachineManager.swift | 5 ++++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Sources/Containerization/LinuxContainer.swift b/Sources/Containerization/LinuxContainer.swift index d49126a6..b43900e6 100644 --- a/Sources/Containerization/LinuxContainer.swift +++ b/Sources/Containerization/LinuxContainer.swift @@ -526,14 +526,9 @@ extension LinuxContainer { // The container cgroup limit stays at the requested memory, but the VM // gets an additional 50MB for the guest agent (could be higher, could be lower // but this is a decent baseline for now). - // - // Clamp to system RAM if the total would exceed it as Virtualization.framework - // bounds us to this. let guestAgentOverhead: UInt64 = 50.mib() - let vmMemory = min( - self.memoryInBytes + guestAgentOverhead, - ProcessInfo.processInfo.physicalMemory - ) + let mib: UInt64 = 1.mib() + let vmMemory = (self.memoryInBytes + guestAgentOverhead + mib - 1) & ~(mib - 1) // Prepare file mounts. This transforms single-file mounts into directory shares. let fileMountContext = try FileMountContext.prepare(mounts: self.config.mounts) diff --git a/Sources/Containerization/VZVirtualMachineManager.swift b/Sources/Containerization/VZVirtualMachineManager.swift index 427c3ad0..27849729 100644 --- a/Sources/Containerization/VZVirtualMachineManager.swift +++ b/Sources/Containerization/VZVirtualMachineManager.swift @@ -52,12 +52,15 @@ public struct VZVirtualMachineManager: VirtualMachineManager { // Use nested virtualization if requested in config or set as default in manager let useNestedVirtualization = vmConfig.nestedVirtualization || self.nestedVirtualization + // Clamp to system RAM as Virtualization.framework bounds us to this. + let memoryInBytes = min(vmConfig.memoryInBytes, ProcessInfo.processInfo.physicalMemory) + return try VZVirtualMachineInstance( group: self.group, logger: self.logger, with: { instanceConfig in instanceConfig.cpus = vmConfig.cpus - instanceConfig.memoryInBytes = vmConfig.memoryInBytes + instanceConfig.memoryInBytes = memoryInBytes instanceConfig.kernel = self.kernel instanceConfig.initialFilesystem = self.initialFilesystem