目录
1. 前言
特别注意:
2. 实战分享
2.1 常见错误LOG
2.2 解决问题
2.2.1 硬件设计
2.2.2 软件解决
关键系统文件备份
更改文件系统同步机制
针对metadata丢失的对策(来自谷歌的patch)
1. 前言
【问题描述】:
系统启动过程中,或者运行过程中突然断开外部供电(系统异常断电),导致再次供电后系统无法正常启动。
现象:
1. 安卓系统会卡在开机动画
2. 有一部分设备会进入Recovery模式,无法正常开机
【适用产品/场景】:
智能硬件、移动手机、车载座舱类产品;这类产品一般使用安卓、Linux或者Ubuntu这类非试试系统,这类系统一般使用文件系统的。
【适用平台】:
Android/Linux系统,高通移动,IOT和车载平台芯片
特别注意:
在特定的文件系统发生的概率会很高,在移动和IOT平台发生的概率会很高。
复现概率: F2FS文件系统 > EXT4(车载平台使用较多)
PS:具体原因大家可以网络上搜索一下,这里简单说明下原因跟文件系统读写机制有关系,跟文件系统缓存机制有关系。
2. 实战分享
2.1 常见错误LOG
【常见log 1】metadata数据丢失,无效的key
invalid keyblob, decryptWithKeymasterKey失败
E vold : Customer VoldNativeService::mountFstab
E vold : Customer fscrypt_mount_metadata_encrypted: /data needs_encrypt= 0
D vold : Customer read_key metadata_key_dir/key: /metadata/vold/metadata_encryption/key
I hwservicemanager: getTransport: Cannot find entry android.hardware.keymaster@3.0::IKeymasterDevice/default in either framework or device manifest.
I vold : List of Keymaster HALs found:
I vold : Keymaster HAL #1: Keymaster HAL: 4 from QTI SecurityLevel: TRUSTED_ENVIRONMENT HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
D vold : Computing HMAC with params { (seed: 744723236d6e834a1e2cee3198a74f16bb328edc5c8c5e3a6e2b8debad9de8e, nonce: 02f7ac441af115d6e6ad9e61cea9bb07eaa175ece60843172ecfa2fd89c26df) }
D vold : Computing HMAC for Keymaster HAL: 4 from QTI SecurityLevel: TRUSTED_ENVIRONMENT HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
D vdc : Waited 0ms for vold
I vold : Using Keymaster HAL: 4 from QTI for encryption. Security level: TRUSTED_ENVIRONMENT, HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
D vold : Customer read_key nees_cp=1 dir=/metadata/vold/metadata_encryption/key temp=/metadata/vold/metadata_encryption/tmp
D vold : Key exists, using: /metadata/vold/metadata_encryption/key
I hwservicemanager: getTransport: Cannot find entry android.hardware.keymaster@3.0::IKeymasterDevice/default in either framework or device manifest.
I vold : List of Keymaster HALs found:
I vold : Keymaster HAL #1: Keymaster HAL: 4 from QTI SecurityLevel: TRUSTED_ENVIRONMENT HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
I vold : Using Keymaster HAL: 4 from QTI for encryption. Security level: TRUSTED_ENVIRONMENT, HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
E KeymasterUtils: rsp_header->status: -33
E vold : begin failed, code -33
E vold : Customer retrieveKey decryptWithKeymasterKey fail
E vold : Customer read_key retrieveOrGenerateKey fail
E vold : Customer read_key FAIL
【常见log 2】
Failed to read runtime-permissions.xml: /data/misc_de/0/apexdata/com.android.permission/runtime-permissions.xml
--------- beginning of crash
E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: main
E AndroidRuntime: java.lang.IllegalStateException: Failed to read runtime-permissions.xml: /data/misc_de/0/apexdata/com.android.permission/runtime-permissions.xml
E AndroidRuntime: at com.android.permission.persistence.RuntimePermissionsPersistenceImpl.readForUser(RuntimePermissionsPersistenceImpl.java:80)
E AndroidRuntime: at com.android.server.pm.Settings$RuntimePermissionPersistence.readStateForUserSync(Settings.java:5721)
E AndroidRuntime: at com.android.server.pm.Settings.readLPw(Settings.java:3199)
E AndroidRuntime: at com.android.server.pm.PackageManagerService.<init>(PackageManagerService.java:1912)
E AndroidRuntime: at com.android.server.pm.PackageManagerService.main(PackageManagerService.java:1496)
E AndroidRuntime: at com.android.server.SystemServer.startBootstrapServices(SystemServer.java:1235)
E AndroidRuntime: at com.android.server.SystemServer.run(SystemServer.java:939)
E AndroidRuntime: at com.android.server.SystemServer.main(SystemServer.java:651)
E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeIE AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:920)
E AndroidRuntime: Caused by: org.xmlpull.v1.XmlPullParserException: Invalid stream or encoding: java.io.IOException: read failed: EIO (I/O error) (position:START_DOCUMENT null@1:1) caused by: java.io.IOException: read failed: EIO (I/O error)
E AndroidRuntime: at com.android.kxml2.io.KXmlParser.setInput(KXmlParser.java:1809)
E AndroidRuntime: at com.android.permission.persistence.RuntimePermissionsPersistenceImpl.readForUser(RuntimePermissionsPersistenceImpl.java:74)
E AndroidRuntime: ... 10 more
E AndroidRuntime: Error reporting crash
E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke interface method 'void android.app.IActivityManager.handleApplicationCrash(android.os.IBinder, android.app.ApplicationErrorReport$ParcelableCrashInfo)' on a null object reference
E AndroidRuntime: at com.android.internal.os.RuntimeInit$KillApplicationHandler.uncaughtException(RuntimeInit.java:156)
E AndroidRuntime: at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1073)
E AndroidRuntime: at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
E AndroidRuntime: at java.lang.Thread.dispatchUncaughtException(Thread.java:2306)
2.2 解决问题
这里解决问题,大致分为两大类;一是从硬件设计角度规避,二是从软件角度修复和避免问题发生
2.2.1 硬件设计
从问题发生的手法和发生的设备看,我们可以看出来这类问题发生有相同之处,那就是这类设备是自身不带电池的(类似手机的Battery),是靠外部电源供电的(稳压源,电源适配器或者POE供电),受供电稳定性的影响(可以认为是人为直接断电,手机这样的产品因为电池不可拆卸,一般不会发生类似问题),设备会出现突然断电的情况(系统来不及反应,无法保存重要文件)。
- 硬件设计思路:
增加超级电容或者备用电源,在系统突然断电后,由超级电容供电,同时系统进入关机流程,保留关键数据。
- 系统处理流程:
设备异常断电->硬件检测切换到超级电容供电->软件检测供电切换上报低电量->电源模块判断低电量报警触发关机流程->各个模块处理关机流程->设备关机
2.2.2 软件解决
-
关键系统文件备份
如runtime-permissions.xml,packages.xml影响启动的文件进行备份,在系统启动过程中如果发现问题,转而使用备份文件,这样系统就可以继续执行启动过程。
参考代码
后续更新参考代码
-
更改文件系统同步机制
changed userdata fsync_mode from nobarrier to strict
这里特别指的是F2FS这种带缓存机制的文件系统,将文件系统写入缓存改为fsync这种及时写入的方式,防止因为缓存数据没有及时写入磁盘,异常断电造成的文件丢失或者损坏。
文件:default/fstab.qcom
/dev/block/bootdevice/by-name/userdata /data f2fs
-noatime,nosuid,nodev,discard,inlinecrypt,reserve_root=32768,resgid=1065,fsync_mode=nobarrier
+noatime,nosuid,nodev,discard,inlinecrypt,reserve_root=32768,resgid=1065,fsync_mode=strict
-
针对metadata丢失的对策(来自谷歌的patch)
fstab: data=journal,commit=1 for /metadata
Since Ext4 doesn't implement "-o sync", it commits metadata at every 5 secs.
This may cause /metadata corruption.
Bug: 162883014 Signed-off-by: Jaegeuk Kim <jaegeuk@google> Signed-off-by: Randall Huang <huangrandall@google> Change-Id: Icd38754bad1b1529d01165ea8c703c214d20bb4b
-/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync
-wait,formattable,first_stage_mount,check
+/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,data=journal,commit=1
+wait,formattable,first_stage_mount,check
Patch来源:https://cs.android/android/_/android/device/google/coral/+/5af424740c5de0d61dd5a00c9c22d566c3393b60
创作不易,欢迎点赞收藏,欢迎评论交流!
支持原创,从你我做起!
发布评论