Skip to content

Commit

Permalink
data: support sparse copy across volumes
Browse files Browse the repository at this point in the history
Use copyfile(3) with COPYFILE_DATA_SPARSE flag which attempts to
preserve sparseness when copying across different volumes, which
FileManger.copyItem(at:, to:) doesn't. Cloning behaviour from
FileManger.copyItem(at:, to:) is preserved with the COPYFILE_CLONE flag.
  • Loading branch information
ktprograms authored and osy committed Mar 6, 2023
1 parent 53902a3 commit 95a9eb1
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions Platform/UTMData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ class UTMData: ObservableObject {
let newName: String = newDefaultVMName(base: vm.detailsTitleLabel)
let newPath = UTMVirtualMachine.virtualMachinePath(newName, inParentURL: documentsURL)

try fileManager.copyItem(at: vm.path, to: newPath)
try copyItemWithCopyfile(at: vm.path, to: newPath)
guard let newVM = UTMVirtualMachine(url: newPath) else {
throw NSLocalizedString("Failed to clone VM.", comment: "UTMData")
}
Expand All @@ -487,7 +487,7 @@ class UTMData: ObservableObject {
if fileManager.fileExists(atPath: url.path) {
try fileManager.removeItem(at: url)
}
try fileManager.copyItem(at: sourceUrl, to: url)
try copyItemWithCopyfile(at: sourceUrl, to: url)
}

/// Save a copy of the VM and all data to arbitary location and delete the original data
Expand Down Expand Up @@ -635,6 +635,15 @@ class UTMData: ObservableObject {
await listAdd(vm: vm)
await listSelect(vm: vm)
}

func copyItemWithCopyfile(at srcURL: URL, to dstURL: URL) throws {
// let state = copyfile_state_alloc()
let status = copyfile(srcURL.path, dstURL.path, nil, copyfile_flags_t(COPYFILE_ALL | COPYFILE_RECURSIVE | COPYFILE_CLONE | COPYFILE_DATA_SPARSE))
// copyfile_state_free(state)
if status < 0 {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno))
}
}

// MARK: - Downloading VMs

Expand Down

0 comments on commit 95a9eb1

Please sign in to comment.