美文网首页BUG分析
Android 8.1下内置存储sdcard无法挂载

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

作者: 土贝口小土孩 | 来源:发表于2020-08-15 16:43 被阅读0次

    平台:

    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文件,在读到<volumes>标签时,给mPrimaryStorageUuid赋值,从如下文件内容看,异常设备中是有值的。
    异常设备
    2|rk3399:/data/system # cat storage.xml
    <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
    <volumes version="3" primaryStorageUuid="b3929278-9b6d-42b4-bc36-25624ac57088" forceAdoptable="false">
    <volume type="0" fsUuid="5892-50F7" userFlags="1" createdMillis="1596803101624" lastTrimMillis="0" lastBenchMillis="0" />
    <volume type="0" fsUuid="A228-275C" userFlags="1" createdMillis="1592010634266" lastTrimMillis="0" lastBenchMillis="0" />
    <volume type="1" fsUuid="b3929278-9b6d-42b4-bc36-25624ac57088" partGuid="785A63E9-AB9F-4EC6-AB3C-7835858B887D" nickname="SanDisk SD 卡" userFlags="0" createdMillis="1592011533004" lastTrimMillis="0" lastBenchMillis="1592011548005" />
    <volume type="0" fsUuid="6636-3230" userFlags="0" createdMillis="1591193458084" lastTrimMillis="0" lastBenchMillis="0" />
    <volume type="0" fsUuid="6437-3432" userFlags="0" createdMillis="1591776505636" lastTrimMillis="0" lastBenchMillis="0" />
    </volumes>
    
    
    正常设备
    rk3399:/data/system # cat storage.xml
    <volumes version="3" forceAdoptable="false">
    <volume type="0" fsUuid="5892-50F7" userFlags="0" createdMillis="1573013876754" lastTrimMillis="0" lastBenchMillis="0" />
    <volume type="0" fsUuid="8765-4321" userFlags="0" createdMillis="1592815201367" lastTrimMillis="0" lastBenchMillis="0" />
    </volumes>
    
    
    1. 总结
      该问题的解决,可以通过删除 data/system/storage.xml 并重启设备 来完成,这样SMS会重新写这个文件。

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

    相关文章

      网友评论

        本文标题:Android 8.1下内置存储sdcard无法挂载

        本文链接:https://www.haomeiwen.com/subject/dieadktx.html