实现 storaged

Android 8 添加了对 storaged 的支持,这是一种 Android 原生守护程序,用于收集和发布 Android 设备上的存储指标。

  • 对于每日磁盘统计信息,storaged 会定期解析 /sys/block/mmcblk0/stat(eMMC 存储设备)或 /sys/block/sda/stat(非 eMMC 设备)。
  • 对于 eMMC 生命周期,storaged 会解析 /d/mmc0/mmc0:001/ext_csd(如果可用)。
  • 对于应用 I/O 归责,storaged 会定期遍历 /proc/uid_io/stats 并维护解析后的数据,其中包括来自所有应用(而不仅仅是正在运行的应用)的数据。dumpsys 可以调用 storaged 以在错误报告中记录应用 I/O 使用情况。

Diskstat(包括停滞的磁盘统计信息)和 eMMC 信息会记录到 Android 事件日志,平台检查服务会在其中收集日志。

storaged 操作会自动发生,并完全由 Android 框架处理,因此您无需执行任何实现工作。此页面介绍了 storaged 的设计(包括新的接口)以及如何使用它从内核获取 I/O 状态。

storaged 设计

为了实现核算和权限灵活性,storaged 被实现为一个内核模块,该模块返回每个 UID 的 I/O 信息(而不是使用标准的 proc/PID/io)。每个 I/O 请求的原始 I/O 数据将继续存储并在内核 task_struct 中更新,并且内核会跟踪进程何时退出,这样就不会遗漏自上次 storaged 轮询事件以来发生的 I/O 使用情况。

只有当框架将其 UID 切换到前台/后台或 storaged 守护进程请求报告时,该模块才会读取原始数据并进行处理。届时,该模块将从内核导出一个文件节点,用于与框架和 storaged 守护进程进行通信。

storaged 引入了 /proc/uid_io/stats 接口,该接口返回系统中每个 UID 的 I/O 统计信息列表。格式为

<uid>: <foreground read bytes> <foreground write bytes> <foreground read chars> <foreground write chars> <background read bytes> <background write bytes> <background read chars> <background write chars>
  • 读取/写入字节是来自存储设备的 I/O 事件。
  • 读取/写入字符(也以字节为单位)是读取/写入 syscalls 请求的数据。

从内核获取 I/O 状态

要从内核转储 I/O 使用情况,请使用带有 -u 选项的 storaged 命令。

命令:storaged -u

命令输出格式:name/uid fg_rchar fg_wchar fg_rbytes fg_wbytes bg_rchar bg_wchar bg_rbytes bg_wbytes fg_fsync bg_fsync

注意: 此输出类似于 proc/uid_io/stats 的输出。这是因为 storaged 处理来自 /proc/uid_io/stats 的数据并生成其自身的数据。

示例输出

com.google.android.backuptransport  2269  60  0  0  1719845663  143912573  149065728  184180736
com.android.vending  2170  60  0  0  219904796  38693092  174436352  18944000