User Data Checkpoint(UDC)

分类: bet28365365体育投注 时间: 2025-08-11 09:20:26 作者: admin 阅读: 7722 点赞: 360
User Data Checkpoint(UDC)

目录背景实现机制源码解析1. Checkpoint模块1.1 cp_needsCheckpointcheckpointing的流程mount_all阶段挂载data分区时ActivityManager finishBoot阶段管理 keymaster 密钥监控运行状况checkpoint配置验证参考

背景

​ 由于AB升级的回滚机制只支持到early_boot阶段,如果OTA升级的过程中,data分区被修改了,并且OTA升级失败了,则data分区是无法回滚到之前的状态的。UDC功能是为了解决OTA升级失败后,当data分区被修改后,不支持回滚data分区的问题。UDC同时支持绑定key版本以及防止key回滚的功能。

实现机制

​ 对于f2fs,UDC添加checkpoint功能到4.20版本的内核中,其他版本的内核也可以移植该功能过去。所以,f2fs系统是默认支持checkpoint功能的。对于在 /data 装载的设备,请将 checkpoint=fs 标记添加到 fstab 的 部分。

​ 对于其他文件系统,UDC会使用dm-bow,必须在内核配置中启用 dm-bow。对于在 /data 装载的设备,请将 checkpoint=block 标记添加到 fstab 的 部分。

源码解析

1. Checkpoint模块

init: Calling: /system/bin/vdc checkpoint needsCheckpoint -> vold->needsCheckpoint(&enabled) -> cp_needsCheckpoint

1.1 cp_needsCheckpoint

bool cp_needsCheckpoint() {

std::lock_guard lock(isCheckpointingLock);

// Make sure we only return true during boot. See b/138952436 for discussion

// 已经checkpoint过了,就直接返回了

if (needsCheckpointWasCalled) return isCheckpointing;

needsCheckpointWasCalled = true;

bool ret;

std::string content;

sp module = IBootControl::getService();

if (isCheckpointing) return isCheckpointing;

// 正常情况isSlotMarkedSuccessful返回为true,不走进去

if (module && module->isSlotMarkedSuccessful(module->getCurrentSlot()) == BoolResult::FALSE) {

// OTA阶段为false,走这里;返回true

isCheckpointing = true;

return true;

}// const std::string kMetadataCPFile = "/metadata/vold/checkpoint";

// 找不到文件,返回false

ret = android::base::ReadFileToString(kMetadataCPFile, &content);

if (ret) {

ret = content != "0";

isCheckpointing = ret;

return ret;

}

return false; // 正常情况返回false

}

checkpointing的流程

mount_all阶段挂载data分区时

调用cp_needsCheckpoint函数:如果是OTA升级阶段或者是第一次刷固件的时候(调用boot_ctrl判断当前slot是否已经Marked Successful了,如果没有,表明此时处于OTA升级阶段或者是第一次刷固件的时候,需要进行checkpoint),则返回true;正常情况就是false

如果上面返回true,则调用UpdateCheckpointPartition函数:mount data分区的时候加上checkpoint=disable选项。然后如果OTA升级失败了,就可以恢复到这个点上了。

ActivityManager finishBoot阶段

调用cp_commitChanges函数:调用boot_ctrl的markBootSuccessful函数,以及用checkpoint=enable选项,重新挂载data分区(f2fs文件系统就会自动将对data分区的改动写入data分区中,表明OTA升级成功)。

ActivityManager: About to commit checkpoint

如果在mount_all到finishboot期间,OTA升级失败并重启了,则写入到data分区的数据重启之后全部无效。这就达到了data分区回滚的目的了。

管理 keymaster 密钥

​ Keymaster 密钥用于设备加密或其他目的。为管理这些密钥,Android 特地推迟到提交检查点之后才调用密钥删除命令。

监控运行状况

​ 该线程在开机的post-fs-data:vdc checkpoint prepareCheckpoint阶段运行,要在start checkpoint之后才会运行该线程。运行状况守护进程会检查是否有足够的磁盘空间来创建检查点。运行状况守护进程位于 Checkpoint.cpp 中的 cp_healthDaemon 内。

​ 默认表现:当data分区的可用空间小于100M的时候,它就会提交检查点(cp_commitChanges提交对data分区的修改)或者重启设备(放弃对data分区的修改)。

运行状况守护进程具有以下可配置的行为:

ro.sys.cp_msleeptime:控制设备检查磁盘使用情况的频率。(隔多久去检查磁盘的可用空间,默认为1秒钟)

ro.sys.cp_min_free_bytes:控制运行状况守护进程查找的最小值。(可用空间的最小值,默认为100M)

ro.sys.cp_commit_on_full:控制运行状况守护进程在磁盘已满时,是重新启动设备还是提交检查点并继续运行。

checkpoint配置

在device/softwinner/ceres-common/init.sun50iw10p1.rc文件的on fs中添加

mount_all /vendor/etc/fstab.sun50iw10p1 --early

在device/softwinner/ceres-common/init.sun50iw10p1.rc文件的on late-fs中添加

mount_all /vendor/etc/fstab.sun50iw10p1 --late

在device/softwinner/ceres-b3/fstab.sun50iw10p1文件的data分区中添加latemount和checkpoint=fs

/dev/block/by-name/UDISK /data f2fs noatime,nosuid,nodev,discard wait,check,formattable,quota,reservedsize=33554432,fileencryption=aes-256-xts:aes-256-cts,latemount,checkpoint=fs

在device/softwinner/ceres-b3/fstab.sun50iw10p1文件的metadata分区中添加first_stage_mount。

/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,errors=panic wait,first_stage_mount,formattable,check

在device/softwinner/ceres-b3/BoardConfig.mk文件中添加:

BOARD_USES_METADATA_PARTITION := true

验证

要测试您的 UDC 实现,请运行 VTS 测试的 VtsKernelCheckpointTest 测试集。

参考

1. f2fs: checkpoint disabling

https://lwn.net/Articles/763072/

相关推荐