Android14 Settings属性断电上电不记忆问题分析解决
文章目录
一、前言
Android 系统如果修改了Settings属性后等几秒再断电上电会有属性未保存的情况。
比如,开关wifi和时间同步等开关,修改开关状态后,进行断电上电关开机 会发现有状态不保存的问题。
wifi开关或者同步时间开关这些数据都是Settings.Global属性保存在data目录下的文件数据。
一般手机和平板断电不换马上关机,是有大屏设备或者机顶盒等设备会出现这个问题。
之前Android9不记得是否会有这个问题了,但是Android13 和 Android14 是必现的。
这个问题是Android共性问题,如果想要了解的可以收藏查看。
二、分析解决
1、问题原因
data写入数据之后,没有及时回写磁盘就会发生这种不保存的情况。
其实这种情况不仅仅是Settings属性,其他data目录下保存的数据也可以出现这个问题。
你修改对应数据,当场cat这个文件可能是保存的,
但是断电上电重启后,你回发现还是之前的数据值。
为啥cat 到的数据是缓存数据,而不是磁盘的数据,这个我也不清楚具体原理!
2、问题解决
这个问题有三个方法解决,其实都是和执行同步数据相关。
只是手段不同和效果不同。
(1)同步一下修改文件的整个目录
需要修改两个文件
①system/core/fs_mgr/fs_mgr_fstab.cpp
system/core$ git diff fs_mgr/fs_mgr_fstab.cpp
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index f5ab5571f..4874a3da6 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -74,6 +74,7 @@ FlagList kMountFlagsList[] = {
{"slave", MS_SLAVE},
{"shared", MS_SHARED},
{"defaults", 0},
+ {"dirsync", MS_DIRSYNC},
};
off64_t CalculateZramSize(int percentage) {
上面这个文件是系统原生的,大概是添加执行同步目录的意思。
可以看到这里是在定义命令后续加了 {“dirsync”, MS_DIRSYNC}。
这里只是添加了定义,并未执行。
第二个的修改,可能不同的供应商会有不同的目录。
②/device/rockchip/common/scripts/fstab_tools/fstab.in
这个目录一看就知道是RK方案上的目录。
/device/rockchip/common$ git diff scripts/fstab_tools/fstab.in
diff --git a/scripts/fstab_tools/fstab.in b/scripts/fstab_tools/fstab.in
index 2ec6c265..07c701f4 100755
--- a/scripts/fstab_tools/fstab.in
+++ b/scripts/fstab_tools/fstab.in
@@ -23,6 +23,6 @@ ${_block_prefix}odm /odm ext4 ro,barrier=1 ${_flags},first_stage_mount
# For sdmmc
/devices/platform/${_sdmmc_device}/mmc_host* auto auto defaults voldmanaged=sdcard1:auto
# Full disk encryption has less effect on rk3326, so default to enable this.
-/dev/block/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065 latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,reservedsize=128M,checkpoint=fs
+/dev/block/by-name/userdata /data f2fs noatime,nosuid,nodev,dirsync,discard,reserve_root=32768,resgid=1065 latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,reservedsize=128M,checkpoint=fs
上面看的代码很多,其实就是在 /dev/block/by-name/userdata /data 后面加了 dirsync 命令的执行。
上面是加在 nodev 关键字后面,不清楚加在末尾或者其他位置是否会有影响。
有兴趣的可以试试。
其他方案的这个文件目录一般是:
/device/google/cuttlefish/shared/config/fstab.in
具体内容是差不多的。
(2)修改data分区的格式
修改fstab.in 和 recovery.fstab 为ext4
ext4 的读写应该没有f2fs快,不过没有电池或者掉电的话,用ext4可能会比较好,它的掉电稳定性会好一点。
①fstab.in
+++ b/release/device/google/cuttlefish/shared/config/fstab.in
@@ -5,7 +5,7 @@
# Add all non-dynamic partitions except system, after this comment
-/dev/block/by-name/userdata /data f2fs nodev,XXX
+/dev/block/by-name/userdata /data ext4 nodev,XXX
②recovery.fstab
在RK方案下的文件目录:
\device\rockchip\rk3588\rk3588_u\recovery.fstab
/dev/block/by-name/cache /cache ext4 defaults defaults
/dev/block/by-name/metadata /metadata ext4 defaults defaults
-/dev/block/by-name/userdata /data f2fs defaults defaults
+/dev/block/by-name/userdata /data ext4 defaults defaults
把data分区的格式替换成了 ext4 格式,这样数据修改后系统会及时sync。
这个也是为啥保存在system的prop属性,修改后,断电上电也能保存成功的原因。
但是带来的影响是data下面的数据复制可能会慢一些。
311D2 方案的文件目录:
./amlogic/common/recovery/recovery.fstab
3、Java代码中执行shell的sync命令
//do sync
public static void fileSync() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//sync
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("sync");
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
这里是等待1秒后,再执行sync命令;
因为sync执行一次其实很快,一般十几毫秒;
有可能数据还未成功设置到缓存中,延迟一下比较保险。
wifi开关后,执行一下这个sync 的代码方法,也是可以让这个系统同步数据的,从而保存数据到磁盘中。
其实代码中执行sync并不是一定会马上同步,估计是在系统不忙的情况会同步。
三、其他
1、三种同步操作解决方法总结
上面三种方法,大致情况:
第一种是修改文件后,会执行当前目录会被执行sync,不确定是不是data目录的sync;
第二种是修改data 的分区格式,也是会及时sync;
第三种是直接执行sync,进行同步操作。
如果是大屏设备存在断电马上关机的情况,建议是第二种方法;
如果是不行影响系统,只是某一些属性需要快速记忆就使用第三种就行方法。
第一种方法,在3588 Android14 试过,烧录后会导致系统无法正常启动。
其实第一种和第二种方法,在不同的系统如果对这些属性不了解的情况,
直接修改 也是可能导致系统异常的。
所以还是要编译验证才知道效果。
很多方案需要修改配置的文件位置可能不同,需要使用find命令在源码查找一下。
find . -name fs_mgr_fstab.cpp
find . -name fstab.in
find . -name recovery.fstab
不同方案具体情况不同,这里的修改也是仅供参考。
如果要测试对data分析读写速度的影响,可以用一个大文件从U判断复制到sdcard目录,对比分区修改前后的影响看看,如果没啥影响最好。
在验证中发现,有少数的Settings属性是默认不记忆的,
比如wifi开关、同步时间属性是有断电上电不记忆的,但是蓝牙属性是断电上电会记忆的;
这种情况,有可能是蓝牙在开关过程有做其他操作,系统会有类似sync的动作。
2、mount命令查看各分区下的格式:
mount 命令可以查看各分区的情况,但是日志太多了,最好过滤一下
console:/ #
console:/ # mount | grep "on /data "
/dev/block/dm-8 on /data type f2fs (rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,alloc_mode=default,checkpoint_merge,fsync_mode=posix,discard_unit=block,memory=normal)
console:/ # mount | grep "on /d^C
130|console:/ #
130|console:/ #
130|console:/ #
130|console:/ # mount | grep "on /system "
1|console:/ # mount | grep "on /vendor "
/dev/block/dm-3 on /vendor type ext4 (ro,seclabel,relatime)
console:/ #
1|console:/ # mount | grep "on /system"
/dev/block/dm-1 on /system_dlkm type ext4 (ro,seclabel,relatime)
/dev/block/dm-2 on /system_ext type ext4 (ro,seclabel,relatime)
console:/ #
可以看到data目录下是f2fs格式,system、vendor是 ext4 格式。
3、Android13 wifi状态问题分析
https://blog.csdn.net/wenzhi20102321/article/details/130411508