Loading README.md +4 −0 Changes for README.md: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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, Loading docs/sphinx/users/running.md +2 −0 Changes for docs/sphinx/users/running.md: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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` Loading src/daemon/malleability/malleable_manager.cpp +13 −0 Changes for src/daemon/malleability/malleable_manager.cpp: 13 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 { Loading tests/unit/test_replica_migration_adapter.cpp +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 Loading @@ -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 Loading
README.md +4 −0 Changes for README.md: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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, Loading
docs/sphinx/users/running.md +2 −0 Changes for docs/sphinx/users/running.md: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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` Loading
src/daemon/malleability/malleable_manager.cpp +13 −0 Changes for src/daemon/malleability/malleable_manager.cpp: 13 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 { Loading
tests/unit/test_replica_migration_adapter.cpp +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 Loading @@ -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