Commit 6c7d71eb authored by Ramon Nou's avatar Ramon Nou
Browse files

Start phase A replica repair hardening

parent e04c5d8c
Loading
Loading
Loading
Loading
Loading

REPLICA.md

0 → 100644
+1178 −0

File added.

Preview size limit exceeded, changes collapsed.

+7 −4
Changes for src/client/preload_context.cpp: 7 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -1604,8 +1604,10 @@ PreloadContext::enqueue_metadata_size_repairs(
        const bool append, const bool clear_inline,
        const std::vector<int8_t>& failed_copies) {
    std::lock_guard<std::mutex> lock(repair_queue_mutex_);
    const auto kind = append ? gkfs::rpc::repair_kind::deferred
                             : gkfs::rpc::repair_kind::metadata_size;
    // Append changes still use the metadata-size executor. The append flag and
    // reserved offset are stored in the task; deferred is only a queue
    // predicate sentinel and is intentionally not executable by workers.
    const auto kind = gkfs::rpc::repair_kind::metadata_size;
    const auto generation = current_repair_generation(path, kind);
    for(const auto target_copy : failed_copies) {
        gkfs::rpc::repair_task task;
@@ -1629,8 +1631,9 @@ PreloadContext::enqueue_metadata_inline_repairs(
        const std::string& path, const std::string& data, const uint64_t offset,
        const bool append, const std::vector<int8_t>& failed_copies) {
    std::lock_guard<std::mutex> lock(repair_queue_mutex_);
    const auto kind = append ? gkfs::rpc::repair_kind::deferred
                             : gkfs::rpc::repair_kind::metadata_inline;
    // Append inline writes are executable metadata-inline repairs. The append
    // flag remains part of the task payload; deferred tasks are not executable.
    const auto kind = gkfs::rpc::repair_kind::metadata_inline;
    const auto generation = current_repair_generation(path, kind);
    for(const auto target_copy : failed_copies) {
        gkfs::rpc::repair_task task;
+36 −0
Changes for tests/unit/test_repair_queue.cpp: 36 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -180,3 +180,39 @@ TEST_CASE("repair queue snapshot preserves pending tasks", "[replication][repair
    REQUIRE(snapshot.front().retry_count == 2);
    REQUIRE(snapshot.front().generation == 9);
}

TEST_CASE("repair queue keeps append metadata repairs executable",
          "[replication][repair]") {
    gkfs::rpc::repair_queue queue;
    const auto now = std::chrono::steady_clock::now();

    gkfs::rpc::repair_task size_task{"/append", 0, 0, 1, 4, 0, EIO, now};
    size_task.kind = gkfs::rpc::repair_kind::metadata_size;
    size_task.append = true;
    size_task.offset = 128;
    REQUIRE(queue.enqueue(size_task));

    gkfs::rpc::repair_task inline_task{"/append", 0, 0, 1, 5, 0, EIO, now};
    inline_task.kind = gkfs::rpc::repair_kind::metadata_inline;
    inline_task.append = true;
    inline_task.data = "payload";
    REQUIRE(queue.enqueue(inline_task));

    const auto first = queue.pop_ready(
            [](const auto& task) {
                return task.kind != gkfs::rpc::repair_kind::deferred;
            },
            now);
    REQUIRE(first);
    REQUIRE(first->append);
    REQUIRE(first->kind == gkfs::rpc::repair_kind::metadata_size);

    const auto second = queue.pop_ready(
            [](const auto& task) {
                return task.kind != gkfs::rpc::repair_kind::deferred;
            },
            now);
    REQUIRE(second);
    REQUIRE(second->append);
    REQUIRE(second->kind == gkfs::rpc::repair_kind::metadata_inline);
}
 No newline at end of file