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

Commit 63e0a6f2 authored by David Anderson's avatar David Anderson Committed by Automerger Merge Worker
Browse files

Merge changes Ib33dc593,I6550682f,Ic0681cbf,Iaaf96a37,I89b15492 into main am:...

Merge changes Ib33dc593,I6550682f,Ic0681cbf,Iaaf96a37,I89b15492 into main am: 9c525ff0 am: 9b306bab

Original change: https://android-review.googlesource.com/c/platform/system/core/+/2695350



Change-Id: I65507f16445cf8a39f5f9ad4911f64943d367dfc
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 120a47b2 9b306bab
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ cc_test {
    ],
    srcs: [
        "testing/dm_user_harness.cpp",
        "testing/harness.cpp",
        "user-space-merge/snapuserd_test.cpp",
    ],
    shared_libs: [
+116 −0
Original line number Diff line number Diff line
// 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.

#include "harness.h"

#ifdef __ANDROID__
#include <linux/memfd.h>
#endif
#include <sys/mman.h>
#include <sys/resource.h>
#include <unistd.h>

#include <android-base/file.h>
#include <ext4_utils/ext4_utils.h>
#include <libdm/loop_control.h>
#include "snapuserd_logging.h"

namespace android {
namespace snapshot {

using namespace std::chrono_literals;
using android::base::unique_fd;
using android::dm::LoopDevice;

#ifdef __ANDROID__
// Prefer this on device since it is a real block device, which is more similar
// to how we use snapuserd.
class MemoryBackedDevice final : public IBackingDevice {
  public:
    bool Init(uint64_t size) {
        memfd_.reset(memfd_create("snapuserd_test", MFD_ALLOW_SEALING));
        if (memfd_ < 0) {
            PLOG(ERROR) << "memfd_create failed";
            return false;
        }
        if (ftruncate(memfd_.get(), size) < 0) {
            PLOG(ERROR) << "ftruncate failed";
            return false;
        }
        if (fcntl(memfd_.get(), F_ADD_SEALS, F_SEAL_GROW | F_SEAL_SHRINK) < 0) {
            PLOG(ERROR) << "fcntl seal failed";
            return false;
        }
        dev_ = std::make_unique<LoopDevice>(memfd_, 10s);
        return dev_->valid();
    }
    const std::string& GetPath() override { return dev_->device(); }
    uint64_t GetSize() override {
        unique_fd fd(open(GetPath().c_str(), O_RDONLY | O_CLOEXEC));
        if (fd < 0) {
            PLOG(ERROR) << "open failed: " << GetPath();
            return 0;
        }
        return get_block_device_size(fd.get());
    }

  private:
    unique_fd memfd_;
    std::unique_ptr<LoopDevice> dev_;
};
#endif

class FileBackedDevice final : public IBackingDevice {
  public:
    bool Init(uint64_t size) {
        if (temp_.fd < 0) {
            return false;
        }
        if (ftruncate(temp_.fd, size) < 0) {
            PLOG(ERROR) << "ftruncate failed: " << temp_.path;
            return false;
        }
        path_ = temp_.path;
        return true;
    }

    const std::string& GetPath() override { return path_; }
    uint64_t GetSize() override {
        off_t off = lseek(temp_.fd, 0, SEEK_END);
        if (off < 0) {
            PLOG(ERROR) << "lseek failed: " << temp_.path;
            return 0;
        }
        return off;
    }

  private:
    TemporaryFile temp_;
    std::string path_;
};

std::unique_ptr<IBackingDevice> ITestHarness::CreateBackingDevice(uint64_t size) {
#ifdef __ANDROID__
    auto dev = std::make_unique<MemoryBackedDevice>();
#else
    auto dev = std::make_unique<FileBackedDevice>();
#endif
    if (!dev->Init(size)) {
        return nullptr;
    }
    return dev;
}

}  // namespace snapshot
}  // namespace android
+9 −0
Original line number Diff line number Diff line
@@ -33,6 +33,14 @@ class IUserDevice {
    virtual bool Destroy() = 0;
};

// Interface for an fd/temp file that is a block device when possible.
class IBackingDevice {
  public:
    virtual ~IBackingDevice() {}
    virtual const std::string& GetPath() = 0;
    virtual uint64_t GetSize() = 0;
};

class ITestHarness {
  public:
    virtual ~ITestHarness() {}
@@ -41,6 +49,7 @@ class ITestHarness {
                                                          uint64_t num_sectors) = 0;
    virtual IBlockServerFactory* GetBlockServerFactory() = 0;
    virtual bool HasUserDevice() = 0;
    virtual std::unique_ptr<IBackingDevice> CreateBackingDevice(uint64_t size);
};

}  // namespace snapshot
+12 −5
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

#include "handler_manager.h"

#include <pthread.h>
#include <sys/eventfd.h>

#include <android-base/logging.h>
@@ -132,6 +133,8 @@ bool SnapshotHandlerManager::DeleteHandler(const std::string& misc_name) {
void SnapshotHandlerManager::RunThread(std::shared_ptr<HandlerThread> handler) {
    LOG(INFO) << "Entering thread for handler: " << handler->misc_name();

    pthread_setname_np(pthread_self(), "Handler");

    if (!handler->snapuserd()->Start()) {
        LOG(ERROR) << " Failed to launch all worker threads";
    }
@@ -201,9 +204,8 @@ bool SnapshotHandlerManager::StartMerge(std::lock_guard<std::mutex>* proof_of_lo

    handler->snapuserd()->MonitorMerge();

    if (!is_merge_monitor_started_) {
        std::thread(&SnapshotHandlerManager::MonitorMerge, this).detach();
        is_merge_monitor_started_ = true;
    if (!merge_monitor_.joinable()) {
        merge_monitor_ = std::thread(&SnapshotHandlerManager::MonitorMerge, this);
    }

    merge_handlers_.push(handler);
@@ -220,6 +222,7 @@ void SnapshotHandlerManager::WakeupMonitorMergeThread() {
}

void SnapshotHandlerManager::MonitorMerge() {
    pthread_setname_np(pthread_self(), "Merge Monitor");
    while (!stop_monitor_merge_thread_) {
        uint64_t testVal;
        ssize_t ret =
@@ -357,8 +360,12 @@ void SnapshotHandlerManager::JoinAllThreads() {
        if (th.joinable()) th.join();
    }

    if (merge_monitor_.joinable()) {
        stop_monitor_merge_thread_ = true;
        WakeupMonitorMergeThread();

        merge_monitor_.join();
    }
}

auto SnapshotHandlerManager::FindHandler(std::lock_guard<std::mutex>* proof_of_lock,
+1 −1
Original line number Diff line number Diff line
@@ -122,9 +122,9 @@ class SnapshotHandlerManager final : public ISnapshotHandlerManager {
    std::mutex lock_;
    HandlerList dm_users_;

    bool is_merge_monitor_started_ = false;
    bool stop_monitor_merge_thread_ = false;
    int active_merge_threads_ = 0;
    std::thread merge_monitor_;
    int num_partitions_merge_complete_ = 0;
    std::queue<std::shared_ptr<HandlerThread>> merge_handlers_;
    android::base::unique_fd monitor_merge_event_fd_;
Loading