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;
}

问题

补充

参考

posted @ 2021-06-30 20:14  pyjetson  阅读(1697)  评论(1编辑  收藏  举报