From fea916daccae1a3a0ca05d855125b91276eb65af Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Wed, 17 Aug 2022 20:57:39 +0400 Subject: [PATCH] OCI blob compression: fix Data memory leak when using InputFilter (#183) * OCI blob compression: fix Data memory leak when using InputFilter * Rename mappedDiskOffset to mappedDiskReadOffset * Update progress.completedUnitCount differently --- Sources/tart/VMDirectory+OCI.swift | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Sources/tart/VMDirectory+OCI.swift b/Sources/tart/VMDirectory+OCI.swift index 1789ac75..c6f35d2b 100644 --- a/Sources/tart/VMDirectory+OCI.swift +++ b/Sources/tart/VMDirectory+OCI.swift @@ -117,13 +117,15 @@ extension VMDirectory { // Read VM's compressed disk as chunks // and sequentially upload them as blobs - let disk = try FileHandle(forReadingFrom: diskURL) - var diskReadBytes: UInt64 = 0 - let compressingFilter = try InputFilter(.compress, using: .lz4, bufferCapacity: Self.bufferSizeBytes) { _ in - let data = try disk.read(upToCount: Self.bufferSizeBytes) - diskReadBytes += UInt64(data?.count ?? 0) + let mappedDisk = try Data(contentsOf: diskURL, options: [.alwaysMapped]) + let mappedDiskSize = mappedDisk.count + var mappedDiskReadOffset = 0 + let compressingFilter = try InputFilter(.compress, using: .lz4, bufferCapacity: Self.bufferSizeBytes) { (length: Int) -> Data? in + let bytesRead = min(length, mappedDiskSize - mappedDiskReadOffset) + let data = mappedDisk.subdata(in: mappedDiskReadOffset ..< mappedDiskReadOffset + bytesRead) + mappedDiskReadOffset += bytesRead - progress.completedUnitCount += Int64(data?.count ?? 0) + progress.completedUnitCount = Int64(mappedDiskReadOffset) return data } @@ -145,7 +147,7 @@ extension VMDirectory { let manifest = OCIManifest( config: OCIManifestConfig(size: ociConfigJSON.count, digest: ociConfigDigest), layers: layers, - uncompressedDiskSize: diskReadBytes + uncompressedDiskSize: UInt64(mappedDiskReadOffset) ) // Manifest