macOS APFS命令行

在构建 darwin-jail 时,可以看到macOS的chroot目录是非常庞大的,如果没有结合 APFS 卷管理进行有效的 snapshot / clone ,那么jail的价值就非常低。

APFS的GUI程序Disk Utility缺乏一些特定的功能,需要通过命令行来补充(例如不能仅umount而不弹出)。不过,命令行 diskutils 实际上也比较复杂,需要仔细归类整理学习。

警告

我这里的一些案例是我参考学习笔记,针对我自己的笔记本上环境:

当前系统挂载卷情况
Filesystem        Size    Used   Avail Capacity iused ifree %iused  Mounted on
/dev/disk1s1s1   233Gi    10Gi    66Gi    14%    425k  689M    0%   /
devfs            209Ki   209Ki     0Bi   100%     724     0  100%   /dev
/dev/disk1s2     233Gi   2.3Gi    66Gi     4%    2.9k  689M    0%   /System/Volumes/Preboot
/dev/disk1s6     233Gi   7.0Gi    66Gi    10%       7  689M    0%   /System/Volumes/VM
/dev/disk1s5     233Gi   4.0Mi    66Gi     1%      30  689M    0%   /System/Volumes/Update
/dev/disk1s4     233Gi   147Gi    66Gi    70%    1.1M  689M    0%   /System/Volumes/Data
map auto_home      0Bi     0Bi     0Bi   100%       0     0     -   /System/Volumes/Data/home
/dev/disk3s1      16Gi    16Gi   469Mi    98%    524k  4.8M   10%   /Library/Developer/CoreSimulator/Volumes/iOS_21F79
/dev/disk5s1     8.4Gi   8.1Gi   248Mi    98%      13  2.5M    0%   /Library/Developer/CoreSimulator/Cryptex/Images/bundle/SimRuntimeBundle-60102D0A-9DCB-436B-865C-4450EEA066C6
/dev/disk7s1      18Gi    18Gi   472Mi    98%    459k  4.8M    9%   /Library/Developer/CoreSimulator/Volumes/iOS_22C150

你的环境可能不同,需要自行调整。

检查和修复 fsck_apfs

使用Disk Utiulity的首要目标是使用 fsck_apfs 修复,不过需要仔细核对确认需要检查卷的设备名,例如 disk3s1 ,并且检查卷是否加密。

备注

diskutil apfs unlockVolume 是用来解锁一个加密数据卷,这里只是做一个案例演示,我没有加密卷

如果没有指定解锁路径,就会尝试解锁当前根文件系统的数据卷

-W 尝试使用空密码解锁

解锁一个卷并且不挂载卷案例:

解锁卷并且不挂载卷
# 我这里尝试用一个模拟器卷设备来实践
diskutil apfs unlockVolume /dev/disk7s1 -nomount

这里我遇到提示是这个卷已经 unlock 过了,所以实际没有变化:

解锁卷并且不挂载卷,不过卷已经unlock
The APFS Volume disk7s1 is already unlocked (mounted)

对于 unlock 的卷就可以执行 fsck_apfs ,有一些常用选项:

  • -S : 跳过检查 APFS快照

  • -n : 只检查不修复

  • -y : 尝试修复所有找到的错误

  • -q : 执行快速检查(quick check)来验证快照和超级块检查点是否正常

检查APFS
fsck_apfs -n /dev/disk7s1

apfs_fsck 检查不需要 umount ,我的实践案例输出类似如下:

检查APFS输出案例
** Checking the container superblock.
   Checking the checkpoint with transaction ID 378.
