Loading debuggerd/tombstoned/tombstoned.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -158,7 +158,7 @@ class CrashQueue { } } return std::move(result); return result; } std::optional<CrashOutput> get_output(DebuggerdDumpType dump_type) { Loading fs_mgr/fs_mgr.cpp +8 −192 Original line number Diff line number Diff line Loading @@ -1433,16 +1433,16 @@ bool WasMetadataEncryptionInterrupted(const FstabEntry& entry) { // When multiple fstab records share the same mount_point, it will try to mount each // one in turn, and ignore any duplicates after a first successful mount. // Returns -1 on error, and FS_MGR_MNTALL_* otherwise. MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; int error_count = 0; CheckpointManager checkpoint_manager; AvbUniquePtr avb_handle(nullptr); bool wiped = false; bool userdata_mounted = false; if (fstab->empty()) { return {FS_MGR_MNTALL_FAIL, userdata_mounted}; return FS_MGR_MNTALL_FAIL; } bool scratch_can_be_mounted = true; Loading Loading @@ -1521,7 +1521,7 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { if (!avb_handle) { LERROR << "Failed to open AvbHandle"; set_type_property(encryptable); return {FS_MGR_MNTALL_FAIL, userdata_mounted}; return FS_MGR_MNTALL_FAIL; } } if (avb_handle->SetUpAvbHashtree(¤t_entry, true /* wait_for_verity_dev */) == Loading Loading @@ -1557,7 +1557,7 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { if (status == FS_MGR_MNTALL_FAIL) { // Fatal error - no point continuing. return {status, userdata_mounted}; return status; } if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { Loading @@ -1577,7 +1577,7 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { nullptr)) { LERROR << "Encryption failed"; set_type_property(encryptable); return {FS_MGR_MNTALL_FAIL, userdata_mounted}; return FS_MGR_MNTALL_FAIL; } } } Loading Loading @@ -1696,9 +1696,9 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { set_type_property(encryptable); if (error_count) { return {FS_MGR_MNTALL_FAIL, userdata_mounted}; return FS_MGR_MNTALL_FAIL; } else { return {encryptable, userdata_mounted}; return encryptable; } } Loading Loading @@ -1735,190 +1735,6 @@ int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab) { return ret; } static std::chrono::milliseconds GetMillisProperty(const std::string& name, std::chrono::milliseconds default_value) { auto value = GetUintProperty(name, static_cast<uint64_t>(default_value.count())); return std::chrono::milliseconds(std::move(value)); } static bool fs_mgr_unmount_all_data_mounts(const std::string& data_block_device) { LINFO << __FUNCTION__ << "(): about to umount everything on top of " << data_block_device; Timer t; auto timeout = GetMillisProperty("init.userspace_reboot.userdata_remount.timeoutmillis", 5s); while (true) { bool umount_done = true; Fstab proc_mounts; if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) { LERROR << __FUNCTION__ << "(): Can't read /proc/mounts"; return false; } // Now proceed with other bind mounts on top of /data. for (const auto& entry : proc_mounts) { std::string block_device; if (StartsWith(entry.blk_device, "/dev/block") && !Realpath(entry.blk_device, &block_device)) { PWARNING << __FUNCTION__ << "(): failed to realpath " << entry.blk_device; block_device = entry.blk_device; } if (data_block_device == block_device) { if (umount2(entry.mount_point.c_str(), 0) != 0) { PERROR << __FUNCTION__ << "(): Failed to umount " << entry.mount_point; umount_done = false; } } } if (umount_done) { LINFO << __FUNCTION__ << "(): Unmounting /data took " << t; return true; } if (t.duration() > timeout) { LERROR << __FUNCTION__ << "(): Timed out unmounting all mounts on " << data_block_device; Fstab remaining_mounts; if (!ReadFstabFromFile("/proc/mounts", &remaining_mounts)) { LERROR << __FUNCTION__ << "(): Can't read /proc/mounts"; } else { LERROR << __FUNCTION__ << "(): Following mounts remaining"; for (const auto& e : remaining_mounts) { LERROR << __FUNCTION__ << "(): mount point: " << e.mount_point << " block device: " << e.blk_device; } } return false; } std::this_thread::sleep_for(50ms); } } 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 false; } std::string current = block_device; DeviceMapper& dm = DeviceMapper::Instance(); while (true) { dm_stack->push_back(current); if (!dm.IsDmBlockDevice(current)) { break; } auto parent = dm.GetParentBlockDeviceByPath(current); if (!parent) { return false; } current = *parent; } return true; } FstabEntry* fs_mgr_get_mounted_entry_for_userdata(Fstab* fstab, const std::string& data_block_device) { std::vector<std::string> dm_stack; if (!UnwindDmDeviceStack(data_block_device, &dm_stack)) { LERROR << "Failed to unwind dm-device stack for " << data_block_device; return nullptr; } for (auto& entry : *fstab) { if (entry.mount_point != "/data") { continue; } std::string block_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 (!Realpath(entry.blk_device, &block_device)) { PWARNING << "Failed to realpath " << entry.blk_device; block_device = entry.blk_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 onto " << data_block_device; return nullptr; } // TODO(b/143970043): return different error codes based on which step failed. int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) { Fstab proc_mounts; if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) { LERROR << "Can't read /proc/mounts"; return -1; } auto mounted_entry = GetEntryForMountPoint(&proc_mounts, "/data"); if (mounted_entry == nullptr) { LERROR << "/data is not mounted"; return -1; } std::string block_device; if (!Realpath(mounted_entry->blk_device, &block_device)) { PERROR << "Failed to realpath " << mounted_entry->blk_device; return -1; } auto fstab_entry = fs_mgr_get_mounted_entry_for_userdata(fstab, block_device); if (fstab_entry == nullptr) { LERROR << "Can't find /data in fstab"; return -1; } bool force_umount = GetBoolProperty("sys.init.userdata_remount.force_umount", false); if (force_umount) { LINFO << "Will force an umount of userdata even if it's not required"; } if (!force_umount && !SupportsCheckpoint(fstab_entry)) { LINFO << "Userdata doesn't support checkpointing. Nothing to do"; return 0; } CheckpointManager checkpoint_manager; if (!force_umount && !checkpoint_manager.NeedsCheckpoint()) { LINFO << "Checkpointing not needed. Don't remount"; return 0; } if (!force_umount && fstab_entry->fs_mgr_flags.checkpoint_fs) { // Userdata is f2fs, simply remount it. if (!checkpoint_manager.Update(fstab_entry)) { LERROR << "Failed to remount userdata in checkpointing mode"; return -1; } if (mount(block_device.c_str(), fstab_entry->mount_point.c_str(), "none", MS_REMOUNT | fstab_entry->flags, fstab_entry->fs_options.c_str()) != 0) { PERROR << "Failed to remount userdata in checkpointing mode"; return -1; } } else { LINFO << "Unmounting /data before remounting into checkpointing mode"; if (!fs_mgr_unmount_all_data_mounts(block_device)) { LERROR << "Failed to umount /data"; return -1; } DeviceMapper& dm = DeviceMapper::Instance(); while (dm.IsDmBlockDevice(block_device)) { auto next_device = dm.GetParentBlockDeviceByPath(block_device); auto name = dm.GetDmDeviceNameByPath(block_device); if (!name) { LERROR << "Failed to get dm-name for " << block_device; return -1; } LINFO << "Deleting " << block_device << " named " << *name; if (!dm.DeleteDevice(*name, 3s)) { return -1; } if (!next_device) { LERROR << "Failed to find parent device for " << block_device; } block_device = *next_device; } LINFO << "Remounting /data"; // TODO(b/143970043): remove this hack after fs_mgr_mount_all is refactored. auto result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA); return result.code == FS_MGR_MNTALL_FAIL ? -1 : 0; } return 0; } // wrapper to __mount() and expects a fully prepared fstab_rec, // unlike fs_mgr_do_mount which does more things with avb / verity etc. int fs_mgr_do_mount_one(const FstabEntry& entry, const std::string& alt_mount_point) { Loading fs_mgr/include/fs_mgr.h +2 −19 Original line number Diff line number Diff line Loading @@ -58,13 +58,8 @@ enum mount_mode { #define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY 4 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0 #define FS_MGR_MNTALL_FAIL (-1) struct MountAllResult { // One of the FS_MGR_MNTALL_* returned code defined above. int code; // Whether userdata was mounted as a result of |fs_mgr_mount_all| call. bool userdata_mounted; }; // fs_mgr_mount_all() updates fstab entries that reference device-mapper. int fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode); struct HashtreeInfo { // The hash algorithm used to build the merkle tree. Loading @@ -75,13 +70,6 @@ struct HashtreeInfo { bool check_at_most_once; }; // fs_mgr_mount_all() updates fstab entries that reference device-mapper. // Returns a |MountAllResult|. The first element is one of the FS_MNG_MNTALL_* return codes // defined above, and the second element tells whether this call to fs_mgr_mount_all was responsible // for mounting userdata. Later is required for init to correctly enqueue fs-related events as part // of userdata remount during userspace reboot. MountAllResult fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode); #define FS_MGR_DOMNT_FAILED (-1) #define FS_MGR_DOMNT_BUSY (-2) #define FS_MGR_DOMNT_SUCCESS 0 Loading Loading @@ -127,11 +115,6 @@ enum FsMgrUmountStatus : int { // it destroys verity devices from device mapper after the device is unmounted. int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab); // Finds a entry in |fstab| that was used to mount a /data on |data_block_device|. android::fs_mgr::FstabEntry* fs_mgr_get_mounted_entry_for_userdata( android::fs_mgr::Fstab* fstab, const std::string& data_block_device); int fs_mgr_remount_userdata_into_checkpointing(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/libsnapshot/device_info.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,24 @@ bool DeviceInfo::IsFirstStageInit() const { return first_stage_init_; } bool DeviceInfo::SetActiveBootSlot([[maybe_unused]] unsigned int slot) { #ifdef LIBSNAPSHOT_USE_HAL if (!EnsureBootHal()) { return false; } CommandResult result = boot_control_->SetActiveBootSlot(slot); if (!result.success) { LOG(ERROR) << "Error setting slot " << slot << " active: " << result.errMsg; return false; } return true; #else LOG(ERROR) << "HAL support not enabled."; return false; #endif } bool DeviceInfo::SetSlotAsUnbootable([[maybe_unused]] unsigned int slot) { #ifdef LIBSNAPSHOT_USE_HAL if (!EnsureBootHal()) { Loading fs_mgr/libsnapshot/device_info.h +1 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ class DeviceInfo final : public SnapshotManager::IDeviceInfo { std::string GetSuperDevice(uint32_t slot) const override; bool IsOverlayfsSetup() const override; bool SetBootControlMergeStatus(MergeStatus status) override; bool SetActiveBootSlot(unsigned int slot) override; bool SetSlotAsUnbootable(unsigned int slot) override; bool IsRecovery() const override; std::unique_ptr<IImageManager> OpenImageManager() const override; Loading Loading
debuggerd/tombstoned/tombstoned.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -158,7 +158,7 @@ class CrashQueue { } } return std::move(result); return result; } std::optional<CrashOutput> get_output(DebuggerdDumpType dump_type) { Loading
fs_mgr/fs_mgr.cpp +8 −192 Original line number Diff line number Diff line Loading @@ -1433,16 +1433,16 @@ bool WasMetadataEncryptionInterrupted(const FstabEntry& entry) { // When multiple fstab records share the same mount_point, it will try to mount each // one in turn, and ignore any duplicates after a first successful mount. // Returns -1 on error, and FS_MGR_MNTALL_* otherwise. MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; int error_count = 0; CheckpointManager checkpoint_manager; AvbUniquePtr avb_handle(nullptr); bool wiped = false; bool userdata_mounted = false; if (fstab->empty()) { return {FS_MGR_MNTALL_FAIL, userdata_mounted}; return FS_MGR_MNTALL_FAIL; } bool scratch_can_be_mounted = true; Loading Loading @@ -1521,7 +1521,7 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { if (!avb_handle) { LERROR << "Failed to open AvbHandle"; set_type_property(encryptable); return {FS_MGR_MNTALL_FAIL, userdata_mounted}; return FS_MGR_MNTALL_FAIL; } } if (avb_handle->SetUpAvbHashtree(¤t_entry, true /* wait_for_verity_dev */) == Loading Loading @@ -1557,7 +1557,7 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { if (status == FS_MGR_MNTALL_FAIL) { // Fatal error - no point continuing. return {status, userdata_mounted}; return status; } if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { Loading @@ -1577,7 +1577,7 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { nullptr)) { LERROR << "Encryption failed"; set_type_property(encryptable); return {FS_MGR_MNTALL_FAIL, userdata_mounted}; return FS_MGR_MNTALL_FAIL; } } } Loading Loading @@ -1696,9 +1696,9 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { set_type_property(encryptable); if (error_count) { return {FS_MGR_MNTALL_FAIL, userdata_mounted}; return FS_MGR_MNTALL_FAIL; } else { return {encryptable, userdata_mounted}; return encryptable; } } Loading Loading @@ -1735,190 +1735,6 @@ int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab) { return ret; } static std::chrono::milliseconds GetMillisProperty(const std::string& name, std::chrono::milliseconds default_value) { auto value = GetUintProperty(name, static_cast<uint64_t>(default_value.count())); return std::chrono::milliseconds(std::move(value)); } static bool fs_mgr_unmount_all_data_mounts(const std::string& data_block_device) { LINFO << __FUNCTION__ << "(): about to umount everything on top of " << data_block_device; Timer t; auto timeout = GetMillisProperty("init.userspace_reboot.userdata_remount.timeoutmillis", 5s); while (true) { bool umount_done = true; Fstab proc_mounts; if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) { LERROR << __FUNCTION__ << "(): Can't read /proc/mounts"; return false; } // Now proceed with other bind mounts on top of /data. for (const auto& entry : proc_mounts) { std::string block_device; if (StartsWith(entry.blk_device, "/dev/block") && !Realpath(entry.blk_device, &block_device)) { PWARNING << __FUNCTION__ << "(): failed to realpath " << entry.blk_device; block_device = entry.blk_device; } if (data_block_device == block_device) { if (umount2(entry.mount_point.c_str(), 0) != 0) { PERROR << __FUNCTION__ << "(): Failed to umount " << entry.mount_point; umount_done = false; } } } if (umount_done) { LINFO << __FUNCTION__ << "(): Unmounting /data took " << t; return true; } if (t.duration() > timeout) { LERROR << __FUNCTION__ << "(): Timed out unmounting all mounts on " << data_block_device; Fstab remaining_mounts; if (!ReadFstabFromFile("/proc/mounts", &remaining_mounts)) { LERROR << __FUNCTION__ << "(): Can't read /proc/mounts"; } else { LERROR << __FUNCTION__ << "(): Following mounts remaining"; for (const auto& e : remaining_mounts) { LERROR << __FUNCTION__ << "(): mount point: " << e.mount_point << " block device: " << e.blk_device; } } return false; } std::this_thread::sleep_for(50ms); } } 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 false; } std::string current = block_device; DeviceMapper& dm = DeviceMapper::Instance(); while (true) { dm_stack->push_back(current); if (!dm.IsDmBlockDevice(current)) { break; } auto parent = dm.GetParentBlockDeviceByPath(current); if (!parent) { return false; } current = *parent; } return true; } FstabEntry* fs_mgr_get_mounted_entry_for_userdata(Fstab* fstab, const std::string& data_block_device) { std::vector<std::string> dm_stack; if (!UnwindDmDeviceStack(data_block_device, &dm_stack)) { LERROR << "Failed to unwind dm-device stack for " << data_block_device; return nullptr; } for (auto& entry : *fstab) { if (entry.mount_point != "/data") { continue; } std::string block_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 (!Realpath(entry.blk_device, &block_device)) { PWARNING << "Failed to realpath " << entry.blk_device; block_device = entry.blk_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 onto " << data_block_device; return nullptr; } // TODO(b/143970043): return different error codes based on which step failed. int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) { Fstab proc_mounts; if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) { LERROR << "Can't read /proc/mounts"; return -1; } auto mounted_entry = GetEntryForMountPoint(&proc_mounts, "/data"); if (mounted_entry == nullptr) { LERROR << "/data is not mounted"; return -1; } std::string block_device; if (!Realpath(mounted_entry->blk_device, &block_device)) { PERROR << "Failed to realpath " << mounted_entry->blk_device; return -1; } auto fstab_entry = fs_mgr_get_mounted_entry_for_userdata(fstab, block_device); if (fstab_entry == nullptr) { LERROR << "Can't find /data in fstab"; return -1; } bool force_umount = GetBoolProperty("sys.init.userdata_remount.force_umount", false); if (force_umount) { LINFO << "Will force an umount of userdata even if it's not required"; } if (!force_umount && !SupportsCheckpoint(fstab_entry)) { LINFO << "Userdata doesn't support checkpointing. Nothing to do"; return 0; } CheckpointManager checkpoint_manager; if (!force_umount && !checkpoint_manager.NeedsCheckpoint()) { LINFO << "Checkpointing not needed. Don't remount"; return 0; } if (!force_umount && fstab_entry->fs_mgr_flags.checkpoint_fs) { // Userdata is f2fs, simply remount it. if (!checkpoint_manager.Update(fstab_entry)) { LERROR << "Failed to remount userdata in checkpointing mode"; return -1; } if (mount(block_device.c_str(), fstab_entry->mount_point.c_str(), "none", MS_REMOUNT | fstab_entry->flags, fstab_entry->fs_options.c_str()) != 0) { PERROR << "Failed to remount userdata in checkpointing mode"; return -1; } } else { LINFO << "Unmounting /data before remounting into checkpointing mode"; if (!fs_mgr_unmount_all_data_mounts(block_device)) { LERROR << "Failed to umount /data"; return -1; } DeviceMapper& dm = DeviceMapper::Instance(); while (dm.IsDmBlockDevice(block_device)) { auto next_device = dm.GetParentBlockDeviceByPath(block_device); auto name = dm.GetDmDeviceNameByPath(block_device); if (!name) { LERROR << "Failed to get dm-name for " << block_device; return -1; } LINFO << "Deleting " << block_device << " named " << *name; if (!dm.DeleteDevice(*name, 3s)) { return -1; } if (!next_device) { LERROR << "Failed to find parent device for " << block_device; } block_device = *next_device; } LINFO << "Remounting /data"; // TODO(b/143970043): remove this hack after fs_mgr_mount_all is refactored. auto result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA); return result.code == FS_MGR_MNTALL_FAIL ? -1 : 0; } return 0; } // wrapper to __mount() and expects a fully prepared fstab_rec, // unlike fs_mgr_do_mount which does more things with avb / verity etc. int fs_mgr_do_mount_one(const FstabEntry& entry, const std::string& alt_mount_point) { Loading
fs_mgr/include/fs_mgr.h +2 −19 Original line number Diff line number Diff line Loading @@ -58,13 +58,8 @@ enum mount_mode { #define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY 4 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0 #define FS_MGR_MNTALL_FAIL (-1) struct MountAllResult { // One of the FS_MGR_MNTALL_* returned code defined above. int code; // Whether userdata was mounted as a result of |fs_mgr_mount_all| call. bool userdata_mounted; }; // fs_mgr_mount_all() updates fstab entries that reference device-mapper. int fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode); struct HashtreeInfo { // The hash algorithm used to build the merkle tree. Loading @@ -75,13 +70,6 @@ struct HashtreeInfo { bool check_at_most_once; }; // fs_mgr_mount_all() updates fstab entries that reference device-mapper. // Returns a |MountAllResult|. The first element is one of the FS_MNG_MNTALL_* return codes // defined above, and the second element tells whether this call to fs_mgr_mount_all was responsible // for mounting userdata. Later is required for init to correctly enqueue fs-related events as part // of userdata remount during userspace reboot. MountAllResult fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode); #define FS_MGR_DOMNT_FAILED (-1) #define FS_MGR_DOMNT_BUSY (-2) #define FS_MGR_DOMNT_SUCCESS 0 Loading Loading @@ -127,11 +115,6 @@ enum FsMgrUmountStatus : int { // it destroys verity devices from device mapper after the device is unmounted. int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab); // Finds a entry in |fstab| that was used to mount a /data on |data_block_device|. android::fs_mgr::FstabEntry* fs_mgr_get_mounted_entry_for_userdata( android::fs_mgr::Fstab* fstab, const std::string& data_block_device); int fs_mgr_remount_userdata_into_checkpointing(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/libsnapshot/device_info.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,24 @@ bool DeviceInfo::IsFirstStageInit() const { return first_stage_init_; } bool DeviceInfo::SetActiveBootSlot([[maybe_unused]] unsigned int slot) { #ifdef LIBSNAPSHOT_USE_HAL if (!EnsureBootHal()) { return false; } CommandResult result = boot_control_->SetActiveBootSlot(slot); if (!result.success) { LOG(ERROR) << "Error setting slot " << slot << " active: " << result.errMsg; return false; } return true; #else LOG(ERROR) << "HAL support not enabled."; return false; #endif } bool DeviceInfo::SetSlotAsUnbootable([[maybe_unused]] unsigned int slot) { #ifdef LIBSNAPSHOT_USE_HAL if (!EnsureBootHal()) { Loading
fs_mgr/libsnapshot/device_info.h +1 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ class DeviceInfo final : public SnapshotManager::IDeviceInfo { std::string GetSuperDevice(uint32_t slot) const override; bool IsOverlayfsSetup() const override; bool SetBootControlMergeStatus(MergeStatus status) override; bool SetActiveBootSlot(unsigned int slot) override; bool SetSlotAsUnbootable(unsigned int slot) override; bool IsRecovery() const override; std::unique_ptr<IImageManager> OpenImageManager() const override; Loading