Loading fs_mgr/fs_mgr.cpp +84 −34 Original line number Diff line number Diff line Loading @@ -908,7 +908,7 @@ class CheckpointManager { public: CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {} bool Update(FstabEntry* entry) { bool Update(FstabEntry* entry, const std::string& block_device = std::string()) { if (!entry->fs_mgr_flags.checkpoint_blk && !entry->fs_mgr_flags.checkpoint_fs) { return true; } Loading @@ -927,7 +927,7 @@ class CheckpointManager { return true; } if (!UpdateCheckpointPartition(entry)) { if (!UpdateCheckpointPartition(entry, block_device)) { LERROR << "Could not set up checkpoint partition, skipping!"; return false; } Loading Loading @@ -957,7 +957,7 @@ class CheckpointManager { } private: bool UpdateCheckpointPartition(FstabEntry* entry) { bool UpdateCheckpointPartition(FstabEntry* entry, const std::string& block_device) { if (entry->fs_mgr_flags.checkpoint_fs) { if (is_f2fs(entry->fs_type)) { entry->fs_options += ",checkpoint=disable"; Loading @@ -965,7 +965,10 @@ class CheckpointManager { LERROR << entry->fs_type << " does not implement checkpoints."; } } else if (entry->fs_mgr_flags.checkpoint_blk) { unique_fd fd(TEMP_FAILURE_RETRY(open(entry->blk_device.c_str(), O_RDONLY | O_CLOEXEC))); auto actual_block_device = block_device.empty() ? entry->blk_device : block_device; if (fs_mgr_find_bow_device(actual_block_device).empty()) { unique_fd fd( TEMP_FAILURE_RETRY(open(entry->blk_device.c_str(), O_RDONLY | O_CLOEXEC))); if (fd < 0) { PERROR << "Cannot open device " << entry->blk_device; return false; Loading @@ -978,8 +981,8 @@ class CheckpointManager { } android::dm::DmTable table; if (!table.AddTarget( std::make_unique<android::dm::DmTargetBow>(0, size, entry->blk_device))) { if (!table.AddTarget(std::make_unique<android::dm::DmTargetBow>( 0, size, entry->blk_device))) { LERROR << "Failed to add bow target"; return false; } Loading @@ -999,6 +1002,7 @@ class CheckpointManager { device_map_[name] = entry->blk_device; entry->blk_device = name; } } return true; } Loading @@ -1007,6 +1011,50 @@ class CheckpointManager { std::map<std::string, std::string> device_map_; }; std::string fs_mgr_find_bow_device(const std::string& block_device) { if (block_device.substr(0, 5) != "/dev/") { LOG(ERROR) << "Expected block device, got " << block_device; return std::string(); } std::string sys_dir = std::string("/sys/") + block_device.substr(5); for (;;) { std::string name; if (!android::base::ReadFileToString(sys_dir + "/dm/name", &name)) { PLOG(ERROR) << block_device << " is not dm device"; return std::string(); } if (name == "bow\n") return sys_dir; std::string slaves = sys_dir + "/slaves"; std::unique_ptr<DIR, decltype(&closedir)> directory(opendir(slaves.c_str()), closedir); if (!directory) { PLOG(ERROR) << "Can't open slave directory " << slaves; return std::string(); } int count = 0; for (dirent* entry = readdir(directory.get()); entry; entry = readdir(directory.get())) { if (entry->d_type != DT_LNK) continue; if (count == 1) { LOG(ERROR) << "Too many slaves in " << slaves; return std::string(); } ++count; sys_dir = std::string("/sys/block/") + entry->d_name; } if (count != 1) { LOG(ERROR) << "No slave in " << slaves; return std::string(); } } } static bool IsMountPointMounted(const std::string& mount_point) { // Check if this is already mounted. Fstab fstab; Loading Loading @@ -1144,7 +1192,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { } encryptable = status; if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) { if (!call_vdc({"cryptfs", "encryptFstab", attempted_entry.mount_point})) { if (!call_vdc({"cryptfs", "encryptFstab", attempted_entry.blk_device, attempted_entry.mount_point})) { LERROR << "Encryption failed"; return FS_MGR_MNTALL_FAIL; } Loading Loading @@ -1215,7 +1264,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; } else if (mount_errno != EBUSY && mount_errno != EACCES && should_use_metadata_encryption(attempted_entry)) { if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.mount_point})) { if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.blk_device, attempted_entry.mount_point})) { ++error_count; } encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; Loading Loading @@ -1345,7 +1395,7 @@ static int fs_mgr_do_mount_helper(Fstab* fstab, const std::string& n_name, } } if (!checkpoint_manager.Update(&fstab_entry)) { if (!checkpoint_manager.Update(&fstab_entry, n_blk_device)) { LERROR << "Could not set up checkpoint partition, skipping!"; continue; } Loading fs_mgr/include/fs_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -104,3 +104,7 @@ enum FsMgrUmountStatus : int { // fs_mgr_umount_all() is the reverse of fs_mgr_mount_all. In particular, // it destroys verity devices from device mapper after the device is unmounted. int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab); // Finds the dm_bow device on which this block device is stacked, or returns // empty string std::string fs_mgr_find_bow_device(const std::string& block_device); Loading
fs_mgr/fs_mgr.cpp +84 −34 Original line number Diff line number Diff line Loading @@ -908,7 +908,7 @@ class CheckpointManager { public: CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {} bool Update(FstabEntry* entry) { bool Update(FstabEntry* entry, const std::string& block_device = std::string()) { if (!entry->fs_mgr_flags.checkpoint_blk && !entry->fs_mgr_flags.checkpoint_fs) { return true; } Loading @@ -927,7 +927,7 @@ class CheckpointManager { return true; } if (!UpdateCheckpointPartition(entry)) { if (!UpdateCheckpointPartition(entry, block_device)) { LERROR << "Could not set up checkpoint partition, skipping!"; return false; } Loading Loading @@ -957,7 +957,7 @@ class CheckpointManager { } private: bool UpdateCheckpointPartition(FstabEntry* entry) { bool UpdateCheckpointPartition(FstabEntry* entry, const std::string& block_device) { if (entry->fs_mgr_flags.checkpoint_fs) { if (is_f2fs(entry->fs_type)) { entry->fs_options += ",checkpoint=disable"; Loading @@ -965,7 +965,10 @@ class CheckpointManager { LERROR << entry->fs_type << " does not implement checkpoints."; } } else if (entry->fs_mgr_flags.checkpoint_blk) { unique_fd fd(TEMP_FAILURE_RETRY(open(entry->blk_device.c_str(), O_RDONLY | O_CLOEXEC))); auto actual_block_device = block_device.empty() ? entry->blk_device : block_device; if (fs_mgr_find_bow_device(actual_block_device).empty()) { unique_fd fd( TEMP_FAILURE_RETRY(open(entry->blk_device.c_str(), O_RDONLY | O_CLOEXEC))); if (fd < 0) { PERROR << "Cannot open device " << entry->blk_device; return false; Loading @@ -978,8 +981,8 @@ class CheckpointManager { } android::dm::DmTable table; if (!table.AddTarget( std::make_unique<android::dm::DmTargetBow>(0, size, entry->blk_device))) { if (!table.AddTarget(std::make_unique<android::dm::DmTargetBow>( 0, size, entry->blk_device))) { LERROR << "Failed to add bow target"; return false; } Loading @@ -999,6 +1002,7 @@ class CheckpointManager { device_map_[name] = entry->blk_device; entry->blk_device = name; } } return true; } Loading @@ -1007,6 +1011,50 @@ class CheckpointManager { std::map<std::string, std::string> device_map_; }; std::string fs_mgr_find_bow_device(const std::string& block_device) { if (block_device.substr(0, 5) != "/dev/") { LOG(ERROR) << "Expected block device, got " << block_device; return std::string(); } std::string sys_dir = std::string("/sys/") + block_device.substr(5); for (;;) { std::string name; if (!android::base::ReadFileToString(sys_dir + "/dm/name", &name)) { PLOG(ERROR) << block_device << " is not dm device"; return std::string(); } if (name == "bow\n") return sys_dir; std::string slaves = sys_dir + "/slaves"; std::unique_ptr<DIR, decltype(&closedir)> directory(opendir(slaves.c_str()), closedir); if (!directory) { PLOG(ERROR) << "Can't open slave directory " << slaves; return std::string(); } int count = 0; for (dirent* entry = readdir(directory.get()); entry; entry = readdir(directory.get())) { if (entry->d_type != DT_LNK) continue; if (count == 1) { LOG(ERROR) << "Too many slaves in " << slaves; return std::string(); } ++count; sys_dir = std::string("/sys/block/") + entry->d_name; } if (count != 1) { LOG(ERROR) << "No slave in " << slaves; return std::string(); } } } static bool IsMountPointMounted(const std::string& mount_point) { // Check if this is already mounted. Fstab fstab; Loading Loading @@ -1144,7 +1192,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { } encryptable = status; if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) { if (!call_vdc({"cryptfs", "encryptFstab", attempted_entry.mount_point})) { if (!call_vdc({"cryptfs", "encryptFstab", attempted_entry.blk_device, attempted_entry.mount_point})) { LERROR << "Encryption failed"; return FS_MGR_MNTALL_FAIL; } Loading Loading @@ -1215,7 +1264,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; } else if (mount_errno != EBUSY && mount_errno != EACCES && should_use_metadata_encryption(attempted_entry)) { if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.mount_point})) { if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.blk_device, attempted_entry.mount_point})) { ++error_count; } encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; Loading Loading @@ -1345,7 +1395,7 @@ static int fs_mgr_do_mount_helper(Fstab* fstab, const std::string& n_name, } } if (!checkpoint_manager.Update(&fstab_entry)) { if (!checkpoint_manager.Update(&fstab_entry, n_blk_device)) { LERROR << "Could not set up checkpoint partition, skipping!"; continue; } Loading
fs_mgr/include/fs_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -104,3 +104,7 @@ enum FsMgrUmountStatus : int { // fs_mgr_umount_all() is the reverse of fs_mgr_mount_all. In particular, // it destroys verity devices from device mapper after the device is unmounted. int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab); // Finds the dm_bow device on which this block device is stacked, or returns // empty string std::string fs_mgr_find_bow_device(const std::string& block_device);