** Checking the space manager.
** Checking the space manager free queue trees.
** Checking the object map.
** Checking volume /dev/rdisk7s1.
** Checking the APFS volume superblock.
   The volume iOS 18.2 Simulator was formatted by newfs_apfs (2142.41.2.100.2) and last modified by apfs_sealvolume (2317.60.23.0.1.
** Checking the object map.
** Checking the snapshot metadata tree.
** Checking the snapshot metadata.
** Checking the fsroot tree.
** Checking the file extent tree.
** Checking the extent ref tree.
** Verifying volume object map space.
** Verifying allocated space.
** The volume /dev/rdisk7s1 with UUID 3C7EC13C-C4A2-41D3-99F9-ABE9C63638CF appears to be OK.

其他的一些案例组合:

fsck_apfs 案例
# 检查卷但不修复卷,包括快照
fsck_apfs -n /dev/disk7s1

# 检查卷并自动修复所有错误,包括快照
fsck_apfs -y /dev/disk7s1

# 检查卷但不修复卷,不包括快照
fsck_apfs -n -S /dev/disk7s1

# 检查卷但不修复卷,不包括快照
fsck_apfs -n -S /dev/disk7

使用 diskutil 获取信息

diskutil 提供了获取文件系统信息的功能

  • 快速发现设备标识和简短综述:

设备列表
diskutil list

输出案例:

只有 disk0 是物理存储设备
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:                        EFI EFI                     314.6 MB   disk0s1
   2:                 Apple_APFS Container disk1         250.7 GB   disk0s2

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +250.7 GB   disk1
                                 Physical Store disk0s2
   1:                APFS Volume macOS                   11.2 GB    disk1s1
   2:              APFS Snapshot com.apple.os.update-... 11.2 GB    disk1s1s1
   3:                APFS Volume Preboot                 2.5 GB     disk1s2
   4:                APFS Volume Recovery                1.3 GB     disk1s3
   5:                APFS Volume macOS - 数据            148.5 GB   disk1s4
   6:                APFS Volume VM                      7.5 GB     disk1s6

/dev/disk2 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +17.6 GB    disk2
   1:                 Apple_APFS Container disk3         17.6 GB    disk2s1

/dev/disk3 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +17.6 GB    disk3
                                 Physical Store disk2s1
   1:                APFS Volume iOS 17.5 21F79 Simul... 17.0 GB    disk3s1

/dev/disk4 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +9.0 GB     disk4
   1:                 Apple_APFS Container disk5         9.0 GB     disk4s1

/dev/disk5 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +9.0 GB     disk5
                                 Physical Store disk4s1
   1:                APFS Volume iOS 18.2 Simulator B... 8.7 GB     disk5s1

/dev/disk6 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +19.8 GB    disk6
   1:                 Apple_APFS Container disk7         19.8 GB    disk6s1

/dev/disk7 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +19.8 GB    disk7
                                 Physical Store disk6s1
   1:                APFS Volume iOS 18.2 Simulator      19.3 GB    disk7s1

  • 提供完整的扩展信息列表:

输出完整扩展列表
diskutil info -all

可以看到整个系统完整的磁盘信息:

输出完整扩展列表
  Device Identifier:         disk0
   Device Node:               /dev/disk0
   Whole:                     Yes
   Part of Whole:             disk0
   Device / Media Name:       APPLE SSD AP0256M

   Volume Name:               Not applicable (no file system)
   Mounted:                   Not applicable (no file system)
   File System:               None

   Content (IOContent):       GUID_partition_scheme
   OS Can Be Installed:       No
   Media Type:                Generic
   Protocol:                  PCI-Express
   SMART Status:              Verified

   Disk Size:                 251.0 GB (251000193024 Bytes) (exactly 490234752 512-Byte-Units)
   Device Block Size:         4096 Bytes

   Media OS Use Only:         No
   Media Read-Only:           No
   Volume Read-Only:          Not applicable (no file system)

   Device Location:           Internal
   Removable Media:           Fixed

   Solid State:               Yes
   Virtual:                   No
   Hardware AES Support:      Yes

**********

   Device Identifier:         disk0s1
   Device Node:               /dev/disk0s1
   Whole:                     No
   Part of Whole:             disk0

   Volume Name:               EFI
   Mounted:                   No

   Partition Type:            EFI
   File System Personality:   MS-DOS FAT32
   Type (Bundle):             msdos
   Name (User Visible):       MS-DOS (FAT32)

   OS Can Be Installed:       No
   Media Type:                Generic
   Protocol:                  PCI-Express
   SMART Status:              Verified
   Volume UUID:               E783267B-A4C3-3556-B751-DBED770EB996
   Disk / Partition UUID:     A4B42C4A-9409-44CE-9BF9-FF1F3A1FBA5E
   Partition Offset:          24576 Bytes (6 4096-Byte-Device-Blocks)

   Disk Size:                 314.6 MB (314572800 Bytes) (exactly 614400 512-Byte-Units)
   Device Block Size:         4096 Bytes

   Volume Total Space:        0 B (0 Bytes) (exactly 0 512-Byte-Units)
   Volume Free Space:         0 B (0 Bytes) (exactly 0 512-Byte-Units)

   Media OS Use Only:         No
   Media Read-Only:           No
   Volume Read-Only:          Not applicable (not mounted)

   Device Location:           Internal
   Removable Media:           Fixed

   Solid State:               Yes
   Hardware AES Support:      Yes

**********

   Device Identifier:         disk0s2
   Device Node:               /dev/disk0s2
   Whole:                     No
   Part of Whole:             disk0

   Volume Name:               Not applicable (no file system)
   Mounted:                   Not applicable (no file system)
   File System:               None

   Partition Type:            Apple_APFS
   OS Can Be Installed:       No
   Media Type:                Generic
   Protocol:                  PCI-Express
   SMART Status:              Verified
   Disk / Partition UUID:     6114F496-C5BA-4169-B391-4204FCF43C87
   Partition Offset:          314597376 Bytes (76806 4096-Byte-Device-Blocks)

   Disk Size:                 250.7 GB (250685575168 Bytes) (exactly 489620264 512-Byte-Units)
   Device Block Size:         4096 Bytes

   Media OS Use Only:         No
   Media Read-Only:           No
   Volume Read-Only:          Not applicable (no file system)

   Device Location:           Internal
   Removable Media:           Fixed

   Solid State:               Yes
   Hardware AES Support:      Yes

   This disk is an APFS Physical Store.  APFS Information:
   APFS Container:            disk1
   Fusion Drive:              No

**********

   Device Identifier:         disk1
   Device Node:               /dev/disk1
   Whole:                     Yes
   Part of Whole:             disk1
   Device / Media Name:       APPLE SSD AP0256M

   Volume Name:               Not applicable (no file system)
   Mounted:                   Not applicable (no file system)
   File System:               None

   Content (IOContent):       EF57347C-0000-11AA-AA11-00306543ECAC
   OS Can Be Installed:       No
   Media Type:                Generic
   Protocol:                  PCI-Express
   SMART Status:              Verified
   Disk / Partition UUID:     4A1E5071-CE57-439A-AC03-534611B723A8

   Disk Size:                 250.7 GB (250685575168 Bytes) (exactly 489620264 512-Byte-Units)
   Device Block Size:         4096 Bytes

   Media OS Use Only:         No
   Media Read-Only:           No
   Volume Read-Only:          Not applicable (no file system)

   Device Location:           Internal
   Removable Media:           Fixed

   Solid State:               Yes
   Virtual:                   Yes
   Hardware AES Support:      Yes

   This disk is an APFS Container.  APFS Information:
   APFS Physical Store:       disk0s2
   Fusion Drive:              No
   EFI Driver Version:        2332101001000000
...

可以看到:

  • disk0 是物理介质 APPLE SSD AP0256M

  • disk1APFS Container

  • 非常有用的命令 diskutil apfs list ( 非常类似 ZFS zfs list )

能够以树状结构展示出整个APFS文件系统分布,非常形象
diskutil apfs list

可以清晰地看出APFS的磁盘分布结构

  • 检查所有挂载的卷组:

列出卷组(仅显示containers)
diskutil apfs listVolumeGroups

输出类似:

列出卷组(仅显示containers)
APFS Containers (4 found)
|
+-- Container disk1 4A1E5071-CE57-439A-AC03-534611B723A8
|   |
|   +-> Volume Group 564530EF-88C5-412F-8412-4C16B78006D1
|       =================================================
|       APFS Volume Disk (Role):   disk1s1 (System)
|       Name:                      macOS
|       Volume UUID:               C0DA95D4-1A9C-473E-9DEE-F72D11E07DCB
|       Capacity Consumed:         11240091648 B (11.2 GB)
|       -------------------------------------------------
|       APFS Volume Disk (Role):   disk1s4 (Data)
|       Name:                      macOS - 数据
|       Volume UUID:               564530EF-88C5-412F-8412-4C16B78006D1
|       Capacity Consumed:         148546113536 B (148.5 GB)
|
+-- Container disk3 04883FB1-412C-4A2D-89E4-B10E1E6F9770
|   |
|   +-> No Volume Groups among 1 Volume
|
+-- Container disk5 D007A0BD-6331-488D-9957-E67413333D03
|   |
|   +-> No Volume Groups among 1 Volume
|
+-- Container disk7 89237CE4-8B2E-480E-9446-4C5999F41232
    |
    +-> No Volume Groups among 1 Volume
  • 列出加密(安全Token)用户:

列出加密用户
diskutil apfs listUsers /

输出

列出加密用户
Cryptographic users for disk1s1s1 (2 found)
|
+-- 72C3FE7C-8A09-44A7-A27B-3709437EE746
|   Type: Local Open Directory User
|
+-- 819878E2-1799-467F-A7D3-675A3FD4CCDA
    Type: Local Open Directory User

diskutil 的主要工具

diskutil apfs [verb] 提供了一系列功能:

  • list

  • listSnapshots

  • listVolumeGroups

  • convert : 将HFS+转换为APFS

  • create : 创建一个简单卷

  • createContainer : 创建空白容器

  • deleteContainer

  • resizeContainer

  • addVolume

  • deleteVolume

  • deleteVolumeGroup

  • ...

备注

还有很多参数有待后续实践再补充整理

参考