High Sierraが発表され,新しいファイルシステムであるAPFS(Apple File System)への期待が高まっています.
使っているという声は聞こえてきませんが,APFS自体はすでにSierraに実装されています.
そこで,APFSのRamDiskを作ってみたり,APFSの特徴であるスナップショットなどを試してみたいと思います.
(ググってもググっても出てこなかったので,断片的な情報をつなぎ合わせてみた,というのが正しいところです)
注意事項
本記事の内容は無保証です.
APFSのスナップショット機能は,Appleから正式にアナウンスのあったものではありません.
コマンド名が変更されることは容易に予想できますし,正式版のスナップショットとのデータの互換性も保証しません.
sudoを使用しているため,操作を間違うとあなたのmacOSに損害を与える可能性もあります.
上記のことを理解した上でお試しください.
APFSフォーマットのRamDisk作成
まずは肩慣らしとして,APFSフォーマットのRamDiskを作成してみます.
なお,この作業は次節の内容とは無関係なので,興味がなければ読み飛ばしていただいて構いません.
基本的にはhdiutilコマンドでメモリ上にディスクイメージの容量を確保し,diskutilコマンドでパーティション作成とフォーマットを行いマウントします.
今回は実験用に10MBというごく小さなRamDiskを確保しています.
1セクタのサイズは512byteなので,hdiutilコマンドのram://
に続く数字と,diskutilコマンドの最後のパラメータ(10mは10MBを表す)を適当に計算して調整してください.
$ hdiutil attach -nomount ram://20480
/dev/disk4 // ←の名前を↓に書く
$ diskutil partitionDisk /dev/disk4 1 apfs test 10m
Started partitioning on disk4
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk4s1 as APFS with name test
spaceman_metazone_init:262: not creating spaceman metazone, container is only 10444800 bytes, block_size 4096 block count 2550
spaceman_metazone_init:262: not creating spaceman metazone, container is only 10444800 bytes, block_size 4096 block count 2550
nx_mount:981: checkpoint search: largest xid 1, best xid 1 @ 1
nx_mount:1043: sanity checking all nx state... please be patient
apfs_newfs:14968: FS will NOT be encrypted
Mounting disk
Finished partitioning on disk4
/dev/disk4 (disk image):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme +10.5 MB disk4
1: Apple_APFS 10.4 MB disk4s1
$ diskutil ap list
APFS Container (1 found)
|
+-- Container disk5 89E211AE-CE3B-416D-B904-CDCE5A9C9AE6
====================================================
APFS Container Reference: disk5
Capacity Ceiling (Size): 10444800 B (10.4 MB)
Capacity In Use By Volumes: 376832 B (376.8 KB) (3.6% used)
Capacity Available: 10067968 B (10.1 MB) (96.4% free)
|
+-< Physical Store disk4s1 F70DCEE3-D6EE-433E-A221-875C41E80DDF
| -----------------------------------------------------------
| APFS Physical Store Disk: disk4s1
| Size: 10444800 B (10.4 MB)
|
+-> Volume disk5s1 EC206B01-7A86-4F51-8A1B-DED10FF54493
---------------------------------------------------
APFS Volume Disk (Role): disk5s1 (No specific role)
Name: test
Mount Point: /Volumes/test
Capacity Consumed: 24576 B (24.6 KB)
Capacity Reserve: None
Capacity Quota: None
Encrypted: No
$
エラーがなければ/Volumes/testにマウントされています.
lsコマンドやmountコマンドでご確認ください.
$ ls -F /Volumes/
Macintosh HD@ Ramdisk/ test/
$ mount
/dev/disk2 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
/dev/disk3s1 on /Volumes/Ramdisk (hfs, local, nodev, nosuid, noowners, mounted by suda)
/dev/disk5s1 on /Volumes/test (apfs, local, nodev, nosuid, journaled, noowners, mounted by suda)
$
APFSフォーマットのディスクイメージの作成
続いて,APFSフォーマットのディスクイメージ(dmgファイル)を作成してみます.
以下の例では前節で作成したRamDisk上にディスクイメージを置いていますが,どこに置いても構いません.
また,サイズを5MBとしていますが,適当に変更してください.
$ hdiutil create -fs APFS -volname "APFS" -size 5MB /Volumes/test/test.dmg
WARNING: You are using a pre-release version of the Apple File System called
APFS which is meant for evaluation and development purposes only. Files
stored on this volume may not be accessible in future releases of OS X.
You should back up all of your data before using APFS and regularly back up
data while using APFS, including before upgrading to future releases of OS X.
Continue? [y/N] y
created: /Volumes/test/test.dmg
$ hdiutil mount /Volumes/test/test.dmg
/dev/disk6 GUID_partition_scheme
/dev/disk6s1 Apple_APFS
/dev/disk7 EF57347C-0000-11AA-AA11-0030654
/dev/disk7s1 41504653-0000-11AA-AA11-0030654 /Volumes/APFS
$
エラーがなければ/Volumes/APFSにマウントされています.
lsコマンドやmountコマンドでご確認ください.
$ ls /Volumes/
APFS Macintosh HD Ramdisk test
$ mount
/dev/disk2 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
/dev/disk3s1 on /Volumes/Ramdisk (hfs, local, nodev, nosuid, noowners, mounted by suda)
/dev/disk5s1 on /Volumes/test (apfs, local, nodev, nosuid, journaled, noowners, mounted by suda)
/dev/disk7s1 on /Volumes/APFS (apfs, local, nodev, nosuid, journaled, noowners, mounted by suda)
$
mountコマンドの他に,diskutilコマンドを使用してAPFSファイルシステムのマウント状態を表示する方法があります.
$ diskutil apfs list
APFS Containers (2 found)
|
+-- Container disk5 89E211AE-CE3B-416D-B904-CDCE5A9C9AE6
| ====================================================
| APFS Container Reference: disk5
| Capacity Ceiling (Size): 10444800 B (10.4 MB)
| Capacity In Use By Volumes: 5619712 B (5.6 MB) (53.8% used)
| Capacity Available: 4825088 B (4.8 MB) (46.2% free)
| |
| +-< Physical Store disk4s1 F70DCEE3-D6EE-433E-A221-875C41E80DDF
| | -----------------------------------------------------------
| | APFS Physical Store Disk: disk4s1
| | Size: 10444800 B (10.4 MB)
| |
| +-> Volume disk5s1 EC206B01-7A86-4F51-8A1B-DED10FF54493
| ---------------------------------------------------
| APFS Volume Disk (Role): disk5s1 (No specific role)
| Name: test
| Mount Point: /Volumes/test
| Capacity Consumed: 5267456 B (5.3 MB)
| Capacity Reserve: None
| Capacity Quota: None
| Encrypted: No
|
+-- Container disk7 1A3CEC30-ADAE-4E3F-B350-68710E632A4D
====================================================
APFS Container Reference: disk7
Capacity Ceiling (Size): 5201920 B (5.2 MB)
Capacity In Use By Volumes: 405504 B (405.5 KB) (7.8% used)
Capacity Available: 4796416 B (4.8 MB) (92.2% free)
|
+-< Physical Store disk6s1 45CBBF41-7B07-4BFB-AB8B-E8F02C087A34
| -----------------------------------------------------------
| APFS Physical Store Disk: disk6s1
| Size: 5201920 B (5.2 MB)
|
+-> Volume disk7s1 4A3DFDAB-92BB-4C8E-83E3-4963840C8DE2
---------------------------------------------------
APFS Volume Disk (Role): disk7s1 (No specific role)
Name: APFS
Mount Point: /Volumes/APFS
Capacity Consumed: 49152 B (49.2 KB)
Capacity Reserve: None
Capacity Quota: None
Encrypted: No
スナップショットを作成・復元する方法
まずは/Volumes/APFSにファイルを作っておきます.
$ touch /Volumes/APFS/foo.txt
$ touch /Volumes/APFS/bar.txt
$ touch /Volumes/APFS/baz.txt
$ ls -l /Volumes/APFS/
total 0
-rw-r--r-- 1 suda staff 0 7 3 15:13 bar.txt
-rw-r--r-- 1 suda staff 0 7 3 15:13 baz.txt
-rw-r--r-- 1 suda staff 0 7 3 15:13 foo.txt
$
スナップショットの作成
続けて,testsnapという名称のスナップショットを作成します.
警告が出るので,読んでおいてください.
なお,スナップショットは多数作成できます.
$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs_snapshot -c testsnap /Volumes/APFS
WARNING: You are using apfs_snapshot utility on pre-release version of the
Apple File System called APFS which is meant for evaluation and development
purposes only. Please note that apfs_snapshot may be removed in a future
release and should only be used for testing.
$
スナップショットの確認
作成したスナップショットを確認してみましょう.
警告のあとにtestsnapという文字が見えています.
$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs_snapshot -l /Volumes/APFS
WARNING: You are using apfs_snapshot utility on pre-release version of the
Apple File System called APFS which is meant for evaluation and development
purposes only. Please note that apfs_snapshot may be removed in a future
release and should only be used for testing.
testsnap (xid: 6)
$
スナップショットをリードオンリーでマウント
下記のようにファイルを増やした(=ファイルシステムの内容を書き換えた)場合でも,予め作成しておいたスナップショットをマウントすれば,スナップショット作成時点でのファイルを入手できます.
$ touch /Volumes/APFS/qux.txt
$ touch /Volumes/APFS/quux.txt
$ touch /Volumes/APFS/corge.txt
$ ls -l /Volumes/APFS/
total 0
-rw-r--r-- 1 suda staff 0 7 3 15:13 bar.txt
-rw-r--r-- 1 suda staff 0 7 3 15:13 baz.txt
-rw-r--r-- 1 suda staff 0 7 3 15:26 corge.txt
-rw-r--r-- 1 suda staff 0 7 3 15:13 foo.txt
-rw-r--r-- 1 suda staff 0 7 3 15:26 quux.txt
-rw-r--r-- 1 suda staff 0 7 3 15:26 qux.txt
$
それでは,スナップショットをリードオンリーで/tmp/testsnapにマウントしてみます.
$ mkdir /tmp/testsnap
$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/mount_apfs -s testsnap /Volumes/APFS/ /tmp/testsnap
Password:
mount_apfs: snapshot implicitly mounted readonly
$
あとは/tmp/testsnapから必要なファイルを救出してください.
ここでは,mountコマンドとlsコマンドでマウント状態とスナップショットの内容を確認するにとどめておきます.
$ mount
/dev/disk2 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
/dev/disk3s1 on /Volumes/Ramdisk (hfs, local, nodev, nosuid, noowners, mounted by suda)
/dev/disk5s1 on /Volumes/test (apfs, local, nodev, nosuid, journaled, noowners, mounted by suda)
/dev/disk7s1 on /Volumes/APFS (apfs, local, nodev, nosuid, journaled, noowners, mounted by suda)
testsnap@/Volumes/APFS on /private/tmp/testsnap (apfs, local, read-only, journaled)
$ ls -l /tmp/testsnap
total 0
-rw-r--r-- 1 suda staff 0 7 3 15:13 bar.txt
-rw-r--r-- 1 suda staff 0 7 3 15:13 baz.txt
-rw-r--r-- 1 suda staff 0 7 3 15:13 foo.txt
$
禁断の奥義:ファイルシステムをスナップショット作成時に巻き戻す
スナップショットは内部の仕組みがどうであれ,バックアップです.
つまり,ある瞬間のバックアップの状態にファイルシステムを巻き戻すことも可能です.
あまり使う場面が想像できないのですが,一応その方法を書いておきます.
まずは,先ほどリードオンリーマウントした/tmp/testsnap
をアンマウントしておきます.
$ sudo umount /tmp/testsnap
続けてファイルシステムを巻き戻します.
注意点として,巻き戻しただけではまだ新しいファイルが存在します.
このタイミングで新しいファイルを書き込んだときにどうなるのか興味がありますが,おとなしくアンマウント→マウントしておきましょう.
$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs_snapshot -b testsnap /Volumes/APFS
WARNING: You are using apfs_snapshot utility on pre-release version of the
Apple File System called APFS which is meant for evaluation and development
purposes only. Please note that apfs_snapshot may be removed in a future
release and should only be used for testing.
Revert will take place on remount of Volume
$ ls /Volumes/APFS/
bar.txt baz.txt corge.txt foo.txt quux.txt qux.txt
$ umount /Volumes/APFS
$ hdiutil mount /Volumes/test/test.dmg
/dev/disk6 GUID_partition_scheme
/dev/disk6s1 Apple_APFS
/dev/disk7 EF57347C-0000-11AA-AA11-0030654
/dev/disk7s1 41504653-0000-11AA-AA11-0030654 /Volumes/APFS
$ ls /Volumes/APFS/
bar.txt baz.txt foo.txt
$
※スナップショットを複数撮った上で上記作業を行うと,巻き戻したファイルシステム以降に撮ったスナップショットが全て無くなります.
あとがき
ファイルを書き換えた後に,やはり元のファイルが必要だったという経験は誰しもが通る道だと思います.
そのようなときのために,ZFSなどではスナップショット機能を利用した{アワリー|デイリー|ウィークリー}バックアップが役に立ちます.
実際に筆者も研究室のファイルサーバをZFSで運用しており,スナップショット機能を利用したデイリーバックアップを提供しています.
macOSにはTimeMachineという仕組みがあるので,わざわざスナップショットを撮る必要性があるか?と問われると何とも言えませんが,あれば何かの際に役に立つと思い,その方法を公開します.