开机慢issue分析
工作中遇到一个开机时间慢的issue。
解这类问题的步骤一般都是固定的,主要是从boot各阶段分别分析,同时与正常的进行对比。
具体的关键字以及工具等,可以参考QCOM的相关文档,或者我的另一篇blog也会进行部分总结。对于这部分,本人经验还不是特别足,见谅。
好了,直接看问题吧。
issue1:开机时间比正常的多20s左右。
抓取log分析:
Device log:
12-31 20:31:47.198 663 931 W vold : Found symlink /proc/753/fd/7 referencing /data/vendor/iop/io-prefetcher.db 12-31 20:31:47.295 663 931 W vold : Sending Terminated to 753
12-31 20:31:48.886 663 931 W vold : Found symlink /proc/1012/fd/7 referencing /data/vendor/iop/io-prefetcher.db 12-31 20:31:48.886 663 931 W vold : Sending Killed to 1012
上面的log中显示vold进程send Terminated 信号给pid 753的进程。我们知道terminated 终止信号,对应的signal号就是15。
紧接着又发了killed信号给pid 1012的进程。killed信号对应signal 9。
Kernel log:
<14>[ 10.702102] c7 1 init: starting service 'iop-hal-2-0'... ... <14>[ 30.165415] c5 1 init: Service 'iop-hal-2-0' (pid 753) received signal 15 <14>[ 30.165434] c5 1 init: Sending signal 9 to service 'iop-hal-2-0' (pid 753) process group... <14>[ 30.165630] c5 1 libprocessgroup: Successfully killed process cgroup uid 0 pid 753 in 0ms <14>[ 30.168037] c5 1 init: starting service 'iop-hal-2-0'... <14>[ 31.756452] c7 1 init: Service 'iop-hal-2-0' (pid 1012) received signal 9 <14>[ 31.756472] c7 1 init: Sending signal 9 to service 'iop-hal-2-0' (pid 1012) process group... <14>[ 31.756613] c7 1 libprocessgroup: Successfully killed process cgroup uid 0 pid 1012 in 0ms
发现kernel log中,iop-hal-2-0 service收到了signal 15、signal 9。导致了服务重启。init的服务就是整个启动流程的一部分,当完成所有init中的工作时,才算开机完成。因此,服务的重启会影响整个开机的时间。
那么为什么vold会去杀iop-hal-2-0 service呢?
后来了解到:由于项目使用了全盘加密功能(Full Disk Encryption)。开机过程中会对磁盘进行加密,但是iop service一开机就创建了一个database,这个DB是在FDE之前创建的,并且创建在了一个临时的data区上。所以,当vold发现有service使用了临时data区;而当加密完成后,临时data区会被remove掉,那么vold就会主动去kill对应的进程。
后续将创建DB的流程放在FDE之后,就可以解决这个issue了。或者等FDE完成后,再让iop service创建DB。
issue2:开机第一次,如果设置了密码锁,解锁之后,会有20s左右的黑屏时间,进入home idle界面很慢,总共花费40s多。未设置密码锁的,不受影响。
这个问题与issue1实际是同样的问题,还是由于FDE功能这个元凶。在解锁界面时,其实是输完密码,验证正确之后,会进行解锁。那么没输密码前,此时的data区还是临时区,当解锁完成后,还是会将临时data区删掉。那么IOP service就还是会被杀掉。
这条log就不贴了,与上面log十分相似。
其实我们可以在解密之后,再让IOP service创建DB,那就不会有这个问题了。可以自行添加prop的方法,在init.rc中on post-fs-data之后,设置一个prop,然后让IOP service读取这个prop,当prop被设置之后,才开始创建DB。
但是因为我司代码多个项目公用,为了统一方案不引起其他平台出问题,最后解决方案是回退QCOM的修改:仍然把创建DB的步骤放在了第一次调用io-prefetch的地方。