- Added copy-indexed migration plans with generation validation, source-copy reads, Simple Hash and Random Slicing topology mutation support, checkpoint recovery, and daemon-loss/restart integration coverage.
- Malleability and distribution improvements ([!320](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/320))
- Added blocking `mutate sync` and explicit `expand`/`shrink` commands, with hostfile validation, status polling, and finalize after successful redistribution.
- Added optional storage-calibrated Random Slicing weights, calibration statistics in the hostfile, and startup readiness checks.
- Corrected old/new host ordering and ownership during mutation, including shrink metadata migration; retried legacy directory RPCs after `ENOBUFS`.
- Added `GKFS_DAEMON_MIGRATION_PARALLELISM` (default `1`, range `1`–`32`) for bounded parallel eager chunk migration per daemon, with completion-safe progress and checkpoint accounting.
- Added mutation integration coverage for serial, parallel, and invalid worker settings, including data integrity, checkpoints, and daemon selection logs.
Changes for README.md: 67 added lines, 5 removed lines.
Original line number
Diff line number
Diff line
@@ -514,7 +514,31 @@ GekkoFS supports changing the daemon topology while preserving existing data and
During redistribution, applications must not access the mounted GekkoFS file system. If the GekkoFS proxy is used, proxies must be restarted manually after the topology change.
To build the control tool, configure with `-DGKFS_BUILD_TOOLS=ON`. This builds `gkfs_malleability`. The control tool reads the marker hostfile directly; it does not need separate expand or shrink hostfiles and it does not start daemons. The `scripts/run/gkfs` wrapper uses the same model: prepare one workspace hostfile with `+` and `-` markers, make sure added daemons are already running, then run `scripts/run/gkfs mutate` to call `gkfs_malleability mutate start/status/finalize` and let finalize clean the workspace hostfile.
To build the control tool, configure with `-DGKFS_BUILD_TOOLS=ON`. This builds `gkfs_malleability`. It supports three workflows:
1.**Marker-based asynchronous workflow:** use `mutate start`, `mutate status`, and `mutate finalize`. Mark removals with `-`; for additions, start the new daemons with `GKFS_DAEMON_EXPAND=ON` so they publish `+` entries. The caller controls when to poll and finalize.
2.**Marker-based synchronous workflow:** prepare the same `+`/`-` markers, then run `mutate sync`. It performs the start, waits for redistribution, and finalizes before returning.
3.**Explicit synchronous workflow:** use `expand <host...>` / `shrink <host...>`. Start all current and target daemons normally and ensure their entries are in the same hostfile. Do not add `+` or `-` markers manually and do not set `GKFS_DAEMON_EXPAND`; the command writes the needed marker internally, runs redistribution, and finalizes synchronously.
For all workflows, set `GKFS_DAEMON_KEEP_HOSTS_FILE=ON` on daemons that may stop, so shutdown preserves the shared hostfile through finalization.
The `scripts/run/gkfs mutate` wrapper uses the asynchronous marker workflow. It does not start daemons.
Examples of the explicit synchronous commands:
```bash
gkfs_malleability expand node3 node4
gkfs_malleability shrink node1 node2
```
All daemons, including expansion targets, must already be running and
registered in the shared hostfile, and `GKFS_DAEMON_KEEP_HOSTS_FILE=ON` must
preserve that file during daemon shutdown. Host-list commands do not require
`GKFS_DAEMON_EXPAND=ON` or manually authored markers. Hostnames without
rootdir suffixes work only when they identify one entry unambiguously; an RPC
URI can identify a daemon on a shared host. Each command runs redistribution
and finalization synchronously. If redistribution fails, the markers remain
for diagnosis or retry. A shrink must leave at least one daemon active.
The clients can be restarted, or the user can sent to them a signal (SIGUSR1) to force a reload of the hostfile.
@@ -525,7 +549,7 @@ Malleability uses one workspace hostfile. Entries in this file are the source of
| Line form | Meaning |
|---|---|
| `node uri ...` | active daemon |
| `+node uri ...` | daemon being added; new daemons write this automatically when started with `GKFS_DAEMON_EXPAND=ON` |
| `+node uri ...` | daemon being added; the synchronous `expand` command writes this marker |
| `-node uri ...` | daemon being removed |
| `# GKFS_RS_INTERVAL host=<id> start=<x> end=<y>` | Random Slicing interval-table comment; ignored by normal hostfile parsing but loaded by Random Slicing clients/daemons |
| `# GKFS_RS_LAYOUT version=1 hash=<hash>` | Versioned canonical hash for the adjacent Random Slicing interval table; a present record must match before clients/daemons install the table |
@@ -627,6 +651,27 @@ wait_for_mutate() {
#### Expand: add daemon nodes
To allow concurrent eager chunk transfers, set the daemon environment **before
launching both existing and new daemons** (not just on the `gkfs_malleability`
CLI):
```bash
export GKFS_DAEMON_MIGRATION_PARALLELISM=4
```
This permits up to four simultaneous chunk migration jobs **per daemon** during
`mutate start`. The default is `1` (serial); supported values are `1` through
`32`. It applies to primary and replicated chunk transfers, not metadata
redistribution or `GKFS_EXPAND_ON_DEMAND=ON` lazy reads. More workers may use
more memory and overload receiving daemons; compare mutation time and
-`GKFS_DAEMON_ENABLE_PROMETHEUS` - Enable Prometheus output and general operation-stat collection when compiled with `GKFS_ENABLE_PROMETHEUS` (default: OFF).
@@ -978,9 +1037,12 @@ Environment variable prefixes are scoped by component:
-`GKFS_DAEMON_STATS_FILE` - Write periodic statistics to this file.
-`GKFS_DAEMON_STATS_LOG` - Write periodic statistics to the configured daemon log file (default: OFF).
-`GKFS_DAEMON_MIGRATION_PARALLELISM` - Maximum concurrent chunk migration jobs per daemon during eager mutation (integer 1–32; default: 1). Applies to primary and replicated chunk transfers, not metadata redistribution. Each worker can hold a chunk buffer; increase carefully to avoid overloading destinations. Invalid values fall back to 1.
These variables are read once during daemon startup. They add no statistics
collection overhead when unset. Existing command-line options remain supported.
Set daemon environment variables before launching daemons. Metrics settings
are read during startup; migration parallelism is read when eager chunk
redistribution starts. Unset metrics settings add no statistics collection