macOS Catalina 以降、Apple は APFS コンテナ内でシステムデータとユーザーデータを分離する新しいファイルシステム階層を導入しました。システムファイル用に読み取り専用でマウントされる Macintosh HD、アプリケーションや環境設定などユーザーが扱うファイル用に書き込み可能でマウントされる Macintosh HD - Data です。RecoveryOS に使われる Recovery など、ほかのボリュームもあります。
$ diskutil list
/dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *1.0 TB disk0
1: Apple_APFS_ISC Container disk2 524.3 MB disk0s1
2: Apple_APFS Container disk3 994.7 GB disk0s2
3: Apple_APFS_Recovery Container disk1 5.4 GB disk0s3
/dev/disk3 (synthesized):
#: TYPE NAME SIZE IDENTIFIER
0: APFS Container Scheme - +994.7 GB disk3
Physical Store disk0s2
1: APFS Volume Macintosh HD - Data 410.4 GB disk3s1
2: APFS Volume Macintosh HD 8.9 GB disk3s3
3: APFS Snapshot com.apple.os.update-... 8.9 GB disk3s3s1
4: APFS Volume Preboot 4.7 GB disk3s4
5: APFS Volume Recovery 769.9 MB disk3s5
6: APFS Volume VM 2.1 GB disk3s6
各ボリュームの役割は、Apple の APFS Reference に記載されたスーパーブロック構造(apfs_superblock_t)で定義されています。
#define APFS_VOL_ROLE_NONE 0x0000
#define APFS_VOL_ROLE_SYSTEM 0x0001
#define APFS_VOL_ROLE_USER 0x0002
#define APFS_VOL_ROLE_RECOVERY 0x0004
#define APFS_VOL_ROLE_VM 0x0008
#define APFS_VOL_ROLE_PREBOOT 0x0010
#define APFS_VOL_ROLE_INSTALLER 0x0020
#define APFS_VOL_ROLE_DATA 0x0040
#define APFS_VOL_ROLE_BASEBAND 0x0080
これは当時の macOS では新しい仕組みでしたが、iOS では以前から使われていました。システムの起動時には、Macintosh HD(APFS_VOL_ROLE_SYSTEM)と Macintosh HD - Data(APFS_VOL_ROLE_DATA)の内容が firmlink によって結合され、単一の論理ボリュームとして表示されます。
Firmlink
Firmlink はシンボリックリンクに似ていますが、ディレクトリ専用で双方向にたどれます。これにより macOS は Macintosh HD と Macintosh HD - Data の内容を結合できます。たとえば読み取り専用の Macintosh HD にある /Users は、書き込み可能な Macintosh HD - Data の /Shared への firmlink です。Apple の System Integrity Protection(SIP)も自然に機能します。SIP で保護されたシステムアプリケーションは読み取り専用の /System/Applications にあり、ユーザーのアプリケーションは /Applications にインストールされますが、利用者にはどちらもルートの /Applications に統合して見えます。
システムの firmlink は /usr/share/firmlinks にあります。
$ cat /usr/share/firmlinks
/AppleInternal AppleInternal
/Applications Applications
/Library Library
/System/Library/Caches System/Library/Caches
/System/Library/Assets System/Library/Assets
/System/Library/PreinstalledAssets System/Library/PreinstalledAssets
/System/Library/AssetsV2 System/Library/AssetsV2
/System/Library/PreinstalledAssetsV2 System/Library/PreinstalledAssetsV2
/System/Library/CoreServices/CoreTypes.bundle/Contents/Library System/Library/CoreServices/CoreTypes.bundle/Contents/Library
/System/Library/Speech System/Library/Speech
/Users Users
/Volumes Volumes
/cores cores
/opt opt
/private private
/usr/local usr/local
/usr/libexec/cups usr/libexec/cups
/usr/share/snmp usr/share/snmp
独自の Synthetic Firmlink を作成する
Catalina 以降でルート直下のディレクトリを作成するには、synthetic firmlink を使います。
/etcにsynthetic.confというファイルを作成します。- 権限が次のように設定されていることを確認します。
root: read, write
wheel: read
everyone: read
通常は “sudo touch /etc/synthetic.conf” で上記を満たせます。
ディレクトリ /Users/foo/bar を /baz にリンクするには、作成したファイルに次のエントリを追加します。
# create a firmlink named "baz" at / which points to "Users/foo/bar"
baz Users/foo/bar
利用可能なオプションは man synthetic.conf でも確認できます。2 つの値はスペースではなくタブで区切る必要があり、パスの先頭には / を付けない点に注意してください。システムを再起動すると、変更が反映されます。