Commit d5b9804d authored by Ramon Nou's avatar Ramon Nou
Browse files

Reject replica migration without source-copy reads

parent e3fcdf1e
Loading
Loading
Loading
Loading
Loading
+4 −0
Changes for README.md: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1048,6 +1048,10 @@ Client-metrics require the CMake argument `-DGKFS_ENABLE_CLIENT_METRICS=ON` (see
- `LIBGKFS_NUM_REPL` - Number of replicas for data.
- Mutation/redistribution is rejected while `LIBGKFS_NUM_REPL` is nonzero until
  replica-aware placement and recovery are implemented.
- The migration planner and recovery state track replica copy indices and
  placement generations, but the live daemon executor still rejects
  replica-tagged migration jobs until it has an explicit remote source-copy
  read path.
- `LIBGKFS_REPAIR_STATUS_PATH` - Optional path for client-local repair counters and queue status.
- `LIBGKFS_REPAIR_JOURNAL_PATH` - Optional path for client-local pending repair tasks. The journal is
  single-owner: do not share it between client processes. Its `.lock` sidecar records the owning host,
+2 −0
Changes for docs/sphinx/users/running.md: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -370,6 +370,8 @@ set up for each client independently.

Mutation and redistribution are currently rejected while replication is enabled;
replica-aware placement during topology changes is not yet supported.
The internal planner tracks copy indices and placement generations, but live
replica migration remains disabled until daemon-side source-copy reads exist.

For client-local repair recovery, set `LIBGKFS_REPAIR_JOURNAL_PATH` to a writable
journal path. One client process owns a journal at a time. The adjacent `.lock`
+13 −0
Changes for src/daemon/malleability/malleable_manager.cpp: 13 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@

#include <daemon/malleability/malleable_manager.hpp>
#include <daemon/malleability/migration_checkpoint.hpp>
#include <common/rpc/replica_migration_adapter.hpp>
#include <daemon/malleability/rpc/forward_redistribution.hpp>
#include <daemon/backend/metadata/db.hpp>
#include <daemon/backend/data/chunk_storage.hpp>
@@ -677,6 +678,18 @@ MalleableManager::redistribute_metadata() {

int
MalleableManager::do_migration(gkfs::rpc::MigrationJob& job) {
    // The current daemon migration path reads only its local primary chunk
    // storage. Do not let a replica-tagged job silently use that path: it must
    // first gain an explicit source-copy read operation.
    if(gkfs::rpc::is_replica_migration_job(job)) {
        GKFS_DATA->spdlogger()->warn(
                "{}() Replica migration requires a source-copy read path; "
                "rejecting path '{}' chunk {} copy {} -> {}",
                __func__, job.path, job.chunk_id, job.source_copy,
                job.target_copy);
        return -ENOTSUP;
    }

    // Read chunk data from local storage
    std::string chunk_path;
    try {
+8 −0
Changes for tests/unit/test_replica_migration_adapter.cpp: 8 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -48,3 +48,11 @@ TEST_CASE("primary migration jobs remain non-replica jobs",
    const gkfs::rpc::MigrationJob job{"/file", 0, 1, 2};
    REQUIRE_FALSE(gkfs::rpc::is_replica_migration_job(job));
}

TEST_CASE("replica migration jobs are distinguishable before daemon I/O",
          "[replication][mutation]") {
    gkfs::rpc::MigrationJob job{"/file", 0, 1, 2};
    job.source_copy = 1;
    job.target_copy = 0;
    REQUIRE(gkfs::rpc::is_replica_migration_job(job));
}
 No newline at end of file