Skip to content

feat: expose runtime directory-sharing devices with live share swap#216

Open
jlagedo wants to merge 2 commits into
Code-Hex:mainfrom
jlagedo:feat/runtime-directory-share
Open

feat: expose runtime directory-sharing devices with live share swap#216
jlagedo wants to merge 2 commits into
Code-Hex:mainfrom
jlagedo:feat/runtime-directory-share

Conversation

@jlagedo
Copy link
Copy Markdown

@jlagedo jlagedo commented May 23, 2026

Summary

This adds support for runtime directory sharing: reading the directory-sharing devices off a running VirtualMachine and hot-swapping the directories a guest sees without recreating the VM.

The Virtualization framework exposes VZVirtioFileSystemDevice as a live device on a started VM, with a read/write share property (macOS 12+). Until now vz only surfaced the configuration side (VirtioFileSystemDeviceConfiguration), so callers could set a share before Start() but never change it afterwards. This PR fills that gap.

What's added

VirtualMachine.DirectorySharingDevices() []*VirtioFileSystemDevice
Returns the live directory-sharing devices on a running VM. Mirrors the existing SocketDevices() / USBControllers() accessors. Returns nil on macOS < 12.

VirtioFileSystemDevice — the runtime device (distinct from VirtioFileSystemDeviceConfiguration):

  • SetShare(share DirectoryShare) — swaps the directory share on the running device. The mutation runs on the VM's serial dispatch queue, as the framework requires for all VZVirtualMachine interactions.
  • Share() DirectoryShare — reads back the current share (also on the VM queue), reconstructing the concrete *SingleDirectoryShare / *MultipleDirectoryShare via Obj-C class introspection. Restores get/set symmetry with the underlying share property.

This lets a host add or remove the directories a guest sees while the VM keeps running.

Implementation notes

  • Follows the established runtime-device pattern (socket.go, usb.go): the device wrapper stores the VM's dispatchQueue and embeds *pointer.
  • The device wrapper itself uses no release finalizer — these objects are owned by the VM's array (Apple's get-rule), matching VirtioSocketDevice. Only the value returned by Share() is retained on the C side and released via a Go finalizer, since it crosses the boundary as an owned object.
  • All live calls go through dispatch_sync on the VM queue, consistent with the memory-balloon runtime device.
  • Gated on macOS 12 in both the Go and Objective-C layers.

Testing

make download_kernel && make test (run locally on Apple silicon, codesigned):

  • TestDirectorySharingDevices — a configured file-system device is returned from a created VM.
  • TestVirtioFileSystemDeviceSetShare — boots a VM with a single-directory share, asserts Share() reports *SingleDirectoryShare, mounts in-guest and sees the file; then hot-swaps to a multiple-directory share via SetShare, asserts Share() now reports *MultipleDirectoryShare, remounts in-guest and verifies the swapped-in content is visible while the original file is gone.

Existing TestSingleDirectoryShare / TestMultipleDirectoryShare continue to pass (no regression). go vet ./... is clean.

Test plan

  • go build ./...
  • go vet ./...
  • make test (new + existing shared-directory tests pass, codesigned, real guest)

🤖 Generated with Claude Code

jlagedo and others added 2 commits May 23, 2026 17:46
Add VZVirtualMachine.directorySharingDevices() and a runtime
VirtioFileSystemDevice type with SetShare(), so a host can change which
directories a guest sees on a running VM (macOS 12+) without recreating it.
Apple supports this (VZVirtioFileSystemDevice.share is get/set on the runtime
device, reachable via VZVirtualMachine.directorySharingDevices), but the binding
only exposed the config-time setter.

Mirrors the existing SocketDevices() pattern: NSArray -> ToPointerSlice -> wrap
each pointer with the VM's serial dispatch queue. SetShare runs the mutation on
that queue, as the framework requires.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expose a Share() getter on the running file system device so the directory
share set via SetShare (or at configuration time) can be read back, restoring
get/set symmetry with the VZVirtioFileSystemDevice.share property. The getter
reads on the VM's serial dispatch queue and reconstructs the concrete
*SingleDirectoryShare or *MultipleDirectoryShare via Obj-C class introspection.

Add integration tests covering the runtime directory-sharing API:
- TestDirectorySharingDevices verifies a configured device is returned.
- TestVirtioFileSystemDeviceSetShare boots a VM, asserts the reported share
  type, hot-swaps single -> multiple share at runtime, and verifies the guest
  sees the swapped-in content after remount.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant