Android 常用命令和工具解析之存储相关
1 基本概念
2 命令解读
2.1 adb shell df
df 命令主要用于需要检查文件系统上已使用和可用的磁盘空间的数量。如果没有指定文件名,则显示在当前所有挂载的文件系统上可用的空间。其原理是从proc/mounts 或 /etc/mtab 中检索磁盘信息。
注意:df命令并不是来打印当前磁盘各个文件的大小,而是打印当前挂载的文件系统和块设备之间的关系。
df命令平时使用的多的参数是df -h和df -a。
df -a能够打印当前所有文件系统,包括伪的(具有0块的伪文件系统(没有直接绑定到物理设备))、重复的、不可访问的文件系统。
df -h是以人类可读的方式打印,它还会自动过滤到那些没有占空间的文件系统,例如:
C:\Users\pengcheng.ding>adb shell df -h
Filesystem Size Used Avail Use% Mounted on
/dev/block/dm-5 692M 690M 2.0M 100% /
tmpfs 911M 3.1M 908M 1% /dev
tmpfs 911M 0 911M 0% /mnt
/dev/block/dm-6 337M 336M 1.0M 100% /system_ext
/dev/block/dm-7 215M 214M 684K 100% /vendor
/dev/block/dm-8 122M 121M 392K 100% /product
tmpfs 911M 16K 911M 1% /apex
tmpfs 911M 764K 910M 1% /linkerconfig
/dev/block/mmcblk0p7 16M 116K 16M 1% /metadata
/dev/block/mmcblk0p9 2.9M 84K 2.9M 3% /mnt/vendor/protect_f
/dev/block/mmcblk0p10 5.4M 76K 5.4M 2% /mnt/vendor/protect_s
/dev/block/mmcblk0p6 52M 1.6M 50M 4% /mnt/vendor/nvdata
/dev/block/mmcblk0p5 24M 32K 24M 1% /mnt/vendor/nvcfg
/dev/block/mmcblk0p12 38M 52K 38M 1% /mnt/vendor/persist
/dev/block/dm-43 24G 23G 1.0G 96% /data
/dev/block/loop8 22M 22M 28K 100% /apex/com.android.extservices@340090000
/dev/block/loop5 232K 104K 128K 45% /apex/com.android.scheduling@340090000
tmpfs 911M 0 911M 0% /data_mirror
/dev/block/loop7 7.6M 7.6M 28K 100% /apex/com.android.wifi@340090000
/dev/block/loop10 24M 24M 32K 100% /apex/com.android.art@340090000
/dev/block/loop9 3.1M 3.0M 32K 99% /apex/com.android.neuralnetworks@340090000
/dev/block/loop6 232K 196K 36K 85% /apex/com.android.configinfrastructure@340090000
/dev/block/loop13 4.2M 4.2M 32K 100% /apex/com.android.media@340090000
/dev/block/loop12 12M 12M 28K 100% /apex/com.android.vndk.v34@1
/dev/block/loop11 764K 736K 28K 97% /apex/com.android.tzdata@340090000
/dev/block/loop14 14M 14M 32K 100% /apex/com.android.permission@340090000
/dev/block/loop17 2.0M 2.0M 32K 99% /apex/com.android.os.statsd@340090000
/dev/block/loop18 20M 20M 28K 100% /apex/com.android.media.swcodec@340090000
/dev/block/loop16 2.8M 2.8M 28K 100% /apex/com.android.resolv@340090000
/dev/block/loop15 21M 21M 32K 100% /apex/com.android.btservices@340090000
/dev/block/loop19 18M 18M 40K 100% /apex/com.android.adservices@340090000
/dev/block/loop20 488K 460K 28K 95% /apex/com.android.sdkext@340090000
/dev/block/loop22 33M 33M 28K 100% /apex/com.android.i18n@1
/dev/block/loop24 4.1M 4.0M 32K 100% /apex/com.android.adbd@340090000
/dev/block/loop23 14M 14M 28K 100% /apex/com.android.tethering@340090000
/dev/block/loop21 19M 19M 28K 100% /apex/com.android.vndk.v33@1
/dev/block/loop27 8.0M 8.0M 32K 100% /apex/com.android.mediaprovider@340090000
/dev/block/loop31 3.1M 3.1M 32K 100% /apex/com.android.conscrypt@340090000
/dev/block/loop26 3.3M 3.3M 32K 100% /apex/com.android.runtime@1
/dev/block/loop25 12M 12M 28K 100% /apex/com.android.cellbroadcast@340090000
/dev/block/loop29 5.2M 5.2M 32K 100% /apex/com.android.devicelock@1
/dev/block/loop30 2.7M 2.6M 28K 99% /apex/com.android.appsearch@340090000
/dev/block/loop28 2.8M 2.8M 28K 100% /apex/com.android.uwb@340090000
/dev/block/loop32 712K 684K 28K 97% /apex/com.android.ipsec@340090000
/dev/block/loop36 8.4M 8.4M 28K 100% /apex/com.android.healthfitness@340090000
/dev/block/loop34 2.1M 2.1M 32K 99% /apex/com.android.ondevicepersonalization@340090000
/dev/block/loop35 17M 17M 28K 100% /apex/com.android.vndk.v31@1
/dev/block/loop33 252K 220K 32K 88% /apex/com.android.virt@2
/dev/block/loop38 1.0M 0.9M 28K 98% /apex/com.android.rkpd@1
/dev/block/loop37 45M 45M 32K 100% /apex/com.android.vndk.v30@1
/dev/fuse 24G 23G 1.0G 96% /mnt/installer/0/emulated
字段Filesystem
filesystem字段为当前的文件系统类型,通常有如下几个类型:
- /dev/block/dm-*:通常表示设备映射(Device Mapper)的块设备。设备映射是 Linux 内核中的一个功能,用于实现高级磁盘映射和管理功能,例如卷管理、快照等。这些文件系统通常代表实际的磁盘分区或逻辑卷。
- /dev/block/mmcblk0p*:通常表示 MMC 块设备(如 SD 卡、eMMC 等)的分区。这些文件系统代表了存储在移动存储设备上的文件系统。
- /dev/block/loop*:代表回环设备(loop device),用于在文件系统中创建虚拟块设备,可以将文件系统映射为块设备进行访问。
- tmpfs:基于内存的临时文件系统,数据存储在内存中而不是硬盘上。通常用于存储临时数据和文件系统操作。
- /dev/fuse:它是一个特殊的设备文件,用于实现用户空间文件系统(Filesystem in Userspace,FUSE)的功能。FUSE 是一个允许非特权用户创建文件系统的框架,它允许用户空间的程序通过 FUSE 接口来实现文件系统操作,而无需修改内核。这种机制使得开发者可以在用户空间实现各种自定义的文件系统,而无需深入了解内核编程。有些地方将 FUSE 文件系统称为虚拟文件系统,是因为这种文件系统并不是基于硬件设备或真实存储介质的,而是在用户空间中通过程序动态创建的。从内核的角度看,FUSE 文件系统并不是一个传统意义上的文件系统,它是在用户空间中模拟文件系统接口的一种机制。
字段Mounted on
Mounted on字段显示了文件系统挂载的目标路径。
/dev/block/dm-7块设备总大小215M,已经使用214M,挂载在/vendor目录
/dev/block/dm-7 215M 214M 684K 100% /vendor
/apex目录是一个基于内存的临时数据,占用了16K的大小
tmpfs 911M 16K 911M 1% /apex
下面这种看起来是mainline里面的应用,被作为回环设备进行挂载
/dev/block/loop12 12M 12M 28K 100% /apex/com.android.vndk.v34@1
/dev/block/dm-43块设备总大小24G,已经使用23G,挂载在/data目录
/dev/block/dm-43 24G 23G 1.0G 96% /data
/dev/fuse作为虚拟文件系统被挂载在/mnt.installer/0/emulated
/dev/fuse 24G 23G 1.0G 96% /mnt/installer/0/emulated
为什么/dev/fuse和/data使用情况基本保持一致?
2.2 adb shell du
du命令主要用于需要了解系统上的目录或文件所使用的磁盘空间量。当试图识别占用大部分磁盘空间的大文件或目录时,它特别方便。
du命令可以直接遍历当前目录各个子文件或者子文件夹大小,用起来很方便。
其中du --max-depth=1 指定深度为1
2.3 dumpsys devicestoragemonitor
参考Android 系统服务之DeviceStorageMonitorService-CSDN博客
3 Android相关机制
3.1 DeviceStorageMonitorService
DeviceStorageMonitorService是framework中实时检查当前设备是否存在底存储空间状态的服务,他继承于systemserver。 参考Android 系统服务之DeviceStorageMonitorService-CSDN博客
我们可以通过dumpsys devicestoragemonitor来获取他的一些信息。
C:\Users\pengcheng.ding>adb shell dumpsys devicestoragemonitor
Known volumes:
Default:
level=LOW lastUsableBytes=476016640
lowBytes=524288000 fullBytes=1048576
path=/data
mSeq=1 mForceState=UNKNOWN
这里我们接着来讨论一下df命令里面为什么/dev/fuse和/data使用情况基本保持一致?因此我做了如下几个实验:
步骤一:填充/sdcard/Movies,/dev/block/dm-43和/dev/fuse的可用空间为557M
步骤二:确认当前是否处于低存储状态,确认当前还未达到LOW状态
步骤三:adb push 150M文件到/sdcard/Movies目录,确认状态
填充到/sdcard/Movies目录会占用/data目录空间,即/data剩余可用减少了151M从而导致设备进入LOW状态。
此时紧接着继续推送一个55M的文件,能够继续推送成功,即lowBytes并不会阻碍文件存储,但是install应用的地方会去检验这个值。
步骤四:adb push 150M文件到/data目录,确认状态
总结:通过步骤3和步骤4可以看出来/data和/sdcard/目录基本完全一致,他们的设备存储介质是一致的?
3.2 /sdcard目录到是怎么回事?
进入根目录,执行ls -la命令:
D50:/ # ls -la
drwxrwx--x 62 system system 4096 2025-02-24 22:08 data
lrw-r--r-- 1 root root 21 2009-01-01 08:00 sdcard -> /storage/self/primary
进入/storage/self/primary的父目录,执行ls -la命令:
D50:/storage/self # ls -la
lrwxrwxrwx 1 root root 19 2025-02-24 20:00 primary -> /storage/emulated/0
因此我们可以发现/mnt/installer/0/emulated和/storage/emulated基本一致,那么为什么他们是一致的呢?中途也没有发现任何软链接引用的地方?
那么这两个目录和/data目录有什么关联呢?也没有发现任何软链接引用的地方?
因此/mnt/installer/0/emulated和/storage/emulated和/data/media居然指向同样的地方?
- reboot设备在开机logo阶段,执行df -h此时还没有/dev/fuse节点的文件系统,因此此时系统上层还未创建虚拟文件系统,因此针对linux内核来说它就是一个虚拟的。
- 完全开机之后,执行df -h出现了/dev/fuse,但是挂载的路径却变成了/storage/emulated,如下截图,因此这个挂载点可能还是随机的,但都是同一个物理块