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

Commit 9006e4ae authored by David Anderson's avatar David Anderson Committed by Automerger Merge Worker
Browse files

Merge changes Ic18443d4,I9e9af999,I10e099fe,I00cf6ec9,Ia1ea4ba7 into main am:...

Merge changes Ic18443d4,I9e9af999,I10e099fe,I00cf6ec9,Ia1ea4ba7 into main am: 7bd9162b am: fc3b1222

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



Change-Id: Id8ef968a9bdb3e9ce040afe5a25da6b5952ab8e7
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 63e0a6f2 fc3b1222
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ cc_library_static {
    ramdisk_available: true,
    vendor_ramdisk_available: true,
    recovery_available: true,
    host_supported: true,
}

cc_defaults {
@@ -222,6 +223,7 @@ cc_test {
    srcs: [
        "testing/dm_user_harness.cpp",
        "testing/harness.cpp",
        "testing/host_harness.cpp",
        "user-space-merge/snapuserd_test.cpp",
    ],
    shared_libs: [
@@ -255,4 +257,5 @@ cc_test {
    },
    auto_gen_config: true,
    require_root: false,
    host_supported: true,
}
+4 −2
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@

#pragma once

#include <linux/types.h>

namespace android {
namespace snapshot {

@@ -70,7 +72,7 @@ struct disk_header {

    /* In sectors */
    uint32_t chunk_size;
} __packed;
} __attribute__((packed));

// A disk exception is a mapping of old_chunk to new_chunk
// old_chunk is the chunk ID of a dm-snapshot device.
@@ -78,7 +80,7 @@ struct disk_header {
struct disk_exception {
    uint64_t old_chunk;
    uint64_t new_chunk;
} __packed;
} __attribute__((packed));

// Control structures to communicate with dm-user
// It comprises of header and a payload
+112 −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 "host_harness.h"

#include "snapuserd_logging.h"

namespace android {
namespace snapshot {

void TestBlockServerQueue::WaitForShutdown() {
    std::unique_lock lock(m_);
    if (shutdown_) {
        return;
    }
    cv_.wait(lock, [this]() -> bool { return shutdown_; });
}

void TestBlockServerQueue::Shutdown() {
    std::unique_lock lock(m_);
    shutdown_ = true;
    cv_.notify_all();
}

TestBlockServer::TestBlockServer(std::shared_ptr<TestBlockServerQueue> queue,
                                 const std::string& misc_name)
    : queue_(queue), misc_name_(misc_name) {}

bool TestBlockServer::ProcessRequests() {
    queue_->WaitForShutdown();
    return false;
}

void* TestBlockServer::GetResponseBuffer(size_t size, size_t to_write) {
    std::string buffer(size, '\0');
    buffered_.emplace_back(std::move(buffer), to_write);
    return buffered_.back().first.data();
}

bool TestBlockServer::SendBufferedIo() {
    for (const auto& [data, to_write] : buffered_) {
        sent_io_ += data.substr(0, to_write);
    }
    buffered_.clear();
    return true;
}

TestBlockServerOpener::TestBlockServerOpener(std::shared_ptr<TestBlockServerQueue> queue,
                                             const std::string& misc_name)
    : queue_(queue), misc_name_(misc_name) {}

std::unique_ptr<IBlockServer> TestBlockServerOpener::Open(IBlockServer::Delegate*, size_t) {
    return std::make_unique<TestBlockServer>(queue_, misc_name_);
}

std::shared_ptr<TestBlockServerOpener> TestBlockServerFactory::CreateTestOpener(
        const std::string& misc_name) {
    if (queues_.count(misc_name)) {
        LOG(ERROR) << "Cannot create opener for " << misc_name << ", already exists";
        return nullptr;
    }
    auto queue = std::make_shared<TestBlockServerQueue>();
    queues_.emplace(misc_name, queue);
    return std::make_shared<TestBlockServerOpener>(queue, misc_name);
}

std::shared_ptr<IBlockServerOpener> TestBlockServerFactory::CreateOpener(
        const std::string& misc_name) {
    return CreateTestOpener(misc_name);
}

bool TestBlockServerFactory::DeleteQueue(const std::string& misc_name) {
    auto iter = queues_.find(misc_name);
    if (iter == queues_.end()) {
        LOG(ERROR) << "Cannot delete queue " << misc_name << ", not found";
        return false;
    }
    iter->second->Shutdown();
    queues_.erase(iter);
    return true;
}

HostUserDevice::HostUserDevice(TestBlockServerFactory* factory, const std::string& misc_name)
    : factory_(factory), misc_name_(misc_name) {}

bool HostUserDevice::Destroy() {
    return factory_->DeleteQueue(misc_name_);
}

std::unique_ptr<IUserDevice> HostTestHarness::CreateUserDevice(const std::string&,
                                                               const std::string& misc_name,
                                                               uint64_t) {
    return std::make_unique<HostUserDevice>(&factory_, misc_name);
}

IBlockServerFactory* HostTestHarness::GetBlockServerFactory() {
    return &factory_;
}

}  // namespace snapshot
}  // namespace android
+105 −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.

#pragma once

#include <condition_variable>
#include <mutex>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "harness.h"

namespace android {
namespace snapshot {

class TestBlockServerQueue final {
  public:
    void WaitForShutdown();
    void Shutdown();

  private:
    std::mutex m_;
    std::condition_variable cv_;
    bool shutdown_ = false;
};

class TestBlockServer final : public IBlockServer {
  public:
    TestBlockServer(std::shared_ptr<TestBlockServerQueue> queue, const std::string& misc_name);
    bool ProcessRequests() override;
    void* GetResponseBuffer(size_t size, size_t to_write) override;
    bool SendBufferedIo() override;

    std::string&& sent_io() { return std::move(sent_io_); }

  private:
    std::shared_ptr<TestBlockServerQueue> queue_;
    std::string misc_name_;
    std::string sent_io_;
    std::vector<std::pair<std::string, size_t>> buffered_;
};

class TestBlockServerOpener final : public IBlockServerOpener {
  public:
    TestBlockServerOpener(std::shared_ptr<TestBlockServerQueue> queue,
                          const std::string& misc_name);
    std::unique_ptr<IBlockServer> Open(IBlockServer::Delegate* delegate,
                                       size_t buffer_size) override;

  private:
    std::shared_ptr<TestBlockServerQueue> queue_;
    std::string misc_name_;
};

class TestBlockServerFactory final : public IBlockServerFactory {
  public:
    std::shared_ptr<IBlockServerOpener> CreateOpener(const std::string& misc_name) override;
    std::shared_ptr<TestBlockServerOpener> CreateTestOpener(const std::string& misc_name);
    bool DeleteQueue(const std::string& misc_name);

  private:
    std::unordered_map<std::string, std::shared_ptr<TestBlockServerQueue>> queues_;
};

class TestBlockServerFactory;

class HostUserDevice final : public IUserDevice {
  public:
    HostUserDevice(TestBlockServerFactory* factory, const std::string& misc_name);
    const std::string& GetPath() override { return empty_path_; }
    bool Destroy();

  private:
    TestBlockServerFactory* factory_;
    std::string misc_name_;
    std::string empty_path_;
};

class HostTestHarness final : public ITestHarness {
  public:
    std::unique_ptr<IUserDevice> CreateUserDevice(const std::string& dev_name,
                                                  const std::string& misc_name,
                                                  uint64_t num_sectors) override;
    IBlockServerFactory* GetBlockServerFactory() override;
    bool HasUserDevice() override { return false; }

  private:
    TestBlockServerFactory factory_;
};

}  // namespace snapshot
}  // namespace android
+3 −1
Original line number Diff line number Diff line
@@ -33,9 +33,11 @@ class ReadWorker : public Worker, public IBlockServer::Delegate {
    bool Run();
    bool Init() override;
    void CloseFds() override;
    bool RequestSectors(uint64_t sector, uint64_t size) override;

    IBlockServer* block_server() const { return block_server_.get(); }

  private:
    bool RequestSectors(uint64_t sector, uint64_t size) override;
    bool SendBufferedIo();

    bool ProcessCowOp(const CowOperation* cow_op, void* buffer);
Loading