Merge "Add logs in SuperLayoutBuilder::Open when the metadata isn't supported" into main
diff --git a/OWNERS b/OWNERS
index 682a067..96b4f54 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1 +1,2 @@
+# Bug component: 128577
enh@google.com
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index d20de6b..5393e25 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -188,6 +188,7 @@
cc_library_static {
name: "libdebuggerd",
defaults: ["debuggerd_defaults"],
+ ramdisk_available: true,
recovery_available: true,
vendor_ramdisk_available: true,
@@ -221,9 +222,6 @@
"libbase",
"libcutils",
],
- runtime_libs: [
- "libdexfile", // libdexfile_support dependency
- ],
whole_static_libs: [
"libasync_safe",
@@ -250,6 +248,19 @@
"libdexfile",
],
},
+ ramdisk: {
+ exclude_static_libs: [
+ "libdexfile_support",
+ ],
+ exclude_runtime_libs: [
+ "libdexfile",
+ ],
+ },
+ android: {
+ runtime_libs: [
+ "libdexfile", // libdexfile_support dependency
+ ],
+ },
},
product_variables: {
diff --git a/debuggerd/proto/Android.bp b/debuggerd/proto/Android.bp
index 73cf573..804f805 100644
--- a/debuggerd/proto/Android.bp
+++ b/debuggerd/proto/Android.bp
@@ -35,6 +35,7 @@
"com.android.runtime",
],
+ ramdisk_available: true,
recovery_available: true,
vendor_ramdisk_available: true,
}
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index f6ffb64..dc57149 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -27,6 +27,7 @@
*/
#pragma once
+#include <functional>
#include <string>
#include "fastboot_driver.h"
#include "fastboot_driver_interface.h"
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 0a836e4..4e4d20e 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -60,7 +60,6 @@
defaults: ["fs_mgr_defaults"],
export_include_dirs: ["include"],
local_include_dirs: ["include/"],
- include_dirs: ["system/vold"],
cflags: [
"-D_FILE_OFFSET_BITS=64",
],
@@ -90,8 +89,6 @@
static_libs: [
"libavb",
"libfs_avb",
- "libfstab",
- "libdm",
"libgsi",
],
export_static_lib_headers: [
@@ -174,47 +171,6 @@
],
}
-cc_library_static {
- // Do not ever make this a shared library as long as it is vendor_available.
- // It does not have a stable interface.
- name: "libfstab",
- vendor_available: true,
- ramdisk_available: true,
- vendor_ramdisk_available: true,
- recovery_available: true,
- apex_available: [
- "//apex_available:anyapex",
- "//apex_available:platform",
- ],
- host_supported: true,
- defaults: ["fs_mgr_defaults"],
- local_include_dirs: ["include/"],
- srcs: [
- "fs_mgr_fstab.cpp",
- "fs_mgr_boot_config.cpp",
- "fs_mgr_slotselect.cpp",
- ],
- target: {
- darwin: {
- enabled: false,
- },
- vendor: {
- cflags: [
- // Skipping entries in fstab should only be done in a system
- // process as the config file is in /system_ext.
- // Remove the op from the vendor variant.
- "-DNO_SKIP_MOUNT",
- ],
- },
- },
- export_include_dirs: ["include_fstab"],
- header_libs: [
- "libbase_headers",
- "libgsi_headers",
- ],
- min_sdk_version: "31",
-}
-
cc_binary {
name: "remount",
defaults: ["fs_mgr_defaults"],
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index e568a9b..d55f8d3 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -2227,8 +2227,8 @@
}
bool fs_mgr_mount_overlayfs_fstab_entry(const FstabEntry& entry) {
- auto overlayfs_valid_result = fs_mgr_overlayfs_valid();
- if (overlayfs_valid_result == OverlayfsValidResult::kNotSupported) {
+ const auto overlayfs_check_result = android::fs_mgr::CheckOverlayfs();
+ if (!overlayfs_check_result.supported) {
LERROR << __FUNCTION__ << "(): kernel does not support overlayfs";
return false;
}
@@ -2280,10 +2280,7 @@
}
}
- auto options = "lowerdir=" + lowerdir;
- if (overlayfs_valid_result == OverlayfsValidResult::kOverrideCredsRequired) {
- options += ",override_creds=off";
- }
+ const auto options = "lowerdir=" + lowerdir + overlayfs_check_result.mount_flags;
// Use "overlay-" + entry.blk_device as the mount() source, so that adb-remout-test don't
// confuse this with adb remount overlay, whose device name is "overlay".
@@ -2339,30 +2336,34 @@
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;
- }
+namespace android {
+namespace fs_mgr {
+
+OverlayfsCheckResult CheckOverlayfs() {
if (!fs_mgr_filesystem_available("overlay")) {
- return OverlayfsValidResult::kNotSupported;
+ return {.supported = false};
}
struct utsname uts;
if (uname(&uts) == -1) {
- return OverlayfsValidResult::kNotSupported;
+ return {.supported = false};
}
int major, minor;
if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
- return OverlayfsValidResult::kNotSupported;
+ return {.supported = false};
}
- if (major < 4) {
- return OverlayfsValidResult::kOk;
+ // Overlayfs available in the kernel, and patched for override_creds?
+ if (access("/sys/module/overlay/parameters/override_creds", F_OK) == 0) {
+ auto mount_flags = ",override_creds=off"s;
+ if (major > 5 || (major == 5 && minor >= 15)) {
+ mount_flags += ",userxattr"s;
+ }
+ return {.supported = true, .mount_flags = mount_flags};
}
- if (major > 4) {
- return OverlayfsValidResult::kNotSupported;
+ if (major < 4 || (major == 4 && minor <= 3)) {
+ return {.supported = true};
}
- if (minor > 3) {
- return OverlayfsValidResult::kNotSupported;
- }
- return OverlayfsValidResult::kOk;
+ return {.supported = false};
}
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/fs_mgr_overlayfs_control.cpp b/fs_mgr/fs_mgr_overlayfs_control.cpp
index 69a2ac0..68576f2 100644
--- a/fs_mgr/fs_mgr_overlayfs_control.cpp
+++ b/fs_mgr/fs_mgr_overlayfs_control.cpp
@@ -18,17 +18,10 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
-#include <selinux/selinux.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <sys/param.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/vfs.h>
#include <unistd.h>
#include <algorithm>
@@ -38,13 +31,9 @@
#include <vector>
#include <android-base/file.h>
-#include <android-base/macros.h>
#include <android-base/properties.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/file_wait.h>
#include <fs_mgr_dm_linear.h>
#include <fs_mgr_overlayfs.h>
#include <fstab/fstab.h>
@@ -71,22 +60,25 @@
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
// after 'trigger load_persist_props_action' is done.
static bool fs_mgr_boot_completed() {
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.
static bool ScratchIsOnData() {
// The scratch partition of DSU is managed by gsid.
if (fs_mgr_is_dsu_running()) {
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) {
@@ -131,7 +123,7 @@
}
std::string fs_mgr_overlayfs_setup_dir(const std::string& dir) {
- auto top = dir + kOverlayTopDir;
+ auto top = dir + "/" + kOverlayTopDir;
AutoSetFsCreateCon createcon(kOverlayfsFileContext);
if (!createcon.Ok()) {
@@ -195,10 +187,6 @@
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) {
for (const auto& entry : fstab) {
if (entry.fs_mgr_flags.logical) {
@@ -258,8 +246,8 @@
}
auto slot_number = fs_mgr_overlayfs_slot_number();
- auto super_device = fs_mgr_overlayfs_super_device(slot_number);
- if (!fs_mgr_rw_access(super_device)) {
+ const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
+ if (access(super_device.c_str(), R_OK | W_OK)) {
return OverlayfsTeardownResult::Ok;
}
@@ -290,9 +278,9 @@
bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point,
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;
return true;
}
@@ -300,7 +288,7 @@
auto cleanup_all = mount_point.empty();
const auto partition_name = android::base::Basename(mount_point);
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";
auto ret = fs_mgr_rm_all(newpath);
if (!rename(oldpath.c_str(), newpath.c_str())) {
@@ -346,72 +334,6 @@
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
// first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
static std::string GetDsuScratchDevice() {
@@ -456,14 +378,14 @@
// thus do not rely on fsck to correct problems that could creep in.
auto fs_type = ""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";
- command = kMkF2fs + " -w ";
+ command = kMkF2fs + " -w "s;
command += std::to_string(getpagesize());
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";
- 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 {
LERROR << "No supported mkfs command or filesystem driver available, supported filesystems "
"are: f2fs, ext4";
@@ -506,7 +428,7 @@
auto partition_create = !*partition_exists;
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);
if (!builder) {
LERROR << "open " << super_device << " metadata";
@@ -646,8 +568,8 @@
static bool CanUseSuperPartition(const Fstab& fstab) {
auto slot_number = fs_mgr_overlayfs_slot_number();
- auto super_device = fs_mgr_overlayfs_super_device(slot_number);
- if (!fs_mgr_rw_access(super_device) || !fs_mgr_overlayfs_has_logical(fstab)) {
+ const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
+ if (access(super_device.c_str(), R_OK | W_OK) || !fs_mgr_overlayfs_has_logical(fstab)) {
return false;
}
auto metadata = ReadMetadata(super_device, slot_number);
@@ -697,8 +619,8 @@
// If the partition exists, assume first that it can be mounted.
if (partition_exists) {
if (MountScratch(scratch_device)) {
- if (fs_mgr_access(std::string(kScratchMountPoint) + kOverlayTopDir) ||
- fs_mgr_filesystem_has_space(kScratchMountPoint)) {
+ const auto top = kScratchMountPoint + "/"s + kOverlayTopDir;
+ if (access(top.c_str(), F_OK) == 0 || fs_mgr_filesystem_has_space(kScratchMountPoint)) {
return true;
}
// declare it useless, no overrides and no free space
@@ -717,32 +639,6 @@
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() {
// Never allow on non-debuggable build.
return kAllowOverlayfs;
@@ -844,7 +740,7 @@
if (!info.device.empty()) {
return {std::move(info)};
}
- if (!fs_mgr_in_recovery()) {
+ if (!InRecovery()) {
return {};
}
@@ -867,8 +763,7 @@
}
// Avoid uart spam by first checking for a scratch partition.
- auto metadata_slot = fs_mgr_overlayfs_slot_number();
- auto super_device = fs_mgr_overlayfs_super_device(metadata_slot);
+ const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
auto metadata = ReadCurrentMetadata(super_device);
if (!metadata) {
return {};
@@ -1030,7 +925,7 @@
if (!OverlayfsTeardownAllowed()) {
return;
}
- if (!fs_mgr_in_recovery()) {
+ if (!InRecovery()) {
LERROR << __FUNCTION__ << "(): must be called within recovery.";
return;
}
diff --git a/fs_mgr/fs_mgr_overlayfs_control.h b/fs_mgr/fs_mgr_overlayfs_control.h
index 50e83e8..b175101 100644
--- a/fs_mgr/fs_mgr_overlayfs_control.h
+++ b/fs_mgr/fs_mgr_overlayfs_control.h
@@ -14,8 +14,6 @@
#pragma once
-#include <string>
-
#include <fstab/fstab.h>
// If "mount_point" is non-null, set up exactly one overlay.
diff --git a/fs_mgr/fs_mgr_overlayfs_mount.cpp b/fs_mgr/fs_mgr_overlayfs_mount.cpp
index c057c2b..8fb63b1 100644
--- a/fs_mgr/fs_mgr_overlayfs_mount.cpp
+++ b/fs_mgr/fs_mgr_overlayfs_mount.cpp
@@ -14,26 +14,20 @@
* limitations under the License.
*/
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <selinux/selinux.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <sys/mount.h>
-#include <sys/param.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/types.h>
-#include <sys/utsname.h>
#include <sys/vfs.h>
#include <unistd.h>
#include <algorithm>
#include <memory>
-#include <optional>
#include <string>
#include <vector>
@@ -45,7 +39,6 @@
#include <ext4_utils/ext4_utils.h>
#include <fs_mgr.h>
#include <fs_mgr/file_wait.h>
-#include <fs_mgr_dm_linear.h>
#include <fs_mgr_overlayfs.h>
#include <fstab/fstab.h>
#include <libdm/dm.h>
@@ -62,39 +55,21 @@
constexpr char kPreferCacheBackingStorageProp[] = "fs_mgr.overlayfs.prefer_cache_backing_storage";
-bool fs_mgr_access(const std::string& path) {
- return access(path.c_str(), F_OK) == 0;
-}
+constexpr char kCacheMountPoint[] = "/cache";
+constexpr char kPhysicalDevice[] = "/dev/block/by-name/";
-const auto kLowerdirOption = "lowerdir=";
-const auto 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");
-}
+constexpr char kLowerdirOption[] = "lowerdir=";
+constexpr char kUpperdirOption[] = "upperdir=";
bool fs_mgr_is_dsu_running() {
// Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
// 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
// implies not running a DSU system.
- if (fs_mgr_in_recovery()) return false;
+ if (InRecovery()) return false;
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() {
// Never fallback to legacy cache mount point if within a DSU system,
// because running a DSU system implies the device supports dynamic
@@ -105,7 +80,8 @@
// For non-A/B devices prefer cache backing storage if
// 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__) {
return {kCacheMountPoint, kScratchMountPoint};
}
@@ -118,11 +94,6 @@
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,
// means we will try to wrap with overlayfs.
bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
@@ -141,13 +112,11 @@
(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) {
if (entry->fs_mgr_flags.logical) {
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;
}
if (entry->blk_device != "/dev/root") {
@@ -155,10 +124,10 @@
}
// special case for system-as-root (taimen and others)
- auto blk_device = std::string(kPhysicalDevice) + "system";
- if (!fs_mgr_access(blk_device)) {
+ auto blk_device = kPhysicalDevice + "system"s;
+ if (access(blk_device.c_str(), F_OK)) {
blk_device += fs_mgr_get_slot_suffix();
- if (!fs_mgr_access(blk_device)) {
+ if (access(blk_device.c_str(), F_OK)) {
return false;
}
}
@@ -237,28 +206,17 @@
if (!fs_mgr_is_dir(mount_point)) return "";
const auto base = android::base::Basename(mount_point) + "/";
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;
if (!fs_mgr_is_dir(upper)) continue;
auto work = dir + kWorkName;
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 "";
}
-static inline bool KernelSupportsUserXattrs() {
- struct utsname uts;
- uname(&uts);
-
- int major, minor;
- if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
- return false;
- }
- return major > 5 || (major == 5 && minor >= 15);
-}
-
const std::string fs_mgr_mount_point(const std::string& mount_point) {
if ("/"s != mount_point) return mount_point;
return "/system";
@@ -270,13 +228,7 @@
auto candidate = fs_mgr_get_overlayfs_candidate(mount_point);
if (candidate.empty()) return "";
auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + candidate + kUpperName +
- ",workdir=" + candidate + kWorkName;
- if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) {
- ret += ",override_creds=off";
- }
- if (KernelSupportsUserXattrs()) {
- ret += ",userxattr";
- }
+ ",workdir=" + candidate + kWorkName + android::fs_mgr::CheckOverlayfs().mount_flags;
for (const auto& flag : android::base::Split(entry.fs_options, ",")) {
if (android::base::StartsWith(flag, "context=")) {
ret += "," + flag;
@@ -527,13 +479,13 @@
}
// 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 (!fs_mgr_access(device_path)) {
+ if (access(device_path.c_str(), F_OK)) {
LOG(ERROR) << "Path does not exist: " << device_path;
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;
return false;
}
@@ -589,9 +541,6 @@
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
// first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
static std::string GetDsuScratchDevice() {
@@ -633,7 +582,7 @@
// NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed().
// Setup is allowed only if teardown is also allowed.
-bool OverlayfsSetupAllowed(bool verbose = false) {
+bool OverlayfsSetupAllowed(bool verbose) {
if (!kAllowOverlayfs) {
if (verbose) {
LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds";
@@ -641,14 +590,14 @@
return false;
}
// Check mandatory kernel patches.
- if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
+ if (!android::fs_mgr::CheckOverlayfs().supported) {
if (verbose) {
LOG(ERROR) << "Kernel does not support overlayfs";
}
return false;
}
// in recovery or fastbootd, not allowed!
- if (fs_mgr_in_recovery()) {
+ if (InRecovery()) {
if (verbose) {
LOG(ERROR) << "Unsupported overlayfs setup from recovery";
}
@@ -728,7 +677,7 @@
// if verity is still disabled, i.e. no reboot occurred), and skips calling
// fs_mgr_overlayfs_mount_all().
auto scratch_device = GetBootScratchDevice();
- if (!fs_mgr_rw_access(scratch_device)) {
+ if (access(scratch_device.c_str(), R_OK | W_OK)) {
return;
}
if (!WaitForFile(scratch_device, 10s)) {
@@ -737,7 +686,8 @@
if (!MountScratch(scratch_device, true /* readonly */)) {
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();
if (has_overlayfs_dir) {
MountScratch(scratch_device);
diff --git a/fs_mgr/fs_mgr_overlayfs_mount.h b/fs_mgr/fs_mgr_overlayfs_mount.h
index ae3ea84..f0afac1 100644
--- a/fs_mgr/fs_mgr_overlayfs_mount.h
+++ b/fs_mgr/fs_mgr_overlayfs_mount.h
@@ -20,9 +20,12 @@
#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);
+constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
+
+constexpr char kScratchMountPoint[] = "/mnt/scratch";
+constexpr char kOverlayTopDir[] = "overlay";
+constexpr char kUpperName[] = "upper";
+constexpr char kWorkName[] = "work";
#if ALLOW_ADBD_DISABLE_VERITY
constexpr bool kAllowOverlayfs = true;
@@ -45,18 +48,13 @@
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_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);
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();
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);
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 46cdb62..7e4d5e5 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -23,15 +23,7 @@
#include <fs_mgr.h>
#include <fstab/fstab.h>
-#include "fs_mgr_priv_boot_config.h"
-
-/* The CHECK() in logging.h will use program invocation name as the tag.
- * Thus, the log will have prefix "init: " when libfs_mgr is statically
- * linked in the init process. This might be opaque when debugging.
- * Appends "in libfs_mgr" at the end of the abort message to explicitly
- * indicate the check happens in fs_mgr.
- */
-#define FS_MGR_CHECK(x) CHECK(x) << "in libfs_mgr "
+#include "libfstab/fstab_priv.h"
#define FS_MGR_TAG "[libfs_mgr] "
@@ -89,28 +81,25 @@
using namespace std::chrono_literals;
bool fs_mgr_set_blk_ro(const std::string& blockdev, bool readonly = true);
-bool fs_mgr_update_for_slotselect(android::fs_mgr::Fstab* fstab);
bool fs_mgr_is_device_unlocked();
-const std::string& get_android_dt_dir();
-bool is_dt_compatible();
bool fs_mgr_is_ext4(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);
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);
+
+struct OverlayfsCheckResult {
+ bool supported;
+ std::string mount_flags;
+};
+
+OverlayfsCheckResult CheckOverlayfs();
+
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/fs_mgr_vendor_overlay.cpp b/fs_mgr/fs_mgr_vendor_overlay.cpp
index 6b32b4d..bacfa4b 100644
--- a/fs_mgr/fs_mgr_vendor_overlay.cpp
+++ b/fs_mgr/fs_mgr_vendor_overlay.cpp
@@ -85,10 +85,8 @@
return false;
}
- auto options = kLowerdirOption + source_directory + ":" + vendor_mount_point;
- if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) {
- options += ",override_creds=off";
- }
+ const auto options = kLowerdirOption + source_directory + ":" + vendor_mount_point +
+ android::fs_mgr::CheckOverlayfs().mount_flags;
auto report = "__mount(source=overlay,target="s + vendor_mount_point + ",type=overlay," +
options + ")=";
auto ret = mount("overlay", vendor_mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME,
@@ -120,7 +118,7 @@
const auto vendor_overlay_dirs = fs_mgr_get_vendor_overlay_dirs(vndk_version);
if (vendor_overlay_dirs.empty()) return true;
- if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
+ if (!android::fs_mgr::CheckOverlayfs().supported) {
LINFO << "vendor overlay: kernel does not support overlayfs";
return false;
}
diff --git a/fs_mgr/include_fstab b/fs_mgr/include_fstab
new file mode 120000
index 0000000..728737f
--- /dev/null
+++ b/fs_mgr/include_fstab
@@ -0,0 +1 @@
+libfstab/include
\ No newline at end of file
diff --git a/fs_mgr/libfiemap/fiemap_writer_test.cpp b/fs_mgr/libfiemap/fiemap_writer_test.cpp
index bd97a78..c37329c 100644
--- a/fs_mgr/libfiemap/fiemap_writer_test.cpp
+++ b/fs_mgr/libfiemap/fiemap_writer_test.cpp
@@ -27,6 +27,7 @@
#include <sys/vfs.h>
#include <unistd.h>
+#include <cstring>
#include <string>
#include <utility>
@@ -518,7 +519,8 @@
ASSERT_EQ(ret, 0);
// mount the file system
- ASSERT_EQ(mount(loop_dev.device().c_str(), mntpoint_.c_str(), "f2fs", 0, nullptr), 0);
+ ASSERT_EQ(mount(loop_dev.device().c_str(), mntpoint_.c_str(), "f2fs", 0, nullptr), 0)
+ << strerror(errno);
}
void TearDown() override {
diff --git a/fs_mgr/libfstab/Android.bp b/fs_mgr/libfstab/Android.bp
new file mode 100644
index 0000000..df0269c
--- /dev/null
+++ b/fs_mgr/libfstab/Android.bp
@@ -0,0 +1,62 @@
+//
+// Copyright (C) 2023 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.
+//
+
+package {
+ default_applicable_licenses: [
+ "Android-Apache-2.0",
+ "system_core_fs_mgr_license",
+ ],
+}
+
+cc_library_static {
+ // Do not ever make this a shared library as long as it is vendor_available.
+ // It does not have a stable interface.
+ name: "libfstab",
+ vendor_available: true,
+ ramdisk_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ host_supported: true,
+ defaults: ["fs_mgr_defaults"],
+ export_include_dirs: ["include"],
+ header_libs: [
+ "libbase_headers",
+ "libgsi_headers",
+ ],
+ srcs: [
+ "fstab.cpp",
+ "boot_config.cpp",
+ "slotselect.cpp",
+ ],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ vendor: {
+ cflags: [
+ // Skipping entries in fstab should only be done in a system
+ // process as the config file is in /system_ext.
+ // Remove the op from the vendor variant.
+ "-DNO_SKIP_MOUNT",
+ ],
+ },
+ },
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
+ min_sdk_version: "31",
+}
diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/libfstab/boot_config.cpp
similarity index 82%
rename from fs_mgr/fs_mgr_boot_config.cpp
rename to fs_mgr/libfstab/boot_config.cpp
index 75d1e0d..fee4015 100644
--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/libfstab/boot_config.cpp
@@ -20,11 +20,39 @@
#include <vector>
#include <android-base/file.h>
+#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include <android-base/properties.h>
-#include "fs_mgr_priv.h"
+#include "fstab_priv.h"
+#include "logging_macros.h"
+
+namespace android {
+namespace fs_mgr {
+
+const std::string& GetAndroidDtDir() {
+ // Set once and saves time for subsequent calls to this function
+ static const std::string kAndroidDtDir = [] {
+ std::string android_dt_dir;
+ if ((fs_mgr_get_boot_config_from_bootconfig_source("android_dt_dir", &android_dt_dir) ||
+ fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) &&
+ !android_dt_dir.empty()) {
+ // Ensure the returned path ends with a /
+ if (android_dt_dir.back() != '/') {
+ android_dt_dir.push_back('/');
+ }
+ } else {
+ // Fall back to the standard procfs-based path
+ android_dt_dir = "/proc/device-tree/firmware/android/";
+ }
+ LINFO << "Using Android DT directory " << android_dt_dir;
+ return android_dt_dir;
+ }();
+ return kAndroidDtDir;
+}
+
+} // namespace fs_mgr
+} // namespace android
std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline) {
static constexpr char quote = '"';
@@ -84,7 +112,7 @@
bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig,
const std::string& android_key, std::string* out_val) {
- FS_MGR_CHECK(out_val != nullptr);
+ FSTAB_CHECK(out_val != nullptr);
const std::string bootconfig_key("androidboot." + android_key);
for (const auto& [key, value] : fs_mgr_parse_proc_bootconfig(bootconfig)) {
@@ -100,7 +128,7 @@
bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& android_key,
std::string* out_val) {
- FS_MGR_CHECK(out_val != nullptr);
+ FSTAB_CHECK(out_val != nullptr);
const std::string cmdline_key("androidboot." + android_key);
for (const auto& [key, value] : fs_mgr_parse_cmdline(cmdline)) {
@@ -140,11 +168,11 @@
// kernel cmdline (in that order). Returns 'true' if successfully
// found, 'false' otherwise.
bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) {
- FS_MGR_CHECK(out_val != nullptr);
+ FSTAB_CHECK(out_val != nullptr);
// firstly, check the device tree
if (is_dt_compatible()) {
- std::string file_name = get_android_dt_dir() + "/" + key;
+ std::string file_name = android::fs_mgr::GetAndroidDtDir() + key;
if (android::base::ReadFileToString(file_name, out_val)) {
if (!out_val->empty()) {
out_val->pop_back(); // Trims the trailing '\0' out.
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/libfstab/fstab.cpp
similarity index 94%
rename from fs_mgr/fs_mgr_fstab.cpp
rename to fs_mgr/libfstab/fstab.cpp
index c85e831..86ba031 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/libfstab/fstab.cpp
@@ -36,7 +36,8 @@
#include <android-base/strings.h>
#include <libgsi/libgsi.h>
-#include "fs_mgr_priv.h"
+#include "fstab_priv.h"
+#include "logging_macros.h"
using android::base::EndsWith;
using android::base::ParseByteCount;
@@ -50,11 +51,10 @@
namespace fs_mgr {
namespace {
-constexpr char kDefaultAndroidDtDir[] = "/proc/device-tree/firmware/android";
constexpr char kProcMountsPath[] = "/proc/mounts";
struct FlagList {
- const char *name;
+ const char* name;
uint64_t flag;
};
@@ -80,7 +80,7 @@
off64_t CalculateZramSize(int percentage) {
off64_t total;
- total = sysconf(_SC_PHYS_PAGES);
+ total = sysconf(_SC_PHYS_PAGES);
total *= percentage;
total /= 100;
@@ -328,8 +328,7 @@
// some recovery fstabs still contain the FDE options since they didn't do
// anything in recovery mode anyway (except possibly to cause the
// reservation of a crypto footer) and thus never got removed.
- if (entry->fs_mgr_flags.crypt && !entry->fs_mgr_flags.vold_managed &&
- access("/system/bin/recovery", F_OK) != 0) {
+ if (entry->fs_mgr_flags.crypt && !entry->fs_mgr_flags.vold_managed && !InRecovery()) {
LERROR << "FDE is no longer supported; 'encryptable' can only be used for adoptable "
"storage";
return false;
@@ -337,25 +336,14 @@
return true;
}
-std::string InitAndroidDtDir() {
- std::string android_dt_dir;
- // The platform may specify a custom Android DT path in kernel cmdline
- if (!fs_mgr_get_boot_config_from_bootconfig_source("android_dt_dir", &android_dt_dir) &&
- !fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) {
- // Fall back to the standard procfs-based path
- android_dt_dir = kDefaultAndroidDtDir;
- }
- return android_dt_dir;
-}
-
bool IsDtFstabCompatible() {
std::string dt_value;
- std::string file_name = get_android_dt_dir() + "/fstab/compatible";
+ std::string file_name = GetAndroidDtDir() + "fstab/compatible";
if (ReadDtFile(file_name, &dt_value) && dt_value == "android,fstab") {
// If there's no status property or its set to "ok" or "okay", then we use the DT fstab.
std::string status_value;
- std::string status_file_name = get_android_dt_dir() + "/fstab/status";
+ std::string status_file_name = GetAndroidDtDir() + "fstab/status";
return !ReadDtFile(status_file_name, &status_value) || status_value == "ok" ||
status_value == "okay";
}
@@ -368,7 +356,7 @@
return {};
}
- std::string fstabdir_name = get_android_dt_dir() + "/fstab";
+ std::string fstabdir_name = GetAndroidDtDir() + "fstab";
std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
if (!fstabdir) return {};
@@ -401,7 +389,7 @@
std::string mount_point;
file_name =
- android::base::StringPrintf("%s/%s/mnt_point", fstabdir_name.c_str(), dp->d_name);
+ android::base::StringPrintf("%s/%s/mnt_point", fstabdir_name.c_str(), dp->d_name);
if (ReadDtFile(file_name, &value)) {
LINFO << "dt_fstab: Using a specified mount point " << value << " for " << dp->d_name;
mount_point = value;
@@ -417,14 +405,16 @@
}
fstab_entry.push_back(value);
- file_name = android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
+ file_name =
+ android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
if (!ReadDtFile(file_name, &value)) {
LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
return {};
}
fstab_entry.push_back(value);
- file_name = android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
+ file_name =
+ android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
if (!ReadDtFile(file_name, &value)) {
LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
return {};
@@ -520,6 +510,9 @@
// 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.
std::string GetFstabPath() {
+ if (InRecovery()) {
+ return "/etc/recovery.fstab";
+ }
for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
std::string suffix;
@@ -835,15 +828,8 @@
fstab->clear();
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;
+ const std::string default_fstab_path = GetFstabPath();
if (!default_fstab_path.empty() && ReadFstabFromFile(default_fstab_path, &default_fstab)) {
for (auto&& entry : default_fstab) {
fstab->emplace_back(std::move(entry));
@@ -878,7 +864,7 @@
std::set<std::string> GetBootDevices() {
// First check bootconfig, then kernel commandline, then the device tree
- std::string dt_file_name = get_android_dt_dir() + "/boot_devices";
+ std::string dt_file_name = GetAndroidDtDir() + "boot_devices";
std::string value;
if (fs_mgr_get_boot_config_from_bootconfig_source("boot_devices", &value) ||
fs_mgr_get_boot_config_from_bootconfig_source("boot_device", &value)) {
@@ -936,18 +922,22 @@
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 android
-// FIXME: The same logic is duplicated in system/core/init/
-const std::string& get_android_dt_dir() {
- // Set once and saves time for subsequent calls to this function
- static const std::string kAndroidDtDir = android::fs_mgr::InitAndroidDtDir();
- return kAndroidDtDir;
-}
-
bool is_dt_compatible() {
- std::string file_name = get_android_dt_dir() + "/compatible";
+ std::string file_name = android::fs_mgr::GetAndroidDtDir() + "compatible";
std::string dt_value;
if (android::fs_mgr::ReadDtFile(file_name, &dt_value)) {
if (dt_value == "android,firmware") {
diff --git a/fs_mgr/fs_mgr_priv_boot_config.h b/fs_mgr/libfstab/fstab_priv.h
similarity index 70%
rename from fs_mgr/fs_mgr_priv_boot_config.h
rename to fs_mgr/libfstab/fstab_priv.h
index 6a38401..5d226f8 100644
--- a/fs_mgr/fs_mgr_priv_boot_config.h
+++ b/fs_mgr/libfstab/fstab_priv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -14,16 +14,17 @@
* limitations under the License.
*/
-#ifndef __CORE_FS_MGR_PRIV_BOOTCONFIG_H
-#define __CORE_FS_MGR_PRIV_BOOTCONFIG_H
+#pragma once
-#include <sys/cdefs.h>
#include <string>
#include <utility>
#include <vector>
-std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline);
+#include <fstab/fstab.h>
+// Do not include logging_macros.h here as this header is used by fs_mgr, too.
+
+std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline);
bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& key,
std::string* out_val);
bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val);
@@ -34,4 +35,16 @@
std::string* out_val);
bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val);
-#endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
+bool fs_mgr_update_for_slotselect(android::fs_mgr::Fstab* fstab);
+bool is_dt_compatible();
+
+namespace android {
+namespace fs_mgr {
+
+bool InRecovery();
+bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out);
+bool SkipMountWithConfig(const std::string& skip_config, Fstab* fstab, bool verbose);
+std::string GetFstabPath();
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/fuzz/Android.bp b/fs_mgr/libfstab/fuzz/Android.bp
similarity index 100%
rename from fs_mgr/fuzz/Android.bp
rename to fs_mgr/libfstab/fuzz/Android.bp
diff --git a/fs_mgr/fuzz/fs_mgr_fstab_fuzzer.cpp b/fs_mgr/libfstab/fuzz/fs_mgr_fstab_fuzzer.cpp
similarity index 97%
rename from fs_mgr/fuzz/fs_mgr_fstab_fuzzer.cpp
rename to fs_mgr/libfstab/fuzz/fs_mgr_fstab_fuzzer.cpp
index b5fdad4..b09b273 100644
--- a/fs_mgr/fuzz/fs_mgr_fstab_fuzzer.cpp
+++ b/fs_mgr/libfstab/fuzz/fs_mgr_fstab_fuzzer.cpp
@@ -20,6 +20,8 @@
#include <fstab/fstab.h>
#include <fuzzer/FuzzedDataProvider.h>
+#include "../fstab_priv.h"
+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider fdp(data, size);
diff --git a/fs_mgr/fuzz/fstab.dict b/fs_mgr/libfstab/fuzz/fstab.dict
similarity index 100%
rename from fs_mgr/fuzz/fstab.dict
rename to fs_mgr/libfstab/fuzz/fstab.dict
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/libfstab/include/fstab/fstab.h
similarity index 91%
rename from fs_mgr/include_fstab/fstab/fstab.h
rename to fs_mgr/libfstab/include/fstab/fstab.h
index 9cb1546..0a45fe8 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/libfstab/include/fstab/fstab.h
@@ -93,13 +93,6 @@
// Unless explicitly requested, a lookup on mount point should always return the 1st one.
using Fstab = std::vector<FstabEntry>;
-// Exported for testability. Regular users should use ReadFstabFromFile().
-bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out);
-// Exported for testability. Regular users should use ReadDefaultFstab().
-std::string GetFstabPath();
-// Exported for testability.
-bool SkipMountWithConfig(const std::string& skip_config, Fstab* fstab, bool verbose);
-
bool ReadFstabFromFile(const std::string& path, Fstab* fstab);
bool ReadFstabFromProcMounts(Fstab* fstab);
bool ReadFstabFromDt(Fstab* fstab, bool verbose = true);
@@ -131,5 +124,9 @@
// expected name.
std::string GetVerityDeviceName(const FstabEntry& entry);
+// Returns the Android Device Tree directory as specified in the kernel bootconfig or cmdline.
+// If the platform does not configure a custom DT path, returns the standard one (based in procfs).
+const std::string& GetAndroidDtDir();
+
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/libfstab/logging_macros.h b/fs_mgr/libfstab/logging_macros.h
new file mode 100644
index 0000000..7ea1b77
--- /dev/null
+++ b/fs_mgr/libfstab/logging_macros.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 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 <android-base/logging.h>
+
+#define FSTAB_TAG "[libfstab] "
+
+/* The CHECK() in logging.h will use program invocation name as the tag.
+ * Thus, the log will have prefix "init: " when libfs_mgr is statically
+ * linked in the init process. This might be opaque when debugging.
+ * Append a library name tag at the end of the abort message to aid debugging.
+ */
+#define FSTAB_CHECK(x) CHECK(x) << "in " << FSTAB_TAG
+
+// Logs a message to kernel
+#define LINFO LOG(INFO) << FSTAB_TAG
+#define LWARNING LOG(WARNING) << FSTAB_TAG
+#define LERROR LOG(ERROR) << FSTAB_TAG
+#define LFATAL LOG(FATAL) << FSTAB_TAG
+
+// Logs a message with strerror(errno) at the end
+#define PINFO PLOG(INFO) << FSTAB_TAG
+#define PWARNING PLOG(WARNING) << FSTAB_TAG
+#define PERROR PLOG(ERROR) << FSTAB_TAG
+#define PFATAL PLOG(FATAL) << FSTAB_TAG
diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/libfstab/slotselect.cpp
similarity index 97%
rename from fs_mgr/fs_mgr_slotselect.cpp
rename to fs_mgr/libfstab/slotselect.cpp
index 09c1b7e..97b2ba1 100644
--- a/fs_mgr/fs_mgr_slotselect.cpp
+++ b/fs_mgr/libfstab/slotselect.cpp
@@ -18,8 +18,8 @@
#include <string>
-#include "fs_mgr.h"
-#include "fs_mgr_priv.h"
+#include "fstab_priv.h"
+#include "logging_macros.h"
// Realistically, this file should be part of the android::fs_mgr namespace;
using namespace android::fs_mgr;
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index 8f35381..bd017ff 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -101,7 +101,7 @@
}
cc_library_static {
- name: "libsnapshot",
+ name: "libsnapshot_static",
defaults: [
"libsnapshot_defaults",
"libsnapshot_hal_deps",
@@ -112,6 +112,25 @@
],
}
+cc_library {
+ name: "libsnapshot",
+ defaults: [
+ "libsnapshot_defaults",
+ "libsnapshot_cow_defaults",
+ "libsnapshot_hal_deps",
+ ],
+ srcs: [":libsnapshot_sources"],
+ shared_libs: [
+ "libfs_mgr_binder",
+ "liblp",
+ "libprotobuf-cpp-lite",
+ ],
+ static_libs: [
+ "libc++fs",
+ "libsnapshot_cow",
+ ]
+}
+
cc_library_static {
name: "libsnapshot_init",
native_coverage : true,
@@ -247,7 +266,7 @@
"libgsi",
"libgmock",
"liblp",
- "libsnapshot",
+ "libsnapshot_static",
"libsnapshot_cow",
"libsnapshot_test_helpers",
"libsparse",
@@ -330,8 +349,6 @@
"libbrotli",
"libc++fs",
"libfstab",
- "libsnapshot",
- "libsnapshot_cow",
"libz",
"update_metadata-protos",
],
@@ -344,6 +361,7 @@
"liblog",
"liblp",
"libprotobuf-cpp-lite",
+ "libsnapshot",
"libstatslog",
"libutils",
],
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
index 489669a..f37aed1 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
@@ -310,9 +310,34 @@
bool CowReader::VerifyMergeOps() {
auto itr = GetMergeOpIter(true);
std::unordered_map<uint64_t, const CowOperation*> overwritten_blocks;
+ bool non_ordered_op_found = false;
+
while (!itr->AtEnd()) {
const auto& op = itr->Get();
uint64_t offset;
+
+ // Op should not be a metadata
+ if (IsMetadataOp(*op)) {
+ LOG(ERROR) << "Metadata op: " << op << " found during merge sequence";
+ return false;
+ }
+
+ // Sequence ops should contain all the ordered ops followed
+ // by Replace and Zero ops. If we find the first op which
+ // is not ordered, that means all ordered ops processing
+ // has been completed.
+ if (!IsOrderedOp(*op)) {
+ non_ordered_op_found = true;
+ }
+
+ // Since, all ordered ops processing has been completed,
+ // check that the subsequent ops are not ordered.
+ if (non_ordered_op_found && IsOrderedOp(*op)) {
+ LOG(ERROR) << "Invalid sequence - non-ordered and ordered ops"
+ << " cannot be mixed during sequence generation";
+ return false;
+ }
+
if (!GetSourceOffset(op, &offset)) {
itr->Next();
continue;
diff --git a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
index 978a7f2..71664bf 100644
--- a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd.cpp
@@ -734,8 +734,8 @@
off_t offset = 0;
for (int i = 0; i < num_threads; i++) {
- std::async(std::launch::async, &Snapuserd::ReadBlocksToCache, this, dm_block_device,
- partition_name, offset, read_sz_per_thread);
+ (void)std::async(std::launch::async, &Snapuserd::ReadBlocksToCache, this, dm_block_device,
+ partition_name, offset, read_sz_per_thread);
offset += read_sz_per_thread;
}
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
index 7268fca..7d2e3a6 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
@@ -305,7 +305,7 @@
return false;
}
- ret = BLOCK_SZ;
+ ret = std::min(BLOCK_SZ, read_size);
}
read_size -= ret;
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
index e52d752..2dd2ec0 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
@@ -308,7 +308,7 @@
ra_thread_status =
std::async(std::launch::async, &ReadAhead::RunThread, read_ahead_thread_.get());
- SNAP_LOG(INFO) << "Read-ahead thread started...";
+ SNAP_LOG(INFO) << "Read-ahead thread started";
}
// Launch worker threads
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
index 3e9588b..8755820 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
@@ -592,7 +592,7 @@
// Check if this block is an XOR op
if (xor_op->new_block == new_block) {
// Read the xor'ed data from COW
- void* buffer = bufsink_.GetPayloadBuffer(BLOCK_SZ);
+ void* buffer = bufsink.GetPayloadBuffer(BLOCK_SZ);
if (!buffer) {
SNAP_LOG(ERROR) << "ReadAhead - failed to allocate buffer";
return false;
diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp
index b9bae25..b7f792f 100644
--- a/fs_mgr/tests/Android.bp
+++ b/fs_mgr/tests/Android.bp
@@ -38,7 +38,6 @@
],
static_libs: [
"libfs_mgr",
- "libfstab",
],
srcs: [
"file_wait_test.cpp",
@@ -109,7 +108,6 @@
],
static_libs: [
"libfs_mgr",
- "libfstab",
"libgmock",
"libgtest",
],
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index 5f889ca..c51df2a 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -31,7 +31,7 @@
#include <fstab/fstab.h>
#include <gtest/gtest.h>
-#include "../fs_mgr_priv_boot_config.h"
+#include "../fs_mgr_priv.h"
using namespace android::fs_mgr;
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index 4d771fa..32947b5 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -23,6 +23,8 @@
#include <gtest/gtest.h>
#include <libdm/dm.h>
+#include "../fs_mgr_priv.h"
+
using testing::Contains;
using testing::Not;
diff --git a/init/Android.bp b/init/Android.bp
index 4416b9d..d4852d6 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -392,6 +392,10 @@
],
static_executable: true,
+ lto: {
+ // b/169004486 ThinLTO breaks x86 static executables.
+ never: true,
+ },
system_shared_libs: [],
cflags: [
@@ -535,6 +539,7 @@
"libprotobuf-cpp-lite",
],
static_libs: [
+ "libfs_mgr",
"libhidl-gen-utils",
],
}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 2176233..fa5e36d 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -1297,7 +1297,6 @@
return create_dirs.error();
}
auto parse_configs = ParseApexConfigs(/*apex_name=*/"");
- ServiceList::GetInstance().MarkServicesUpdate();
if (!parse_configs.ok()) {
return parse_configs.error();
}
@@ -1307,6 +1306,8 @@
return update_linker_config.error();
}
+ // Now start delayed services
+ ServiceList::GetInstance().MarkServicesUpdate();
return {};
}
diff --git a/init/devices.cpp b/init/devices.cpp
index d29ffd6..7c23492 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -568,6 +568,8 @@
return;
} else if (uevent.subsystem == "misc" && StartsWith(uevent.device_name, "dm-user/")) {
devpath = "/dev/dm-user/" + uevent.device_name.substr(8);
+ } else if (uevent.subsystem == "misc" && uevent.device_name == "vfio/vfio") {
+ devpath = "/dev/" + uevent.device_name;
} else {
devpath = "/dev/" + Basename(uevent.path);
}
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 8da6982..0e82022 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -57,6 +57,7 @@
#include <android-base/result.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <fs_mgr.h>
#include <property_info_parser/property_info_parser.h>
#include <property_info_serializer/property_info_serializer.h>
#include <selinux/android.h>
@@ -1317,7 +1318,8 @@
return;
}
- std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(get_android_dt_dir().c_str()), closedir);
+ std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(android::fs_mgr::GetAndroidDtDir().c_str()),
+ closedir);
if (!dir) return;
std::string dt_file;
@@ -1328,7 +1330,7 @@
continue;
}
- std::string file_name = get_android_dt_dir() + dp->d_name;
+ std::string file_name = android::fs_mgr::GetAndroidDtDir() + dp->d_name;
android::base::ReadFileToString(file_name, &dt_file);
std::replace(dt_file.begin(), dt_file.end(), ',', '.');
diff --git a/init/util.cpp b/init/util.cpp
index d0478e8..61d59a4 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -42,6 +42,10 @@
#include <cutils/sockets.h>
#include <selinux/android.h>
+#if defined(__ANDROID__)
+#include <fs_mgr.h>
+#endif
+
#ifdef INIT_FULL_SOURCES
#include <android/api-level.h>
#include <sys/system_properties.h>
@@ -60,8 +64,6 @@
namespace android {
namespace init {
-const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/");
-
const std::string kDataDirPrefix("/data/");
void (*trigger_shutdown)(const std::string& command) = nullptr;
@@ -375,45 +377,18 @@
return dst;
}
-static std::string init_android_dt_dir() {
- // Use the standard procfs-based path by default
- std::string android_dt_dir = kDefaultAndroidDtDir;
- // The platform may specify a custom Android DT path in kernel cmdline
- ImportKernelCmdline([&](const std::string& key, const std::string& value) {
- if (key == "androidboot.android_dt_dir") {
- android_dt_dir = value;
- }
- });
- // ..Or bootconfig
- if (android_dt_dir == kDefaultAndroidDtDir) {
- ImportBootconfig([&](const std::string& key, const std::string& value) {
- if (key == "androidboot.android_dt_dir") {
- android_dt_dir = value;
- }
- });
- }
-
- LOG(INFO) << "Using Android DT directory " << android_dt_dir;
- return android_dt_dir;
-}
-
-// FIXME: The same logic is duplicated in system/core/fs_mgr/
-const std::string& get_android_dt_dir() {
- // Set once and saves time for subsequent calls to this function
- static const std::string kAndroidDtDir = init_android_dt_dir();
- return kAndroidDtDir;
-}
-
// Reads the content of device tree file under the platform's Android DT directory.
// Returns true if the read is success, false otherwise.
bool read_android_dt_file(const std::string& sub_path, std::string* dt_content) {
- const std::string file_name = get_android_dt_dir() + sub_path;
+#if defined(__ANDROID__)
+ const std::string file_name = android::fs_mgr::GetAndroidDtDir() + sub_path;
if (android::base::ReadFileToString(file_name, dt_content)) {
if (!dt_content->empty()) {
dt_content->pop_back(); // Trims the trailing '\0' out.
return true;
}
}
+#endif
return false;
}
diff --git a/init/util.h b/init/util.h
index 3f0a4e0..1c00a3e 100644
--- a/init/util.h
+++ b/init/util.h
@@ -60,9 +60,6 @@
bool is_dir(const char* pathname);
Result<std::string> ExpandProps(const std::string& src);
-// Returns the platform's Android DT directory as specified in the kernel cmdline.
-// If the platform does not configure a custom DT path, returns the standard one (based in procfs).
-const std::string& get_android_dt_dir();
// Reads or compares the content of device tree file under the platform's Android DT directory.
bool read_android_dt_file(const std::string& sub_path, std::string* dt_content);
bool is_android_dt_value_expected(const std::string& sub_path, const std::string& expected_content);
diff --git a/libcutils/OWNERS b/libcutils/OWNERS
index 7529cb9..e1cbe4a 100644
--- a/libcutils/OWNERS
+++ b/libcutils/OWNERS
@@ -1 +1,2 @@
+# Bug component: 128577
include platform/system/core:/janitors/OWNERS
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 06d386f..4506439 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -206,11 +206,11 @@
}
static std::string ConvertUidToPath(const char* cgroup, uid_t uid) {
- return StringPrintf("%s/uid_%d", cgroup, uid);
+ return StringPrintf("%s/uid_%u", cgroup, uid);
}
static std::string ConvertUidPidToPath(const char* cgroup, uid_t uid, int pid) {
- return StringPrintf("%s/uid_%d/pid_%d", cgroup, uid, pid);
+ return StringPrintf("%s/uid_%u/pid_%d", cgroup, uid, pid);
}
static int RemoveProcessGroup(const char* cgroup, uid_t uid, int pid, unsigned int retries) {
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 44dba2a..f51b076 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -114,9 +114,26 @@
IProfileAttribute::~IProfileAttribute() = default;
-void ProfileAttribute::Reset(const CgroupController& controller, const std::string& file_name) {
+const std::string& ProfileAttribute::file_name() const {
+ if (controller()->version() == 2 && !file_v2_name_.empty()) return file_v2_name_;
+ return file_name_;
+}
+
+void ProfileAttribute::Reset(const CgroupController& controller, const std::string& file_name,
+ const std::string& file_v2_name) {
controller_ = controller;
file_name_ = file_name;
+ file_v2_name_ = file_v2_name;
+}
+
+bool ProfileAttribute::GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const {
+ if (controller()->version() == 2) {
+ // all cgroup v2 attributes use the same process group hierarchy
+ *path = StringPrintf("%s/uid_%u/pid_%d/%s", controller()->path(), uid, pid,
+ file_name().c_str());
+ return true;
+ }
+ return GetPathForTask(pid, path);
}
bool ProfileAttribute::GetPathForTask(int tid, std::string* path) const {
@@ -129,12 +146,11 @@
return true;
}
- const std::string& file_name =
- controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_;
if (subgroup.empty()) {
- *path = StringPrintf("%s/%s", controller()->path(), file_name.c_str());
+ *path = StringPrintf("%s/%s", controller()->path(), file_name().c_str());
} else {
- *path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(), file_name.c_str());
+ *path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(),
+ file_name().c_str());
}
return true;
}
@@ -144,9 +160,7 @@
return true;
}
- const std::string& file_name =
- controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_;
- *path = StringPrintf("%s/uid_%d/%s", controller()->path(), uid, file_name.c_str());
+ *path = StringPrintf("%s/uid_%u/%s", controller()->path(), uid, file_name().c_str());
return true;
}
@@ -205,18 +219,7 @@
#endif
-bool SetAttributeAction::ExecuteForProcess(uid_t, pid_t pid) const {
- return ExecuteForTask(pid);
-}
-
-bool SetAttributeAction::ExecuteForTask(int tid) const {
- std::string path;
-
- if (!attribute_->GetPathForTask(tid, &path)) {
- LOG(ERROR) << "Failed to find cgroup for tid " << tid;
- return false;
- }
-
+bool SetAttributeAction::WriteValueToFile(const std::string& path) const {
if (!WriteStringToFile(value_, path)) {
if (access(path.c_str(), F_OK) < 0) {
if (optional_) {
@@ -236,6 +239,28 @@
return true;
}
+bool SetAttributeAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
+ std::string path;
+
+ if (!attribute_->GetPathForProcess(uid, pid, &path)) {
+ LOG(ERROR) << "Failed to find cgroup for uid " << uid << " pid " << pid;
+ return false;
+ }
+
+ return WriteValueToFile(path);
+}
+
+bool SetAttributeAction::ExecuteForTask(int tid) const {
+ std::string path;
+
+ if (!attribute_->GetPathForTask(tid, &path)) {
+ LOG(ERROR) << "Failed to find cgroup for tid " << tid;
+ return false;
+ }
+
+ return WriteValueToFile(path);
+}
+
bool SetAttributeAction::ExecuteForUID(uid_t uid) const {
std::string path;
@@ -816,7 +841,7 @@
attributes_[name] =
std::make_unique<ProfileAttribute>(controller, file_attr, file_v2_attr);
} else {
- iter->second->Reset(controller, file_attr);
+ iter->second->Reset(controller, file_attr, file_v2_attr);
}
} else {
LOG(WARNING) << "Controller " << controller_name << " is not found";
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index a62c5b0..4663f64 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -32,9 +32,11 @@
class IProfileAttribute {
public:
virtual ~IProfileAttribute() = 0;
- virtual void Reset(const CgroupController& controller, const std::string& file_name) = 0;
+ virtual void Reset(const CgroupController& controller, const std::string& file_name,
+ const std::string& file_v2_name) = 0;
virtual const CgroupController* controller() const = 0;
virtual const std::string& file_name() const = 0;
+ virtual bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const = 0;
virtual bool GetPathForTask(int tid, std::string* path) const = 0;
virtual bool GetPathForUID(uid_t uid, std::string* path) const = 0;
};
@@ -50,9 +52,11 @@
~ProfileAttribute() = default;
const CgroupController* controller() const override { return &controller_; }
- const std::string& file_name() const override { return file_name_; }
- void Reset(const CgroupController& controller, const std::string& file_name) override;
+ const std::string& file_name() const override;
+ void Reset(const CgroupController& controller, const std::string& file_name,
+ const std::string& file_v2_name) override;
+ bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const override;
bool GetPathForTask(int tid, std::string* path) const override;
bool GetPathForUID(uid_t uid, std::string* path) const override;
@@ -131,6 +135,8 @@
const IProfileAttribute* attribute_;
std::string value_;
bool optional_;
+
+ bool WriteValueToFile(const std::string& path) const;
};
// Set cgroup profile element
diff --git a/libprocessgroup/task_profiles_test.cpp b/libprocessgroup/task_profiles_test.cpp
index eadbe76..99d819a 100644
--- a/libprocessgroup/task_profiles_test.cpp
+++ b/libprocessgroup/task_profiles_test.cpp
@@ -102,7 +102,8 @@
public:
ProfileAttributeMock(const std::string& file_name) : file_name_(file_name) {}
~ProfileAttributeMock() override = default;
- void Reset(const CgroupController& controller, const std::string& file_name) override {
+ void Reset(const CgroupController& controller, const std::string& file_name,
+ const std::string& file_v2_name) override {
CHECK(false);
}
const CgroupController* controller() const override {
@@ -110,6 +111,9 @@
return {};
}
const std::string& file_name() const override { return file_name_; }
+ bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const override {
+ return GetPathForTask(pid, path);
+ }
bool GetPathForTask(int tid, std::string* path) const override {
#ifdef __ANDROID__
CHECK(CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, path));
@@ -125,9 +129,7 @@
return true;
};
- bool GetPathForUID(uid_t, std::string*) const override {
- return false;
- }
+ bool GetPathForUID(uid_t, std::string*) const override { return false; }
private:
const std::string file_name_;
diff --git a/libstats/pull_rust/stats_pull.rs b/libstats/pull_rust/stats_pull.rs
index 09b2623..d188b5f 100644
--- a/libstats/pull_rust/stats_pull.rs
+++ b/libstats/pull_rust/stats_pull.rs
@@ -111,7 +111,9 @@
static ref COOKIES: Mutex<HashMap<i32, fn() -> StatsPullResult>> = Mutex::new(HashMap::new());
}
-// Safety: We store our callbacks in the global so they are valid.
+/// # Safety
+///
+/// `data` must be a valid pointer with no aliases.
unsafe extern "C" fn callback_wrapper(
atom_tag: i32,
data: *mut AStatsEventList,
@@ -126,7 +128,8 @@
let stats = cb();
let result = stats
.iter()
- .map(|stat| stat.add_astats_event(&mut *data))
+ // Safety: The caller promises that `data` is valid and unaliased.
+ .map(|stat| stat.add_astats_event(unsafe { &mut *data }))
.collect::<Result<Vec<()>, StatsError>>();
match result {
Ok(_) => {
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d2499ef..8f01d93 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -997,7 +997,7 @@
perform_apex_config
# Create directories for boot animation.
- mkdir /data/bootanim 0755 system system encryption=DeleteIfNecessary
+ mkdir /data/misc/bootanim 0755 system system encryption=DeleteIfNecessary
exec_start derive_sdk
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 0b7ffb8..60dcc2a 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -23,6 +23,11 @@
subsystem dma_heap
devname uevent_devpath
dirname /dev/dma_heap
+
+subsystem vfio
+ devname uevent_devpath
+ dirname /dev/vfio
+
# ueventd can only set permissions on device nodes and their associated
# sysfs attributes, not on arbitrary paths.
#
@@ -43,6 +48,7 @@
/dev/binder 0666 root root
/dev/hwbinder 0666 root root
/dev/vndbinder 0666 root root
+/dev/vfio/* 0666 root root
/dev/pmsg0 0222 root log
/dev/dma_heap/system 0444 system system
diff --git a/trusty/keymint/Android.bp b/trusty/keymint/Android.bp
index c19ebbd..19dcc98 100644
--- a/trusty/keymint/Android.bp
+++ b/trusty/keymint/Android.bp
@@ -35,6 +35,7 @@
"liblibc",
"liblog_rust",
],
+ prefer_rlib: true,
required: [
"android.hardware.hardware_keystore.xml",
],
diff --git a/trusty/libtrusty-rs/src/lib.rs b/trusty/libtrusty-rs/src/lib.rs
index 28ea075..22b894a 100644
--- a/trusty/libtrusty-rs/src/lib.rs
+++ b/trusty/libtrusty-rs/src/lib.rs
@@ -102,6 +102,8 @@
let file = File::options().read(true).write(true).open(device)?;
let srv_name = CString::new(service).expect("Service name contained null bytes");
+ // SAFETY: The file descriptor is valid because it came from a `File`, and the name is a
+ // valid C string because it came from a `CString`.
unsafe {
tipc_connect(file.as_raw_fd(), srv_name.as_ptr())?;
}
diff --git a/trusty/storage/proxy/proxy.c b/trusty/storage/proxy/proxy.c
index 3b744ec..67e935e 100644
--- a/trusty/storage/proxy/proxy.c
+++ b/trusty/storage/proxy/proxy.c
@@ -243,9 +243,12 @@
* Start binder threadpool. At least one extra binder thread is needed to
* connect to the wakelock service without relying on polling. If we poll on
* the main thread we end up pausing for at least 1s even if the service
- * starts faster.
+ * starts faster. We set the max thread count to 0 because startThreadPool
+ * "Starts one thread, PLUS those requested in setThreadPoolMaxThreadCount,
+ * PLUS those manually requested in joinThreadPool." We only need a single
+ * binder thread to receive notifications on.
*/
- ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
ABinderProcess_startThreadPool();
/* initialize secure storage directory */