Loading fs_mgr/fs_mgr.cpp +84 −34 Original line number Original line Diff line number Diff line Loading @@ -923,7 +923,7 @@ class CheckpointManager { public: public: CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {} 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) { if (!entry->fs_mgr_flags.checkpoint_blk && !entry->fs_mgr_flags.checkpoint_fs) { return true; return true; } } Loading @@ -942,7 +942,7 @@ class CheckpointManager { return true; return true; } } if (!UpdateCheckpointPartition(entry)) { if (!UpdateCheckpointPartition(entry, block_device)) { LERROR << "Could not set up checkpoint partition, skipping!"; LERROR << "Could not set up checkpoint partition, skipping!"; return false; return false; } } Loading Loading @@ -972,7 +972,7 @@ class CheckpointManager { } } private: private: bool UpdateCheckpointPartition(FstabEntry* entry) { bool UpdateCheckpointPartition(FstabEntry* entry, const std::string& block_device) { if (entry->fs_mgr_flags.checkpoint_fs) { if (entry->fs_mgr_flags.checkpoint_fs) { if (is_f2fs(entry->fs_type)) { if (is_f2fs(entry->fs_type)) { entry->fs_options += ",checkpoint=disable"; entry->fs_options += ",checkpoint=disable"; Loading @@ -980,7 +980,10 @@ class CheckpointManager { LERROR << entry->fs_type << " does not implement checkpoints."; LERROR << entry->fs_type << " does not implement checkpoints."; } } } else if (entry->fs_mgr_flags.checkpoint_blk) { } 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) { if (fd < 0) { PERROR << "Cannot open device " << entry->blk_device; PERROR << "Cannot open device " << entry->blk_device; return false; return false; Loading @@ -993,8 +996,8 @@ class CheckpointManager { } } android::dm::DmTable table; android::dm::DmTable table; if (!table.AddTarget( if (!table.AddTarget(std::make_unique<android::dm::DmTargetBow>( std::make_unique<android::dm::DmTargetBow>(0, size, entry->blk_device))) { 0, size, entry->blk_device))) { LERROR << "Failed to add bow target"; LERROR << "Failed to add bow target"; return false; return false; } } Loading @@ -1014,6 +1017,7 @@ class CheckpointManager { device_map_[name] = entry->blk_device; device_map_[name] = entry->blk_device; entry->blk_device = name; entry->blk_device = name; } } } return true; return true; } } Loading @@ -1022,6 +1026,50 @@ class CheckpointManager { std::map<std::string, std::string> device_map_; 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) { static bool IsMountPointMounted(const std::string& mount_point) { // Check if this is already mounted. // Check if this is already mounted. Fstab fstab; Fstab fstab; Loading Loading @@ -1160,7 +1208,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { } } encryptable = status; encryptable = status; if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) { 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"; LERROR << "Encryption failed"; return FS_MGR_MNTALL_FAIL; return FS_MGR_MNTALL_FAIL; } } Loading Loading @@ -1231,7 +1280,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; } else if (mount_errno != EBUSY && mount_errno != EACCES && } else if (mount_errno != EBUSY && mount_errno != EACCES && should_use_metadata_encryption(attempted_entry)) { 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; ++error_count; } } encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; Loading Loading @@ -1361,7 +1411,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!"; LERROR << "Could not set up checkpoint partition, skipping!"; continue; continue; } } Loading fs_mgr/include/fs_mgr.h +4 −0 Original line number Original line 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, // 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. // it destroys verity devices from device mapper after the device is unmounted. int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab); 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 Original line Diff line number Diff line Loading @@ -923,7 +923,7 @@ class CheckpointManager { public: public: CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {} 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) { if (!entry->fs_mgr_flags.checkpoint_blk && !entry->fs_mgr_flags.checkpoint_fs) { return true; return true; } } Loading @@ -942,7 +942,7 @@ class CheckpointManager { return true; return true; } } if (!UpdateCheckpointPartition(entry)) { if (!UpdateCheckpointPartition(entry, block_device)) { LERROR << "Could not set up checkpoint partition, skipping!"; LERROR << "Could not set up checkpoint partition, skipping!"; return false; return false; } } Loading Loading @@ -972,7 +972,7 @@ class CheckpointManager { } } private: private: bool UpdateCheckpointPartition(FstabEntry* entry) { bool UpdateCheckpointPartition(FstabEntry* entry, const std::string& block_device) { if (entry->fs_mgr_flags.checkpoint_fs) { if (entry->fs_mgr_flags.checkpoint_fs) { if (is_f2fs(entry->fs_type)) { if (is_f2fs(entry->fs_type)) { entry->fs_options += ",checkpoint=disable"; entry->fs_options += ",checkpoint=disable"; Loading @@ -980,7 +980,10 @@ class CheckpointManager { LERROR << entry->fs_type << " does not implement checkpoints."; LERROR << entry->fs_type << " does not implement checkpoints."; } } } else if (entry->fs_mgr_flags.checkpoint_blk) { } 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) { if (fd < 0) { PERROR << "Cannot open device " << entry->blk_device; PERROR << "Cannot open device " << entry->blk_device; return false; return false; Loading @@ -993,8 +996,8 @@ class CheckpointManager { } } android::dm::DmTable table; android::dm::DmTable table; if (!table.AddTarget( if (!table.AddTarget(std::make_unique<android::dm::DmTargetBow>( std::make_unique<android::dm::DmTargetBow>(0, size, entry->blk_device))) { 0, size, entry->blk_device))) { LERROR << "Failed to add bow target"; LERROR << "Failed to add bow target"; return false; return false; } } Loading @@ -1014,6 +1017,7 @@ class CheckpointManager { device_map_[name] = entry->blk_device; device_map_[name] = entry->blk_device; entry->blk_device = name; entry->blk_device = name; } } } return true; return true; } } Loading @@ -1022,6 +1026,50 @@ class CheckpointManager { std::map<std::string, std::string> device_map_; 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) { static bool IsMountPointMounted(const std::string& mount_point) { // Check if this is already mounted. // Check if this is already mounted. Fstab fstab; Fstab fstab; Loading Loading @@ -1160,7 +1208,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { } } encryptable = status; encryptable = status; if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) { 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"; LERROR << "Encryption failed"; return FS_MGR_MNTALL_FAIL; return FS_MGR_MNTALL_FAIL; } } Loading Loading @@ -1231,7 +1280,8 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; } else if (mount_errno != EBUSY && mount_errno != EACCES && } else if (mount_errno != EBUSY && mount_errno != EACCES && should_use_metadata_encryption(attempted_entry)) { 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; ++error_count; } } encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; Loading Loading @@ -1361,7 +1411,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!"; LERROR << "Could not set up checkpoint partition, skipping!"; continue; continue; } } Loading
fs_mgr/include/fs_mgr.h +4 −0 Original line number Original line 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, // 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. // it destroys verity devices from device mapper after the device is unmounted. int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab); 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);