Android 8.1下内置存储sdcard无法挂载

平台:

Rockchip 3399
Android 8.1

问题:

开机后,内置/sdcard分区不可访问,无法挂载,/storage/xxxx对应得是外置存储卡,可以访问。

涉及源码

StorageManagerService (如下简称SMS)
VoldConnector
Vold (system/vold)

分析

  1. 首先看mount结果,与正常设备做对比,发现问题设备没有挂载/data/media


    image.png

    虽然有区别, 但是无法看出问题所在。

  2. 对比SMS中开机时发送的vold指令


    image.png

此处发现,问题设备(左)没有发送下面的命令

SND -> {5 volume mount emulated 3 -1}

这也是解决此问题的关键。

  1. 分析SMS的源码,发现有两处会发送 volume mount 指令给vold。
    一处是mount函数,这个函数一般是通过StorageManager然后通过binder调用过来的,更多时候是给其他service,乃至APP使用,所以分析时我认定此处不是触发volume mount命令的根源,通过添加log也确认了此想法。
    另一处,是SMS中的handler收到H_VOLUME_MOUNT消息时发出的


    image.png
  2. 分析H_VOLUME_MOUNT的发出,这个消息的发出也有好几处地方,通过添加log,确认在onVolumeCreatedLocked函数中发出,但是这里也有好几个分支


    image.png

通过分析更多的log,正常和异常设备,开始时都会调用两次onVolumeCreatedLocked,并且有两种type都会调用,TYPE_EMULATED和PUBLIC,但是通过第3步中命令对比,可以发现问题出现在TYPE_EMULATED这个if分支中,异常设备中,并没有发出SND -> {5 volume mount emulated 3 -1}
原因就是正常设备中,mPrimaryStorageUuid这个字段开机时会被初始化为null,而异常设备不会。如下log
异常设备

image.png

正常设备

image.png

所以在异常设备中,因为mPrimaryStorageUuid这个字段的存在,导致无法执行正确的代码逻辑,没有发出SND -> {5 volume mount emulated 3 -1}指令。

  1. mPrimaryStorageUuid 这个字段的赋值,这个字段是在SMS的构造函数中完成初始化的,SMS的构造函数调用了readSettingsLocked函数,在这个函数中,会解析 /data/system/storage.xml文件,在读到标签时,给mPrimaryStorageUuid赋值,从如下文件内容看,异常设备中是有值的。
异常设备
2|rk3399:/data/system # cat storage.xml










正常设备
rk3399:/data/system # cat storage.xml





  1. 总结
    该问题的解决,可以通过删除 data/system/storage.xml 并重启设备 来完成,这样SMS会重新写这个文件。

但是出现该问题的原因还无法确定,因为出现问题时的log已经没有,即便有,相关信息也比较少,无法定位。
我分析比较可能的原因是插入了一个android设备无法识别(可能是格式问题)的外置存储卡导致,并且从storage.xml中可以看到,异常的uuid是很长一大串的随机数,一些正常的外置卡,则比较规律。

你可能感兴趣的:(Android 8.1下内置存储sdcard无法挂载)