flexblock start
Synopsis
Section titled “Synopsis”flexblock start <DEVICE> [flags]Description
Section titled “Description”start runs the preflight checks, recovers the cache if needed, rebuilds the object index, brings up /dev/ublkbN and serves until interrupted with SIGINT, SIGTERM or SIGHUP. It needs root.
start is also the crash-recovery command. After a daemon crash, run it again before touching anything mounted on the device: until a daemon takes over, umount hangs and cannot be killed, and starting the daemon drains it. There is no separate recover command.
start does not need a current grant. With an expired or non-covering grant it serves throttled.
Serving flags
Section titled “Serving flags”| Flag | Default | Description |
|---|---|---|
--allow-overmemory | — | Start even when the memory reserved at start exceeds half of available memory. |
--cpu-idle-latency <US|off> | 1 | Deepest CPU idle state allowed while serving, as an exit latency in microseconds, at most 1000000. 1 allows only C1. off or 0 leaves the platform policy alone. |
--dry-run | — | Run every check short of serving, print the banner, exit. |
--metrics-port <PORT> | off | Prometheus text endpoint on 0.0.0.0:<PORT>/metrics, unauthenticated. |
--no-fua | — | Sync WAL, superblock and chunk data writes with fdatasync instead of RWF_DSYNC; do not advertise FUA to the guest. |
--no-queue-pinning | — | Do not pin queue threads to physical cores. |
--no-zero-copy | — | Copy request data through daemon buffers instead of registering the kernel’s pages per request. Zero copy needs Linux 6.16 and is the default where available. |
--nr-queues <N> | one per physical core | ublk I/O queues, 1 to 16. |
--queue-depth <N|auto> | auto | io_uring depth per queue, 1 to 4096. auto is 64 for 1 MiB chunks and 32 above. |
--read-ahead <SIZE> | 32M | Kernel read-ahead for the exported device, a whole number of KiB and of logical blocks, up to 64M. 0 disables. |
--replace-ublk | — | Delete a stale ublk device and attach fresh instead of recovering it, forfeiting the reissue of in-flight requests. |
--ublk-dev-id <N> | reuse or auto-assign | Use /dev/ublkbN. Omit to reuse the recorded id or let the kernel assign one. |
--volatile-write-cache | — | Advertise a volatile write cache and sync on FLUSH, for a cache device with one. |
CPU idle latency
Section titled “CPU idle latency”Every request crosses several thread wakeups (application, kernel, queue thread, NVMe completion), and a core parked in a deep C-state adds its exit latency, 170 to 290 µs for C6 on current Xeons, to each one. Under light or synchronous load that multiplies: a single-threaded fsync-per-file workload ran six times slower with the kernel default than with the cap, and the same cap also speeds up the raw NVMe device.
The cap is held through /dev/cpu_dma_latency and applies host-wide while the daemon runs; it is released on exit. A host that cannot open /dev/cpu_dma_latency (no root, or a container without the device) logs a warning and serves without it.
Cache tuning flags
Section titled “Cache tuning flags”| Flag | Default | Description |
|---|---|---|
--a1in-ratio <R> | 0.25 | Fraction of slots for the probationary A1in tier, in (0.05, 0.50]. |
--a1out-multiple <M> | 0.5 | Ghost-list size as a multiple of slots, in [0.5, 64]; twoq-meta only. |
--cache-io-mode <direct|buffered> | direct | Whether cache I/O bypasses the page cache. |
--cache-policy <lru|twoq-meta> | twoq-meta | Replacement policy. 2Q admits new chunks to a probationary A1in queue, and metadata and chunks back from the A1out ghost list of evicted identities to Am. |
--concurrent-compressions <N> | physical cores, 2 to 32 | Chunks compressed at once during flush, plus a WAL-head reserve. |
--concurrent-deletes <N> | 4 × vCPUs, 8 to 256 | Concurrent DELETE batches. |
--concurrent-downloads <N> | 4 × vCPUs, 8 to 128 | Concurrent GETs for misses and prefetch. |
--concurrent-flush-reads <N> | 24 | Flush reads and fetches at once, plus a WAL-head reserve; boosted with uploads. |
--concurrent-uploads <N> | 4 × vCPUs, 8 to 64 | Concurrent PUTs; up to 4× under pressure. |
--flush-interval <D> | 5s | Flush loop wake interval. |
--flush-quiet <D> | 5s, or half of --flush-threshold in whole seconds if shorter | Skip the age-based flush of a chunk written this recently, but not past twice --flush-threshold. 0s disables. Must be shorter than --flush-threshold. |
--flush-threshold <D> | 4m | Age at which a dirty chunk is flushed. |
--max-dirty-ratio <R> | 0.8 | Above this, flush hard and pace new chunks. In (0, 1]. |
--obj-rate-limit <RPS> | unlimited | Cap on object storage GET and PUT requests per second, any positive number; WAL-head flushes are exempt. |
--read-prefetch <N|off> | 32 | Largest window of chunks to hydrate ahead of a sequential cold read, at most 64; each is one chunk of speculative download. |
--retry-cutoff <D> | 24h | How long to keep retrying a failing object storage operation. |
--shutdown-flush-timeout <D> | 1h | Time budget for flushing and discard deletes on SIGINT, SIGTERM or SIGHUP. |
--target-dirty-ratio <R> | 0.6 | Stop flushing hard and pacing below this. In (0, 1), below --max-dirty-ratio. |
The --concurrent-* flags accept any value from 1 to 4096; the ranges in the Default column describe how the default is derived from the host. See Write-Back Behavior, Cache Replacement Policy and Memory before changing them.
Examples
Section titled “Examples”Serve with a stable device path and metrics enabled:
sudo flexblock start /dev/nvme1n1p1 --ublk-dev-id 0 --metrics-port 10056Recover after a crash (recovery is automatic):
sudo flexblock start /dev/nvme1n1p1Check every prerequisite and print the banner without serving:
sudo flexblock start /dev/nvme1n1p1 --dry-runStop cleanly: unmount first, then interrupt the daemon:
sudo umount /mnt/analyticssudo kill -INT "$(pidof flexblock)"