summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-08 04:42:00 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-08 04:42:00 +0000
commit8544ea9e846989aa0c06842f4ba309142f05f05f (patch)
tree21fc5afb06ab4fff333b121ead3c452b18b03f6b
parent7629ddbded94b1c329635869baf2f208d92963e1 (diff)
parent5d4c782b1fedfbf339e7e8a3b5547dd5b29a9526 (diff)
downloadcore-8544ea9e846989aa0c06842f4ba309142f05f05f.tar.gz
Snap for 10460766 from 5d4c782b1fedfbf339e7e8a3b5547dd5b29a9526 to mainline-healthfitness-release
Change-Id: I3e383666517fdf3585d2dd4fe59dcfc862cc0529
-rw-r--r--debuggerd/handler/debuggerd_handler.cpp32
-rw-r--r--fs_mgr/Android.bp5
-rw-r--r--fs_mgr/fs_mgr_fstab.cpp35
-rw-r--r--fs_mgr/include_fstab/fstab/fstab.h1
-rw-r--r--fs_mgr/libdm/dm.cpp19
-rw-r--r--fs_mgr/libdm/dm_test.cpp94
-rw-r--r--fs_mgr/libdm/include/libdm/dm.h2
-rw-r--r--fs_mgr/tests/vts_fs_test.cpp36
-rw-r--r--healthd/BatteryMonitor.cpp2
-rw-r--r--healthd/include/healthd/BatteryMonitor.h1
-rw-r--r--init/devices.cpp18
-rw-r--r--libcutils/Android.bp8
-rw-r--r--rootdir/init.rc2
-rw-r--r--rootdir/ramdisk_node_list1
-rw-r--r--toolbox/modprobe.cpp44
15 files changed, 209 insertions, 91 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index baa5bfb50..c6a535ad6 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -566,20 +566,23 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
process_info = g_callbacks.get_process_info();
}
- // GWP-ASan catches use-after-free and heap-buffer-overflow by using PROT_NONE
- // guard pages, which lead to SEGV. Normally, debuggerd prints a bug report
- // and the process terminates, but in some cases, we actually want to print
- // the bug report and let the signal handler return, and restart the process.
- // In order to do that, we need to disable GWP-ASan's guard pages. The
- // following callbacks handle this case.
- gwp_asan_callbacks_t gwp_asan_callbacks = g_callbacks.get_gwp_asan_callbacks();
- if (signal_number == SIGSEGV && signal_has_si_addr(info) &&
- gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery &&
- gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report &&
- gwp_asan_callbacks.debuggerd_gwp_asan_post_crash_report &&
- gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery(info->si_addr)) {
- gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report(info->si_addr);
- process_info.recoverable_gwp_asan_crash = true;
+ gwp_asan_callbacks_t gwp_asan_callbacks = {};
+ if (g_callbacks.get_gwp_asan_callbacks != nullptr) {
+ // GWP-ASan catches use-after-free and heap-buffer-overflow by using PROT_NONE
+ // guard pages, which lead to SEGV. Normally, debuggerd prints a bug report
+ // and the process terminates, but in some cases, we actually want to print
+ // the bug report and let the signal handler return, and restart the process.
+ // In order to do that, we need to disable GWP-ASan's guard pages. The
+ // following callbacks handle this case.
+ gwp_asan_callbacks = g_callbacks.get_gwp_asan_callbacks();
+ if (signal_number == SIGSEGV && signal_has_si_addr(info) &&
+ gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery &&
+ gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report &&
+ gwp_asan_callbacks.debuggerd_gwp_asan_post_crash_report &&
+ gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery(info->si_addr)) {
+ gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report(info->si_addr);
+ process_info.recoverable_gwp_asan_crash = true;
+ }
}
// If sival_int is ~0, it means that the fallback handler has been called
@@ -764,6 +767,7 @@ void debuggerd_init(debuggerd_callbacks_t* callbacks) {
bool debuggerd_handle_signal(int signal_number, siginfo_t* info, void* context) {
if (signal_number != SIGSEGV || !signal_has_si_addr(info)) return false;
+ if (g_callbacks.get_gwp_asan_callbacks == nullptr) return false;
gwp_asan_callbacks_t gwp_asan_callbacks = g_callbacks.get_gwp_asan_callbacks();
if (gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery == nullptr ||
gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report == nullptr ||
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index dd612720f..bbd068bac 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -181,6 +181,10 @@ cc_library_static {
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"],
srcs: [
@@ -206,6 +210,7 @@ cc_library_static {
"libbase_headers",
"libgsi_headers",
],
+ min_sdk_version: "31",
}
cc_binary {
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 598a3d2ec..da9e45f4e 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -51,6 +51,7 @@ namespace fs_mgr {
namespace {
constexpr char kDefaultAndroidDtDir[] = "/proc/device-tree/firmware/android";
+constexpr char kProcMountsPath[] = "/proc/mounts";
struct FlagList {
const char *name;
@@ -697,9 +698,7 @@ void EnableMandatoryFlags(Fstab* fstab) {
}
}
-bool ReadFstabFromFile(const std::string& path, Fstab* fstab_out) {
- const bool is_proc_mounts = (path == "/proc/mounts");
-
+static bool ReadFstabFromFileCommon(const std::string& path, Fstab* fstab_out) {
std::string fstab_str;
if (!android::base::ReadFileToString(path, &fstab_str, /* follow_symlinks = */ true)) {
PERROR << __FUNCTION__ << "(): failed to read file: '" << path << "'";
@@ -707,11 +706,22 @@ bool ReadFstabFromFile(const std::string& path, Fstab* fstab_out) {
}
Fstab fstab;
- if (!ParseFstabFromString(fstab_str, is_proc_mounts, &fstab)) {
+ if (!ParseFstabFromString(fstab_str, path == kProcMountsPath, &fstab)) {
LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << path << "'";
return false;
}
- if (!is_proc_mounts) {
+
+ EnableMandatoryFlags(&fstab);
+
+ *fstab_out = std::move(fstab);
+ return true;
+}
+
+bool ReadFstabFromFile(const std::string& path, Fstab* fstab) {
+ if (!ReadFstabFromFileCommon(path, fstab)) {
+ return false;
+ }
+ if (path != kProcMountsPath) {
if (!access(android::gsi::kGsiBootedIndicatorFile, F_OK)) {
std::string dsu_slot;
if (!android::gsi::GetActiveDsu(&dsu_slot)) {
@@ -723,20 +733,23 @@ bool ReadFstabFromFile(const std::string& path, Fstab* fstab_out) {
PERROR << __FUNCTION__ << "(): failed to read DSU LP names";
return false;
}
- TransformFstabForDsu(&fstab, dsu_slot, Split(lp_names, ","));
+ TransformFstabForDsu(fstab, dsu_slot, Split(lp_names, ","));
} else if (errno != ENOENT) {
PERROR << __FUNCTION__ << "(): failed to access() DSU booted indicator";
return false;
}
- }
-
- SkipMountingPartitions(&fstab, false /* verbose */);
- EnableMandatoryFlags(&fstab);
- *fstab_out = std::move(fstab);
+ SkipMountingPartitions(fstab, false /* verbose */);
+ }
return true;
}
+bool ReadFstabFromProcMounts(Fstab* fstab) {
+ // Don't call `ReadFstabFromFile` because the code for `path != kProcMountsPath` has an extra
+ // code size cost, even if it's never executed.
+ return ReadFstabFromFileCommon(kProcMountsPath, fstab);
+}
+
// Returns fstab entries parsed from the device tree if they exist
bool ReadFstabFromDt(Fstab* fstab, bool verbose) {
std::string fstab_buf = ReadFstabFromDt();
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index a914b53bb..9cb1546c5 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -101,6 +101,7 @@ std::string GetFstabPath();
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);
bool ReadDefaultFstab(Fstab* fstab);
bool SkipMountingPartitions(Fstab* fstab, bool verbose = false);
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index deffae1ad..1e8c14fe2 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -243,6 +243,25 @@ bool DeviceMapper::GetDeviceUniquePath(const std::string& name, std::string* pat
return true;
}
+bool DeviceMapper::GetDeviceNameAndUuid(dev_t dev, std::string* name, std::string* uuid) {
+ struct dm_ioctl io;
+ InitIo(&io, {});
+ io.dev = dev;
+
+ if (ioctl(fd_, DM_DEV_STATUS, &io) < 0) {
+ PLOG(ERROR) << "Failed to find device dev: " << major(dev) << ":" << minor(dev);
+ return false;
+ }
+
+ if (name) {
+ *name = io.name;
+ }
+ if (uuid) {
+ *uuid = io.uuid;
+ }
+ return true;
+}
+
std::optional<DeviceMapper::Info> DeviceMapper::GetDetailedInfo(const std::string& name) const {
struct dm_ioctl io;
InitIo(&io, name);
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 788cf5174..c522eafae 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -30,6 +30,7 @@
#include <thread>
#include <android-base/file.h>
+#include <android-base/logging.h>
#include <android-base/scopeguard.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
@@ -42,16 +43,40 @@
using namespace std;
using namespace std::chrono_literals;
using namespace android::dm;
-using unique_fd = android::base::unique_fd;
+using android::base::make_scope_guard;
+using android::base::unique_fd;
+
+class DmTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ const testing::TestInfo* const test_info =
+ testing::UnitTest::GetInstance()->current_test_info();
+ test_name_ = test_info->name();
+ test_full_name_ = test_info->test_suite_name() + "/"s + test_name_;
+
+ LOG(INFO) << "Starting test: " << test_full_name_;
+ }
+ void TearDown() override {
+ LOG(INFO) << "Tearing down test: " << test_full_name_;
+
+ auto& dm = DeviceMapper::Instance();
+ ASSERT_TRUE(dm.DeleteDeviceIfExists(test_name_));
+
+ LOG(INFO) << "Teardown complete for test: " << test_full_name_;
+ }
+
+ std::string test_name_;
+ std::string test_full_name_;
+};
-TEST(libdm, HasMinimumTargets) {
+TEST_F(DmTest, HasMinimumTargets) {
DmTargetTypeInfo info;
DeviceMapper& dm = DeviceMapper::Instance();
ASSERT_TRUE(dm.GetTargetByName("linear", &info));
}
-TEST(libdm, DmLinear) {
+TEST_F(DmTest, DmLinear) {
unique_fd tmp1(CreateTempFile("file_1", 4096));
ASSERT_GE(tmp1, 0);
unique_fd tmp2(CreateTempFile("file_2", 4096));
@@ -127,7 +152,7 @@ TEST(libdm, DmLinear) {
ASSERT_TRUE(dev.Destroy());
}
-TEST(libdm, DmSuspendResume) {
+TEST_F(DmTest, DmSuspendResume) {
unique_fd tmp1(CreateTempFile("file_suspend_resume", 512));
ASSERT_GE(tmp1, 0);
@@ -156,7 +181,7 @@ TEST(libdm, DmSuspendResume) {
ASSERT_EQ(dm.GetState(dev.name()), DmDeviceState::ACTIVE);
}
-TEST(libdm, DmVerityArgsAvb2) {
+TEST_F(DmTest, DmVerityArgsAvb2) {
std::string device = "/dev/block/platform/soc/1da4000.ufshc/by-name/vendor_a";
std::string algorithm = "sha1";
std::string digest = "4be7e823b8c40f7bd5c8ccd5123f0722c5baca21";
@@ -178,7 +203,7 @@ TEST(libdm, DmVerityArgsAvb2) {
EXPECT_EQ(target.GetParameterString(), expected);
}
-TEST(libdm, DmSnapshotArgs) {
+TEST_F(DmTest, DmSnapshotArgs) {
DmTargetSnapshot target1(0, 512, "base", "cow", SnapshotStorageMode::Persistent, 8);
if (DmTargetSnapshot::ReportsOverflow("snapshot")) {
EXPECT_EQ(target1.GetParameterString(), "base cow PO 8");
@@ -200,7 +225,7 @@ TEST(libdm, DmSnapshotArgs) {
EXPECT_EQ(target3.name(), "snapshot-merge");
}
-TEST(libdm, DmSnapshotOriginArgs) {
+TEST_F(DmTest, DmSnapshotOriginArgs) {
DmTargetSnapshotOrigin target(0, 512, "base");
EXPECT_EQ(target.GetParameterString(), "base");
EXPECT_EQ(target.name(), "snapshot-origin");
@@ -330,7 +355,7 @@ bool CheckSnapshotAvailability() {
return true;
}
-TEST(libdm, DmSnapshot) {
+TEST_F(DmTest, DmSnapshot) {
if (!CheckSnapshotAvailability()) {
return;
}
@@ -374,7 +399,7 @@ TEST(libdm, DmSnapshot) {
ASSERT_EQ(read, data);
}
-TEST(libdm, DmSnapshotOverflow) {
+TEST_F(DmTest, DmSnapshotOverflow) {
if (!CheckSnapshotAvailability()) {
return;
}
@@ -421,7 +446,7 @@ TEST(libdm, DmSnapshotOverflow) {
}
}
-TEST(libdm, ParseStatusText) {
+TEST_F(DmTest, ParseStatusText) {
DmTargetSnapshot::Status status;
// Bad inputs
@@ -448,7 +473,7 @@ TEST(libdm, ParseStatusText) {
EXPECT_TRUE(DmTargetSnapshot::ParseStatusText("Overflow", &status));
}
-TEST(libdm, DmSnapshotMergePercent) {
+TEST_F(DmTest, DmSnapshotMergePercent) {
DmTargetSnapshot::Status status;
// Correct input
@@ -502,7 +527,7 @@ TEST(libdm, DmSnapshotMergePercent) {
EXPECT_LE(DmTargetSnapshot::MergePercent(status, 0), 0.0);
}
-TEST(libdm, CryptArgs) {
+TEST_F(DmTest, CryptArgs) {
DmTargetCrypt target1(0, 512, "sha1", "abcdefgh", 50, "/dev/loop0", 100);
ASSERT_EQ(target1.name(), "crypt");
ASSERT_TRUE(target1.Valid());
@@ -518,7 +543,7 @@ TEST(libdm, CryptArgs) {
"iv_large_sectors sector_size:64");
}
-TEST(libdm, DefaultKeyArgs) {
+TEST_F(DmTest, DefaultKeyArgs) {
DmTargetDefaultKey target(0, 4096, "aes-xts-plain64", "abcdef0123456789", "/dev/loop0", 0);
target.SetSetDun();
ASSERT_EQ(target.name(), "default-key");
@@ -529,7 +554,7 @@ TEST(libdm, DefaultKeyArgs) {
"iv_large_sectors");
}
-TEST(libdm, DefaultKeyLegacyArgs) {
+TEST_F(DmTest, DefaultKeyLegacyArgs) {
DmTargetDefaultKey target(0, 4096, "AES-256-XTS", "abcdef0123456789", "/dev/loop0", 0);
target.SetUseLegacyOptionsFormat();
ASSERT_EQ(target.name(), "default-key");
@@ -537,7 +562,7 @@ TEST(libdm, DefaultKeyLegacyArgs) {
ASSERT_EQ(target.GetParameterString(), "AES-256-XTS abcdef0123456789 /dev/loop0 0");
}
-TEST(libdm, DeleteDeviceWithTimeout) {
+TEST_F(DmTest, DeleteDeviceWithTimeout) {
unique_fd tmp(CreateTempFile("file_1", 4096));
ASSERT_GE(tmp, 0);
LoopDevice loop(tmp, 10s);
@@ -561,7 +586,7 @@ TEST(libdm, DeleteDeviceWithTimeout) {
ASSERT_EQ(ENOENT, errno);
}
-TEST(libdm, IsDmBlockDevice) {
+TEST_F(DmTest, IsDmBlockDevice) {
unique_fd tmp(CreateTempFile("file_1", 4096));
ASSERT_GE(tmp, 0);
LoopDevice loop(tmp, 10s);
@@ -580,7 +605,7 @@ TEST(libdm, IsDmBlockDevice) {
ASSERT_FALSE(dm.IsDmBlockDevice(loop.device()));
}
-TEST(libdm, GetDmDeviceNameByPath) {
+TEST_F(DmTest, GetDmDeviceNameByPath) {
unique_fd tmp(CreateTempFile("file_1", 4096));
ASSERT_GE(tmp, 0);
LoopDevice loop(tmp, 10s);
@@ -601,7 +626,7 @@ TEST(libdm, GetDmDeviceNameByPath) {
ASSERT_EQ("libdm-test-dm-linear", *name);
}
-TEST(libdm, GetParentBlockDeviceByPath) {
+TEST_F(DmTest, GetParentBlockDeviceByPath) {
unique_fd tmp(CreateTempFile("file_1", 4096));
ASSERT_GE(tmp, 0);
LoopDevice loop(tmp, 10s);
@@ -621,7 +646,7 @@ TEST(libdm, GetParentBlockDeviceByPath) {
ASSERT_EQ(loop.device(), *sub_block_device);
}
-TEST(libdm, DeleteDeviceDeferredNoReferences) {
+TEST_F(DmTest, DeleteDeviceDeferredNoReferences) {
unique_fd tmp(CreateTempFile("file_1", 4096));
ASSERT_GE(tmp, 0);
LoopDevice loop(tmp, 10s);
@@ -647,7 +672,7 @@ TEST(libdm, DeleteDeviceDeferredNoReferences) {
ASSERT_EQ(ENOENT, errno);
}
-TEST(libdm, DeleteDeviceDeferredWaitsForLastReference) {
+TEST_F(DmTest, DeleteDeviceDeferredWaitsForLastReference) {
unique_fd tmp(CreateTempFile("file_1", 4096));
ASSERT_GE(tmp, 0);
LoopDevice loop(tmp, 10s);
@@ -682,7 +707,7 @@ TEST(libdm, DeleteDeviceDeferredWaitsForLastReference) {
ASSERT_EQ(ENOENT, errno);
}
-TEST(libdm, CreateEmptyDevice) {
+TEST_F(DmTest, CreateEmptyDevice) {
DeviceMapper& dm = DeviceMapper::Instance();
ASSERT_TRUE(dm.CreateEmptyDevice("empty-device"));
auto guard =
@@ -692,9 +717,7 @@ TEST(libdm, CreateEmptyDevice) {
ASSERT_EQ(DmDeviceState::SUSPENDED, dm.GetState("empty-device"));
}
-TEST(libdm, UeventAfterLoadTable) {
- static const char* kDeviceName = "libdm-test-uevent-load-table";
-
+TEST_F(DmTest, UeventAfterLoadTable) {
struct utsname u;
ASSERT_EQ(uname(&u), 0);
@@ -706,18 +729,31 @@ TEST(libdm, UeventAfterLoadTable) {
}
DeviceMapper& dm = DeviceMapper::Instance();
- ASSERT_TRUE(dm.CreateEmptyDevice(kDeviceName));
+ ASSERT_TRUE(dm.CreateEmptyDevice(test_name_));
DmTable table;
table.Emplace<DmTargetError>(0, 1);
- ASSERT_TRUE(dm.LoadTable(kDeviceName, table));
+ ASSERT_TRUE(dm.LoadTable(test_name_, table));
std::string ignore_path;
- ASSERT_TRUE(dm.WaitForDevice(kDeviceName, 5s, &ignore_path));
+ ASSERT_TRUE(dm.WaitForDevice(test_name_, 5s, &ignore_path));
- auto info = dm.GetDetailedInfo(kDeviceName);
+ auto info = dm.GetDetailedInfo(test_name_);
ASSERT_TRUE(info.has_value());
ASSERT_TRUE(info->IsSuspended());
- ASSERT_TRUE(dm.DeleteDevice(kDeviceName));
+ ASSERT_TRUE(dm.DeleteDevice(test_name_));
+}
+
+TEST_F(DmTest, GetNameAndUuid) {
+ auto& dm = DeviceMapper::Instance();
+ ASSERT_TRUE(dm.CreatePlaceholderDevice(test_name_));
+
+ dev_t dev;
+ ASSERT_TRUE(dm.GetDeviceNumber(test_name_, &dev));
+
+ std::string name, uuid;
+ ASSERT_TRUE(dm.GetDeviceNameAndUuid(dev, &name, &uuid));
+ ASSERT_EQ(name, test_name_);
+ ASSERT_FALSE(uuid.empty());
}
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index dbef8f902..3e7ecc645 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -298,6 +298,8 @@ class DeviceMapper final : public IDeviceMapper {
// a placeholder table containing dm-error.
bool CreatePlaceholderDevice(const std::string& name);
+ bool GetDeviceNameAndUuid(dev_t dev, std::string* name, std::string* uuid);
+
private:
// Maximum possible device mapper targets registered in the kernel.
// This is only used to read the list of targets from kernel so we allocate
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index bb2ceb9b5..4d771fa04 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -55,6 +55,21 @@ TEST(fs, ErofsSupported) {
}
TEST(fs, PartitionTypes) {
+ // Requirements only apply to Android 13+, 5.10+ devices.
+ int vsr_level = GetVsrLevel();
+ if (vsr_level < __ANDROID_API_T__) {
+ GTEST_SKIP();
+ }
+
+ struct utsname uts;
+ ASSERT_EQ(uname(&uts), 0);
+
+ unsigned int major, minor;
+ ASSERT_EQ(sscanf(uts.release, "%u.%u", &major, &minor), 2);
+ if (major < 5 || (major == 5 && minor < 10)) {
+ GTEST_SKIP();
+ }
+
android::fs_mgr::Fstab fstab;
ASSERT_TRUE(android::fs_mgr::ReadFstabFromFile("/proc/mounts", &fstab));
@@ -64,12 +79,7 @@ TEST(fs, PartitionTypes) {
ASSERT_TRUE(android::base::Readlink("/dev/block/by-name/super", &super_bdev));
ASSERT_TRUE(android::base::Readlink("/dev/block/by-name/userdata", &userdata_bdev));
- int vsr_level = GetVsrLevel();
-
- std::vector<std::string> must_be_f2fs;
- if (vsr_level >= __ANDROID_API_T__) {
- must_be_f2fs.emplace_back("/data");
- }
+ std::vector<std::string> must_be_f2fs = {"/data"};
if (vsr_level >= __ANDROID_API_U__) {
must_be_f2fs.emplace_back("/metadata");
}
@@ -98,17 +108,13 @@ TEST(fs, PartitionTypes) {
continue;
}
- if (vsr_level < __ANDROID_API_T__) {
- continue;
- }
- if (vsr_level == __ANDROID_API_T__ && parent_bdev != super_bdev) {
- // Only check for dynamic partitions at this VSR level.
- continue;
- }
-
if (entry.flags & MS_RDONLY) {
- std::vector<std::string> allowed = {"erofs", "ext4", "f2fs"};
+ if (parent_bdev != super_bdev) {
+ // Ignore non-AOSP partitions (eg anything outside of super).
+ continue;
+ }
+ std::vector<std::string> allowed = {"erofs", "ext4", "f2fs"};
EXPECT_NE(std::find(allowed.begin(), allowed.end(), entry.fs_type), allowed.end())
<< entry.mount_point;
} else {
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index f68d65a54..bd7955a7f 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -244,6 +244,8 @@ BatteryHealth getBatteryHealthStatus(int status) {
value = BatteryHealth::UNSPECIFIED_FAILURE;
else if (status == BatteryMonitor::BH_NOT_AVAILABLE)
value = BatteryHealth::NOT_AVAILABLE;
+ else if (status == BatteryMonitor::BH_INCONSISTENT)
+ value = BatteryHealth::INCONSISTENT;
else
value = BatteryHealth::UNKNOWN;
diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h
index a4c013b86..e9998ba7a 100644
--- a/healthd/include/healthd/BatteryMonitor.h
+++ b/healthd/include/healthd/BatteryMonitor.h
@@ -63,6 +63,7 @@ class BatteryMonitor {
BH_NEEDS_REPLACEMENT,
BH_FAILED,
BH_NOT_AVAILABLE,
+ BH_INCONSISTENT,
};
BatteryMonitor();
diff --git a/init/devices.cpp b/init/devices.cpp
index 39442a0e8..d29ffd604 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -32,6 +32,7 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <libdm/dm.h>
#include <private/android_filesystem_config.h>
#include <selinux/android.h>
#include <selinux/selinux.h>
@@ -112,17 +113,14 @@ static bool FindVbdDevicePrefix(const std::string& path, std::string* result) {
// the supplied buffer with the dm module's instantiated name.
// If it doesn't start with a virtual block device, or there is some
// error, return false.
-static bool FindDmDevice(const std::string& path, std::string* name, std::string* uuid) {
- if (!StartsWith(path, "/devices/virtual/block/dm-")) return false;
+static bool FindDmDevice(const Uevent& uevent, std::string* name, std::string* uuid) {
+ if (!StartsWith(uevent.path, "/devices/virtual/block/dm-")) return false;
+ if (uevent.action == "remove") return false; // Avoid error spam from ioctl
- if (!ReadFileToString("/sys" + path + "/dm/name", name)) {
- return false;
- }
- ReadFileToString("/sys" + path + "/dm/uuid", uuid);
+ dev_t dev = makedev(uevent.major, uevent.minor);
- *name = android::base::Trim(*name);
- *uuid = android::base::Trim(*uuid);
- return true;
+ auto& dm = android::dm::DeviceMapper::Instance();
+ return dm.GetDeviceNameAndUuid(dev, name, uuid);
}
Permissions::Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid,
@@ -392,7 +390,7 @@ std::vector<std::string> DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev
type = "pci";
} else if (FindVbdDevicePrefix(uevent.path, &device)) {
type = "vbd";
- } else if (FindDmDevice(uevent.path, &partition, &uuid)) {
+ } else if (FindDmDevice(uevent, &partition, &uuid)) {
std::vector<std::string> symlinks = {"/dev/block/mapper/" + partition};
if (!uuid.empty()) {
symlinks.emplace_back("/dev/block/mapper/by-uuid/" + uuid);
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index b135e57bc..0b5c1254e 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -286,11 +286,14 @@ cc_defaults {
],
}
+always_static_test_libraries = [
+ "libjsoncpp",
+]
+
test_libraries = [
"libcutils",
"liblog",
"libbase",
- "libjsoncpp",
"libprocessgroup",
"libcgrouprc",
]
@@ -301,6 +304,7 @@ cc_test {
defaults: ["libcutils_test_default"],
host_supported: true,
shared_libs: test_libraries,
+ static_libs: always_static_test_libraries,
require_root: true,
}
@@ -310,7 +314,7 @@ cc_defaults {
static_libs: [
"libc",
"libcgrouprc_format",
- ] + test_libraries,
+ ] + test_libraries + always_static_test_libraries,
stl: "libc++_static",
require_root: true,
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 41c60a7f9..1e6918d00 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -315,7 +315,7 @@ on init
write /proc/sys/kernel/randomize_va_space 2
write /proc/sys/vm/mmap_min_addr 32768
write /proc/sys/net/ipv4/ping_group_range "0 2147483647"
- write /proc/sys/net/unix/max_dgram_qlen 600
+ write /proc/sys/net/unix/max_dgram_qlen 2400
# Assign reasonable ceiling values for socket rcv/snd buffers.
# These should almost always be overridden by the target per the
diff --git a/rootdir/ramdisk_node_list b/rootdir/ramdisk_node_list
index 4f45faaec..d3ab8a66e 100644
--- a/rootdir/ramdisk_node_list
+++ b/rootdir/ramdisk_node_list
@@ -1,4 +1,3 @@
dir dev 0755 0 0
nod dev/null 0600 0 0 c 1 3
nod dev/console 0600 0 0 c 5 1
-nod dev/urandom 0600 0 0 c 1 9
diff --git a/toolbox/modprobe.cpp b/toolbox/modprobe.cpp
index 17f815697..17d4e319b 100644
--- a/toolbox/modprobe.cpp
+++ b/toolbox/modprobe.cpp
@@ -85,6 +85,26 @@ void MyLogger(android::base::LogId id, android::base::LogSeverity severity, cons
}
}
+// Find directories in format of "/lib/modules/x.y.z-*".
+static int KernelVersionNameFilter(const dirent* de) {
+ unsigned int major, minor;
+ static std::string kernel_version;
+ utsname uts;
+
+ if (kernel_version.empty()) {
+ if ((uname(&uts) != 0) || (sscanf(uts.release, "%u.%u", &major, &minor) != 2)) {
+ LOG(ERROR) << "Could not parse the kernel version from uname";
+ return 0;
+ }
+ kernel_version = android::base::StringPrintf("%u.%u", major, minor);
+ }
+
+ if (android::base::StartsWith(de->d_name, kernel_version)) {
+ return 1;
+ }
+ return 0;
+}
+
} // anonymous namespace
extern "C" int modprobe_main(int argc, char** argv) {
@@ -192,9 +212,22 @@ extern "C" int modprobe_main(int argc, char** argv) {
}
if (mod_dirs.empty()) {
- utsname uts;
- uname(&uts);
- mod_dirs.emplace_back(android::base::StringPrintf("/lib/modules/%s", uts.release));
+ static constexpr auto LIB_MODULES_PREFIX = "/lib/modules/";
+ dirent** kernel_dirs = NULL;
+
+ int n = scandir(LIB_MODULES_PREFIX, &kernel_dirs, KernelVersionNameFilter, NULL);
+ if (n == -1) {
+ PLOG(ERROR) << "Failed to scan dir " << LIB_MODULES_PREFIX;
+ return EXIT_FAILURE;
+ } else if (n > 0) {
+ while (n--) {
+ mod_dirs.emplace_back(LIB_MODULES_PREFIX + std::string(kernel_dirs[n]->d_name));
+ }
+ }
+ free(kernel_dirs);
+
+ // Allow modules to be directly inside /lib/modules
+ mod_dirs.emplace_back(LIB_MODULES_PREFIX);
}
LOG(DEBUG) << "mode is " << mode;
@@ -212,11 +245,6 @@ extern "C" int modprobe_main(int argc, char** argv) {
return EXIT_FAILURE;
}
}
- if (mod_dirs.empty()) {
- LOG(ERROR) << "No module configuration directories given.";
- print_usage();
- return EXIT_FAILURE;
- }
if (parameter_count && modules.size() > 1) {
LOG(ERROR) << "Only one module may be loaded when specifying module parameters.";
print_usage();