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

Commit 160e4c3c authored by Akilesh Kailash's avatar Akilesh Kailash Committed by Gerrit Code Review
Browse files

Merge changes from topic "ota-tune-1" into main

* changes:
  Allow direct reads on source device
  libsnapshot: Tune readahead during OTA for source and COW block device
parents f7fffb62 52f1c19a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -826,6 +826,9 @@ class SnapshotManager final : public ISnapshotManager {
    bool DeleteDeviceIfExists(const std::string& name,
                              const std::chrono::milliseconds& timeout_ms = {});

    // Set read-ahead size during OTA
    void SetReadAheadSize(const std::string& entry_block_device, off64_t size_kb);

    android::dm::IDeviceMapper& dm_;
    std::unique_ptr<IDeviceInfo> device_;
    std::string metadata_dir_;
+46 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <cutils/sockets.h>
@@ -82,12 +83,28 @@ using RepeatedPtrField = google::protobuf::RepeatedPtrField<T>;
using std::chrono::duration_cast;
using namespace std::chrono_literals;
using namespace std::string_literals;
using android::base::Realpath;
using android::base::StringPrintf;

static constexpr char kBootSnapshotsWithoutSlotSwitch[] =
        "/metadata/ota/snapshot-boot-without-slot-switch";
static constexpr char kBootIndicatorPath[] = "/metadata/ota/snapshot-boot";
static constexpr char kRollbackIndicatorPath[] = "/metadata/ota/rollback-indicator";
static constexpr auto kUpdateStateCheckInterval = 2s;
/*
 * The readahead size is set to 32kb so that
 * there is no significant memory pressure (/proc/pressure/memory) during boot.
 * After OTA, during boot, partitions are scanned before marking slot as successful.
 * This scan will trigger readahead both on source and COW block device thereby
 * leading to Inactive(file) pages to be very high.
 *
 * A lower value may help reduce memory pressure further, however, that will
 * increase the boot time. Thus, for device which don't care about OTA boot
 * time, they could use O_DIRECT functionality wherein the I/O to the source
 * block device will be O_DIRECT.
 */
static constexpr auto kCowReadAheadSizeKb = 32;
static constexpr auto kSourceReadAheadSizeKb = 32;

// Note: IImageManager is an incomplete type in the header, so the default
// destructor doesn't work.
@@ -1748,6 +1765,9 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,
                snapuserd_argv->emplace_back(std::move(message));
            }

            SetReadAheadSize(cow_image_device, kCowReadAheadSizeKb);
            SetReadAheadSize(source_device, kSourceReadAheadSizeKb);

            // Do not attempt to connect to the new snapuserd yet, it hasn't
            // been started. We do however want to wait for the misc device
            // to have been created.
@@ -4407,5 +4427,31 @@ bool SnapshotManager::PrepareDeviceToBootWithoutSnapshot() {
    return true;
}

void SnapshotManager::SetReadAheadSize(const std::string& entry_block_device, off64_t size_kb) {
    std::string block_device;
    if (!Realpath(entry_block_device, &block_device)) {
        PLOG(ERROR) << "Failed to realpath " << entry_block_device;
        return;
    }

    static constexpr std::string_view kDevBlockPrefix("/dev/block/");
    if (!android::base::StartsWith(block_device, kDevBlockPrefix)) {
        LOG(ERROR) << block_device << " is not a block device";
        return;
    }

    std::string block_name = block_device.substr(kDevBlockPrefix.length());
    std::string sys_partition =
            android::base::StringPrintf("/sys/class/block/%s/partition", block_name.c_str());
    struct stat info;
    if (lstat(sys_partition.c_str(), &info) == 0) {
        block_name += "/..";
    }
    std::string sys_ra = android::base::StringPrintf("/sys/class/block/%s/queue/read_ahead_kb",
                                                     block_name.c_str());
    std::string size = std::to_string(size_kb);
    android::base::WriteStringToFile(size, sys_ra.c_str());
}

}  // namespace snapshot
}  // namespace android
+2 −2
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ Extractor::Extractor(const std::string& base_path, const std::string& cow_path)
bool Extractor::Init() {
    auto opener = factory_.CreateTestOpener(control_name_);
    handler_ = std::make_shared<SnapshotHandler>(control_name_, cow_path_, base_path_, base_path_,
                                                 opener, 1, false, false);
                                                 opener, 1, false, false, false);
    if (!handler_->InitCowDevice()) {
        return false;
    }
@@ -50,7 +50,7 @@ bool Extractor::Init() {
    }

    read_worker_ = std::make_unique<ReadWorker>(cow_path_, base_path_, control_name_, base_path_,
                                                handler_->GetSharedPtr(), opener);
                                                handler_->GetSharedPtr(), opener, false);
    if (!read_worker_->Init()) {
        return false;
    }
+5 −4
Original line number Diff line number Diff line
@@ -51,10 +51,11 @@ SnapshotHandlerManager::SnapshotHandlerManager() {
std::shared_ptr<HandlerThread> SnapshotHandlerManager::AddHandler(
        const std::string& misc_name, const std::string& cow_device_path,
        const std::string& backing_device, const std::string& base_path_merge,
        std::shared_ptr<IBlockServerOpener> opener, int num_worker_threads, bool use_iouring) {
    auto snapuserd = std::make_shared<SnapshotHandler>(misc_name, cow_device_path, backing_device,
                                                       base_path_merge, opener, num_worker_threads,
                                                       use_iouring, perform_verification_);
        std::shared_ptr<IBlockServerOpener> opener, int num_worker_threads, bool use_iouring,
        bool o_direct) {
    auto snapuserd = std::make_shared<SnapshotHandler>(
            misc_name, cow_device_path, backing_device, base_path_merge, opener, num_worker_threads,
            use_iouring, perform_verification_, o_direct);
    if (!snapuserd->InitCowDevice()) {
        LOG(ERROR) << "Failed to initialize Snapuserd";
        return nullptr;
+4 −2
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@ class ISnapshotHandlerManager {
                                                      const std::string& backing_device,
                                                      const std::string& base_path_merge,
                                                      std::shared_ptr<IBlockServerOpener> opener,
                                                      int num_worker_threads, bool use_iouring) = 0;
                                                      int num_worker_threads, bool use_iouring,
                                                      bool o_direct) = 0;

    // Start serving requests on a snapshot handler.
    virtual bool StartHandler(const std::string& misc_name) = 0;
@@ -96,7 +97,8 @@ class SnapshotHandlerManager final : public ISnapshotHandlerManager {
                                              const std::string& backing_device,
                                              const std::string& base_path_merge,
                                              std::shared_ptr<IBlockServerOpener> opener,
                                              int num_worker_threads, bool use_iouring) override;
                                              int num_worker_threads, bool use_iouring,
                                              bool o_direct) override;
    bool StartHandler(const std::string& misc_name) override;
    bool DeleteHandler(const std::string& misc_name) override;
    bool InitiateMerge(const std::string& misc_name) override;
Loading