fs_mgr_overlayfs: Cleanup -user build stubs
* Categorize functions in fs_mgr_overlayfs.h into three classes: - Type 1: common and non-critical utilities. - Type 2: internal routines for facilitating remount. - Type 3: external entry points for users of fs_mgr_overlayfs, like fs_mgr_overlayfs_mount_all(). * Move type 1 to common utils header fs_mgr_priv.h & fs_mgr.cpp. * Move type 2 to new private header fs_mgr_priv_overlayfs.h. * Keep type 3 in fs_mgr_overlayfs.h. * Move set-verity-state.cpp under fs_mgr so it can include fs_mgr_priv_overlayfs.h. File is reformatted as a result. We should eventually merge and dedup set-verity-state and fs_mgr_remount. * Add myself to OWNERS for remount-related maintenance work. Bug: 241179247 Bug: 241688845 Test: Full build -user and -userdebug build. Test: Presubmit Test: Treehugger run v2/android-gki/adb_remount Change-Id: Id5fd0e2b12c693939d712a586dd553cc4d8bfeb1
This commit is contained in:
parent
0cba7afd67
commit
ad06b405ee
14 changed files with 483 additions and 463 deletions
|
@ -254,3 +254,39 @@ cc_binary {
|
|||
"clean_scratch_files",
|
||||
],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "set-verity-state",
|
||||
srcs: ["set-verity-state.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder",
|
||||
"libcrypto",
|
||||
"libcrypto_utils",
|
||||
"libfs_mgr_binder",
|
||||
"libutils",
|
||||
],
|
||||
static_libs: [
|
||||
"libavb_user",
|
||||
],
|
||||
header_libs: [
|
||||
"libcutils_headers",
|
||||
],
|
||||
|
||||
cflags: ["-Werror"],
|
||||
cppflags: [
|
||||
"-DALLOW_DISABLE_VERITY=0",
|
||||
],
|
||||
product_variables: {
|
||||
debuggable: {
|
||||
cppflags: [
|
||||
"-UALLOW_DISABLE_VERITY",
|
||||
"-DALLOW_DISABLE_VERITY=1",
|
||||
],
|
||||
},
|
||||
},
|
||||
symlinks: [
|
||||
"enable-verity",
|
||||
"disable-verity",
|
||||
],
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
bowgotsai@google.com
|
||||
dvander@google.com
|
||||
elsk@google.com
|
||||
yochiang@google.com
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <libgen.h>
|
||||
#include <selinux/selinux.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -30,6 +31,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/swap.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
@ -2359,3 +2361,49 @@ bool fs_mgr_load_verity_state(int* mode) {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fs_mgr_filesystem_available(const std::string& filesystem) {
|
||||
std::string filesystems;
|
||||
if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false;
|
||||
return filesystems.find("\t" + filesystem + "\n") != std::string::npos;
|
||||
}
|
||||
|
||||
std::string fs_mgr_get_context(const std::string& mount_point) {
|
||||
char* ctx = nullptr;
|
||||
if (getfilecon(mount_point.c_str(), &ctx) == -1) {
|
||||
PERROR << "getfilecon " << mount_point;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string context(ctx);
|
||||
free(ctx);
|
||||
return context;
|
||||
}
|
||||
|
||||
OverlayfsValidResult fs_mgr_overlayfs_valid() {
|
||||
// Overlayfs available in the kernel, and patched for override_creds?
|
||||
if (access("/sys/module/overlay/parameters/override_creds", F_OK) == 0) {
|
||||
return OverlayfsValidResult::kOverrideCredsRequired;
|
||||
}
|
||||
if (!fs_mgr_filesystem_available("overlay")) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
struct utsname uts;
|
||||
if (uname(&uts) == -1) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
int major, minor;
|
||||
if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
if (major < 4) {
|
||||
return OverlayfsValidResult::kOk;
|
||||
}
|
||||
if (major > 4) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
if (minor > 3) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
return OverlayfsValidResult::kOk;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include <storage_literals/storage_literals.h>
|
||||
|
||||
#include "fs_mgr_priv.h"
|
||||
#include "fs_mgr_priv_overlayfs.h"
|
||||
#include "libfiemap/utility.h"
|
||||
|
||||
using namespace std::literals;
|
||||
|
@ -71,62 +72,9 @@ bool fs_mgr_access(const std::string& path) {
|
|||
return access(path.c_str(), F_OK) == 0;
|
||||
}
|
||||
|
||||
// determine if a filesystem is available
|
||||
bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) {
|
||||
std::string filesystems;
|
||||
if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false;
|
||||
return filesystems.find("\t" + filesystem + "\n") != std::string::npos;
|
||||
}
|
||||
|
||||
const auto kLowerdirOption = "lowerdir="s;
|
||||
const auto kUpperdirOption = "upperdir="s;
|
||||
|
||||
} // namespace
|
||||
|
||||
#if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs
|
||||
|
||||
bool fs_mgr_wants_overlayfs(FstabEntry*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Fstab fs_mgr_overlayfs_candidate_list(const Fstab&) {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(Fstab*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_setup(const char*, bool*, bool) {
|
||||
LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds";
|
||||
return false;
|
||||
}
|
||||
|
||||
OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char*, bool*) {
|
||||
return OverlayfsTeardownResult::Ok;
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_is_setup() {
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
void MapScratchPartitionIfNeeded(Fstab*, const std::function<bool(const std::set<std::string>&)>&) {
|
||||
}
|
||||
|
||||
void CleanupOldScratchFiles() {}
|
||||
|
||||
void TeardownAllOverlayForMountPoint(const std::string&) {}
|
||||
|
||||
} // namespace fs_mgr
|
||||
} // namespace android
|
||||
|
||||
#else // ALLOW_ADBD_DISABLE_VERITY == 0
|
||||
|
||||
namespace {
|
||||
|
||||
bool fs_mgr_in_recovery() {
|
||||
// Check the existence of recovery binary instead of using the compile time
|
||||
// __ANDROID_RECOVERY__ macro.
|
||||
|
@ -234,6 +182,28 @@ bool fs_mgr_update_blk_device(FstabEntry* entry) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) {
|
||||
struct statfs fs;
|
||||
if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) ||
|
||||
(fs.f_type != EXT4_SUPER_MAGIC)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC));
|
||||
if (fd < 0) return false;
|
||||
|
||||
struct ext4_super_block sb;
|
||||
if ((TEMP_FAILURE_RETRY(lseek64(fd, 1024, SEEK_SET)) < 0) ||
|
||||
(TEMP_FAILURE_RETRY(read(fd, &sb, sizeof(sb))) < 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct fs_info info;
|
||||
if (ext4_parse_sb(&sb, &info) < 0) return false;
|
||||
|
||||
return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0;
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_enabled(FstabEntry* entry) {
|
||||
// readonly filesystem, can not be mount -o remount,rw
|
||||
// for squashfs, erofs or if free space is (near) zero making such a remount
|
||||
|
@ -886,10 +856,10 @@ const std::string kMkExt4("/system/bin/mke2fs");
|
|||
|
||||
// Only a suggestion for _first_ try during mounting
|
||||
std::string fs_mgr_overlayfs_scratch_mount_type() {
|
||||
if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("f2fs")) {
|
||||
if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_filesystem_available("f2fs")) {
|
||||
return "f2fs";
|
||||
}
|
||||
if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("ext4")) {
|
||||
if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_filesystem_available("ext4")) {
|
||||
return "ext4";
|
||||
}
|
||||
return "auto";
|
||||
|
@ -1233,11 +1203,41 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) {
|
|||
return fs_mgr_overlayfs_mount_scratch(scratch_device, mnt_type);
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_invalid() {
|
||||
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true;
|
||||
#if ALLOW_ADBD_DISABLE_VERITY
|
||||
constexpr bool kAllowOverlayfs = true;
|
||||
#else
|
||||
constexpr bool kAllowOverlayfs = false;
|
||||
#endif
|
||||
|
||||
// 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!
|
||||
return fs_mgr_in_recovery();
|
||||
if (fs_mgr_in_recovery()) {
|
||||
if (verbose) {
|
||||
LOG(ERROR) << "Unsupported overlayfs setup from recovery";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool OverlayfsTeardownAllowed() {
|
||||
// Never allow on non-debuggable build.
|
||||
return kAllowOverlayfs;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -1331,7 +1331,7 @@ static void TryMountScratch() {
|
|||
}
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
|
||||
if (fs_mgr_overlayfs_invalid()) {
|
||||
if (!OverlayfsSetupAllowed()) {
|
||||
return false;
|
||||
}
|
||||
auto ret = true;
|
||||
|
@ -1352,8 +1352,7 @@ bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
|
|||
}
|
||||
|
||||
bool fs_mgr_overlayfs_setup(const char* mount_point, bool* want_reboot, bool just_disabled_verity) {
|
||||
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
|
||||
LOG(ERROR) << "Overlayfs is not supported";
|
||||
if (!OverlayfsSetupAllowed(/*verbose=*/true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1523,7 +1522,8 @@ static bool MapDsuScratchDevice(std::string* device) {
|
|||
return true;
|
||||
}
|
||||
|
||||
OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool* want_reboot) {
|
||||
static OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point,
|
||||
bool* want_reboot) {
|
||||
bool should_destroy_scratch = false;
|
||||
auto rv = OverlayfsTeardownResult::Ok;
|
||||
for (const auto& overlay_mount_point : OverlayMountPoints()) {
|
||||
|
@ -1555,6 +1555,10 @@ OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool*
|
|||
|
||||
// Returns false if teardown not permitted. If something is altered, set *want_reboot.
|
||||
OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point, bool* want_reboot) {
|
||||
if (!OverlayfsTeardownAllowed()) {
|
||||
// Nothing to teardown.
|
||||
return OverlayfsTeardownResult::Ok;
|
||||
}
|
||||
// If scratch exists, but is not mounted, lets gain access to clean
|
||||
// specific override entries.
|
||||
auto mount_scratch = false;
|
||||
|
@ -1577,12 +1581,14 @@ OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point, bool*
|
|||
}
|
||||
|
||||
bool fs_mgr_overlayfs_is_setup() {
|
||||
if (!OverlayfsSetupAllowed()) {
|
||||
return false;
|
||||
}
|
||||
if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;
|
||||
Fstab fstab;
|
||||
if (!ReadDefaultFstab(&fstab)) {
|
||||
return false;
|
||||
}
|
||||
if (fs_mgr_overlayfs_invalid()) return false;
|
||||
for (const auto& entry : fs_mgr_overlayfs_candidate_list(fstab)) {
|
||||
if (fs_mgr_is_verity_enabled(entry)) continue;
|
||||
if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) return true;
|
||||
|
@ -1595,7 +1601,7 @@ namespace fs_mgr {
|
|||
|
||||
void MapScratchPartitionIfNeeded(Fstab* fstab,
|
||||
const std::function<bool(const std::set<std::string>&)>& init) {
|
||||
if (fs_mgr_overlayfs_invalid()) {
|
||||
if (!OverlayfsSetupAllowed()) {
|
||||
return;
|
||||
}
|
||||
if (GetEntryForMountPoint(fstab, kScratchMountPoint) != nullptr) {
|
||||
|
@ -1632,6 +1638,9 @@ void MapScratchPartitionIfNeeded(Fstab* fstab,
|
|||
}
|
||||
|
||||
void CleanupOldScratchFiles() {
|
||||
if (!OverlayfsTeardownAllowed()) {
|
||||
return;
|
||||
}
|
||||
if (!ScratchIsOnData()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1641,6 +1650,9 @@ void CleanupOldScratchFiles() {
|
|||
}
|
||||
|
||||
void TeardownAllOverlayForMountPoint(const std::string& mount_point) {
|
||||
if (!OverlayfsTeardownAllowed()) {
|
||||
return;
|
||||
}
|
||||
if (!fs_mgr_in_recovery()) {
|
||||
LERROR << __FUNCTION__ << "(): must be called within recovery.";
|
||||
return;
|
||||
|
@ -1701,8 +1713,6 @@ void TeardownAllOverlayForMountPoint(const std::string& mount_point) {
|
|||
} // namespace fs_mgr
|
||||
} // namespace android
|
||||
|
||||
#endif // ALLOW_ADBD_DISABLE_VERITY != 0
|
||||
|
||||
bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only) {
|
||||
Fstab fstab;
|
||||
if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
|
||||
|
@ -1722,65 +1732,3 @@ bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overl
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) {
|
||||
struct statfs fs;
|
||||
if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) ||
|
||||
(fs.f_type != EXT4_SUPER_MAGIC)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC));
|
||||
if (fd < 0) return false;
|
||||
|
||||
struct ext4_super_block sb;
|
||||
if ((TEMP_FAILURE_RETRY(lseek64(fd, 1024, SEEK_SET)) < 0) ||
|
||||
(TEMP_FAILURE_RETRY(read(fd, &sb, sizeof(sb))) < 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct fs_info info;
|
||||
if (ext4_parse_sb(&sb, &info) < 0) return false;
|
||||
|
||||
return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0;
|
||||
}
|
||||
|
||||
std::string fs_mgr_get_context(const std::string& mount_point) {
|
||||
char* ctx = nullptr;
|
||||
if (getfilecon(mount_point.c_str(), &ctx) == -1) {
|
||||
PLOG(ERROR) << "getfilecon " << mount_point;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string context(ctx);
|
||||
free(ctx);
|
||||
return context;
|
||||
}
|
||||
|
||||
OverlayfsValidResult fs_mgr_overlayfs_valid() {
|
||||
// Overlayfs available in the kernel, and patched for override_creds?
|
||||
if (fs_mgr_access("/sys/module/overlay/parameters/override_creds")) {
|
||||
return OverlayfsValidResult::kOverrideCredsRequired;
|
||||
}
|
||||
if (!fs_mgr_overlayfs_filesystem_available("overlay")) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
struct utsname uts;
|
||||
if (uname(&uts) == -1) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
int major, minor;
|
||||
if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
if (major < 4) {
|
||||
return OverlayfsValidResult::kOk;
|
||||
}
|
||||
if (major > 4) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
if (minor > 3) {
|
||||
return OverlayfsValidResult::kNotSupported;
|
||||
}
|
||||
return OverlayfsValidResult::kOk;
|
||||
}
|
||||
|
|
|
@ -99,6 +99,16 @@ 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);
|
||||
std::string fs_mgr_get_context(const std::string& mount_point);
|
||||
|
||||
enum class OverlayfsValidResult {
|
||||
kNotSupported = 0,
|
||||
kOk,
|
||||
kOverrideCredsRequired,
|
||||
};
|
||||
OverlayfsValidResult fs_mgr_overlayfs_valid();
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
bool UnmapDevice(const std::string& name);
|
||||
|
|
49
fs_mgr/fs_mgr_priv_overlayfs.h
Normal file
49
fs_mgr/fs_mgr_priv_overlayfs.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <fstab/fstab.h>
|
||||
|
||||
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);
|
||||
|
||||
// If "mount_point" is non-null, set up exactly one overlay.
|
||||
// If "mount_point" is null, setup any overlays.
|
||||
//
|
||||
// If |want_reboot| is non-null, and a reboot is needed to apply overlays, then
|
||||
// it will be true on return. The caller is responsible for initializing it.
|
||||
bool fs_mgr_overlayfs_setup(const char* mount_point = nullptr, bool* want_reboot = nullptr,
|
||||
bool just_disabled_verity = true);
|
||||
|
||||
enum class OverlayfsTeardownResult {
|
||||
Ok,
|
||||
Busy, // Indicates that overlays are still in use.
|
||||
Error
|
||||
};
|
||||
OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point = nullptr,
|
||||
bool* want_reboot = nullptr);
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
void CleanupOldScratchFiles();
|
||||
|
||||
} // namespace fs_mgr
|
||||
} // namespace android
|
|
@ -42,6 +42,8 @@
|
|||
#include <libavb_user/libavb_user.h>
|
||||
#include <libgsi/libgsid.h>
|
||||
|
||||
#include "fs_mgr_priv_overlayfs.h"
|
||||
|
||||
using namespace std::literals;
|
||||
using android::fs_mgr::Fstab;
|
||||
using android::fs_mgr::FstabEntry;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <fs_mgr_overlayfs.h>
|
||||
#include <fs_mgr_vendor_overlay.h>
|
||||
#include <fstab/fstab.h>
|
||||
|
||||
|
|
|
@ -17,51 +17,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include <fstab/fstab.h>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
// Keep the list short and only add interfaces that must be exported public.
|
||||
|
||||
android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);
|
||||
|
||||
bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry);
|
||||
bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab);
|
||||
bool fs_mgr_overlayfs_is_setup();
|
||||
bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev);
|
||||
bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true);
|
||||
std::string fs_mgr_get_context(const std::string& mount_point);
|
||||
|
||||
// If "mount_point" is non-null, set up exactly one overlay.
|
||||
// If "mount_point" is null, setup any overlays.
|
||||
//
|
||||
// If |want_reboot| is non-null, and a reboot is needed to apply overlays, then
|
||||
// it will be true on return. The caller is responsible for initializing it.
|
||||
bool fs_mgr_overlayfs_setup(const char* mount_point = nullptr, bool* want_reboot = nullptr,
|
||||
bool just_disabled_verity = true);
|
||||
|
||||
enum class OverlayfsTeardownResult {
|
||||
Ok,
|
||||
Busy, // Indicates that overlays are still in use.
|
||||
Error
|
||||
};
|
||||
OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point = nullptr,
|
||||
bool* want_reboot = nullptr);
|
||||
|
||||
enum class OverlayfsValidResult {
|
||||
kNotSupported = 0,
|
||||
kOk,
|
||||
kOverrideCredsRequired,
|
||||
};
|
||||
OverlayfsValidResult fs_mgr_overlayfs_valid();
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
void MapScratchPartitionIfNeeded(Fstab* fstab,
|
||||
const std::function<bool(const std::set<std::string>&)>& init);
|
||||
void CleanupOldScratchFiles();
|
||||
|
||||
// Teardown overlays of all sources (cache dir, scratch device, DSU) for |mount_point|.
|
||||
// Teardown all overlays if |mount_point| is empty.
|
||||
|
|
258
fs_mgr/set-verity-state.cpp
Normal file
258
fs_mgr/set-verity-state.cpp
Normal file
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <cutils/android_reboot.h>
|
||||
#include <fs_mgr_overlayfs.h>
|
||||
#include <libavb_user/libavb_user.h>
|
||||
|
||||
#include "fs_mgr_priv_overlayfs.h"
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace {
|
||||
|
||||
void print_usage() {
|
||||
printf("Usage:\n"
|
||||
"\tdisable-verity\n"
|
||||
"\tenable-verity\n"
|
||||
"\tset-verity-state [0|1]\n"
|
||||
"Options:\n"
|
||||
"\t-h --help\tthis help\n"
|
||||
"\t-R --reboot\tautomatic reboot if needed for new settings to take effect\n"
|
||||
"\t-v --verbose\tbe noisy\n");
|
||||
}
|
||||
|
||||
#ifdef ALLOW_DISABLE_VERITY
|
||||
const bool kAllowDisableVerity = true;
|
||||
#else
|
||||
const bool kAllowDisableVerity = false;
|
||||
#endif
|
||||
|
||||
static bool SetupOrTeardownOverlayfs(bool enable) {
|
||||
bool want_reboot = false;
|
||||
if (enable) {
|
||||
if (!fs_mgr_overlayfs_setup(nullptr, &want_reboot)) {
|
||||
LOG(ERROR) << "Overlayfs setup failed.";
|
||||
return want_reboot;
|
||||
}
|
||||
if (want_reboot) {
|
||||
printf("enabling overlayfs\n");
|
||||
}
|
||||
} else {
|
||||
auto rv = fs_mgr_overlayfs_teardown(nullptr, &want_reboot);
|
||||
if (rv == OverlayfsTeardownResult::Error) {
|
||||
LOG(ERROR) << "Overlayfs teardown failed.";
|
||||
return want_reboot;
|
||||
}
|
||||
if (rv == OverlayfsTeardownResult::Busy) {
|
||||
LOG(ERROR) << "Overlayfs is still active until reboot.";
|
||||
return true;
|
||||
}
|
||||
if (want_reboot) {
|
||||
printf("disabling overlayfs\n");
|
||||
}
|
||||
}
|
||||
return want_reboot;
|
||||
}
|
||||
|
||||
/* Helper function to get A/B suffix, if any. If the device isn't
|
||||
* using A/B the empty string is returned. Otherwise either "_a",
|
||||
* "_b", ... is returned.
|
||||
*/
|
||||
std::string get_ab_suffix() {
|
||||
return android::base::GetProperty("ro.boot.slot_suffix", "");
|
||||
}
|
||||
|
||||
bool is_avb_device_locked() {
|
||||
return android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked";
|
||||
}
|
||||
|
||||
bool is_debuggable() {
|
||||
return android::base::GetBoolProperty("ro.debuggable", false);
|
||||
}
|
||||
|
||||
bool is_using_avb() {
|
||||
// Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
|
||||
// contract, androidboot.vbmeta.digest is set by the bootloader
|
||||
// when using AVB).
|
||||
return !android::base::GetProperty("ro.boot.vbmeta.digest", "").empty();
|
||||
}
|
||||
|
||||
[[noreturn]] void reboot(const std::string& name) {
|
||||
LOG(INFO) << "Rebooting device for new settings to take effect";
|
||||
::sync();
|
||||
android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot," + name);
|
||||
::sleep(60);
|
||||
LOG(ERROR) << "Failed to reboot";
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
struct SetVerityStateResult {
|
||||
bool success = false;
|
||||
bool want_reboot = false;
|
||||
};
|
||||
|
||||
/* Use AVB to turn verity on/off */
|
||||
SetVerityStateResult SetVerityState(bool enable_verity) {
|
||||
std::string ab_suffix = get_ab_suffix();
|
||||
bool verity_enabled = false;
|
||||
|
||||
if (is_avb_device_locked()) {
|
||||
LOG(ERROR) << "Device must be bootloader unlocked to change verity state";
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<AvbOps, decltype(&avb_ops_user_free)> ops(avb_ops_user_new(),
|
||||
&avb_ops_user_free);
|
||||
if (!ops) {
|
||||
LOG(ERROR) << "Error getting AVB ops";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!avb_user_verity_get(ops.get(), ab_suffix.c_str(), &verity_enabled)) {
|
||||
LOG(ERROR) << "Error getting verity state";
|
||||
return {};
|
||||
}
|
||||
|
||||
if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
|
||||
LOG(INFO) << "Verity is already " << (verity_enabled ? "enabled" : "disabled");
|
||||
return {.success = true, .want_reboot = false};
|
||||
}
|
||||
|
||||
if (!avb_user_verity_set(ops.get(), ab_suffix.c_str(), enable_verity)) {
|
||||
LOG(ERROR) << "Error setting verity state";
|
||||
return {};
|
||||
}
|
||||
|
||||
LOG(INFO) << "Successfully " << (enable_verity ? "enabled" : "disabled") << " verity";
|
||||
return {.success = true, .want_reboot = true};
|
||||
}
|
||||
|
||||
class MyLogger {
|
||||
public:
|
||||
explicit MyLogger(bool verbose) : verbose_(verbose) {}
|
||||
|
||||
void operator()(android::base::LogId id, android::base::LogSeverity severity, const char* tag,
|
||||
const char* file, unsigned int line, const char* message) {
|
||||
// Hide log starting with '[fs_mgr]' unless it's an error.
|
||||
if (verbose_ || severity >= android::base::ERROR || message[0] != '[') {
|
||||
fprintf(stderr, "%s\n", message);
|
||||
}
|
||||
logd_(id, severity, tag, file, line, message);
|
||||
}
|
||||
|
||||
private:
|
||||
android::base::LogdLogger logd_;
|
||||
bool verbose_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
bool auto_reboot = false;
|
||||
bool verbose = false;
|
||||
|
||||
struct option longopts[] = {
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{"reboot", no_argument, nullptr, 'R'},
|
||||
{"verbose", no_argument, nullptr, 'v'},
|
||||
{0, 0, nullptr, 0},
|
||||
};
|
||||
for (int opt; (opt = ::getopt_long(argc, argv, "hRv", longopts, nullptr)) != -1;) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
print_usage();
|
||||
return 0;
|
||||
case 'R':
|
||||
auto_reboot = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
android::base::InitLogging(argv, MyLogger(verbose));
|
||||
|
||||
bool enable_verity = false;
|
||||
const std::string progname = getprogname();
|
||||
if (progname == "enable-verity") {
|
||||
enable_verity = true;
|
||||
} else if (progname == "disable-verity") {
|
||||
enable_verity = false;
|
||||
} else if (optind < argc && (argv[optind] == "1"s || argv[optind] == "0"s)) {
|
||||
// progname "set-verity-state"
|
||||
enable_verity = (argv[optind] == "1"s);
|
||||
} else {
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!kAllowDisableVerity || !is_debuggable()) {
|
||||
errno = EPERM;
|
||||
PLOG(ERROR) << "Cannot disable/enable verity on user build";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (getuid() != 0) {
|
||||
errno = EACCES;
|
||||
PLOG(ERROR) << "Must be running as root (adb root)";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!is_using_avb()) {
|
||||
LOG(ERROR) << "Expected AVB device, VB1.0 is no longer supported";
|
||||
return 1;
|
||||
}
|
||||
|
||||
int exit_code = 0;
|
||||
bool want_reboot = false;
|
||||
|
||||
auto ret = SetVerityState(enable_verity);
|
||||
if (ret.success) {
|
||||
want_reboot |= ret.want_reboot;
|
||||
} else {
|
||||
exit_code = 1;
|
||||
}
|
||||
|
||||
// Disable any overlayfs unconditionally if we want verity enabled.
|
||||
// Enable overlayfs only if verity is successfully disabled or is already disabled.
|
||||
if (enable_verity || ret.success) {
|
||||
// Start a threadpool to service waitForService() callbacks as
|
||||
// fs_mgr_overlayfs_* might call waitForService() to get the image service.
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
want_reboot |= SetupOrTeardownOverlayfs(!enable_verity);
|
||||
}
|
||||
|
||||
if (want_reboot) {
|
||||
if (auto_reboot) {
|
||||
reboot(progname);
|
||||
}
|
||||
printf("Reboot the device for new settings to take effect\n");
|
||||
}
|
||||
|
||||
return exit_code;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
../.clang-format-2
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2019 The Android Open Source Project
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "set-verity-state",
|
||||
srcs: ["set-verity-state.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder",
|
||||
"libcrypto",
|
||||
"libcrypto_utils",
|
||||
"libfs_mgr_binder",
|
||||
"libutils",
|
||||
],
|
||||
static_libs: [
|
||||
"libavb_user",
|
||||
],
|
||||
header_libs: [
|
||||
"libcutils_headers",
|
||||
],
|
||||
|
||||
cflags: ["-Werror"],
|
||||
cppflags: [
|
||||
"-DALLOW_DISABLE_VERITY=0",
|
||||
],
|
||||
product_variables: {
|
||||
debuggable: {
|
||||
cppflags: [
|
||||
"-UALLOW_DISABLE_VERITY",
|
||||
"-DALLOW_DISABLE_VERITY=1",
|
||||
],
|
||||
},
|
||||
},
|
||||
symlinks: [
|
||||
"enable-verity",
|
||||
"disable-verity",
|
||||
],
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
dvander@google.com
|
||||
yochiang@google.com
|
||||
bowgotsai@google.com
|
|
@ -1,256 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <cutils/android_reboot.h>
|
||||
#include <fs_mgr_overlayfs.h>
|
||||
#include <libavb_user/libavb_user.h>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace {
|
||||
|
||||
void print_usage() {
|
||||
printf(
|
||||
"Usage:\n"
|
||||
"\tdisable-verity\n"
|
||||
"\tenable-verity\n"
|
||||
"\tset-verity-state [0|1]\n"
|
||||
"Options:\n"
|
||||
"\t-h --help\tthis help\n"
|
||||
"\t-R --reboot\tautomatic reboot if needed for new settings to take effect\n"
|
||||
"\t-v --verbose\tbe noisy\n");
|
||||
}
|
||||
|
||||
#ifdef ALLOW_DISABLE_VERITY
|
||||
const bool kAllowDisableVerity = true;
|
||||
#else
|
||||
const bool kAllowDisableVerity = false;
|
||||
#endif
|
||||
|
||||
static bool SetupOrTeardownOverlayfs(bool enable) {
|
||||
bool want_reboot = false;
|
||||
if (enable) {
|
||||
if (!fs_mgr_overlayfs_setup(nullptr, &want_reboot)) {
|
||||
LOG(ERROR) << "Overlayfs setup failed.";
|
||||
return want_reboot;
|
||||
}
|
||||
if (want_reboot) {
|
||||
printf("enabling overlayfs\n");
|
||||
}
|
||||
} else {
|
||||
auto rv = fs_mgr_overlayfs_teardown(nullptr, &want_reboot);
|
||||
if (rv == OverlayfsTeardownResult::Error) {
|
||||
LOG(ERROR) << "Overlayfs teardown failed.";
|
||||
return want_reboot;
|
||||
}
|
||||
if (rv == OverlayfsTeardownResult::Busy) {
|
||||
LOG(ERROR) << "Overlayfs is still active until reboot.";
|
||||
return true;
|
||||
}
|
||||
if (want_reboot) {
|
||||
printf("disabling overlayfs\n");
|
||||
}
|
||||
}
|
||||
return want_reboot;
|
||||
}
|
||||
|
||||
/* Helper function to get A/B suffix, if any. If the device isn't
|
||||
* using A/B the empty string is returned. Otherwise either "_a",
|
||||
* "_b", ... is returned.
|
||||
*/
|
||||
std::string get_ab_suffix() {
|
||||
return android::base::GetProperty("ro.boot.slot_suffix", "");
|
||||
}
|
||||
|
||||
bool is_avb_device_locked() {
|
||||
return android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked";
|
||||
}
|
||||
|
||||
bool is_debuggable() {
|
||||
return android::base::GetBoolProperty("ro.debuggable", false);
|
||||
}
|
||||
|
||||
bool is_using_avb() {
|
||||
// Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
|
||||
// contract, androidboot.vbmeta.digest is set by the bootloader
|
||||
// when using AVB).
|
||||
return !android::base::GetProperty("ro.boot.vbmeta.digest", "").empty();
|
||||
}
|
||||
|
||||
[[noreturn]] void reboot(const std::string& name) {
|
||||
LOG(INFO) << "Rebooting device for new settings to take effect";
|
||||
::sync();
|
||||
android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot," + name);
|
||||
::sleep(60);
|
||||
LOG(ERROR) << "Failed to reboot";
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
struct SetVerityStateResult {
|
||||
bool success = false;
|
||||
bool want_reboot = false;
|
||||
};
|
||||
|
||||
/* Use AVB to turn verity on/off */
|
||||
SetVerityStateResult SetVerityState(bool enable_verity) {
|
||||
std::string ab_suffix = get_ab_suffix();
|
||||
bool verity_enabled = false;
|
||||
|
||||
if (is_avb_device_locked()) {
|
||||
LOG(ERROR) << "Device must be bootloader unlocked to change verity state";
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<AvbOps, decltype(&avb_ops_user_free)> ops(avb_ops_user_new(), &avb_ops_user_free);
|
||||
if (!ops) {
|
||||
LOG(ERROR) << "Error getting AVB ops";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!avb_user_verity_get(ops.get(), ab_suffix.c_str(), &verity_enabled)) {
|
||||
LOG(ERROR) << "Error getting verity state";
|
||||
return {};
|
||||
}
|
||||
|
||||
if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
|
||||
LOG(INFO) << "Verity is already " << (verity_enabled ? "enabled" : "disabled");
|
||||
return {.success = true, .want_reboot = false};
|
||||
}
|
||||
|
||||
if (!avb_user_verity_set(ops.get(), ab_suffix.c_str(), enable_verity)) {
|
||||
LOG(ERROR) << "Error setting verity state";
|
||||
return {};
|
||||
}
|
||||
|
||||
LOG(INFO) << "Successfully " << (enable_verity ? "enabled" : "disabled") << " verity";
|
||||
return {.success = true, .want_reboot = true};
|
||||
}
|
||||
|
||||
class MyLogger {
|
||||
public:
|
||||
explicit MyLogger(bool verbose) : verbose_(verbose) {}
|
||||
|
||||
void operator()(android::base::LogId id, android::base::LogSeverity severity, const char* tag,
|
||||
const char* file, unsigned int line, const char* message) {
|
||||
// Hide log starting with '[fs_mgr]' unless it's an error.
|
||||
if (verbose_ || severity >= android::base::ERROR || message[0] != '[') {
|
||||
fprintf(stderr, "%s\n", message);
|
||||
}
|
||||
logd_(id, severity, tag, file, line, message);
|
||||
}
|
||||
|
||||
private:
|
||||
android::base::LogdLogger logd_;
|
||||
bool verbose_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
bool auto_reboot = false;
|
||||
bool verbose = false;
|
||||
|
||||
struct option longopts[] = {
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{"reboot", no_argument, nullptr, 'R'},
|
||||
{"verbose", no_argument, nullptr, 'v'},
|
||||
{0, 0, nullptr, 0},
|
||||
};
|
||||
for (int opt; (opt = ::getopt_long(argc, argv, "hRv", longopts, nullptr)) != -1;) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
print_usage();
|
||||
return 0;
|
||||
case 'R':
|
||||
auto_reboot = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
android::base::InitLogging(argv, MyLogger(verbose));
|
||||
|
||||
bool enable_verity = false;
|
||||
const std::string progname = getprogname();
|
||||
if (progname == "enable-verity") {
|
||||
enable_verity = true;
|
||||
} else if (progname == "disable-verity") {
|
||||
enable_verity = false;
|
||||
} else if (optind < argc && (argv[optind] == "1"s || argv[optind] == "0"s)) {
|
||||
// progname "set-verity-state"
|
||||
enable_verity = (argv[optind] == "1"s);
|
||||
} else {
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!kAllowDisableVerity || !is_debuggable()) {
|
||||
errno = EPERM;
|
||||
PLOG(ERROR) << "Cannot disable/enable verity on user build";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (getuid() != 0) {
|
||||
errno = EACCES;
|
||||
PLOG(ERROR) << "Must be running as root (adb root)";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!is_using_avb()) {
|
||||
LOG(ERROR) << "Expected AVB device, VB1.0 is no longer supported";
|
||||
return 1;
|
||||
}
|
||||
|
||||
int exit_code = 0;
|
||||
bool want_reboot = false;
|
||||
|
||||
auto ret = SetVerityState(enable_verity);
|
||||
if (ret.success) {
|
||||
want_reboot |= ret.want_reboot;
|
||||
} else {
|
||||
exit_code = 1;
|
||||
}
|
||||
|
||||
// Disable any overlayfs unconditionally if we want verity enabled.
|
||||
// Enable overlayfs only if verity is successfully disabled or is already disabled.
|
||||
if (enable_verity || ret.success) {
|
||||
// Start a threadpool to service waitForService() callbacks as
|
||||
// fs_mgr_overlayfs_* might call waitForService() to get the image service.
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
want_reboot |= SetupOrTeardownOverlayfs(!enable_verity);
|
||||
}
|
||||
|
||||
if (want_reboot) {
|
||||
if (auto_reboot) {
|
||||
reboot(progname);
|
||||
}
|
||||
printf("Reboot the device for new settings to take effect\n");
|
||||
}
|
||||
|
||||
return exit_code;
|
||||
}
|
Loading…
Reference in a new issue