Android の df コマンドについて
最近 Android 用の mackerel-agent を作ろうとしていて、Android の /proc/meminfo
を読んだりしていたのですが、 filesystem の metrics は df -P
コマンドを使っていました。*1
Android にも df
コマンドは存在していたのでパースしようとしたのですが、バージョンごとの違いなどがあったのでメモ。
バージョンによる挙動
Andorid 6.0.1 (Marshmallow) まで
- Android 6.0 / SO-02H
$ adb shell shell@SO-02H:/ $ df Filesystem Size Used Free Blksize /dev 889.4M 104.0K 889.3M 4096 /sys/fs/cgroup 889.4M 0.0K 889.4M 4096 /sys/fs/cgroup/memory: Permission denied /mnt 889.4M 0.0K 889.4M 4096 /tmp 889.4M 4.0K 889.4M 4096 /system 4.9G 3.9G 1.1G 4096 /data 21.9G 12.1G 9.8G 4096 /oem 503.7M 340.1M 163.6M 4096 /cache 341.0M 304.0K 340.7M 4096 /rca 8.4M 6.4M 1.9M 1024 /idd 14.0M 4.9M 9.0M 1024 /persist 27.5M 804.0K 26.7M 4096 /firmware 80.0M 56.5M 23.5M 16384 /lta-label 11.7M 1.1M 10.6M 4096 /storage 889.4M 0.0K 889.4M 4096 /mnt/runtime/default/emulated: Permission denied /storage/emulated 21.9G 12.1G 9.8G 4096 /mnt/runtime/read/emulated: Permission denied /mnt/runtime/write/emulated: Permission denied
Android 6.0 までの df
コマンドは coreutils の df
とは大きく異なります。
マウントされた先しか見ることが出来ない他、 -h
などのオプションは一切使えません。
$ adb shell
shell@SO-02H:/ $ df -h
Filesystem Size Used Free Blksize
-h: No such file or directory
Android 7.0 (Nougat) 以降? *2
- Android 7.0 / Nexus 5X
$ adb shell bullhead:/ $ df Filesystem 1K-blocks Used Available Use% Mounted on tmpfs 922680 428 922252 1% /dev tmpfs 922680 0 922680 0% /mnt /dev/block/dm-0 2999516 2430552 552580 82% /system /dev/block/dm-1 241908 184160 52752 78% /vendor /dev/block/platform/soc.0/f9824900.sdhci/by-name/cache 92656 4504 86188 5% /cache /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem 88016 56720 31296 65% /firmware /dev/block/dm-2 26094648 12222956 13855308 47% /data /dev/fuse 26094648 12222956 13855308 47% /storage/emulated
Android 7.0 では coreutils と同じ形式になりました。
-h
や -P
などのオプションも使えるようになり便利。
$ adb shell bullhead:/ $ df -h Filesystem Size Used Avail Use% Mounted on tmpfs 901M 428K 901M 1% /dev tmpfs 901M 0 901M 0% /mnt /dev/block/dm-0 2.8G 2.3G 540M 82% /system /dev/block/dm-1 236M 180M 52M 78% /vendor /dev/block/platform/soc.0/f9824900.sdhci/by-name/cache 90M 4.3M 84M 5% /cache /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem 86M 55M 31M 65% /firmware tmpfs 901M 0 901M 0% /storage /dev/block/dm-2 25G 12G 13G 47% /data /dev/fuse 25G 12G 13G 47% /storage/emulated
細かい話
- Android 6.0 までの実装は以下にあり、Android toolbox に含まれていました。
/proc/mounts
から読み取っていますが特にオプションを受け取るなどは行っていません。
platform_system_core/df.c at marshmallow-release · android/platform_system_core · GitHub
Lose df to toybox. · android/platform_system_core@cca6019 · GitHub
toybox とは linux コマンド群の BSD ライセンス実装です*3。
おまけ
toybox 自体は 6.0 から Android に取り込まれているので、toybox を使えば 6.0 でも新しい df
を使えました。
$ adb shell shell@SO-02H:/ $ toybox df Filesystem 1K-blocks Used Available Use% Mounted on tmpfs 910748 104 910644 1% /dev none 910748 0 910748 0% /sys/fs/cgroup tmpfs 910748 0 910748 0% /mnt tmpfs 910748 4 910744 1% /tmp /dev/block/dm-0 5174428 4054116 1103928 79% /system /dev/block/bootdevice/by-name/userdata 22994780 12698312 10280084 56% /data /dev/block/bootdevice/by-name/oem 515776 348284 156844 69% /oem /dev/block/bootdevice/by-name/cache 349136 304 341624 1% /cache /dev/block/bootdevice/by-name/diag 14327 5165 8835 37% /idd /dev/block/bootdevice/by-name/persist 28144 804 26688 3% /persist /dev/block/bootdevice/by-name/modem 81872 57824 24048 71% /firmware /dev/block/bootdevice/by-name/LTALabel 12016 1168 10524 10% /lta-label /dev/fuse 22994780 12698312 10280084 56% /storage/emulated
ただ、toybox のバージョンが少し古いので長い filesystem
に対応できずはみ出しています。*4
ということで、今回は Android 6.0 以前と Android 7.0 以降でパースを分けるという対応になりそうです。toybox
のおかげで色々コマンド打てるようになって便利。
*1:https://github.com/mackerelio/mackerel-agent/blob/master/util/filesystem.go
*2:未来のことはわからない
*3:busybox は GPL2 なので Android のライセンス上含められなかったそう
*4:ここで修正されている https://github.com/landley/toybox/commit/c10638d3b16d065c1efd97ae17c1a8bf417be706