ハイライト
macOS Sonoma の Virtualization framework は、サイズ変更可能なディスプレイ、VM 状態の保存/復元、Network Block Device(NBD)ストレージ、NVMe コントローラーサポート、Rosetta 2 キャッシュ最適化を追加し、仮想 Mac と Linux VM をより使いやすく、柔軟で、高性能にしました。
主要内容
以前、Virtualization framework で VM を動かすと、ディスプレイ解像度は固定でした。ウィンドウを大きくしても VM 画面は追従せず、黒帯が出るか、手動で解像度を変える必要がありました。仮想 Mac 内での日常作業体験はあまり良くありませんでした。
(01:19)macOS Sonoma は automaticallyReconfiguresDisplay プロパティを追加しました。有効にすると、VM の表示解像度がウィンドウサイズにリアルタイムで追従し、画面利用率が向上します。
もう一つの課題は VM のライフサイクル管理でした。以前は VM を閉じると電源断と同じで、未保存の作業状態はすべて失われました。再起動はコールドブートで、アプリ、ドキュメント、ブラウザータブをすべて開き直す必要がありました。
(01:31)Sonoma は保存と復元を導入しました。実行中の VM をディスクファイルに完全シリアライズし、いつでも保存時点の状態に復元できます。作業進捗のバックアップやタスク切り替えに有用です。
ストレージ面では、以前はディスクイメージをローカルに置くしかありませんでした。今は Network Block Device(NBD)プロトコルでリモートストレージをマウントでき、VM ディスクをリモートサーバー上に置けます。データセンターシナリオで特に価値があります。
(12:04)Linux VM 内の Rosetta 2 性能も向上しました。翻訳キャッシュデーモンが追加され、繰り返し使う x86_64 コードの再翻訳が不要になり、コンパイルやパッケージインストールなど exec 集約タスクが明らかに速くなります。
詳細
サイズ変更可能なディスプレイ
(01:58)VZVirtualMachineView にブール属性 automaticallyReconfiguresDisplay が追加されました。true にすると、ウィンドウサイズ変更が VM の解像度調整を自動通知します。
let virtualMachineView = VZVirtualMachineView()
virtualMachineView.virtualMachine = virtualMachine
virtualMachineView.automaticallyReconfiguresDisplay = true
キーポイント:
VZVirtualMachineViewは Virtualization framework が提供するネイティブビューコンポーネントですautomaticallyReconfiguresDisplayのデフォルトはfalseで、従来の固定解像度動作を維持しますtrueにすると VM 内部が表示設定変更イベントを受け、動的に解像度を調整します- 仮想 Mac と Linux VM の両方がこの機能をサポートします
VM 状態の保存と復元
(04:20)保存前に VM を一時停止し、実行が安定状態であることを確認します:
// virtualMachine is a running VZVirtualMachine.
try await virtualMachine.pause()
let saveFileURL = URL(filePath: "SaveFile.vzvmsave", directoryHint: .notDirectory)
try await virtualMachine.saveMachineStateTo(url: saveFileURL)
キーポイント:
pause()で VM をサスペンドし、CPU 実行を停止しますsaveMachineStateTo(url:)で完全なランタイム状態を指定ファイルに書き込みます- 外部リソース(ディスクイメージなど)は別途コピー/バックアップが必要です
- 保存ファイルはハードウェア暗号化され、他の Mac やユーザーアカウントからは読めません
(04:58)復元時は同一設定から新しい VM インスタンスを作成し、保存ファイルを読み込みます:
let configuration = VZVirtualMachineConfiguration()
// Customize configuration.
let virtualMachine = VZVirtualMachine(configuration: configuration)
let saveFileURL = URL(filePath: "SaveFile.vzvmsave", directoryHint: .notDirectory)
try await virtualMachine.restoreMachineStateFrom(url: saveFileURL)
try await virtualMachine.resume()
キーポイント:
- 復元前に
start()を直接呼ぶとコールドブートになります restoreMachineStateFrom(url:)で保存状態データを読み込みますresume()で実行を再開し、VM は保存時の正確な状態に戻ります- 保存ファイルにはバージョン番号があり、形式非互換時はフレームワークが特定エラーコードを返します
Network Block Device(NBD)ストレージ
(09:28)Virtualization framework は NBD プロトコルのクライアントを実装しています。ストレージは任意の場所の NBD サーバー上に置けます:
let url = URL(string: "nbd://localhost:10809/myDisk")!
let attachment = try VZNetworkBlockDeviceStorageDeviceAttachment(url: url)
let blockDevice = VZVirtioBlockDeviceConfiguration(attachment: attachment)
キーポイント:
VZNetworkBlockDeviceStorageDeviceAttachmentは新しいアタッチメントタイプです- URL 形式は
nbd://host:port/diskNameです VZVirtioBlockDeviceConfigurationまたはVZUSBMassStorageDeviceConfigurationと組み合わせ可能です- VM から完全に透過的で、ストレージがリモートであることは VM から感知できません
(10:02)ネットワーク接続が切断される可能性があるため、delegate で状態変化を監視できます:
let url = URL(string: "nbd://localhost:10809/myDisk")!
let attachment = try VZNetworkBlockDeviceStorageDeviceAttachment(url: url)
let delegate = NetworkBlockDeviceAttachmentDelegate()
attachment.delegate = delegate
let blockDevice = VZVirtioBlockDeviceConfiguration(attachment: attachment)
キーポイント:
- delegate は
VZNetworkBlockDeviceStorageDeviceAttachmentDelegateプロトコルに準拠します - 接続切断時は VM を一時停止するか再接続を試みます
- 特殊イメージ形式や物理ドライブなど、カスタム I/O ロジックは NBD サーバー側で実装できます
NVMe コントローラーサポート
(11:21)一部 Linux カーネルには virtio ドライバーがありませんが、通常 NVMe ドライバーはあります。Sonoma は NVMe コントローラーのエミュレーションを追加しました:
let nvmeDevice = VZNVMExpressControllerDeviceConfiguration(attachment: attachment)
キーポイント:
VZNVMExpressControllerDeviceConfigurationは新しいデバイスタイプです- Linux VM のみ。仮想 Mac は引き続き virtio block を推奨します
- NBD アタッチメントもサポートします
Rosetta 2 キャッシュ最適化
(13:46)Linux VM 内の Rosetta 2 に翻訳キャッシュデーモンが追加されました。通信チャネルを設定し、VM 内でデーモンを起動する必要があります:
// Rosetta 2 ランタイムとキャッシュデーモンの通信チャネルを設定
let rosettaConfiguration = VZRosettaDirectoryShare()
// VM 内でデーモン起動後、動的リンク要求はデーモンへ転送
// Rosetta 2 ランタイムはデーモンから事前翻訳済みバイナリを直接取得
キーポイント:
- 翻訳結果はディスクにキャッシュされ、複数 App で共有されます
- 同一ライブラリ/実行ファイルの再翻訳を回避します
- コンパイル、パッケージインストールなど exec 集約タスクで最も効果が大きいです
重要ポイント
-
スナップショット機能付き VM マネージャーを作る
saveMachineStateToとrestoreMachineStateFromで App 終了時に VM 状態を自動保存し、次回起動を瞬時に- 実装:
applicationWillTerminateで保存 API を呼び、App ライフサイクルイベントを監視
-
リモート開発環境を構築
- NBD で VM ディスクを社内サーバーやクラウドホストに置き、ローカル Mac は計算のみ実行
- 実装:NBD サーバーを構築し、
VZNetworkBlockDeviceStorageDeviceAttachmentでリモートディスクをマウント
-
x86 Linux 互換テストツールを作る
- Rosetta 2 キャッシュ最適化で Apple Silicon Mac 上で x86_64 Linux ビルド/テストを高速実行
- 実装:Linux VM を作成、Rosetta 2 を有効化、共有フォルダでプロジェクトコードをマウント
-
解像度適応型の仮想デスクトップクライアント
automaticallyReconfiguresDisplayを有効化し、リモート仮想デスクトップが常にローカルウィンドウを埋める- 実装:
VZVirtualMachineView作成時に属性を設定し、コンテナビューのサイズ変化を監視
関連セッション
- Create macOS or Linux virtual machines — WWDC22 の Virtualization framework 入門。本 Session の前に基礎を学ぶのに適しています
- What’s new in Swift — 本 Session の API は Swift async/await を多用。最新 Swift 機能の理解が API 利用に役立ちます
- Meet SwiftData — VM 管理 App で設定とスナップショットメタデータを永続化するなら SwiftData が理想です
コメント
GitHub Issues · utterances