Merge changes I2581fd7c,I1ed57e6d into main am: 64062f8f4a
Original change: https://android-review.googlesource.com/c/platform/system/core/+/2671040 Change-Id: I6d8a5c24fcbafcb2fa0ec513d6bdf0b41cb0e527 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
112b3505e9
7 changed files with 75 additions and 210 deletions
|
|
@ -328,8 +328,7 @@ bool ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) {
|
||||||
// some recovery fstabs still contain the FDE options since they didn't do
|
// some recovery fstabs still contain the FDE options since they didn't do
|
||||||
// anything in recovery mode anyway (except possibly to cause the
|
// anything in recovery mode anyway (except possibly to cause the
|
||||||
// reservation of a crypto footer) and thus never got removed.
|
// reservation of a crypto footer) and thus never got removed.
|
||||||
if (entry->fs_mgr_flags.crypt && !entry->fs_mgr_flags.vold_managed &&
|
if (entry->fs_mgr_flags.crypt && !entry->fs_mgr_flags.vold_managed && !InRecovery()) {
|
||||||
access("/system/bin/recovery", F_OK) != 0) {
|
|
||||||
LERROR << "FDE is no longer supported; 'encryptable' can only be used for adoptable "
|
LERROR << "FDE is no longer supported; 'encryptable' can only be used for adoptable "
|
||||||
"storage";
|
"storage";
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -520,6 +519,9 @@ std::vector<FstabPtrEntryType*> GetEntriesByPred(FstabPtr fstab, const Pred& pre
|
||||||
// ramdisk's copy of the fstab had to be located in the root directory, but now
|
// ramdisk's copy of the fstab had to be located in the root directory, but now
|
||||||
// the system/etc directory is supported too and is the preferred location.
|
// the system/etc directory is supported too and is the preferred location.
|
||||||
std::string GetFstabPath() {
|
std::string GetFstabPath() {
|
||||||
|
if (InRecovery()) {
|
||||||
|
return "/etc/recovery.fstab";
|
||||||
|
}
|
||||||
for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
|
for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
|
||||||
std::string suffix;
|
std::string suffix;
|
||||||
|
|
||||||
|
|
@ -835,15 +837,8 @@ bool ReadDefaultFstab(Fstab* fstab) {
|
||||||
fstab->clear();
|
fstab->clear();
|
||||||
ReadFstabFromDt(fstab, false /* verbose */);
|
ReadFstabFromDt(fstab, false /* verbose */);
|
||||||
|
|
||||||
std::string default_fstab_path;
|
|
||||||
// Use different fstab paths for normal boot and recovery boot, respectively
|
|
||||||
if ((access("/sbin/recovery", F_OK) == 0) || (access("/system/bin/recovery", F_OK) == 0)) {
|
|
||||||
default_fstab_path = "/etc/recovery.fstab";
|
|
||||||
} else { // normal boot
|
|
||||||
default_fstab_path = GetFstabPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
Fstab default_fstab;
|
Fstab default_fstab;
|
||||||
|
const std::string default_fstab_path = GetFstabPath();
|
||||||
if (!default_fstab_path.empty() && ReadFstabFromFile(default_fstab_path, &default_fstab)) {
|
if (!default_fstab_path.empty() && ReadFstabFromFile(default_fstab_path, &default_fstab)) {
|
||||||
for (auto&& entry : default_fstab) {
|
for (auto&& entry : default_fstab) {
|
||||||
fstab->emplace_back(std::move(entry));
|
fstab->emplace_back(std::move(entry));
|
||||||
|
|
@ -936,6 +931,17 @@ std::string GetVerityDeviceName(const FstabEntry& entry) {
|
||||||
return base_device + "-verity";
|
return base_device + "-verity";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InRecovery() {
|
||||||
|
// Check the existence of recovery binary instead of using the compile time
|
||||||
|
// __ANDROID_RECOVERY__ macro.
|
||||||
|
// If BOARD_USES_RECOVERY_AS_BOOT is true, both normal and recovery boot
|
||||||
|
// mode would use the same init binary, which would mean during normal boot
|
||||||
|
// the '/init' binary is actually a symlink pointing to
|
||||||
|
// init_second_stage.recovery, which would be compiled with
|
||||||
|
// __ANDROID_RECOVERY__ defined.
|
||||||
|
return access("/system/bin/recovery", F_OK) == 0 || access("/sbin/recovery", F_OK) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fs_mgr
|
} // namespace fs_mgr
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,10 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <selinux/selinux.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/utsname.h>
|
|
||||||
#include <sys/vfs.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
@ -38,13 +31,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
#include <android-base/macros.h>
|
|
||||||
#include <android-base/properties.h>
|
#include <android-base/properties.h>
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
#include <android-base/unique_fd.h>
|
|
||||||
#include <ext4_utils/ext4_utils.h>
|
|
||||||
#include <fs_mgr.h>
|
#include <fs_mgr.h>
|
||||||
#include <fs_mgr/file_wait.h>
|
|
||||||
#include <fs_mgr_dm_linear.h>
|
#include <fs_mgr_dm_linear.h>
|
||||||
#include <fs_mgr_overlayfs.h>
|
#include <fs_mgr_overlayfs.h>
|
||||||
#include <fstab/fstab.h>
|
#include <fstab/fstab.h>
|
||||||
|
|
@ -71,22 +60,25 @@ namespace {
|
||||||
|
|
||||||
constexpr char kDataScratchSizeMbProp[] = "fs_mgr.overlayfs.data_scratch_size_mb";
|
constexpr char kDataScratchSizeMbProp[] = "fs_mgr.overlayfs.data_scratch_size_mb";
|
||||||
|
|
||||||
|
constexpr char kPhysicalDevice[] = "/dev/block/by-name/";
|
||||||
|
constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata";
|
||||||
|
|
||||||
|
constexpr char kMkF2fs[] = "/system/bin/make_f2fs";
|
||||||
|
constexpr char kMkExt4[] = "/system/bin/mke2fs";
|
||||||
|
|
||||||
// Return true if everything is mounted, but before adb is started. Right
|
// Return true if everything is mounted, but before adb is started. Right
|
||||||
// after 'trigger load_persist_props_action' is done.
|
// after 'trigger load_persist_props_action' is done.
|
||||||
static bool fs_mgr_boot_completed() {
|
static bool fs_mgr_boot_completed() {
|
||||||
return android::base::GetBoolProperty("ro.persistent_properties.ready", false);
|
return android::base::GetBoolProperty("ro.persistent_properties.ready", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr auto kPhysicalDevice = "/dev/block/by-name/";
|
|
||||||
constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata";
|
|
||||||
|
|
||||||
// Note: this is meant only for recovery/first-stage init.
|
// Note: this is meant only for recovery/first-stage init.
|
||||||
static bool ScratchIsOnData() {
|
static bool ScratchIsOnData() {
|
||||||
// The scratch partition of DSU is managed by gsid.
|
// The scratch partition of DSU is managed by gsid.
|
||||||
if (fs_mgr_is_dsu_running()) {
|
if (fs_mgr_is_dsu_running()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return fs_mgr_access(kScratchImageMetadata);
|
return access(kScratchImageMetadata, F_OK) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) {
|
static bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) {
|
||||||
|
|
@ -131,7 +123,7 @@ static bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int l
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fs_mgr_overlayfs_setup_dir(const std::string& dir) {
|
std::string fs_mgr_overlayfs_setup_dir(const std::string& dir) {
|
||||||
auto top = dir + kOverlayTopDir;
|
auto top = dir + "/" + kOverlayTopDir;
|
||||||
|
|
||||||
AutoSetFsCreateCon createcon(kOverlayfsFileContext);
|
AutoSetFsCreateCon createcon(kOverlayfsFileContext);
|
||||||
if (!createcon.Ok()) {
|
if (!createcon.Ok()) {
|
||||||
|
|
@ -195,10 +187,6 @@ static uint32_t fs_mgr_overlayfs_slot_number() {
|
||||||
return SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
|
return SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string fs_mgr_overlayfs_super_device(uint32_t slot_number) {
|
|
||||||
return kPhysicalDevice + fs_mgr_get_super_partition_name(slot_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool fs_mgr_overlayfs_has_logical(const Fstab& fstab) {
|
static bool fs_mgr_overlayfs_has_logical(const Fstab& fstab) {
|
||||||
for (const auto& entry : fstab) {
|
for (const auto& entry : fstab) {
|
||||||
if (entry.fs_mgr_flags.logical) {
|
if (entry.fs_mgr_flags.logical) {
|
||||||
|
|
@ -258,8 +246,8 @@ OverlayfsTeardownResult fs_mgr_overlayfs_teardown_scratch(const std::string& ove
|
||||||
}
|
}
|
||||||
|
|
||||||
auto slot_number = fs_mgr_overlayfs_slot_number();
|
auto slot_number = fs_mgr_overlayfs_slot_number();
|
||||||
auto super_device = fs_mgr_overlayfs_super_device(slot_number);
|
const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
|
||||||
if (!fs_mgr_rw_access(super_device)) {
|
if (access(super_device.c_str(), R_OK | W_OK)) {
|
||||||
return OverlayfsTeardownResult::Ok;
|
return OverlayfsTeardownResult::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,9 +278,9 @@ OverlayfsTeardownResult fs_mgr_overlayfs_teardown_scratch(const std::string& ove
|
||||||
|
|
||||||
bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point,
|
bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point,
|
||||||
bool* change, bool* should_destroy_scratch = nullptr) {
|
bool* change, bool* should_destroy_scratch = nullptr) {
|
||||||
const auto top = overlay + kOverlayTopDir;
|
const auto top = overlay + "/" + kOverlayTopDir;
|
||||||
|
|
||||||
if (!fs_mgr_access(top)) {
|
if (access(top.c_str(), F_OK)) {
|
||||||
if (should_destroy_scratch) *should_destroy_scratch = true;
|
if (should_destroy_scratch) *should_destroy_scratch = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -300,7 +288,7 @@ bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string
|
||||||
auto cleanup_all = mount_point.empty();
|
auto cleanup_all = mount_point.empty();
|
||||||
const auto partition_name = android::base::Basename(mount_point);
|
const auto partition_name = android::base::Basename(mount_point);
|
||||||
const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name));
|
const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name));
|
||||||
const auto newpath = cleanup_all ? overlay + "/." + (kOverlayTopDir + 1) + ".teardown"
|
const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir + ".teardown"
|
||||||
: top + "/." + partition_name + ".teardown";
|
: top + "/." + partition_name + ".teardown";
|
||||||
auto ret = fs_mgr_rm_all(newpath);
|
auto ret = fs_mgr_rm_all(newpath);
|
||||||
if (!rename(oldpath.c_str(), newpath.c_str())) {
|
if (!rename(oldpath.c_str(), newpath.c_str())) {
|
||||||
|
|
@ -346,72 +334,6 @@ bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mount kScratchMountPoint
|
|
||||||
bool MountScratch(const std::string& device_path, bool readonly = false) {
|
|
||||||
if (readonly) {
|
|
||||||
if (!fs_mgr_access(device_path)) {
|
|
||||||
LOG(ERROR) << "Path does not exist: " << device_path;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!fs_mgr_rw_access(device_path)) {
|
|
||||||
LOG(ERROR) << "Path does not exist or is not readwrite: " << device_path;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const char*> filesystem_candidates;
|
|
||||||
if (fs_mgr_is_f2fs(device_path)) {
|
|
||||||
filesystem_candidates = {"f2fs", "ext4"};
|
|
||||||
} else if (fs_mgr_is_ext4(device_path)) {
|
|
||||||
filesystem_candidates = {"ext4", "f2fs"};
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "Scratch partition is not f2fs or ext4";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoSetFsCreateCon createcon(kOverlayfsFileContext);
|
|
||||||
if (!createcon.Ok()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (mkdir(kScratchMountPoint, 0755) && (errno != EEXIST)) {
|
|
||||||
PERROR << "create " << kScratchMountPoint;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FstabEntry entry;
|
|
||||||
entry.blk_device = device_path;
|
|
||||||
entry.mount_point = kScratchMountPoint;
|
|
||||||
entry.flags = MS_NOATIME | MS_RDONLY;
|
|
||||||
if (!readonly) {
|
|
||||||
entry.flags &= ~MS_RDONLY;
|
|
||||||
entry.flags |= MS_SYNCHRONOUS;
|
|
||||||
entry.fs_options = "nodiscard";
|
|
||||||
fs_mgr_set_blk_ro(device_path, false);
|
|
||||||
}
|
|
||||||
// check_fs requires apex runtime library
|
|
||||||
if (fs_mgr_overlayfs_already_mounted("/data", false)) {
|
|
||||||
entry.fs_mgr_flags.check = true;
|
|
||||||
}
|
|
||||||
bool mounted = false;
|
|
||||||
for (auto fs_type : filesystem_candidates) {
|
|
||||||
entry.fs_type = fs_type;
|
|
||||||
if (fs_mgr_do_mount_one(entry) == 0) {
|
|
||||||
mounted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!createcon.Restore()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!mounted) {
|
|
||||||
rmdir(kScratchMountPoint);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string kMkF2fs("/system/bin/make_f2fs");
|
|
||||||
const std::string kMkExt4("/system/bin/mke2fs");
|
|
||||||
|
|
||||||
// Note: The scratch partition of DSU is managed by gsid, and should be initialized during
|
// Note: The scratch partition of DSU is managed by gsid, and should be initialized during
|
||||||
// first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
|
// first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
|
||||||
static std::string GetDsuScratchDevice() {
|
static std::string GetDsuScratchDevice() {
|
||||||
|
|
@ -456,14 +378,14 @@ bool MakeScratchFilesystem(const std::string& scratch_device) {
|
||||||
// thus do not rely on fsck to correct problems that could creep in.
|
// thus do not rely on fsck to correct problems that could creep in.
|
||||||
auto fs_type = ""s;
|
auto fs_type = ""s;
|
||||||
auto command = ""s;
|
auto command = ""s;
|
||||||
if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_filesystem_available("f2fs")) {
|
if (!access(kMkF2fs, X_OK) && fs_mgr_filesystem_available("f2fs")) {
|
||||||
fs_type = "f2fs";
|
fs_type = "f2fs";
|
||||||
command = kMkF2fs + " -w ";
|
command = kMkF2fs + " -w "s;
|
||||||
command += std::to_string(getpagesize());
|
command += std::to_string(getpagesize());
|
||||||
command += " -f -d1 -l" + android::base::Basename(kScratchMountPoint);
|
command += " -f -d1 -l" + android::base::Basename(kScratchMountPoint);
|
||||||
} else if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_filesystem_available("ext4")) {
|
} else if (!access(kMkExt4, X_OK) && fs_mgr_filesystem_available("ext4")) {
|
||||||
fs_type = "ext4";
|
fs_type = "ext4";
|
||||||
command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
|
command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M "s + kScratchMountPoint;
|
||||||
} else {
|
} else {
|
||||||
LERROR << "No supported mkfs command or filesystem driver available, supported filesystems "
|
LERROR << "No supported mkfs command or filesystem driver available, supported filesystems "
|
||||||
"are: f2fs, ext4";
|
"are: f2fs, ext4";
|
||||||
|
|
@ -506,7 +428,7 @@ static bool CreateDynamicScratch(std::string* scratch_device, bool* partition_ex
|
||||||
|
|
||||||
auto partition_create = !*partition_exists;
|
auto partition_create = !*partition_exists;
|
||||||
auto slot_number = fs_mgr_overlayfs_slot_number();
|
auto slot_number = fs_mgr_overlayfs_slot_number();
|
||||||
auto super_device = fs_mgr_overlayfs_super_device(slot_number);
|
const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
|
||||||
auto builder = MetadataBuilder::New(super_device, slot_number);
|
auto builder = MetadataBuilder::New(super_device, slot_number);
|
||||||
if (!builder) {
|
if (!builder) {
|
||||||
LERROR << "open " << super_device << " metadata";
|
LERROR << "open " << super_device << " metadata";
|
||||||
|
|
@ -646,8 +568,8 @@ static bool CreateScratchOnData(std::string* scratch_device, bool* partition_exi
|
||||||
|
|
||||||
static bool CanUseSuperPartition(const Fstab& fstab) {
|
static bool CanUseSuperPartition(const Fstab& fstab) {
|
||||||
auto slot_number = fs_mgr_overlayfs_slot_number();
|
auto slot_number = fs_mgr_overlayfs_slot_number();
|
||||||
auto super_device = fs_mgr_overlayfs_super_device(slot_number);
|
const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
|
||||||
if (!fs_mgr_rw_access(super_device) || !fs_mgr_overlayfs_has_logical(fstab)) {
|
if (access(super_device.c_str(), R_OK | W_OK) || !fs_mgr_overlayfs_has_logical(fstab)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto metadata = ReadMetadata(super_device, slot_number);
|
auto metadata = ReadMetadata(super_device, slot_number);
|
||||||
|
|
@ -697,8 +619,8 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) {
|
||||||
// If the partition exists, assume first that it can be mounted.
|
// If the partition exists, assume first that it can be mounted.
|
||||||
if (partition_exists) {
|
if (partition_exists) {
|
||||||
if (MountScratch(scratch_device)) {
|
if (MountScratch(scratch_device)) {
|
||||||
if (fs_mgr_access(std::string(kScratchMountPoint) + kOverlayTopDir) ||
|
const auto top = kScratchMountPoint + "/"s + kOverlayTopDir;
|
||||||
fs_mgr_filesystem_has_space(kScratchMountPoint)) {
|
if (access(top.c_str(), F_OK) == 0 || fs_mgr_filesystem_has_space(kScratchMountPoint)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// declare it useless, no overrides and no free space
|
// declare it useless, no overrides and no free space
|
||||||
|
|
@ -717,32 +639,6 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) {
|
||||||
return MountScratch(scratch_device);
|
return MountScratch(scratch_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed().
|
|
||||||
// Setup is allowed only if teardown is also allowed.
|
|
||||||
bool OverlayfsSetupAllowed(bool verbose = false) {
|
|
||||||
if (!kAllowOverlayfs) {
|
|
||||||
if (verbose) {
|
|
||||||
LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check mandatory kernel patches.
|
|
||||||
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
|
|
||||||
if (verbose) {
|
|
||||||
LOG(ERROR) << "Kernel does not support overlayfs";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// in recovery or fastbootd, not allowed!
|
|
||||||
if (fs_mgr_in_recovery()) {
|
|
||||||
if (verbose) {
|
|
||||||
LOG(ERROR) << "Unsupported overlayfs setup from recovery";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool OverlayfsTeardownAllowed() {
|
constexpr bool OverlayfsTeardownAllowed() {
|
||||||
// Never allow on non-debuggable build.
|
// Never allow on non-debuggable build.
|
||||||
return kAllowOverlayfs;
|
return kAllowOverlayfs;
|
||||||
|
|
@ -844,7 +740,7 @@ static std::optional<MapInfo> EnsureScratchMapped() {
|
||||||
if (!info.device.empty()) {
|
if (!info.device.empty()) {
|
||||||
return {std::move(info)};
|
return {std::move(info)};
|
||||||
}
|
}
|
||||||
if (!fs_mgr_in_recovery()) {
|
if (!InRecovery()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -867,8 +763,7 @@ static std::optional<MapInfo> EnsureScratchMapped() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid uart spam by first checking for a scratch partition.
|
// Avoid uart spam by first checking for a scratch partition.
|
||||||
auto metadata_slot = fs_mgr_overlayfs_slot_number();
|
const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
|
||||||
auto super_device = fs_mgr_overlayfs_super_device(metadata_slot);
|
|
||||||
auto metadata = ReadCurrentMetadata(super_device);
|
auto metadata = ReadCurrentMetadata(super_device);
|
||||||
if (!metadata) {
|
if (!metadata) {
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -1030,7 +925,7 @@ void TeardownAllOverlayForMountPoint(const std::string& mount_point) {
|
||||||
if (!OverlayfsTeardownAllowed()) {
|
if (!OverlayfsTeardownAllowed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!fs_mgr_in_recovery()) {
|
if (!InRecovery()) {
|
||||||
LERROR << __FUNCTION__ << "(): must be called within recovery.";
|
LERROR << __FUNCTION__ << "(): must be called within recovery.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <fstab/fstab.h>
|
#include <fstab/fstab.h>
|
||||||
|
|
||||||
// If "mount_point" is non-null, set up exactly one overlay.
|
// If "mount_point" is non-null, set up exactly one overlay.
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <selinux/selinux.h>
|
#include <selinux/selinux.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
@ -33,7 +29,6 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -45,7 +40,6 @@
|
||||||
#include <ext4_utils/ext4_utils.h>
|
#include <ext4_utils/ext4_utils.h>
|
||||||
#include <fs_mgr.h>
|
#include <fs_mgr.h>
|
||||||
#include <fs_mgr/file_wait.h>
|
#include <fs_mgr/file_wait.h>
|
||||||
#include <fs_mgr_dm_linear.h>
|
|
||||||
#include <fs_mgr_overlayfs.h>
|
#include <fs_mgr_overlayfs.h>
|
||||||
#include <fstab/fstab.h>
|
#include <fstab/fstab.h>
|
||||||
#include <libdm/dm.h>
|
#include <libdm/dm.h>
|
||||||
|
|
@ -62,39 +56,21 @@ using namespace android::storage_literals;
|
||||||
|
|
||||||
constexpr char kPreferCacheBackingStorageProp[] = "fs_mgr.overlayfs.prefer_cache_backing_storage";
|
constexpr char kPreferCacheBackingStorageProp[] = "fs_mgr.overlayfs.prefer_cache_backing_storage";
|
||||||
|
|
||||||
bool fs_mgr_access(const std::string& path) {
|
constexpr char kCacheMountPoint[] = "/cache";
|
||||||
return access(path.c_str(), F_OK) == 0;
|
constexpr char kPhysicalDevice[] = "/dev/block/by-name/";
|
||||||
}
|
|
||||||
|
|
||||||
const auto kLowerdirOption = "lowerdir=";
|
constexpr char kLowerdirOption[] = "lowerdir=";
|
||||||
const auto kUpperdirOption = "upperdir=";
|
constexpr char kUpperdirOption[] = "upperdir=";
|
||||||
|
|
||||||
bool fs_mgr_in_recovery() {
|
|
||||||
// Check the existence of recovery binary instead of using the compile time
|
|
||||||
// __ANDROID_RECOVERY__ macro.
|
|
||||||
// If BOARD_USES_RECOVERY_AS_BOOT is true, both normal and recovery boot
|
|
||||||
// mode would use the same init binary, which would mean during normal boot
|
|
||||||
// the '/init' binary is actually a symlink pointing to
|
|
||||||
// init_second_stage.recovery, which would be compiled with
|
|
||||||
// __ANDROID_RECOVERY__ defined.
|
|
||||||
return fs_mgr_access("/system/bin/recovery");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fs_mgr_is_dsu_running() {
|
bool fs_mgr_is_dsu_running() {
|
||||||
// Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
|
// Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
|
||||||
// never called in recovery, the return value of android::gsi::IsGsiRunning()
|
// never called in recovery, the return value of android::gsi::IsGsiRunning()
|
||||||
// is not well-defined. In this case, just return false as being in recovery
|
// is not well-defined. In this case, just return false as being in recovery
|
||||||
// implies not running a DSU system.
|
// implies not running a DSU system.
|
||||||
if (fs_mgr_in_recovery()) return false;
|
if (InRecovery()) return false;
|
||||||
return android::gsi::IsGsiRunning();
|
return android::gsi::IsGsiRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto kCacheMountPoint = "/cache";
|
|
||||||
|
|
||||||
static bool IsABDevice() {
|
|
||||||
return !android::base::GetProperty("ro.boot.slot_suffix", "").empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const std::string> OverlayMountPoints() {
|
std::vector<const std::string> OverlayMountPoints() {
|
||||||
// Never fallback to legacy cache mount point if within a DSU system,
|
// Never fallback to legacy cache mount point if within a DSU system,
|
||||||
// because running a DSU system implies the device supports dynamic
|
// because running a DSU system implies the device supports dynamic
|
||||||
|
|
@ -105,7 +81,8 @@ std::vector<const std::string> OverlayMountPoints() {
|
||||||
|
|
||||||
// For non-A/B devices prefer cache backing storage if
|
// For non-A/B devices prefer cache backing storage if
|
||||||
// kPreferCacheBackingStorageProp property set.
|
// kPreferCacheBackingStorageProp property set.
|
||||||
if (!IsABDevice() && android::base::GetBoolProperty(kPreferCacheBackingStorageProp, false) &&
|
if (fs_mgr_get_slot_suffix().empty() &&
|
||||||
|
android::base::GetBoolProperty(kPreferCacheBackingStorageProp, false) &&
|
||||||
android::base::GetIntProperty("ro.vendor.api_level", -1) < __ANDROID_API_T__) {
|
android::base::GetIntProperty("ro.vendor.api_level", -1) < __ANDROID_API_T__) {
|
||||||
return {kCacheMountPoint, kScratchMountPoint};
|
return {kCacheMountPoint, kScratchMountPoint};
|
||||||
}
|
}
|
||||||
|
|
@ -118,11 +95,6 @@ static bool fs_mgr_is_dir(const std::string& path) {
|
||||||
return !stat(path.c_str(), &st) && S_ISDIR(st.st_mode);
|
return !stat(path.c_str(), &st) && S_ISDIR(st.st_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fs_mgr_rw_access(const std::string& path) {
|
|
||||||
if (path.empty()) return false;
|
|
||||||
return access(path.c_str(), R_OK | W_OK) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// At less than 1% or 8MB of free space return value of false,
|
// At less than 1% or 8MB of free space return value of false,
|
||||||
// means we will try to wrap with overlayfs.
|
// means we will try to wrap with overlayfs.
|
||||||
bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
|
bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
|
||||||
|
|
@ -141,13 +113,11 @@ bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
|
||||||
(static_cast<uint64_t>(vst.f_bfree) * vst.f_frsize) >= kSizeThreshold;
|
(static_cast<uint64_t>(vst.f_bfree) * vst.f_frsize) >= kSizeThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto kPhysicalDevice = "/dev/block/by-name/";
|
|
||||||
|
|
||||||
static bool fs_mgr_update_blk_device(FstabEntry* entry) {
|
static bool fs_mgr_update_blk_device(FstabEntry* entry) {
|
||||||
if (entry->fs_mgr_flags.logical) {
|
if (entry->fs_mgr_flags.logical) {
|
||||||
fs_mgr_update_logical_partition(entry);
|
fs_mgr_update_logical_partition(entry);
|
||||||
}
|
}
|
||||||
if (fs_mgr_access(entry->blk_device)) {
|
if (access(entry->blk_device.c_str(), F_OK) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (entry->blk_device != "/dev/root") {
|
if (entry->blk_device != "/dev/root") {
|
||||||
|
|
@ -155,10 +125,10 @@ static bool fs_mgr_update_blk_device(FstabEntry* entry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case for system-as-root (taimen and others)
|
// special case for system-as-root (taimen and others)
|
||||||
auto blk_device = std::string(kPhysicalDevice) + "system";
|
auto blk_device = kPhysicalDevice + "system"s;
|
||||||
if (!fs_mgr_access(blk_device)) {
|
if (access(blk_device.c_str(), F_OK)) {
|
||||||
blk_device += fs_mgr_get_slot_suffix();
|
blk_device += fs_mgr_get_slot_suffix();
|
||||||
if (!fs_mgr_access(blk_device)) {
|
if (access(blk_device.c_str(), F_OK)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -237,12 +207,12 @@ static std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point
|
||||||
if (!fs_mgr_is_dir(mount_point)) return "";
|
if (!fs_mgr_is_dir(mount_point)) return "";
|
||||||
const auto base = android::base::Basename(mount_point) + "/";
|
const auto base = android::base::Basename(mount_point) + "/";
|
||||||
for (const auto& overlay_mount_point : OverlayMountPoints()) {
|
for (const auto& overlay_mount_point : OverlayMountPoints()) {
|
||||||
auto dir = overlay_mount_point + kOverlayTopDir + "/" + base;
|
auto dir = overlay_mount_point + "/" + kOverlayTopDir + "/" + base;
|
||||||
auto upper = dir + kUpperName;
|
auto upper = dir + kUpperName;
|
||||||
if (!fs_mgr_is_dir(upper)) continue;
|
if (!fs_mgr_is_dir(upper)) continue;
|
||||||
auto work = dir + kWorkName;
|
auto work = dir + kWorkName;
|
||||||
if (!fs_mgr_is_dir(work)) continue;
|
if (!fs_mgr_is_dir(work)) continue;
|
||||||
if (!fs_mgr_rw_access(work)) continue;
|
if (access(work.c_str(), R_OK | W_OK)) continue;
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
|
@ -527,13 +497,13 @@ static bool fs_mgr_overlayfs_mount(const FstabEntry& entry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mount kScratchMountPoint
|
// Mount kScratchMountPoint
|
||||||
static bool MountScratch(const std::string& device_path, bool readonly = false) {
|
bool MountScratch(const std::string& device_path, bool readonly) {
|
||||||
if (readonly) {
|
if (readonly) {
|
||||||
if (!fs_mgr_access(device_path)) {
|
if (access(device_path.c_str(), F_OK)) {
|
||||||
LOG(ERROR) << "Path does not exist: " << device_path;
|
LOG(ERROR) << "Path does not exist: " << device_path;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!fs_mgr_rw_access(device_path)) {
|
} else if (access(device_path.c_str(), R_OK | W_OK)) {
|
||||||
LOG(ERROR) << "Path does not exist or is not readwrite: " << device_path;
|
LOG(ERROR) << "Path does not exist or is not readwrite: " << device_path;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -589,9 +559,6 @@ static bool MountScratch(const std::string& device_path, bool readonly = false)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string kMkF2fs("/system/bin/make_f2fs");
|
|
||||||
const std::string kMkExt4("/system/bin/mke2fs");
|
|
||||||
|
|
||||||
// Note: The scratch partition of DSU is managed by gsid, and should be initialized during
|
// Note: The scratch partition of DSU is managed by gsid, and should be initialized during
|
||||||
// first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
|
// first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
|
||||||
static std::string GetDsuScratchDevice() {
|
static std::string GetDsuScratchDevice() {
|
||||||
|
|
@ -633,7 +600,7 @@ static std::string GetBootScratchDevice() {
|
||||||
|
|
||||||
// NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed().
|
// NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed().
|
||||||
// Setup is allowed only if teardown is also allowed.
|
// Setup is allowed only if teardown is also allowed.
|
||||||
bool OverlayfsSetupAllowed(bool verbose = false) {
|
bool OverlayfsSetupAllowed(bool verbose) {
|
||||||
if (!kAllowOverlayfs) {
|
if (!kAllowOverlayfs) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds";
|
LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds";
|
||||||
|
|
@ -648,7 +615,7 @@ bool OverlayfsSetupAllowed(bool verbose = false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// in recovery or fastbootd, not allowed!
|
// in recovery or fastbootd, not allowed!
|
||||||
if (fs_mgr_in_recovery()) {
|
if (InRecovery()) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
LOG(ERROR) << "Unsupported overlayfs setup from recovery";
|
LOG(ERROR) << "Unsupported overlayfs setup from recovery";
|
||||||
}
|
}
|
||||||
|
|
@ -728,7 +695,7 @@ static void TryMountScratch() {
|
||||||
// if verity is still disabled, i.e. no reboot occurred), and skips calling
|
// if verity is still disabled, i.e. no reboot occurred), and skips calling
|
||||||
// fs_mgr_overlayfs_mount_all().
|
// fs_mgr_overlayfs_mount_all().
|
||||||
auto scratch_device = GetBootScratchDevice();
|
auto scratch_device = GetBootScratchDevice();
|
||||||
if (!fs_mgr_rw_access(scratch_device)) {
|
if (access(scratch_device.c_str(), R_OK | W_OK)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!WaitForFile(scratch_device, 10s)) {
|
if (!WaitForFile(scratch_device, 10s)) {
|
||||||
|
|
@ -737,7 +704,8 @@ static void TryMountScratch() {
|
||||||
if (!MountScratch(scratch_device, true /* readonly */)) {
|
if (!MountScratch(scratch_device, true /* readonly */)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto has_overlayfs_dir = fs_mgr_access(std::string(kScratchMountPoint) + kOverlayTopDir);
|
const auto top = kScratchMountPoint + "/"s + kOverlayTopDir;
|
||||||
|
const bool has_overlayfs_dir = access(top.c_str(), F_OK) == 0;
|
||||||
fs_mgr_overlayfs_umount_scratch();
|
fs_mgr_overlayfs_umount_scratch();
|
||||||
if (has_overlayfs_dir) {
|
if (has_overlayfs_dir) {
|
||||||
MountScratch(scratch_device);
|
MountScratch(scratch_device);
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,12 @@
|
||||||
|
|
||||||
#include <fstab/fstab.h>
|
#include <fstab/fstab.h>
|
||||||
|
|
||||||
bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true);
|
constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
|
||||||
bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry);
|
|
||||||
android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);
|
constexpr char kScratchMountPoint[] = "/mnt/scratch";
|
||||||
|
constexpr char kOverlayTopDir[] = "overlay";
|
||||||
|
constexpr char kUpperName[] = "upper";
|
||||||
|
constexpr char kWorkName[] = "work";
|
||||||
|
|
||||||
#if ALLOW_ADBD_DISABLE_VERITY
|
#if ALLOW_ADBD_DISABLE_VERITY
|
||||||
constexpr bool kAllowOverlayfs = true;
|
constexpr bool kAllowOverlayfs = true;
|
||||||
|
|
@ -45,18 +48,13 @@ class AutoSetFsCreateCon final {
|
||||||
bool restored_ = false;
|
bool restored_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto kScratchMountPoint = "/mnt/scratch";
|
|
||||||
constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
|
|
||||||
|
|
||||||
constexpr auto kUpperName = "upper";
|
|
||||||
constexpr auto kWorkName = "work";
|
|
||||||
constexpr auto kOverlayTopDir = "/overlay";
|
|
||||||
|
|
||||||
bool fs_mgr_is_dsu_running();
|
bool fs_mgr_is_dsu_running();
|
||||||
bool fs_mgr_in_recovery();
|
|
||||||
bool fs_mgr_access(const std::string& path);
|
|
||||||
bool fs_mgr_rw_access(const std::string& path);
|
|
||||||
bool fs_mgr_filesystem_has_space(const std::string& mount_point);
|
bool fs_mgr_filesystem_has_space(const std::string& mount_point);
|
||||||
const std::string fs_mgr_mount_point(const std::string& mount_point);
|
const std::string fs_mgr_mount_point(const std::string& mount_point);
|
||||||
|
bool OverlayfsSetupAllowed(bool verbose = false);
|
||||||
|
bool MountScratch(const std::string& device_path, bool readonly = false);
|
||||||
bool fs_mgr_overlayfs_umount_scratch();
|
bool fs_mgr_overlayfs_umount_scratch();
|
||||||
std::vector<const std::string> OverlayMountPoints();
|
std::vector<const std::string> OverlayMountPoints();
|
||||||
|
bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true);
|
||||||
|
bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry);
|
||||||
|
android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,6 @@ bool is_dt_compatible();
|
||||||
bool fs_mgr_is_ext4(const std::string& blk_device);
|
bool fs_mgr_is_ext4(const std::string& blk_device);
|
||||||
bool fs_mgr_is_f2fs(const std::string& blk_device);
|
bool fs_mgr_is_f2fs(const std::string& blk_device);
|
||||||
|
|
||||||
bool fs_mgr_teardown_verity(android::fs_mgr::FstabEntry* fstab);
|
|
||||||
|
|
||||||
bool fs_mgr_filesystem_available(const std::string& filesystem);
|
bool fs_mgr_filesystem_available(const std::string& filesystem);
|
||||||
std::string fs_mgr_get_context(const std::string& mount_point);
|
std::string fs_mgr_get_context(const std::string& mount_point);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,5 +131,7 @@ std::set<std::string> GetBootDevices();
|
||||||
// expected name.
|
// expected name.
|
||||||
std::string GetVerityDeviceName(const FstabEntry& entry);
|
std::string GetVerityDeviceName(const FstabEntry& entry);
|
||||||
|
|
||||||
|
bool InRecovery();
|
||||||
|
|
||||||
} // namespace fs_mgr
|
} // namespace fs_mgr
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue