Loading fs_mgr/fs_mgr.cpp +30 −48 Original line number Diff line number Diff line Loading @@ -1589,76 +1589,58 @@ static bool fs_mgr_unmount_all_data_mounts(const std::string& block_device) { } } static std::string ResolveBlockDevice(const std::string& block_device) { static bool UnwindDmDeviceStack(const std::string& block_device, std::vector<std::string>* dm_stack) { if (!StartsWith(block_device, "/dev/block/")) { LWARNING << block_device << " is not a block device"; return block_device; } std::string name = block_device.substr(5); if (!StartsWith(name, "block/dm-")) { // Not a dm-device, but might be a symlink. Optimistically try to readlink. std::string result; if (Readlink(block_device, &result)) { return result; } else if (errno == EINVAL) { // After all, it wasn't a symlink. return block_device; } else { LERROR << "Failed to readlink " << block_device; return ""; } return false; } // It's a dm-device, let's find what's inside! std::string sys_dir = "/sys/" + name; std::string current = block_device; DeviceMapper& dm = DeviceMapper::Instance(); while (true) { std::string slaves_dir = sys_dir + "/slaves"; std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(slaves_dir.c_str()), closedir); if (!dir) { LERROR << "Failed to open " << slaves_dir; return ""; } std::string sub_device_name = ""; for (auto entry = readdir(dir.get()); entry; entry = readdir(dir.get())) { if (entry->d_type != DT_LNK) continue; if (!sub_device_name.empty()) { LERROR << "Too many slaves in " << slaves_dir; return ""; } sub_device_name = entry->d_name; } if (sub_device_name.empty()) { LERROR << "No slaves in " << slaves_dir; return ""; dm_stack->push_back(current); if (!dm.IsDmBlockDevice(current)) { break; } if (!StartsWith(sub_device_name, "dm-")) { // Not a dm-device! We can stop now. return "/dev/block/" + sub_device_name; auto parent = dm.GetParentBlockDeviceByPath(current); if (!parent) { return false; } // Still a dm-device, keep digging. sys_dir = "/sys/block/" + sub_device_name; current = *parent; } return true; } FstabEntry* fs_mgr_get_mounted_entry_for_userdata(Fstab* fstab, const FstabEntry& mounted_entry) { std::string resolved_block_device = ResolveBlockDevice(mounted_entry.blk_device); if (resolved_block_device.empty()) { if (mounted_entry.mount_point != "/data") { LERROR << mounted_entry.mount_point << " is not /data"; return nullptr; } std::vector<std::string> dm_stack; if (!UnwindDmDeviceStack(mounted_entry.blk_device, &dm_stack)) { LERROR << "Failed to unwind dm-device stack for " << mounted_entry.blk_device; return nullptr; } LINFO << "/data is mounted on " << resolved_block_device; for (auto& entry : *fstab) { if (entry.mount_point != "/data") { continue; } std::string block_device; if (!Readlink(entry.blk_device, &block_device)) { LWARNING << "Failed to readlink " << entry.blk_device; if (entry.fs_mgr_flags.logical) { if (!fs_mgr_update_logical_partition(&entry)) { LERROR << "Failed to update logic partition " << entry.blk_device; continue; } block_device = entry.blk_device; } else if (!Readlink(entry.blk_device, &block_device)) { PWARNING << "Failed to read link " << entry.blk_device; block_device = entry.blk_device; } if (block_device == resolved_block_device) { if (std::find(dm_stack.begin(), dm_stack.end(), block_device) != dm_stack.end()) { return &entry; } } LERROR << "Didn't find entry that was used to mount /data"; LERROR << "Didn't find entry that was used to mount /data onto " << mounted_entry.blk_device; return nullptr; } Loading Loading
fs_mgr/fs_mgr.cpp +30 −48 Original line number Diff line number Diff line Loading @@ -1589,76 +1589,58 @@ static bool fs_mgr_unmount_all_data_mounts(const std::string& block_device) { } } static std::string ResolveBlockDevice(const std::string& block_device) { static bool UnwindDmDeviceStack(const std::string& block_device, std::vector<std::string>* dm_stack) { if (!StartsWith(block_device, "/dev/block/")) { LWARNING << block_device << " is not a block device"; return block_device; } std::string name = block_device.substr(5); if (!StartsWith(name, "block/dm-")) { // Not a dm-device, but might be a symlink. Optimistically try to readlink. std::string result; if (Readlink(block_device, &result)) { return result; } else if (errno == EINVAL) { // After all, it wasn't a symlink. return block_device; } else { LERROR << "Failed to readlink " << block_device; return ""; } return false; } // It's a dm-device, let's find what's inside! std::string sys_dir = "/sys/" + name; std::string current = block_device; DeviceMapper& dm = DeviceMapper::Instance(); while (true) { std::string slaves_dir = sys_dir + "/slaves"; std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(slaves_dir.c_str()), closedir); if (!dir) { LERROR << "Failed to open " << slaves_dir; return ""; } std::string sub_device_name = ""; for (auto entry = readdir(dir.get()); entry; entry = readdir(dir.get())) { if (entry->d_type != DT_LNK) continue; if (!sub_device_name.empty()) { LERROR << "Too many slaves in " << slaves_dir; return ""; } sub_device_name = entry->d_name; } if (sub_device_name.empty()) { LERROR << "No slaves in " << slaves_dir; return ""; dm_stack->push_back(current); if (!dm.IsDmBlockDevice(current)) { break; } if (!StartsWith(sub_device_name, "dm-")) { // Not a dm-device! We can stop now. return "/dev/block/" + sub_device_name; auto parent = dm.GetParentBlockDeviceByPath(current); if (!parent) { return false; } // Still a dm-device, keep digging. sys_dir = "/sys/block/" + sub_device_name; current = *parent; } return true; } FstabEntry* fs_mgr_get_mounted_entry_for_userdata(Fstab* fstab, const FstabEntry& mounted_entry) { std::string resolved_block_device = ResolveBlockDevice(mounted_entry.blk_device); if (resolved_block_device.empty()) { if (mounted_entry.mount_point != "/data") { LERROR << mounted_entry.mount_point << " is not /data"; return nullptr; } std::vector<std::string> dm_stack; if (!UnwindDmDeviceStack(mounted_entry.blk_device, &dm_stack)) { LERROR << "Failed to unwind dm-device stack for " << mounted_entry.blk_device; return nullptr; } LINFO << "/data is mounted on " << resolved_block_device; for (auto& entry : *fstab) { if (entry.mount_point != "/data") { continue; } std::string block_device; if (!Readlink(entry.blk_device, &block_device)) { LWARNING << "Failed to readlink " << entry.blk_device; if (entry.fs_mgr_flags.logical) { if (!fs_mgr_update_logical_partition(&entry)) { LERROR << "Failed to update logic partition " << entry.blk_device; continue; } block_device = entry.blk_device; } else if (!Readlink(entry.blk_device, &block_device)) { PWARNING << "Failed to read link " << entry.blk_device; block_device = entry.blk_device; } if (block_device == resolved_block_device) { if (std::find(dm_stack.begin(), dm_stack.end(), block_device) != dm_stack.end()) { return &entry; } } LERROR << "Didn't find entry that was used to mount /data"; LERROR << "Didn't find entry that was used to mount /data onto " << mounted_entry.blk_device; return nullptr; } Loading