Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 4e26d419 authored by Michael Bestas's avatar Michael Bestas
Browse files

Merge tag 'android-14.0.0_r17' into staging/lineage-21.0_merge-android-14.0.0_r17

Android 14.0.0 Release 17 (UQ1A.231205.015)

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZXDPNwAKCRDorT+BmrEO
# eFPEAJ90wL0gUa7uT4np0iENNXoQn3QhyQCfXM5wouynx/QjrAwNWCwBBHHnYBE=
# =ulx5
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed Dec  6 21:44:55 2023 EET
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [marginal]
# gpg: initial-contribution@android.com: Verified 2192 signatures in the past
#      2 years.  Encrypted 4 messages in the past 23 months.
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 4340 D135 70EF 945E 8381  0964 E8AD 3F81 9AB1 0E78

# By Suren Baghdasaryan (4) and others
# Via Automerger Merge Worker (186) and Android Build Coastguard Worker (25)
* tag 'android-14.0.0_r17':
  Run fsck to resolve possible data corruption
  Compile with -D_FILE_OFFSET_BITS to support 32-bit userspace
  Move ENOSPC tests to libfiemap.
  Disallow fastboot to modify locked DSU
  Add a fastboot command to show GSI status
  libprocessgroup: optimize SetAttributeAction::ExecuteForProcess performance
  libprocessgroup: fix reset of file_v2_name
  libprocessgroup: optimize SetAttributeAction::ExecuteForProcess performance
  libprocessgroup: fix reset of file_v2_name
  storageproxyd: Start only a single binder thread
  storageproxyd: Start binder thread pool
  Revert "Listen on property_service_for_system socket"
  Revert "Fix deadlock caused by two-threaded property controls"
  init.rc: set f2fs seq_file_ra_mul to 128
  Check AServiceManager_isDeclared before AServiceManager_getService
  Export active dsu slot to system prop

Change-Id: I5956d08cdd524908a9aa61389670182f3b486fe7
parents 0bf77386 de29eec3
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -639,6 +639,12 @@ bool UpdateSuperHandler(FastbootDevice* device, const std::vector<std::string>&
    return UpdateSuper(device, args[1], wipe);
}

static bool IsLockedDsu() {
    std::string active_dsu;
    android::gsi::GetActiveDsu(&active_dsu);
    return android::base::EndsWith(active_dsu, ".lock");
}

bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
    if (args.size() != 2) {
        return device->WriteFail("Invalid arguments");
@@ -653,6 +659,11 @@ bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
        return device->WriteStatus(FastbootResult::FAIL, "No GSI is installed");
    }

    if ((args[1] == "wipe" || args[1] == "disable") && GetDeviceLockStatus() && IsLockedDsu()) {
        // Block commands that modify the states of locked DSU
        return device->WriteFail("Command not available on locked DSU/devices");
    }

    if (args[1] == "wipe") {
        if (!android::gsi::UninstallGsi()) {
            return device->WriteStatus(FastbootResult::FAIL, strerror(errno));
@@ -661,6 +672,17 @@ bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
        if (!android::gsi::DisableGsi()) {
            return device->WriteStatus(FastbootResult::FAIL, strerror(errno));
        }
    } else if (args[1] == "status") {
        std::string active_dsu;
        if (!android::gsi::IsGsiRunning()) {
            device->WriteInfo("Not running");
        } else if (!android::gsi::GetActiveDsu(&active_dsu)) {
            return device->WriteFail(strerror(errno));
        } else {
            device->WriteInfo("Running active DSU: " + active_dsu);
        }
    } else {
        return device->WriteFail("Invalid arguments");
    }
    return device->WriteStatus(FastbootResult::OKAY, "Success");
}
+5 −7
Original line number Diff line number Diff line
@@ -2563,14 +2563,12 @@ int FastBootTool::Main(int argc, char* argv[]) {
                    std::make_unique<ResizeTask>(fp.get(), partition, size, fp->slot_override);
            resize_task->Run();
        } else if (command == "gsi") {
            std::string arg = next_arg(&args);
            if (arg == "wipe") {
                fb->RawCommand("gsi:wipe", "wiping GSI");
            } else if (arg == "disable") {
                fb->RawCommand("gsi:disable", "disabling GSI");
            } else {
                syntax_error("expected 'wipe' or 'disable'");
            if (args.empty()) syntax_error("invalid gsi command");
            std::string cmd("gsi");
            while (!args.empty()) {
                cmd += ":" + next_arg(&args);
            }
            fb->RawCommand(cmd, "");
        } else if (command == "wipe-super") {
            std::string image;
            if (args.empty()) {
+3 −0
Original line number Diff line number Diff line
@@ -93,6 +93,9 @@ cc_test {
    test_options: {
        min_shipping_api_level: 29,
    },
    header_libs: [
        "libstorage_literals_headers",
    ],
    require_root: true,
}

+78 −40
Original line number Diff line number Diff line
@@ -22,21 +22,25 @@
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <unistd.h>

#include <string>
#include <utility>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <fstab/fstab.h>
#include <gtest/gtest.h>
#include <libdm/loop_control.h>
#include <libfiemap/fiemap_writer.h>
#include <libfiemap/split_fiemap_writer.h>
#include <libgsi/libgsi.h>
#include <storage_literals/storage_literals.h>

#include "utility.h"

@@ -46,6 +50,7 @@ namespace fiemap {
using namespace std;
using namespace std::string_literals;
using namespace android::fiemap;
using namespace android::storage_literals;
using unique_fd = android::base::unique_fd;
using LoopDevice = android::dm::LoopDevice;

@@ -427,90 +432,123 @@ TEST_F(SplitFiemapTest, WritePastEnd) {
    ASSERT_FALSE(ptr->Write(buffer.get(), kSize));
}

class VerifyBlockWritesExt4 : public ::testing::Test {
// Get max file size and free space.
std::pair<uint64_t, uint64_t> GetBigFileLimit(const std::string& mount_point) {
    struct statvfs fs;
    if (statvfs(mount_point.c_str(), &fs) < 0) {
        PLOG(ERROR) << "statfs failed";
        return {0, 0};
    }

    auto fs_limit = static_cast<uint64_t>(fs.f_blocks) * (fs.f_bsize - 1);
    auto fs_free = static_cast<uint64_t>(fs.f_bfree) * fs.f_bsize;

    LOG(INFO) << "Big file limit: " << fs_limit << ", free space: " << fs_free;

    return {fs_limit, fs_free};
}

class FsTest : public ::testing::Test {
  protected:
    // 2GB Filesystem and 4k block size by default
    static constexpr uint64_t block_size = 4096;
    static constexpr uint64_t fs_size = 2147483648;
    static constexpr uint64_t fs_size = 64 * 1024 * 1024;

  protected:
    void SetUp() override {
        fs_path = std::string(getenv("TMPDIR")) + "/ext4_2G.img";
    void SetUp() {
        android::fs_mgr::Fstab fstab;
        ASSERT_TRUE(android::fs_mgr::ReadFstabFromFile("/proc/mounts", &fstab));

        ASSERT_EQ(access(tmpdir_.path, F_OK), 0);
        fs_path_ = tmpdir_.path + "/fs_image"s;
        mntpoint_ = tmpdir_.path + "/mnt_point"s;

        auto entry = android::fs_mgr::GetEntryForMountPoint(&fstab, "/data");
        ASSERT_NE(entry, nullptr);
        if (entry->fs_type == "ext4") {
            SetUpExt4();
        } else if (entry->fs_type == "f2fs") {
            SetUpF2fs();
        } else {
            FAIL() << "Unrecognized fs_type: " << entry->fs_type;
        }
    }

    void SetUpExt4() {
        uint64_t count = fs_size / block_size;
        std::string dd_cmd =
                ::android::base::StringPrintf("/system/bin/dd if=/dev/zero of=%s bs=%" PRIu64
                                              " count=%" PRIu64 " > /dev/null 2>&1",
                                              fs_path.c_str(), block_size, count);
                                              fs_path_.c_str(), block_size, count);
        std::string mkfs_cmd =
                ::android::base::StringPrintf("/system/bin/mkfs.ext4 -q %s", fs_path.c_str());
                ::android::base::StringPrintf("/system/bin/mkfs.ext4 -q %s", fs_path_.c_str());
        // create mount point
        mntpoint = std::string(getenv("TMPDIR")) + "/fiemap_mnt";
        ASSERT_EQ(mkdir(mntpoint.c_str(), S_IRWXU), 0);
        ASSERT_EQ(mkdir(mntpoint_.c_str(), S_IRWXU), 0);
        // create file for the file system
        int ret = system(dd_cmd.c_str());
        ASSERT_EQ(ret, 0);
        // Get and attach a loop device to the filesystem we created
        LoopDevice loop_dev(fs_path, 10s);
        LoopDevice loop_dev(fs_path_, 10s);
        ASSERT_TRUE(loop_dev.valid());
        // create file system
        ret = system(mkfs_cmd.c_str());
        ASSERT_EQ(ret, 0);

        // mount the file system
        ASSERT_EQ(mount(loop_dev.device().c_str(), mntpoint.c_str(), "ext4", 0, nullptr), 0);
        ASSERT_EQ(mount(loop_dev.device().c_str(), mntpoint_.c_str(), "ext4", 0, nullptr), 0);
    }

    void TearDown() override {
        umount(mntpoint.c_str());
        rmdir(mntpoint.c_str());
        unlink(fs_path.c_str());
    }

    std::string mntpoint;
    std::string fs_path;
};

class VerifyBlockWritesF2fs : public ::testing::Test {
    // 2GB Filesystem and 4k block size by default
    static constexpr uint64_t block_size = 4096;
    static constexpr uint64_t fs_size = 2147483648;

  protected:
    void SetUp() override {
        fs_path = std::string(getenv("TMPDIR")) + "/f2fs_2G.img";
    void SetUpF2fs() {
        uint64_t count = fs_size / block_size;
        std::string dd_cmd =
                ::android::base::StringPrintf("/system/bin/dd if=/dev/zero of=%s bs=%" PRIu64
                                              " count=%" PRIu64 " > /dev/null 2>&1",
                                              fs_path.c_str(), block_size, count);
                                              fs_path_.c_str(), block_size, count);
        std::string mkfs_cmd =
                ::android::base::StringPrintf("/system/bin/make_f2fs -q %s", fs_path.c_str());
                ::android::base::StringPrintf("/system/bin/make_f2fs -q %s", fs_path_.c_str());
        // create mount point
        mntpoint = std::string(getenv("TMPDIR")) + "/fiemap_mnt";
        ASSERT_EQ(mkdir(mntpoint.c_str(), S_IRWXU), 0);
        ASSERT_EQ(mkdir(mntpoint_.c_str(), S_IRWXU), 0);
        // create file for the file system
        int ret = system(dd_cmd.c_str());
        ASSERT_EQ(ret, 0);
        // Get and attach a loop device to the filesystem we created
        LoopDevice loop_dev(fs_path, 10s);
        LoopDevice loop_dev(fs_path_, 10s);
        ASSERT_TRUE(loop_dev.valid());
        // create file system
        ret = system(mkfs_cmd.c_str());
        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);
    }

    void TearDown() override {
        umount(mntpoint.c_str());
        rmdir(mntpoint.c_str());
        unlink(fs_path.c_str());
        umount(mntpoint_.c_str());
        rmdir(mntpoint_.c_str());
        unlink(fs_path_.c_str());
    }

    std::string mntpoint;
    std::string fs_path;
    TemporaryDir tmpdir_;
    std::string mntpoint_;
    std::string fs_path_;
};

TEST_F(FsTest, LowSpaceError) {
    auto limits = GetBigFileLimit(mntpoint_);
    ASSERT_GE(limits.first, 0);

    FiemapUniquePtr ptr;

    auto test_file = mntpoint_ + "/big_file";
    auto status = FiemapWriter::Open(test_file, limits.first, &ptr);
    ASSERT_FALSE(status.is_ok());
    ASSERT_EQ(status.error_code(), FiemapStatus::ErrorCode::NO_SPACE);

    // Also test for EFBIG.
    status = FiemapWriter::Open(test_file, 16_TiB, &ptr);
    ASSERT_FALSE(status.is_ok());
    ASSERT_NE(status.error_code(), FiemapStatus::ErrorCode::NO_SPACE);
}

bool DetermineBlockSize() {
    struct statfs s;
    if (statfs(gTestDir.c_str(), &s)) {
+0 −70
Original line number Diff line number Diff line
@@ -2312,32 +2312,6 @@ TEST_F(SnapshotUpdateTest, Overflow) {
            << "FinishedSnapshotWrites should detect overflow of CoW device.";
}

TEST_F(SnapshotUpdateTest, LowSpace) {
    static constexpr auto kMaxFree = 10_MiB;
    auto userdata = std::make_unique<LowSpaceUserdata>();
    ASSERT_TRUE(userdata->Init(kMaxFree));

    // Grow all partitions to 10_MiB, total 30_MiB. This requires 30 MiB of CoW space. After
    // using the empty space in super (< 1 MiB), it uses 30 MiB of /userdata space.
    constexpr uint64_t partition_size = 10_MiB;
    SetSize(sys_, partition_size);
    SetSize(vnd_, partition_size);
    SetSize(prd_, partition_size);
    sys_->set_estimate_cow_size(partition_size);
    vnd_->set_estimate_cow_size(partition_size);
    prd_->set_estimate_cow_size(partition_size);

    AddOperationForPartitions();

    // Execute the update.
    ASSERT_TRUE(sm->BeginUpdate());
    auto res = sm->CreateUpdateSnapshots(manifest_);
    ASSERT_FALSE(res);
    ASSERT_EQ(Return::ErrorCode::NO_SPACE, res.error_code());
    ASSERT_GE(res.required_size(), 14_MiB);
    ASSERT_LT(res.required_size(), 40_MiB);
}

TEST_F(SnapshotUpdateTest, AddPartition) {
    group_->add_partition_names("dlkm");

@@ -2699,50 +2673,6 @@ INSTANTIATE_TEST_SUITE_P(Snapshot, FlashAfterUpdateTest, Combine(Values(0, 1), B
                                    "Merge"s;
                         });

class ImageManagerTest : public SnapshotTest {
  protected:
    void SetUp() override {
        SKIP_IF_NON_VIRTUAL_AB();
        SnapshotTest::SetUp();
    }
    void TearDown() override {
        RETURN_IF_NON_VIRTUAL_AB();
        CleanUp();
    }
    void CleanUp() {
        if (!image_manager_) {
            return;
        }
        EXPECT_TRUE(!image_manager_->BackingImageExists(kImageName) ||
                    image_manager_->DeleteBackingImage(kImageName));
    }

    static constexpr const char* kImageName = "my_image";
};

TEST_F(ImageManagerTest, CreateImageNoSpace) {
    bool at_least_one_failure = false;
    for (uint64_t size = 1_MiB; size <= 512_MiB; size *= 2) {
        auto userdata = std::make_unique<LowSpaceUserdata>();
        ASSERT_TRUE(userdata->Init(size));

        uint64_t to_allocate = userdata->free_space() + userdata->bsize();

        auto res = image_manager_->CreateBackingImage(kImageName, to_allocate,
                                                      IImageManager::CREATE_IMAGE_DEFAULT);
        if (!res) {
            at_least_one_failure = true;
        } else {
            ASSERT_EQ(res.error_code(), FiemapStatus::ErrorCode::NO_SPACE) << res.string();
        }

        CleanUp();
    }

    ASSERT_TRUE(at_least_one_failure)
            << "We should have failed to allocate at least one over-sized image";
}

bool Mkdir(const std::string& path) {
    if (mkdir(path.c_str(), 0700) && errno != EEXIST) {
        std::cerr << "Could not mkdir " << path << ": " << strerror(errno) << std::endl;
Loading