Start using new C++ Fstab class widely
Bug: 62292478 Test: boot Test: adb-remount-test.sh Change-Id: Id4715af4c1f03e2cfc67de92d3ea58e933685e51
This commit is contained in:
parent
e610ad619e
commit
23319ebebf
15 changed files with 509 additions and 597 deletions
|
@ -245,9 +245,8 @@ void remount_service(unique_fd fd, const std::string& cmd) {
|
|||
// If we can use overlayfs, lets get it in place first
|
||||
// before we struggle with determining deduplication operations.
|
||||
if (!verity_enabled && fs_mgr_overlayfs_setup()) {
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
|
||||
fs_mgr_free_fstab);
|
||||
if (fs_mgr_overlayfs_mount_all(fstab.get())) {
|
||||
Fstab fstab;
|
||||
if (ReadDefaultFstab(&fstab) && fs_mgr_overlayfs_mount_all(&fstab)) {
|
||||
WriteFdExactly(fd.get(), "overlayfs mounted\n");
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -120,20 +120,21 @@ static int format_f2fs(const std::string& fs_blkdev, uint64_t dev_sz, bool crypt
|
|||
LOG_KLOG, true, nullptr, nullptr, 0);
|
||||
}
|
||||
|
||||
int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
int fs_mgr_do_format(const FstabEntry& entry, bool crypt_footer) {
|
||||
LERROR << __FUNCTION__ << ": Format " << entry.blk_device << " as '" << entry.fs_type << "'";
|
||||
|
||||
LERROR << __FUNCTION__ << ": Format " << fstab->blk_device
|
||||
<< " as '" << fstab->fs_type << "'";
|
||||
|
||||
if (!strncmp(fstab->fs_type, "f2fs", 4)) {
|
||||
rc = format_f2fs(fstab->blk_device, fstab->length, crypt_footer);
|
||||
} else if (!strncmp(fstab->fs_type, "ext4", 4)) {
|
||||
rc = format_ext4(fstab->blk_device, fstab->mount_point, crypt_footer);
|
||||
if (entry.fs_type == "f2fs") {
|
||||
return format_f2fs(entry.blk_device, entry.length, crypt_footer);
|
||||
} else if (entry.fs_type == "ext4") {
|
||||
return format_ext4(entry.blk_device, entry.mount_point, crypt_footer);
|
||||
} else {
|
||||
LERROR << "File system type '" << fstab->fs_type << "' is not supported";
|
||||
LERROR << "File system type '" << entry.fs_type << "' is not supported";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int fs_mgr_do_format(struct fstab_rec* rec, bool crypt_footer) {
|
||||
auto entry = FstabRecToFstabEntry(rec);
|
||||
|
||||
return fs_mgr_do_format(entry, crypt_footer);
|
||||
}
|
||||
|
|
|
@ -70,19 +70,11 @@ bool fs_mgr_access(const std::string& path) {
|
|||
|
||||
#if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(fstab*) {
|
||||
bool fs_mgr_overlayfs_mount_all(Fstab*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab*) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>&) {
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab*) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -131,28 +123,28 @@ bool fs_mgr_dir_is_writable(const std::string& path) {
|
|||
|
||||
// At less than 1% free space return value of false,
|
||||
// means we will try to wrap with overlayfs.
|
||||
bool fs_mgr_filesystem_has_space(const char* mount_point) {
|
||||
bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
|
||||
// If we have access issues to find out space remaining, return true
|
||||
// to prevent us trying to override with overlayfs.
|
||||
struct statvfs vst;
|
||||
if (statvfs(mount_point, &vst)) return true;
|
||||
if (statvfs(mount_point.c_str(), &vst)) return true;
|
||||
|
||||
static constexpr int kPercentThreshold = 1; // 1%
|
||||
|
||||
return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100));
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_enabled(struct fstab_rec* fsrec) {
|
||||
bool fs_mgr_overlayfs_enabled(FstabEntry* entry) {
|
||||
// readonly filesystem, can not be mount -o remount,rw
|
||||
// if squashfs or if free space is (near) zero making such a remount
|
||||
// virtually useless, or if there are shared blocks that prevent remount,rw
|
||||
if (("squashfs"s == fsrec->fs_type) || !fs_mgr_filesystem_has_space(fsrec->mount_point)) {
|
||||
if ("squashfs" == entry->fs_type || !fs_mgr_filesystem_has_space(entry->mount_point)) {
|
||||
return true;
|
||||
}
|
||||
if (fs_mgr_is_logical(fsrec)) {
|
||||
fs_mgr_update_logical_partition(fsrec);
|
||||
if (entry->fs_mgr_flags.logical) {
|
||||
fs_mgr_update_logical_partition(entry);
|
||||
}
|
||||
return fs_mgr_has_shared_blocks(fsrec->mount_point, fsrec->blk_device);
|
||||
return fs_mgr_has_shared_blocks(entry->mount_point, entry->blk_device);
|
||||
}
|
||||
|
||||
bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) {
|
||||
|
@ -250,22 +242,16 @@ bool fs_mgr_rw_access(const std::string& path) {
|
|||
}
|
||||
|
||||
bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true) {
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab("/proc/mounts"),
|
||||
fs_mgr_free_fstab);
|
||||
if (!fstab) return false;
|
||||
Fstab fstab;
|
||||
if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
|
||||
return false;
|
||||
}
|
||||
const auto lowerdir = kLowerdirOption + mount_point;
|
||||
for (auto i = 0; i < fstab->num_entries; ++i) {
|
||||
const auto fsrec = &fstab->recs[i];
|
||||
const auto fs_type = fsrec->fs_type;
|
||||
if (!fs_type) continue;
|
||||
if (overlay_only && ("overlay"s != fs_type) && ("overlayfs"s != fs_type)) continue;
|
||||
auto fsrec_mount_point = fsrec->mount_point;
|
||||
if (!fsrec_mount_point) continue;
|
||||
if (mount_point != fsrec_mount_point) continue;
|
||||
for (const auto& entry : fstab) {
|
||||
if (overlay_only && "overlay" != entry.fs_type && "overlayfs" != entry.fs_type) continue;
|
||||
if (mount_point != entry.mount_point) continue;
|
||||
if (!overlay_only) return true;
|
||||
const auto fs_options = fsrec->fs_options;
|
||||
if (!fs_options) continue;
|
||||
const auto options = android::base::Split(fs_options, ",");
|
||||
const auto options = android::base::Split(entry.fs_options, ",");
|
||||
for (const auto& opt : options) {
|
||||
if (opt == lowerdir) {
|
||||
return true;
|
||||
|
@ -282,28 +268,20 @@ std::vector<std::string> fs_mgr_overlayfs_verity_enabled_list() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool fs_mgr_wants_overlayfs(fstab_rec* fsrec) {
|
||||
if (!fsrec) return false;
|
||||
|
||||
auto fsrec_mount_point = fsrec->mount_point;
|
||||
if (!fsrec_mount_point || !fsrec_mount_point[0]) return false;
|
||||
if (!fsrec->blk_device) return false;
|
||||
|
||||
if (!fsrec->fs_type) return false;
|
||||
|
||||
bool fs_mgr_wants_overlayfs(FstabEntry* entry) {
|
||||
// Don't check entries that are managed by vold.
|
||||
if (fsrec->fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) return false;
|
||||
if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false;
|
||||
|
||||
// Only concerned with readonly partitions.
|
||||
if (!(fsrec->flags & MS_RDONLY)) return false;
|
||||
if (!(entry->flags & MS_RDONLY)) return false;
|
||||
|
||||
// If unbindable, do not allow overlayfs as this could expose us to
|
||||
// security issues. On Android, this could also be used to turn off
|
||||
// the ability to overlay an otherwise acceptable filesystem since
|
||||
// /system and /vendor are never bound(sic) to.
|
||||
if (fsrec->flags & MS_UNBINDABLE) return false;
|
||||
if (entry->flags & MS_UNBINDABLE) return false;
|
||||
|
||||
if (!fs_mgr_overlayfs_enabled(fsrec)) return false;
|
||||
if (!fs_mgr_overlayfs_enabled(entry)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -391,11 +369,11 @@ std::string fs_mgr_overlayfs_super_device(uint32_t slot_number) {
|
|||
return kPhysicalDevice + fs_mgr_get_super_partition_name(slot_number);
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_has_logical(const fstab* fstab) {
|
||||
if (!fstab) return false;
|
||||
for (auto i = 0; i < fstab->num_entries; i++) {
|
||||
const auto fsrec = &fstab->recs[i];
|
||||
if (fs_mgr_is_logical(fsrec)) return true;
|
||||
bool fs_mgr_overlayfs_has_logical(const Fstab& fstab) {
|
||||
for (const auto& entry : fstab) {
|
||||
if (entry.fs_mgr_flags.logical) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -540,15 +518,12 @@ bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> fs_mgr_candidate_list(fstab* fstab, const char* mount_point = nullptr) {
|
||||
std::vector<std::string> fs_mgr_candidate_list(Fstab* fstab, const char* mount_point = nullptr) {
|
||||
std::vector<std::string> mounts;
|
||||
if (!fstab) return mounts;
|
||||
|
||||
auto verity = fs_mgr_overlayfs_verity_enabled_list();
|
||||
for (auto i = 0; i < fstab->num_entries; i++) {
|
||||
const auto fsrec = &fstab->recs[i];
|
||||
if (!fs_mgr_wants_overlayfs(fsrec)) continue;
|
||||
std::string new_mount_point(fs_mgr_mount_point(fsrec->mount_point));
|
||||
for (auto& entry : *fstab) {
|
||||
if (!fs_mgr_wants_overlayfs(&entry)) continue;
|
||||
std::string new_mount_point(fs_mgr_mount_point(entry.mount_point.c_str()));
|
||||
if (mount_point && (new_mount_point != mount_point)) continue;
|
||||
if (std::find(verity.begin(), verity.end(), android::base::Basename(new_mount_point)) !=
|
||||
verity.end()) {
|
||||
|
@ -580,10 +555,9 @@ std::vector<std::string> fs_mgr_candidate_list(fstab* fstab, const char* mount_p
|
|||
if (std::find(verity.begin(), verity.end(), "system") != verity.end()) return mounts;
|
||||
|
||||
// confirm that fstab is missing system
|
||||
if (fs_mgr_get_entry_for_mount_point(const_cast<struct fstab*>(fstab), "/")) {
|
||||
return mounts;
|
||||
}
|
||||
if (fs_mgr_get_entry_for_mount_point(const_cast<struct fstab*>(fstab), "/system")) {
|
||||
if (std::find_if(fstab->begin(), fstab->end(), [](const auto& entry) {
|
||||
return entry.mount_point == "/" || entry.mount_point == "/system ";
|
||||
}) != fstab->end()) {
|
||||
return mounts;
|
||||
}
|
||||
|
||||
|
@ -605,26 +579,20 @@ bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::s
|
|||
PERROR << "create " << kScratchMountPoint;
|
||||
}
|
||||
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> local_fstab(
|
||||
static_cast<fstab*>(calloc(1, sizeof(fstab))), fs_mgr_free_fstab);
|
||||
auto fsrec = static_cast<fstab_rec*>(calloc(1, sizeof(fstab_rec)));
|
||||
local_fstab->num_entries = 1;
|
||||
local_fstab->recs = fsrec;
|
||||
fsrec->blk_device = strdup(device_path.c_str());
|
||||
fsrec->mount_point = strdup(kScratchMountPoint.c_str());
|
||||
fsrec->fs_type = strdup(mnt_type.c_str());
|
||||
fsrec->flags = MS_RELATIME;
|
||||
fsrec->fs_options = strdup("");
|
||||
FstabEntry entry;
|
||||
entry.blk_device = device_path;
|
||||
entry.mount_point = kScratchMountPoint;
|
||||
entry.fs_type = mnt_type;
|
||||
entry.flags = MS_RELATIME;
|
||||
auto save_errno = errno;
|
||||
auto mounted = fs_mgr_do_mount_one(fsrec) == 0;
|
||||
auto mounted = fs_mgr_do_mount_one(entry) == 0;
|
||||
if (!mounted) {
|
||||
free(fsrec->fs_type);
|
||||
if (mnt_type == "f2fs") {
|
||||
fsrec->fs_type = strdup("ext4");
|
||||
entry.fs_type = "ext4";
|
||||
} else {
|
||||
fsrec->fs_type = strdup("f2fs");
|
||||
entry.fs_type = "f2fs";
|
||||
}
|
||||
mounted = fs_mgr_do_mount_one(fsrec) == 0;
|
||||
mounted = fs_mgr_do_mount_one(entry) == 0;
|
||||
if (!mounted) save_errno = errno;
|
||||
}
|
||||
setfscreatecon(nullptr);
|
||||
|
@ -681,7 +649,7 @@ bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_create_scratch(const fstab* fstab, std::string* scratch_device,
|
||||
bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device,
|
||||
bool* partition_exists, bool* change) {
|
||||
*scratch_device = fs_mgr_overlayfs_scratch_device();
|
||||
*partition_exists = fs_mgr_rw_access(*scratch_device);
|
||||
|
@ -765,7 +733,7 @@ bool fs_mgr_overlayfs_create_scratch(const fstab* fstab, std::string* scratch_de
|
|||
}
|
||||
|
||||
// Create and mount kScratchMountPoint storage if we have logical partitions
|
||||
bool fs_mgr_overlayfs_setup_scratch(const fstab* fstab, bool* change) {
|
||||
bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab, bool* change) {
|
||||
if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;
|
||||
|
||||
std::string scratch_device;
|
||||
|
@ -805,20 +773,20 @@ bool fs_mgr_overlayfs_scratch_can_be_mounted(const std::string& scratch_device)
|
|||
return builder->FindPartition(android::base::Basename(kScratchMountPoint)) != nullptr;
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_invalid(const fstab* fstab) {
|
||||
bool fs_mgr_overlayfs_invalid() {
|
||||
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true;
|
||||
|
||||
// in recovery or fastbootd mode, not allowed!
|
||||
if (fs_mgr_access("/system/bin/recovery")) return true;
|
||||
|
||||
return !fstab;
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(fstab* fstab) {
|
||||
bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
|
||||
auto ret = false;
|
||||
if (fs_mgr_overlayfs_invalid(fstab)) return ret;
|
||||
if (fs_mgr_overlayfs_invalid()) return ret;
|
||||
|
||||
auto scratch_can_be_mounted = true;
|
||||
for (const auto& mount_point : fs_mgr_candidate_list(fstab)) {
|
||||
|
@ -839,17 +807,12 @@ bool fs_mgr_overlayfs_mount_all(fstab* fstab) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>& fsrecs) {
|
||||
std::vector<fstab_rec> recs;
|
||||
for (const auto& rec : fsrecs) recs.push_back(*rec);
|
||||
fstab fstab = {static_cast<int>(fsrecs.size()), &recs[0]};
|
||||
return fs_mgr_overlayfs_mount_all(&fstab);
|
||||
}
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab* fstab) {
|
||||
if (fs_mgr_overlayfs_invalid()) return {};
|
||||
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab) {
|
||||
if (fs_mgr_overlayfs_invalid(fstab)) return {};
|
||||
|
||||
if (fs_mgr_get_entry_for_mount_point(fstab, kScratchMountPoint)) {
|
||||
if (std::find_if(fstab->begin(), fstab->end(), [](const auto& entry) {
|
||||
return entry.mount_point == kScratchMountPoint;
|
||||
}) != fstab->end()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -862,13 +825,6 @@ std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab) {
|
|||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>& fsrecs) {
|
||||
std::vector<fstab_rec> recs;
|
||||
for (const auto& rec : fsrecs) recs.push_back(*rec);
|
||||
fstab fstab = {static_cast<int>(fsrecs.size()), &recs[0]};
|
||||
return fs_mgr_overlayfs_required_devices(&fstab);
|
||||
}
|
||||
|
||||
// Returns false if setup not permitted, errno set to last error.
|
||||
// If something is altered, set *change.
|
||||
bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* change) {
|
||||
|
@ -881,10 +837,11 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool*
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
|
||||
fs_mgr_free_fstab);
|
||||
if (!fstab) return ret;
|
||||
auto mounts = fs_mgr_candidate_list(fstab.get(), fs_mgr_mount_point(mount_point));
|
||||
Fstab fstab;
|
||||
if (!ReadDefaultFstab(&fstab)) {
|
||||
return false;
|
||||
}
|
||||
auto mounts = fs_mgr_candidate_list(&fstab, fs_mgr_mount_point(mount_point));
|
||||
if (mounts.empty()) return ret;
|
||||
|
||||
std::string dir;
|
||||
|
@ -892,12 +849,16 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool*
|
|||
if (backing && backing[0] && (overlay_mount_point != backing)) continue;
|
||||
if (overlay_mount_point == kScratchMountPoint) {
|
||||
if (!fs_mgr_rw_access(fs_mgr_overlayfs_super_device(fs_mgr_overlayfs_slot_number())) ||
|
||||
!fs_mgr_overlayfs_has_logical(fstab.get())) {
|
||||
!fs_mgr_overlayfs_has_logical(fstab)) {
|
||||
continue;
|
||||
}
|
||||
if (!fs_mgr_overlayfs_setup_scratch(fstab.get(), change)) continue;
|
||||
if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue;
|
||||
} else {
|
||||
if (!fs_mgr_get_entry_for_mount_point(fstab.get(), overlay_mount_point)) continue;
|
||||
if (std::find_if(fstab.begin(), fstab.end(), [&overlay_mount_point](const auto& entry) {
|
||||
return entry.mount_point == overlay_mount_point;
|
||||
}) == fstab.end()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dir = overlay_mount_point;
|
||||
break;
|
||||
|
@ -959,10 +920,12 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
|
|||
|
||||
bool fs_mgr_overlayfs_is_setup() {
|
||||
if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
|
||||
fs_mgr_free_fstab);
|
||||
if (fs_mgr_overlayfs_invalid(fstab.get())) return false;
|
||||
for (const auto& mount_point : fs_mgr_candidate_list(fstab.get())) {
|
||||
Fstab fstab;
|
||||
if (!ReadDefaultFstab(&fstab)) {
|
||||
return false;
|
||||
}
|
||||
if (fs_mgr_overlayfs_invalid()) return false;
|
||||
for (const auto& mount_point : fs_mgr_candidate_list(&fstab)) {
|
||||
if (fs_mgr_overlayfs_already_mounted(mount_point)) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -137,6 +137,6 @@ bool fs_mgr_update_for_slotselect(Fstab* fstab);
|
|||
bool fs_mgr_is_device_unlocked();
|
||||
const std::string& get_android_dt_dir();
|
||||
bool is_dt_compatible();
|
||||
int load_verity_state(fstab_rec* fstab, int* mode);
|
||||
int load_verity_state(const FstabEntry& entry, int* mode);
|
||||
|
||||
#endif /* __CORE_FS_MGR_PRIV_H */
|
||||
|
|
|
@ -536,8 +536,7 @@ static int read_partition(const char *path, uint64_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int compare_last_signature(struct fstab_rec *fstab, int *match)
|
||||
{
|
||||
static int compare_last_signature(const FstabEntry& entry, int* match) {
|
||||
char tag[METADATA_TAG_MAX_LENGTH + 1];
|
||||
int fd = -1;
|
||||
int rc = -1;
|
||||
|
@ -549,42 +548,40 @@ static int compare_last_signature(struct fstab_rec *fstab, int *match)
|
|||
|
||||
*match = 1;
|
||||
|
||||
if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE,
|
||||
FEC_DEFAULT_ROOTS) == -1) {
|
||||
PERROR << "Failed to open '" << fstab->blk_device << "'";
|
||||
if (fec_open(&f, entry.blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) ==
|
||||
-1) {
|
||||
PERROR << "Failed to open '" << entry.blk_device << "'";
|
||||
return rc;
|
||||
}
|
||||
|
||||
// read verity metadata
|
||||
if (fec_verity_get_metadata(f, &verity) == -1) {
|
||||
PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'";
|
||||
PERROR << "Failed to get verity metadata '" << entry.blk_device << "'";
|
||||
goto out;
|
||||
}
|
||||
|
||||
SHA256(verity.signature, sizeof(verity.signature), curr);
|
||||
|
||||
if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s",
|
||||
basename(fstab->mount_point)) >= (int)sizeof(tag)) {
|
||||
LERROR << "Metadata tag name too long for " << fstab->mount_point;
|
||||
if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s", basename(entry.mount_point.c_str())) >=
|
||||
(int)sizeof(tag)) {
|
||||
LERROR << "Metadata tag name too long for " << entry.mount_point;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (metadata_find(fstab->verity_loc, tag, SHA256_DIGEST_LENGTH,
|
||||
&offset) < 0) {
|
||||
if (metadata_find(entry.verity_loc.c_str(), tag, SHA256_DIGEST_LENGTH, &offset) < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = TEMP_FAILURE_RETRY(open(fstab->verity_loc, O_RDWR | O_SYNC | O_CLOEXEC));
|
||||
fd = TEMP_FAILURE_RETRY(open(entry.verity_loc.c_str(), O_RDWR | O_SYNC | O_CLOEXEC));
|
||||
|
||||
if (fd == -1) {
|
||||
PERROR << "Failed to open " << fstab->verity_loc;
|
||||
PERROR << "Failed to open " << entry.verity_loc;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev),
|
||||
offset)) != sizeof(prev)) {
|
||||
PERROR << "Failed to read " << sizeof(prev) << " bytes from "
|
||||
<< fstab->verity_loc << " offset " << offset;
|
||||
if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev), offset)) != sizeof(prev)) {
|
||||
PERROR << "Failed to read " << sizeof(prev) << " bytes from " << entry.verity_loc
|
||||
<< " offset " << offset;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -594,8 +591,8 @@ static int compare_last_signature(struct fstab_rec *fstab, int *match)
|
|||
/* update current signature hash */
|
||||
if (TEMP_FAILURE_RETRY(pwrite64(fd, curr, sizeof(curr),
|
||||
offset)) != sizeof(curr)) {
|
||||
PERROR << "Failed to write " << sizeof(curr) << " bytes to "
|
||||
<< fstab->verity_loc << " offset " << offset;
|
||||
PERROR << "Failed to write " << sizeof(curr) << " bytes to " << entry.verity_loc
|
||||
<< " offset " << offset;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -607,28 +604,23 @@ out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int get_verity_state_offset(struct fstab_rec *fstab, off64_t *offset)
|
||||
{
|
||||
static int get_verity_state_offset(const FstabEntry& entry, off64_t* offset) {
|
||||
char tag[METADATA_TAG_MAX_LENGTH + 1];
|
||||
|
||||
if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s",
|
||||
basename(fstab->mount_point)) >= (int)sizeof(tag)) {
|
||||
LERROR << "Metadata tag name too long for " << fstab->mount_point;
|
||||
if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s", basename(entry.mount_point.c_str())) >=
|
||||
(int)sizeof(tag)) {
|
||||
LERROR << "Metadata tag name too long for " << entry.mount_point;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return metadata_find(fstab->verity_loc, tag, sizeof(struct verity_state),
|
||||
offset);
|
||||
return metadata_find(entry.verity_loc.c_str(), tag, sizeof(struct verity_state), offset);
|
||||
}
|
||||
|
||||
int load_verity_state(struct fstab_rec* fstab, int* mode) {
|
||||
int match = 0;
|
||||
off64_t offset = 0;
|
||||
|
||||
/* unless otherwise specified, use EIO mode */
|
||||
int load_verity_state(const FstabEntry& entry, int* mode) {
|
||||
// unless otherwise specified, use EIO mode.
|
||||
*mode = VERITY_MODE_EIO;
|
||||
|
||||
/* use the kernel parameter if set */
|
||||
// use the kernel parameter if set.
|
||||
std::string veritymode;
|
||||
if (fs_mgr_get_boot_config("veritymode", &veritymode)) {
|
||||
if (veritymode == "enforcing") {
|
||||
|
@ -637,7 +629,8 @@ int load_verity_state(struct fstab_rec* fstab, int* mode) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (get_verity_state_offset(fstab, &offset) < 0) {
|
||||
off64_t offset = 0;
|
||||
if (get_verity_state_offset(entry, &offset) < 0) {
|
||||
/* fall back to stateless behavior */
|
||||
return 0;
|
||||
}
|
||||
|
@ -645,16 +638,17 @@ int load_verity_state(struct fstab_rec* fstab, int* mode) {
|
|||
if (was_verity_restart()) {
|
||||
/* device was restarted after dm-verity detected a corrupted
|
||||
* block, so use EIO mode */
|
||||
return write_verity_state(fstab->verity_loc, offset, *mode);
|
||||
return write_verity_state(entry.verity_loc.c_str(), offset, *mode);
|
||||
}
|
||||
|
||||
if (!compare_last_signature(fstab, &match) && !match) {
|
||||
int match = 0;
|
||||
if (!compare_last_signature(entry, &match) && !match) {
|
||||
/* partition has been reflashed, reset dm-verity state */
|
||||
*mode = VERITY_MODE_DEFAULT;
|
||||
return write_verity_state(fstab->verity_loc, offset, *mode);
|
||||
return write_verity_state(entry.verity_loc.c_str(), offset, *mode);
|
||||
}
|
||||
|
||||
return read_verity_state(fstab->verity_loc, offset, mode);
|
||||
return read_verity_state(entry.verity_loc.c_str(), offset, mode);
|
||||
}
|
||||
|
||||
// Update the verity table using the actual block device path.
|
||||
|
@ -716,8 +710,7 @@ static void update_verity_table_blk_device(const std::string& blk_device, char**
|
|||
// prepares the verity enabled (MF_VERIFY / MF_VERIFYATBOOT) fstab record for
|
||||
// mount. The 'wait_for_verity_dev' parameter makes this function wait for the
|
||||
// verity device to get created before return
|
||||
int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
|
||||
{
|
||||
int fs_mgr_setup_verity(FstabEntry* entry, bool wait_for_verity_dev) {
|
||||
int retval = FS_MGR_SETUP_VERITY_FAIL;
|
||||
int fd = -1;
|
||||
std::string verity_blk_name;
|
||||
|
@ -725,20 +718,20 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
|
|||
struct fec_verity_metadata verity;
|
||||
struct verity_table_params params = { .table = NULL };
|
||||
|
||||
const std::string mount_point(basename(fstab->mount_point));
|
||||
const std::string mount_point(basename(entry->mount_point.c_str()));
|
||||
bool verified_at_boot = false;
|
||||
|
||||
android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
|
||||
|
||||
if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE,
|
||||
FEC_DEFAULT_ROOTS) < 0) {
|
||||
PERROR << "Failed to open '" << fstab->blk_device << "'";
|
||||
if (fec_open(&f, entry->blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) <
|
||||
0) {
|
||||
PERROR << "Failed to open '" << entry->blk_device << "'";
|
||||
return retval;
|
||||
}
|
||||
|
||||
// read verity metadata
|
||||
if (fec_verity_get_metadata(f, &verity) < 0) {
|
||||
PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'";
|
||||
PERROR << "Failed to get verity metadata '" << entry->blk_device << "'";
|
||||
// Allow verity disabled when the device is unlocked without metadata
|
||||
if (fs_mgr_is_device_unlocked()) {
|
||||
retval = FS_MGR_SETUP_VERITY_SKIPPED;
|
||||
|
@ -760,9 +753,9 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
|
|||
params.ecc.valid = false;
|
||||
}
|
||||
|
||||
params.ecc_dev = fstab->blk_device;
|
||||
params.ecc_dev = entry->blk_device.c_str();
|
||||
|
||||
if (load_verity_state(fstab, ¶ms.mode) < 0) {
|
||||
if (load_verity_state(*entry, ¶ms.mode) < 0) {
|
||||
/* if accessing or updating the state failed, switch to the default
|
||||
* safe mode. This makes sure the device won't end up in an endless
|
||||
* restart loop, and no corrupted data will be exposed to userspace
|
||||
|
@ -803,8 +796,8 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
|
|||
<< " (mode " << params.mode << ")";
|
||||
|
||||
// Update the verity params using the actual block device path
|
||||
update_verity_table_blk_device(fstab->blk_device, ¶ms.table,
|
||||
fstab->fs_mgr_flags & MF_SLOTSELECT);
|
||||
update_verity_table_blk_device(entry->blk_device, ¶ms.table,
|
||||
entry->fs_mgr_flags.slot_select);
|
||||
|
||||
// load the verity mapping table
|
||||
if (load_verity_table(dm, mount_point, verity.data_size, ¶ms, format_verity_table) == 0) {
|
||||
|
@ -848,31 +841,29 @@ loaded:
|
|||
}
|
||||
|
||||
// mark the underlying block device as read-only
|
||||
fs_mgr_set_blk_ro(fstab->blk_device);
|
||||
fs_mgr_set_blk_ro(entry->blk_device);
|
||||
|
||||
// Verify the entire partition in one go
|
||||
// If there is an error, allow it to mount as a normal verity partition.
|
||||
if (fstab->fs_mgr_flags & MF_VERIFYATBOOT) {
|
||||
LINFO << "Verifying partition " << fstab->blk_device << " at boot";
|
||||
if (entry->fs_mgr_flags.verify_at_boot) {
|
||||
LINFO << "Verifying partition " << entry->blk_device << " at boot";
|
||||
int err = read_partition(verity_blk_name.c_str(), verity.data_size);
|
||||
if (!err) {
|
||||
LINFO << "Verified verity partition "
|
||||
<< fstab->blk_device << " at boot";
|
||||
LINFO << "Verified verity partition " << entry->blk_device << " at boot";
|
||||
verified_at_boot = true;
|
||||
}
|
||||
}
|
||||
|
||||
// assign the new verity block device as the block device
|
||||
if (!verified_at_boot) {
|
||||
free(fstab->blk_device);
|
||||
fstab->blk_device = strdup(verity_blk_name.c_str());
|
||||
entry->blk_device = verity_blk_name;
|
||||
} else if (!dm.DeleteDevice(mount_point)) {
|
||||
LERROR << "Failed to remove verity device " << mount_point.c_str();
|
||||
goto out;
|
||||
}
|
||||
|
||||
// make sure we've set everything up properly
|
||||
if (wait_for_verity_dev && !fs_mgr_wait_for_file(fstab->blk_device, 1s)) {
|
||||
if (wait_for_verity_dev && !fs_mgr_wait_for_file(entry->blk_device, 1s)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ enum mount_mode {
|
|||
#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 1
|
||||
#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0
|
||||
#define FS_MGR_MNTALL_FAIL (-1)
|
||||
int fs_mgr_mount_all(fstab* fstab, int mount_mode);
|
||||
// fs_mgr_mount_all() updates fstab entries that reference device-mapper.
|
||||
int fs_mgr_mount_all(Fstab* fstab, int mount_mode);
|
||||
|
||||
#define FS_MGR_DOMNT_FAILED (-1)
|
||||
#define FS_MGR_DOMNT_BUSY (-2)
|
||||
|
@ -68,6 +69,7 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode);
|
|||
int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point);
|
||||
int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point,
|
||||
bool need_cp);
|
||||
int fs_mgr_do_mount_one(const FstabEntry& entry);
|
||||
int fs_mgr_do_mount_one(fstab_rec* rec);
|
||||
int fs_mgr_do_tmpfs_mount(const char *n_name);
|
||||
fstab_rec const* fs_mgr_get_crypt_entry(fstab const* fstab);
|
||||
|
@ -76,15 +78,17 @@ bool fs_mgr_load_verity_state(int* mode);
|
|||
bool fs_mgr_update_verity_state(
|
||||
std::function<void(const std::string& mount_point, int mode)> callback);
|
||||
bool fs_mgr_swapon_all(const Fstab& fstab);
|
||||
bool fs_mgr_update_logical_partition(FstabEntry* entry);
|
||||
bool fs_mgr_update_logical_partition(struct fstab_rec* rec);
|
||||
|
||||
int fs_mgr_do_format(fstab_rec* fstab, bool reserve_footer);
|
||||
int fs_mgr_do_format(const FstabEntry& entry, bool reserve_footer);
|
||||
int fs_mgr_do_format(fstab_rec* rec, bool reserve_footer);
|
||||
|
||||
#define FS_MGR_SETUP_VERITY_SKIPPED (-3)
|
||||
#define FS_MGR_SETUP_VERITY_DISABLED (-2)
|
||||
#define FS_MGR_SETUP_VERITY_FAIL (-1)
|
||||
#define FS_MGR_SETUP_VERITY_SUCCESS 0
|
||||
int fs_mgr_setup_verity(fstab_rec* fstab, bool wait_for_verity_dev);
|
||||
int fs_mgr_setup_verity(FstabEntry* fstab, bool wait_for_verity_dev);
|
||||
|
||||
// Return the name of the super partition if it exists. If a slot number is
|
||||
// specified, the super partition for the corresponding metadata slot will be
|
||||
|
|
|
@ -21,10 +21,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(fstab* fstab);
|
||||
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>& fstab);
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab);
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>& fstab);
|
||||
bool fs_mgr_overlayfs_mount_all(Fstab* fstab);
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab* fstab);
|
||||
bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
|
||||
bool* change = nullptr);
|
||||
bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);
|
||||
|
|
|
@ -156,6 +156,7 @@ struct FstabEntry {
|
|||
bool logical : 1;
|
||||
bool checkpoint_blk : 1;
|
||||
bool checkpoint_fs : 1;
|
||||
bool first_stage_mount : 1;
|
||||
};
|
||||
} fs_mgr_flags;
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ static bool construct_verity_table(const AvbHashtreeDescriptor& hashtree_desc,
|
|||
return table->AddTarget(std::make_unique<android::dm::DmTargetVerity>(target));
|
||||
}
|
||||
|
||||
static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
|
||||
static bool hashtree_dm_verity_setup(FstabEntry* fstab_entry,
|
||||
const AvbHashtreeDescriptor& hashtree_desc,
|
||||
const std::string& salt, const std::string& root_digest,
|
||||
bool wait_for_verity_dev) {
|
||||
|
@ -278,7 +278,7 @@ static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
|
|||
}
|
||||
table.set_readonly(true);
|
||||
|
||||
const std::string mount_point(basename(fstab_entry->mount_point));
|
||||
const std::string mount_point(basename(fstab_entry->mount_point.c_str()));
|
||||
android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
|
||||
if (!dm.CreateDevice(mount_point, table)) {
|
||||
LERROR << "Couldn't create verity device!";
|
||||
|
@ -295,8 +295,7 @@ static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
|
|||
fs_mgr_set_blk_ro(fstab_entry->blk_device);
|
||||
|
||||
// Updates fstab_rec->blk_device to verity device name.
|
||||
free(fstab_entry->blk_device);
|
||||
fstab_entry->blk_device = strdup(dev_path.c_str());
|
||||
fstab_entry->blk_device = dev_path;
|
||||
|
||||
// Makes sure we've set everything up properly.
|
||||
if (wait_for_verity_dev && !fs_mgr_wait_for_file(dev_path, 1s)) {
|
||||
|
@ -449,8 +448,7 @@ AvbUniquePtr AvbHandle::Open() {
|
|||
return avb_handle;
|
||||
}
|
||||
|
||||
AvbHashtreeResult AvbHandle::SetUpAvbHashtree(struct fstab_rec* fstab_entry,
|
||||
bool wait_for_verity_dev) {
|
||||
AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev) {
|
||||
if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ ||
|
||||
avb_slot_data_->num_vbmeta_images < 1) {
|
||||
return AvbHashtreeResult::kFail;
|
||||
|
@ -464,13 +462,13 @@ AvbHashtreeResult AvbHandle::SetUpAvbHashtree(struct fstab_rec* fstab_entry,
|
|||
// Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor
|
||||
// to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix.
|
||||
std::string partition_name;
|
||||
if (fstab_entry->fs_mgr_flags & MF_LOGICAL) {
|
||||
if (fstab_entry->fs_mgr_flags.logical) {
|
||||
partition_name = fstab_entry->logical_partition_name;
|
||||
} else {
|
||||
partition_name = basename(fstab_entry->blk_device);
|
||||
partition_name = basename(fstab_entry->blk_device.c_str());
|
||||
}
|
||||
|
||||
if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) {
|
||||
if (fstab_entry->fs_mgr_flags.slot_select) {
|
||||
auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix());
|
||||
if (ab_suffix != std::string::npos) {
|
||||
partition_name.erase(ab_suffix);
|
||||
|
|
|
@ -85,7 +85,7 @@ class AvbHandle {
|
|||
// failed to get the HASHTREE descriptor, runtime error when set up
|
||||
// device-mapper, etc.
|
||||
// - kDisabled: hashtree is disabled.
|
||||
AvbHashtreeResult SetUpAvbHashtree(fstab_rec* fstab_entry, bool wait_for_verity_dev);
|
||||
AvbHashtreeResult SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev);
|
||||
|
||||
const std::string& avb_version() const { return avb_version_; }
|
||||
|
||||
|
|
|
@ -473,9 +473,10 @@ static Result<int> mount_fstab(const char* fstabfile, int mount_mode) {
|
|||
// Only needed if someone explicitly changes the default log level in their init.rc.
|
||||
android::base::ScopedLogSeverity info(android::base::INFO);
|
||||
|
||||
struct fstab* fstab = fs_mgr_read_fstab(fstabfile);
|
||||
int child_ret = fs_mgr_mount_all(fstab, mount_mode);
|
||||
fs_mgr_free_fstab(fstab);
|
||||
Fstab fstab;
|
||||
ReadFstabFromFile(fstabfile, &fstab);
|
||||
|
||||
int child_ret = fs_mgr_mount_all(&fstab, mount_mode);
|
||||
if (child_ret == -1) {
|
||||
PLOG(ERROR) << "fs_mgr_mount_all returned an error";
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ class FirstStageMount {
|
|||
bool InitRequiredDevices();
|
||||
bool InitMappedDevice(const std::string& verity_device);
|
||||
bool CreateLogicalPartitions();
|
||||
bool MountPartition(fstab_rec* fstab_rec);
|
||||
bool MountPartition(FstabEntry* fstab_entry);
|
||||
bool MountPartitions();
|
||||
bool IsDmLinearEnabled();
|
||||
bool GetDmLinearMetadataDevice();
|
||||
|
@ -80,13 +80,12 @@ class FirstStageMount {
|
|||
|
||||
// Pure virtual functions.
|
||||
virtual bool GetDmVerityDevices() = 0;
|
||||
virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0;
|
||||
virtual bool SetUpDmVerity(FstabEntry* fstab_entry) = 0;
|
||||
|
||||
bool need_dm_verity_;
|
||||
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab_;
|
||||
Fstab fstab_;
|
||||
std::string lp_metadata_partition_;
|
||||
std::vector<fstab_rec*> mount_fstab_recs_;
|
||||
std::set<std::string> required_devices_partition_names_;
|
||||
std::string super_partition_name_;
|
||||
std::unique_ptr<DeviceHandler> device_handler_;
|
||||
|
@ -100,7 +99,7 @@ class FirstStageMountVBootV1 : public FirstStageMount {
|
|||
|
||||
protected:
|
||||
bool GetDmVerityDevices() override;
|
||||
bool SetUpDmVerity(fstab_rec* fstab_rec) override;
|
||||
bool SetUpDmVerity(FstabEntry* fstab_entry) override;
|
||||
};
|
||||
|
||||
class FirstStageMountVBootV2 : public FirstStageMount {
|
||||
|
@ -112,7 +111,7 @@ class FirstStageMountVBootV2 : public FirstStageMount {
|
|||
|
||||
protected:
|
||||
bool GetDmVerityDevices() override;
|
||||
bool SetUpDmVerity(fstab_rec* fstab_rec) override;
|
||||
bool SetUpDmVerity(FstabEntry* fstab_entry) override;
|
||||
bool InitAvbHandle();
|
||||
|
||||
std::string device_tree_vbmeta_parts_;
|
||||
|
@ -131,29 +130,16 @@ static bool IsRecoveryMode() {
|
|||
|
||||
// Class Definitions
|
||||
// -----------------
|
||||
FirstStageMount::FirstStageMount()
|
||||
: need_dm_verity_(false),
|
||||
fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab),
|
||||
uevent_listener_(16 * 1024 * 1024) {
|
||||
// Stores fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>)
|
||||
// for easier manipulation later, e.g., range-base for loop.
|
||||
if (fstab_) {
|
||||
// DT Fstab predated having a first_stage_mount fs_mgr flag, so if it exists, we use it.
|
||||
for (int i = 0; i < fstab_->num_entries; i++) {
|
||||
mount_fstab_recs_.push_back(&fstab_->recs[i]);
|
||||
}
|
||||
} else {
|
||||
// Fstab found in first stage ramdisk, which should be a copy of the normal fstab.
|
||||
// Mounts intended for first stage are explicitly flagged as such.
|
||||
fstab_.reset(fs_mgr_read_fstab_default());
|
||||
if (fstab_) {
|
||||
for (int i = 0; i < fstab_->num_entries; i++) {
|
||||
if (fs_mgr_is_first_stage_mount(&fstab_->recs[i])) {
|
||||
mount_fstab_recs_.push_back(&fstab_->recs[i]);
|
||||
}
|
||||
}
|
||||
FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16 * 1024 * 1024) {
|
||||
if (!ReadFstabFromDt(&fstab_)) {
|
||||
if (ReadDefaultFstab(&fstab_)) {
|
||||
fstab_.erase(std::remove_if(fstab_.begin(), fstab_.end(),
|
||||
[](const auto& entry) {
|
||||
return !entry.fs_mgr_flags.first_stage_mount;
|
||||
}),
|
||||
fstab_.end());
|
||||
} else {
|
||||
LOG(INFO) << "Failed to read fstab from device tree";
|
||||
LOG(INFO) << "Failed to fstab for first stage mount";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +160,7 @@ std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
|
|||
}
|
||||
|
||||
bool FirstStageMount::DoFirstStageMount() {
|
||||
if (!IsDmLinearEnabled() && mount_fstab_recs_.empty()) {
|
||||
if (!IsDmLinearEnabled() && fstab_.empty()) {
|
||||
// Nothing to mount.
|
||||
LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
|
||||
return true;
|
||||
|
@ -194,8 +180,8 @@ bool FirstStageMount::InitDevices() {
|
|||
}
|
||||
|
||||
bool FirstStageMount::IsDmLinearEnabled() {
|
||||
for (auto fstab_rec : mount_fstab_recs_) {
|
||||
if (fs_mgr_is_logical(fstab_rec)) return true;
|
||||
for (const auto& entry : fstab_) {
|
||||
if (entry.fs_mgr_flags.logical) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -381,21 +367,21 @@ bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FirstStageMount::MountPartition(fstab_rec* fstab_rec) {
|
||||
if (fs_mgr_is_logical(fstab_rec)) {
|
||||
if (!fs_mgr_update_logical_partition(fstab_rec)) {
|
||||
bool FirstStageMount::MountPartition(FstabEntry* fstab_entry) {
|
||||
if (fstab_entry->fs_mgr_flags.logical) {
|
||||
if (!fs_mgr_update_logical_partition(fstab_entry)) {
|
||||
return false;
|
||||
}
|
||||
if (!InitMappedDevice(fstab_rec->blk_device)) {
|
||||
if (!InitMappedDevice(fstab_entry->blk_device)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!SetUpDmVerity(fstab_rec)) {
|
||||
PLOG(ERROR) << "Failed to setup verity for '" << fstab_rec->mount_point << "'";
|
||||
if (!SetUpDmVerity(fstab_entry)) {
|
||||
PLOG(ERROR) << "Failed to setup verity for '" << fstab_entry->mount_point << "'";
|
||||
return false;
|
||||
}
|
||||
if (fs_mgr_do_mount_one(fstab_rec)) {
|
||||
PLOG(ERROR) << "Failed to mount '" << fstab_rec->mount_point << "'";
|
||||
if (fs_mgr_do_mount_one(*fstab_entry)) {
|
||||
PLOG(ERROR) << "Failed to mount '" << fstab_entry->mount_point << "'";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -405,28 +391,28 @@ bool FirstStageMount::MountPartitions() {
|
|||
// If system is in the fstab then we're not a system-as-root device, and in
|
||||
// this case, we mount system first then pivot to it. From that point on,
|
||||
// we are effectively identical to a system-as-root device.
|
||||
auto system_partition =
|
||||
std::find_if(mount_fstab_recs_.begin(), mount_fstab_recs_.end(),
|
||||
[](const auto& rec) { return rec->mount_point == "/system"s; });
|
||||
auto system_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) {
|
||||
return entry.mount_point == "/system";
|
||||
});
|
||||
|
||||
if (system_partition != mount_fstab_recs_.end()) {
|
||||
if (!MountPartition(*system_partition)) {
|
||||
if (system_partition != fstab_.end()) {
|
||||
if (!MountPartition(&(*system_partition))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SwitchRoot((*system_partition)->mount_point);
|
||||
SwitchRoot((*system_partition).mount_point);
|
||||
|
||||
mount_fstab_recs_.erase(system_partition);
|
||||
fstab_.erase(system_partition);
|
||||
}
|
||||
|
||||
for (auto fstab_rec : mount_fstab_recs_) {
|
||||
if (!MountPartition(fstab_rec) && !fs_mgr_is_nofail(fstab_rec)) {
|
||||
for (auto& fstab_entry : fstab_) {
|
||||
if (!MountPartition(&fstab_entry) && !fstab_entry.fs_mgr_flags.no_fail) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// heads up for instantiating required device(s) for overlayfs logic
|
||||
const auto devices = fs_mgr_overlayfs_required_devices(mount_fstab_recs_);
|
||||
const auto devices = fs_mgr_overlayfs_required_devices(&fstab_);
|
||||
for (auto const& device : devices) {
|
||||
if (android::base::StartsWith(device, "/dev/block/by-name/")) {
|
||||
required_devices_partition_names_.emplace(basename(device.c_str()));
|
||||
|
@ -438,7 +424,7 @@ bool FirstStageMount::MountPartitions() {
|
|||
}
|
||||
}
|
||||
|
||||
fs_mgr_overlayfs_mount_all(mount_fstab_recs_);
|
||||
fs_mgr_overlayfs_mount_all(&fstab_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -447,25 +433,25 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() {
|
|||
std::string verity_loc_device;
|
||||
need_dm_verity_ = false;
|
||||
|
||||
for (auto fstab_rec : mount_fstab_recs_) {
|
||||
for (const auto& fstab_entry : fstab_) {
|
||||
// Don't allow verifyatboot in the first stage.
|
||||
if (fs_mgr_is_verifyatboot(fstab_rec)) {
|
||||
if (fstab_entry.fs_mgr_flags.verify_at_boot) {
|
||||
LOG(ERROR) << "Partitions can't be verified at boot";
|
||||
return false;
|
||||
}
|
||||
// Checks for verified partitions.
|
||||
if (fs_mgr_is_verified(fstab_rec)) {
|
||||
if (fstab_entry.fs_mgr_flags.verify) {
|
||||
need_dm_verity_ = true;
|
||||
}
|
||||
// Checks if verity metadata is on a separate partition. Note that it is
|
||||
// not partition specific, so there must be only one additional partition
|
||||
// that carries verity state.
|
||||
if (fstab_rec->verity_loc) {
|
||||
if (!fstab_entry.verity_loc.empty()) {
|
||||
if (verity_loc_device.empty()) {
|
||||
verity_loc_device = fstab_rec->verity_loc;
|
||||
} else if (verity_loc_device != fstab_rec->verity_loc) {
|
||||
verity_loc_device = fstab_entry.verity_loc;
|
||||
} else if (verity_loc_device != fstab_entry.verity_loc) {
|
||||
LOG(ERROR) << "More than one verity_loc found: " << verity_loc_device << ", "
|
||||
<< fstab_rec->verity_loc;
|
||||
<< fstab_entry.verity_loc;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -473,9 +459,9 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() {
|
|||
|
||||
// Includes the partition names of fstab records and verity_loc_device (if any).
|
||||
// Notes that fstab_rec->blk_device has A/B suffix updated by fs_mgr when A/B is used.
|
||||
for (auto fstab_rec : mount_fstab_recs_) {
|
||||
if (!fs_mgr_is_logical(fstab_rec)) {
|
||||
required_devices_partition_names_.emplace(basename(fstab_rec->blk_device));
|
||||
for (const auto& fstab_entry : fstab_) {
|
||||
if (!fstab_entry.fs_mgr_flags.logical) {
|
||||
required_devices_partition_names_.emplace(basename(fstab_entry.blk_device.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,19 +472,19 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) {
|
||||
if (fs_mgr_is_verified(fstab_rec)) {
|
||||
int ret = fs_mgr_setup_verity(fstab_rec, false /* wait_for_verity_dev */);
|
||||
bool FirstStageMountVBootV1::SetUpDmVerity(FstabEntry* fstab_entry) {
|
||||
if (fstab_entry->fs_mgr_flags.verify) {
|
||||
int ret = fs_mgr_setup_verity(fstab_entry, false /* wait_for_verity_dev */);
|
||||
switch (ret) {
|
||||
case FS_MGR_SETUP_VERITY_SKIPPED:
|
||||
case FS_MGR_SETUP_VERITY_DISABLED:
|
||||
LOG(INFO) << "Verity disabled/skipped for '" << fstab_rec->mount_point << "'";
|
||||
LOG(INFO) << "Verity disabled/skipped for '" << fstab_entry->mount_point << "'";
|
||||
return true;
|
||||
case FS_MGR_SETUP_VERITY_SUCCESS:
|
||||
// The exact block device name (fstab_rec->blk_device) is changed to
|
||||
// "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
|
||||
// first stage.
|
||||
return InitMappedDevice(fstab_rec->blk_device);
|
||||
return InitMappedDevice(fstab_entry->blk_device);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -531,15 +517,15 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() {
|
|||
std::set<std::string> logical_partitions;
|
||||
|
||||
// fstab_rec->blk_device has A/B suffix.
|
||||
for (auto fstab_rec : mount_fstab_recs_) {
|
||||
if (fs_mgr_is_avb(fstab_rec)) {
|
||||
for (const auto& fstab_entry : fstab_) {
|
||||
if (fstab_entry.fs_mgr_flags.avb) {
|
||||
need_dm_verity_ = true;
|
||||
}
|
||||
if (fs_mgr_is_logical(fstab_rec)) {
|
||||
if (fstab_entry.fs_mgr_flags.logical) {
|
||||
// Don't try to find logical partitions via uevent regeneration.
|
||||
logical_partitions.emplace(basename(fstab_rec->blk_device));
|
||||
logical_partitions.emplace(basename(fstab_entry.blk_device.c_str()));
|
||||
} else {
|
||||
required_devices_partition_names_.emplace(basename(fstab_rec->blk_device));
|
||||
required_devices_partition_names_.emplace(basename(fstab_entry.blk_device.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -569,11 +555,11 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) {
|
||||
if (fs_mgr_is_avb(fstab_rec)) {
|
||||
bool FirstStageMountVBootV2::SetUpDmVerity(FstabEntry* fstab_entry) {
|
||||
if (fstab_entry->fs_mgr_flags.avb) {
|
||||
if (!InitAvbHandle()) return false;
|
||||
AvbHashtreeResult hashtree_result =
|
||||
avb_handle_->SetUpAvbHashtree(fstab_rec, false /* wait_for_verity_dev */);
|
||||
avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
|
||||
switch (hashtree_result) {
|
||||
case AvbHashtreeResult::kDisabled:
|
||||
return true; // Returns true to mount the partition.
|
||||
|
@ -581,7 +567,7 @@ bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) {
|
|||
// The exact block device name (fstab_rec->blk_device) is changed to
|
||||
// "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
|
||||
// first stage.
|
||||
return InitMappedDevice(fstab_rec->blk_device);
|
||||
return InitMappedDevice(fstab_entry->blk_device);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int partition_wiped(char *source);
|
||||
int partition_wiped(const char* source);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@ static int only_one_char(uint8_t *buf, int len, uint8_t c)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int partition_wiped(char *source)
|
||||
{
|
||||
int partition_wiped(const char* source) {
|
||||
uint8_t buf[4096];
|
||||
int fd, ret;
|
||||
|
||||
|
@ -67,4 +66,3 @@ int partition_wiped(char *source)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue