mount_all
目录
概述
rc文件中的配置
on fs
mount_all /vendor/etc/fstab.sun50iw10p1 --early
on late-fs
mount_all /vendor/etc/fstab.sun50iw10p1 --late
这个--early和--late是用在metadata加密的,如果不使用metadata加密,一般是不需要配置--early和--late的
涉及模块文档:
fs_mgr模块-system文件系统管理的主模块
UDC_checkpoint文档
bootctl hal文档
fstab文件
system,vendor,product,metadata都已经挂载了,emmc类型的和voldmanaged的都会去掉,所以mount_all阶段就是挂载userdata的
# Android fstab file.
# The filesystem that contains the filesystem checker binary (typically /system) cannot
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
system /system ext4 ro,barrier=1 wait,first_stage_mount,logical,slotselect,avb=vbmeta,avb_keys=/avb/q-gsi.avbpubkey:/avb/r-gsi.avbpubkey:/avb/s-gsi.avbpubkey
vendor /vendor ext4 ro,barrier=1 wait,first_stage_mount,logical,slotselect
product /product ext4 ro,barrier=1 wait,first_stage_mount,logical,slotselect
# 有check标志,是每次都会运行fsck.f2fs工具的
# wait是等待分区可用
# formattable是可以进行格式化,第一次烧固件就进行格式化操作了
# quota是vold的has_quota属性的
# checkpoint=fs和A/B ota相关
# latemount和fileencryption=aes-256-xts:aes-256-cts,keydirectory=/metadata/vold/metadata_encryption和文件加密相关
# reservedsize=128M和vold的has_reserved属性有关
/dev/block/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,reserve_root=128000,resuid=0,resgid=1065 wait,check,formattable,quota,reservedsize=128M,latemount,checkpoint=fs,fileencryption=aes-256-xts:aes-256-cts,keydirectory=/metadata/vold/metadata_encryption
/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,errors=panic wait,first_stage_mount,formattable,check
/dev/block/by-name/boot /boot emmc defaults defaults
/dev/block/by-name/misc /misc emmc defaults defaults
/dev/block/by-name/super /super emmc defaults defaults
/dev/block/by-name/frp /persistent emmc defaults defaults
/devices/platform/*/4020000.sdmmc/mmc_host/mmc* auto auto defaults voldmanaged=extsd:auto,encryptable=footer
/devices/platform/**/usb* auto auto defaults voldmanaged=usb:auto,encryptable=footer
# add for recovery
none /sdcard emmc defaults defaults,recoveryonly
第一次烧固件开机的log
[ 11.236138] init: processing action (late-fs) from (/vendor/etc/init/hw/init.sun50iw10p1.rc:47)
// checkpoint相关的
[ 11.247418] init: Calling: /system/bin/vdc checkpoint needsCheckpoint
[ 11.272073] vdc: Waited 0ms for vold
[ 11.281566] init: [libfs_mgr]fs_mgr_do_resize: Reszie /dev/block/by-name/userdata as '0'
[ 11.290826] init: [libfs_mgr]dev_sz: 26884947456
[ 11.296900] init: [libfs_mgr]f2fs_sz: 0
[ 11.301315] init: [libfs_mgr]no need resize
[ 11.306052] init: [libfs_mgr]Resize success
[ 11.311258] init: [libfs_mgr]Invalid f2fs superblock on '/dev/block/by-name/userdata'
// 第一次烧固件,肯定挂载失败了
[ 11.320284] init: [libfs_mgr]mount_with_alternatives(): skipping mount due to invalid magic, mountpoint=/data blk_dev=/dev/block/mmcblk0p24 rec[3].fs_type=f2fs
[ 11.337010] init: [libfs_mgr]fs_mgr_mount_all(): /dev/block/mmcblk0p24 is wiped and /data f2fs is formattable. Format it.
[ 11.349343] init: [libfs_mgr]fs_mgr_do_format: Format /dev/block/by-name/userdata as 'f2fs'
// 进行格式化操作的
[ 11.375482] make_f2fs:
[ 11.378286] make_f2fs: F2FS-tools: mkfs.f2fs Ver: 1.13.0 (2019-09-24)
[ 11.385636] make_f2fs:
[ 11.388433] make_f2fs: Info: Disable heap-based policy
[ 11.394235] make_f2fs: Info: Debug level = 1
[ 11.399032] make_f2fs: Info: Trim is enabled
[ 11.403837] make_f2fs: Info: Set conf for android
[ 11.409119] make_f2fs: Info: No support kernel version!
[ 11.415080] make_f2fs: Info: wanted sectors = 6563707 (in 4096 bytes)
[ 11.422297] make_f2fs: Info: total device sectors = 52509663 (in 512 bytes)
[ 11.430116] make_f2fs: Info: Segments per section = 1
[ 11.435786] make_f2fs: Info: Sections per zone = 1
[ 11.441166] make_f2fs: Info: sector size = 512
[ 11.446148] make_f2fs: Info: total sectors = 52509656 (25639 MB)
[ 11.452891] make_f2fs: Info: zone aligned segment0 blkaddr: 512
[ 11.459528] make_f2fs: Info: add quota type = 0 => 4
[ 11.465099] make_f2fs: Info: add quota type = 1 => 5
[ 11.470669] make_f2fs: Info: add quota type = 2 => 6
[ 11.476270] make_f2fs: Info: [/dev/block/by-name/userdata] Discarding device
[ 12.189656] make_f2fs: Info: Secure Discarded 0 MB
[ 12.195259] make_f2fs: [f2fs_init_sit_area: 556] Filling sit area at offset 0x00600000
[ 12.204416] make_f2fs: [f2fs_init_nat_area: 590] Filling nat area at offset 0x00a00000
[ 12.341886] make_f2fs: [f2fs_write_root_inode:1170] Writing root inode (hot node), b000 0 200 at offset 0x00045056
[ 12.353745] make_f2fs: [f2fs_write_default_quota:1246] Writing quota data, at offset 0000b601, 0000b602
[ 12.364586] make_f2fs: [f2fs_write_qf_inode:1337] Writing quota inode (hot node), b000 0 200 at offset 0x00045057
[ 12.376215] make_f2fs: [f2fs_write_default_quota:1246] Writing quota data, at offset 0000b603, 0000b604
[ 12.386966] make_f2fs: [f2fs_write_qf_inode:1337] Writing quota inode (hot node), b000 0 200 at offset 0x00045058
[ 12.398639] make_f2fs: [f2fs_write_default_quota:1246] Writing quota data, at offset 0000b605, 0000b606
[ 12.409379] make_f2fs: [f2fs_write_qf_inode:1337] Writing quota inode (hot node), b000 0 200 at offset 0x00045059
[ 12.421093] make_f2fs: [f2fs_update_nat_root:1391] Writing nat root, at offset 0x00000a00
[ 12.430496] make_f2fs: [f2fs_add_default_dentry_root:1588] Writing default dentry root, at offset 0x0000b600
[ 12.441713] make_f2fs: Info: Overprovision ratio = 1.250%
[ 12.447879] make_f2fs: Info: Overprovision segments = 324 (GC reserved = 167)
[ 12.456003] make_f2fs: [f2fs_write_check_point_pack: 734] Writing main segments, cp at offset 0x00000200
[ 12.466878] make_f2fs: [f2fs_write_check_point_pack: 871] Writing Segment summary for HOT/WARM/COLD_DATA, at offset 0x00000201
[ 12.479883] make_f2fs: [f2fs_write_check_point_pack: 898] Writing Segment summary for HOT_NODE, at offset 0x00000202
[ 12.491912] make_f2fs: [f2fs_write_check_point_pack: 910] Writing Segment summary for WARM_NODE, at offset 0x00000203
[ 12.504025] make_f2fs: [f2fs_write_check_point_pack: 921] Writing Segment summary for COLD_NODE, at offset 0x00000204
[ 12.516117] make_f2fs: [f2fs_write_check_point_pack: 929] Writing cp page2, at offset 0x00000205
[ 12.526181] make_f2fs: [f2fs_write_check_point_pack: 949] Writing NAT bits pages, at offset 0x000003ff
[ 12.536853] make_f2fs: [f2fs_write_check_point_pack: 970] Writing cp page 1 of checkpoint pack 2, at offset 0x00000400
[ 12.549041] make_f2fs: [f2fs_write_check_point_pack: 989] Writing cp page 2 of checkpoint pack 2, at offset 0x00000405
[ 12.561305] make_f2fs: [f2fs_write_super_block:1022] Writing super block, at offset 0x00000000
[ 13.188665] make_f2fs: Info: format successful
[ 13.194106] init: [libfs_mgr]fs_mgr_do_resize: Reszie /dev/block/by-name/userdata as '0'
[ 13.203307] init: [libfs_mgr]dev_sz: 26884947456
[ 13.209508] init: [libfs_mgr]f2fs_sz: 26884943872
[ 13.214808] init: [libfs_mgr]no need resize
[ 13.219513] init: [libfs_mgr]Resize success
// 进行fsck检查操作
[ 13.225111] init: [libfs_mgr]Running /system/bin/fsck.f2fs -a -c 10000 --debug-cache/dev/block/mmcblk0p24
[ 13.252678] fsck.f2fs: Info: Fix the reported corruption.
[ 13.258937] fsck.f2fs: Info: No support kernel version!
[ 13.264937] fsck.f2fs: Info: Segments per section = 1
[ 13.270605] fsck.f2fs: Info: Sections per zone = 1
[ 13.275987] fsck.f2fs: Info: sector size = 512
[ 13.280967] fsck.f2fs: Info: total sectors = 52509663 (25639 MB)
[ 13.287710] fsck.f2fs: Info: MKFS version
[ 13.292213] fsck.f2fs: "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 13.302177] fsck.f2fs: Info: FSCK version
[ 13.306680] fsck.f2fs: from "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 13.317110] fsck.f2fs: to "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 13.327549] fsck.f2fs: Info: superblock features = 1499 : encrypt verity extra_attr project_quota quota_ino casefold
[ 13.339458] fsck.f2fs: Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
[ 13.349518] fsck.f2fs: Info: total FS sectors = 52509656 (25639 MB)
[ 13.356554] fsck.f2fs: Info: CKPT version = 572a842f
[ 13.362118] fsck.f2fs: Info: checkpoint state = 185 : trimmed nat_bits compacted_summary unmount
[ 13.372139] fsck.f2fs: Info: No error was reported
[ 13.377550] fsck.f2fs:
[ 13.380312] fsck.f2fs: c, u, RA, CH, CM, Repl=
[ 13.385364] fsck.f2fs: 10000 9 9 0 9 0
[ 13.397390] F2FS-fs (mmcblk0p24): Using encoding defined by superblock: utf8-12.1.0 with flags 0x0
[ 13.429037] F2FS-fs (mmcblk0p24): Found nat_bits in checkpoint
[ 13.661510] F2FS-fs (mmcblk0p24): Mounted with checkpoint version = 572a842f
// 第一次烧固件,是会挂载成功的
[ 13.669659] init: [libfs_mgr]__mount(source=/dev/block/by-name/userdata,target=/data,type=f2fs)=0: Success
// 文件加密相关的操作
[ 13.725598] init: Calling: /system/bin/vdc cryptfs encryptFstab /dev/block/by-name/userdata /data
[ 13.752659] vdc: Waited 0ms for vold
// 进行第二次check操作
[ 16.766064] fsck.f2fs: Info: Fix the reported corruption.
[ 16.772299] fsck.f2fs: Info: No support kernel version!
[ 16.778305] fsck.f2fs: Info: Segments per section = 1
[ 16.783984] fsck.f2fs: Info: Sections per zone = 1
[ 16.789370] fsck.f2fs: Info: sector size = 4096
[ 16.794457] fsck.f2fs: Info: total sectors = 6563707 (25639 MB)
[ 16.801111] fsck.f2fs: Info: MKFS version
[ 16.805614] fsck.f2fs: "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 16.815585] fsck.f2fs: Info: FSCK version
[ 16.820092] fsck.f2fs: from "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 16.830534] fsck.f2fs: to "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 16.840980] fsck.f2fs: Info: superblock features = 1499 : encrypt verity extra_attr project_quota quota_ino casefold
[ 16.852894] fsck.f2fs: Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
[ 16.862999] fsck.f2fs: [update_superblock: 624] Info: Done to update superblock
[ 16.871215] fsck.f2fs: Info: total FS sectors = 6563707 (25639 MB)
[ 16.878176] fsck.f2fs: Info: CKPT version = 572a8433
[ 16.883755] fsck.f2fs: Info: checkpoint state = 1c5 : trimmed nat_bits crc compacted_summary unmount
[ 16.894117] fsck.f2fs: Info: No error was reported
[ 16.899498] fsck.f2fs:
[ 16.902244] fsck.f2fs: c, u, RA, CH, CM, Repl=
[ 16.907239] fsck.f2fs: 10000 9 9 0 9 0
[ 16.912662] init: Unable to set property 'ro.boottime.init.fsck.data' from uid:0 gid:0 pid:202: Read-only property was already set
[ 16.933008] F2FS-fs (dm-4): Using encoding defined by superblock: utf8-12.1.0 with flags 0x0
[ 16.965890] F2FS-fs (dm-4): Found nat_bits in checkpoint
[ 17.201568] F2FS-fs (dm-4): Mounted with checkpoint version = 572a8433
[ 17.209722] init: Unable to set property 'ro.boottime.init.mount.data' from uid:0 gid:0 pid:202: Read-only property was already set // 向内核添加keyring
[ 17.243155] init: Keyring created with id 51077959 in process 1
[ 17.250665] init: Command 'mount_all /vendor/etc/fstab.sun50iw10p1 --late' action=late-fs (/vendor/etc/init/hw/init.sun50iw10p1.rc:49) took 6004ms and succeeded
正常开机的log
[ 11.430645] init: Calling: /system/bin/vdc checkpoint needsCheckpoint
[ 11.455321] vdc: Waited 0ms for vold
[ 11.464582] init: [libfs_mgr]fs_mgr_do_resize: Reszie /dev/block/by-name/userdata as '0'
[ 11.473827] init: [libfs_mgr]dev_sz: 26884947456
[ 11.480031] init: [libfs_mgr]f2fs_sz: 0
[ 11.484364] init: [libfs_mgr]no need resize
[ 11.489154] init: [libfs_mgr]Resize success
[ 11.494464] init: [libfs_mgr]Invalid f2fs superblock on '/dev/block/by-name/userdata'
// 由于是metadata加密,所以,第一次挂载是失败的
[ 11.503480] init: [libfs_mgr]mount_with_alternatives(): skipping mount due to invalid magic, mountpoint=/data blk_dev=/dev/block/mmcblk0p24 rec[3].fs_type=f2fs
// 进入metadata加密
[ 11.520133] init: Calling: /system/bin/vdc cryptfs mountFstab /dev/block/by-name/userdata /data
// 进行fsck操作
[ 11.546879] vdc: Waited 0ms for vold
[ 11.589325] fsck.f2fs: Info: Fix the reported corruption.
[ 11.595552] fsck.f2fs: Info: No support kernel version!
[ 11.601536] fsck.f2fs: Info: Segments per section = 1
[ 11.607209] fsck.f2fs: Info: Sections per zone = 1
[ 11.612584] fsck.f2fs: Info: sector size = 4096
[ 11.617673] fsck.f2fs: Info: total sectors = 6563707 (25639 MB)
[ 11.624321] fsck.f2fs: Info: MKFS version
[ 11.628808] fsck.f2fs: "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 11.638769] fsck.f2fs: Info: FSCK version
[ 11.643269] fsck.f2fs: from "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 11.653715] fsck.f2fs: to "5.4.99-00087-g9414d2a80b05 #2 SMP PREEMPT Tue Jun 29 13:41:01 CST 2021"
[ 11.664145] fsck.f2fs: Info: superblock features = 1499 : encrypt verity extra_attr project_quota quota_ino casefold
[ 11.676052] fsck.f2fs: Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
[ 11.686112] fsck.f2fs: Info: total FS sectors = 6563707 (25639 MB)
[ 11.693066] fsck.f2fs: Info: CKPT version = 572a869a
[ 11.698667] fsck.f2fs: Info: checkpoint state = 1c5 : trimmed nat_bits crc compacted_summary unmount
[ 11.709019] fsck.f2fs: Info: No error was reported
[ 11.714393] fsck.f2fs:
[ 11.717141] fsck.f2fs: c, u, RA, CH, CM, Repl=
[ 11.722127] fsck.f2fs: 10000 10 10 0 10 0
[ 11.730183] F2FS-fs (dm-4): Using encoding defined by superblock: utf8-12.1.0 with flags 0x0
[ 11.760473] F2FS-fs (dm-4): Found nat_bits in checkpoint
[ 12.001723] F2FS-fs (dm-4): Mounted with checkpoint version = 572a869a
// 向内核添加keyring
[ 12.030932] init: Keyring created with id 925267706 in process 1
[ 12.038575] init: Command 'mount_all /vendor/etc/fstab.sun50iw10p1 --late' action=late-fs (/vendor/etc/init/hw/init.sun50iw10p1.rc:49) took 608ms and succeeded
源码解析
1. init下
1.1 do_mount_all-挂载fstab中剩下的分区
static Result<void> do_mount_all(const BuiltinArguments& args) {
// --early:空,/vendor/etc/fstab.sun50iw10p1,MOUNT_MODE_EARLY,false
// --late:空,/vendor/etc/fstab.sun50iw10p1,MOUNT_MODE_LATE,false
auto mount_all = ParseMountAll(args.args);
if (!mount_all.ok()) return mount_all.error();
const char* prop_post_fix = "default";
bool queue_event = true;
if (mount_all->mode == MOUNT_MODE_EARLY) {
prop_post_fix = "early";
queue_event = false;
} else if (mount_all->mode == MOUNT_MODE_LATE) {
prop_post_fix = "late";
}
std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix;
android::base::Timer t;
Fstab fstab;
if (mount_all->fstab_path.empty()) {
if (!ReadDefaultFstab(&fstab)) {
return Error() << "Could not read default fstab";
}
} else {
// 走这里,读/vendor/etc/fstab.sun50iw10p1文件
if (!ReadFstabFromFile(mount_all->fstab_path, &fstab)) {
return Error() << "Could not read fstab";
}
}
auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_all->mode);
// 设置ro.boottime.init.mount_all.early属性,设置挂载时间
SetProperty(prop_name, std::to_string(t.duration().count()));
// 默认为false,不走这里
if (mount_all->import_rc) {
import_late(mount_all->rc_paths);
}
// --late会走这里
if (queue_event) {
/* queue_fs_event will queue event based on mount_fstab return code
* and return processed return code*/
initial_mount_fstab_return_code = mount_fstab_return_code; // 这个和remount相关的
// 解析mount_all返回的关于data分区加密相关的code
auto queue_fs_result = queue_fs_event(mount_fstab_return_code, false);
if (!queue_fs_result.ok()) {
return Error() << "queue_fs_event() failed: " << queue_fs_result.error();
}
}
return {};
}
1.2 ParseMountAll-解析挂载参数
// mount_all /vendor/etc/fstab.sun50iw10p1 --early
// mount_all /vendor/etc/fstab.sun50iw10p1 --late
Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args) {
bool compat_mode = false;
bool import_rc = false;
if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
if (args.size() <= 1) {
return Error() << "mount_all requires at least 1 argument";
}
compat_mode = true;
import_rc = true;
}
std::size_t first_option_arg = args.size();
enum mount_mode mode = MOUNT_MODE_DEFAULT;
// If we are <= Q, then stop looking for non-fstab arguments at slot 2.
// Otherwise, stop looking at slot 1 (as the fstab path argument is optional >= R).
for (std::size_t na = args.size() - 1; na > (compat_mode ? 1 : 0); --na) {
if (args[na] == "--early") {
first_option_arg = na;
mode = MOUNT_MODE_EARLY;
} else if (args[na] == "--late") {
first_option_arg = na;
mode = MOUNT_MODE_LATE;
import_rc = false;
}
}
std::string fstab_path;
if (first_option_arg > 1) {
fstab_path = args[1];
} else if (compat_mode) {
return Error() << "mount_all argument 1 must be the fstab path";
}
std::vector<std::string> rc_paths;
for (std::size_t na = 2; na < first_option_arg; ++na) {
rc_paths.push_back(args[na]);
}
// --early:空,/vendor/etc/fstab.sun50iw10p1,MOUNT_MODE_EARLY,false
// --late:空,/vendor/etc/fstab.sun50iw10p1,MOUNT_MODE_LATE,false
return MountAllOptions{rc_paths, fstab_path, mode, import_rc};
}
1.3 queue_fs_event
/* Queue event based on fs_mgr return code.
*
* code: return code of fs_mgr_mount_all
*
* This function might request a reboot, in which case it will
* not return.
*
* return code is processed based on input code
*/ // metadata加密的:mount_all返回值FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED,false
static Result<void> queue_fs_event(int code, bool userdata_remount) {
if (code == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
if (userdata_remount) {
// FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION should only happen on FDE devices. Since we don't
// support userdata remount on FDE devices, this should never been triggered. Time to
// panic!
LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?";
trigger_shutdown("reboot,requested-userdata-remount-on-fde-device");
}
ActionManager::GetInstance().QueueEventTrigger("encrypt");
return {};
} else if (code == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
if (userdata_remount) {
// FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED should only happen on FDE devices. Since we
// don't support userdata remount on FDE devices, this should never been triggered.
// Time to panic!
LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?";
trigger_shutdown("reboot,requested-userdata-remount-on-fde-device");
}
SetProperty("ro.crypto.state", "encrypted");
SetProperty("ro.crypto.type", "block");
ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
return {};
} else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
SetProperty("ro.crypto.state", "unencrypted");
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return {};
} else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
SetProperty("ro.crypto.state", "unsupported");
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return {};
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
/* Setup a wipe via recovery, and reboot into recovery */
if (android::gsi::IsGsiRunning()) {
return Error() << "cannot wipe within GSI";
}
PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
return reboot_into_recovery(options);
/* If reboot worked, there is no return. */
} else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
if (!FscryptInstallKeyring()) {
return Error() << "FscryptInstallKeyring() failed";
}
SetProperty("ro.crypto.state", "encrypted");
SetProperty("ro.crypto.type", "file");
// Although encrypted, we have device key, so we do not need to
// do anything different from the nonencrypted case.
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return {};
} else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) { // metadata加密走这里,其他都不看了
if (!FscryptInstallKeyring()) {// 向内核添加keyring
return Error() << "FscryptInstallKeyring() failed";
}// 设置文件加密的属性
SetProperty("ro.crypto.state", "encrypted");
SetProperty("ro.crypto.type", "file");
// Although encrypted, vold has already set the device up, so we do not need to
// do anything different from the nonencrypted case.
// 触发nonencrypted的action
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return {};
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
if (!FscryptInstallKeyring()) {
return Error() << "FscryptInstallKeyring() failed";
}
SetProperty("ro.crypto.state", "encrypted");
SetProperty("ro.crypto.type", "file");
// Although encrypted, vold has already set the device up, so we do not need to
// do anything different from the nonencrypted case.
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return {};
} else if (code > 0) {
Error() << "fs_mgr_mount_all() returned unexpected error " << code;
}
/* else ... < 0: error */
return Error() << "Invalid code: " << code;
}
2. 文件加密初始化模块
2.1 FscryptInstallKeyring-向内核添加keyring
// log:Keyring created with id 646837365 in process 1
bool FscryptInstallKeyring() {
if (keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "fscrypt", 0) != -1) {
LOG(INFO) << "Keyring is already created";
return true;
} // syscall(__NR_add_key, type, description, payload, payload_length, ring_id);
// 向内核添加keyring
key_serial_t device_keyring = add_key("keyring", "fscrypt", 0, 0, KEY_SPEC_SESSION_KEYRING);
if (device_keyring == -1) {
PLOG(ERROR) << "Failed to create keyring";
return false;
}
LOG(INFO) << "Keyring created with id " << device_keyring << " in process " << getpid();
return true;
}