diskreserve

package
v0.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package diskreserve holds back a little of a project's disk for the writes that record what a run did (Task 20381).

A run learns its disk is full when a write fails. The orchestrator checks free space before every task attempt (orchestrator.min_free_disk_mb), but a check is a prediction: a task's own build, a neighbour's test run filling /tmp, or another project on the same volume can take the last megabyte between the check and the moment the task's outcome is stored. The write that fails then is the worst one to lose — the verdict sidecar and the outcome row are what stale-task recovery reads, and with both gone it falls back to the agent's own TASK_DONE (pkg/taskrecover).

So each project keeps .cloop/reserve: Size bytes of preallocated blocks that nothing reads. When one of those critical writes fails for want of space, the orchestrator deletes the reserve and tries the write again. The space it frees is on the volume that refused the write, because the reserve lives in the same .cloop directory as state.db and the verdicts. Then the run pauses until there is room again, and the next check that passes puts the reserve back.

The file is blocks, not a sparse length: Ensure allocates it with fallocate(2) where the filesystem supports it and otherwise writes it out, with random bytes so that a compressing or deduplicating filesystem cannot store it as nothing. A reserve that held no blocks would free nothing.

It is not data. Snapshots skip it and restores leave it alone, `cloop compact` and the janitor never touch it, and pkg/diskusage does not count it — 16 MiB of placeholder in every snapshot, or reported as part of what .cloop costs, would be noise in exactly the tools an operator reads when the disk is full.

The package depends on the standard library alone, so every walker of .cloop can name the file without importing anything heavier.

Index

Constants

View Source
const (
	// Name is the reserve's file name inside a project's .cloop directory.
	Name = "reserve"

	// Size is how much the reserve holds back: 16 MiB. Enough for a verdict
	// sidecar (a few KiB), the state write of one task's outcome and a WAL
	// checkpoint of a busy state.db, with a wide margin; small enough that no
	// operator misses it on a volume worth running a hub on.
	Size int64 = 16 << 20
)

Variables

View Source
var ErrNoRoom = errors.New("diskreserve: not enough free space to create the reserve")

ErrNoRoom reports that the reserve could not be created because its volume does not have room for it. Not a fault: the next check that finds space creates it.

Functions

func Ensure

func Ensure(workDir string) (created bool, err error)

Ensure makes sure the project's reserve exists and holds Size bytes of allocated blocks. It reports whether it created (or re-created) the file.

An existing reserve of the right size is left alone, so calling this before every task attempt costs a stat. One that is short — a crash between create and rename cannot leave one, but a hand-made file can — is replaced.

The file is built under a temporary name and renamed into place, so a disk that fills while it is written never leaves a half-sized reserve that claims to be whole; the temporary is removed. A volume with less than twice Size free is not asked for it: ErrNoRoom, and nothing is written.

func Held

func Held(workDir string) int64

Held returns how many bytes the reserve currently holds on disk: its allocated blocks, which is what deleting it frees. Zero when it is absent.

func IsDiskFull

func IsDiskFull(err error) bool

IsDiskFull reports whether err says a write ran out of room: ENOSPC from the kernel, a disk quota, or SQLite's SQLITE_FULL ("database or disk is full"), which is how a state.db write reports the same condition.

The message is checked as well as the error chain because several layers between a write and its caller wrap with %v, and losing the errno there must not turn a full disk into an unexplained write failure.

func IsName

func IsName(name string) bool

IsName reports whether a top-level entry of a .cloop directory is the reserve. Walkers that enumerate .cloop use it to leave the file out.

func Path

func Path(workDir string) string

Path returns the reserve's path for the project rooted at workDir.

func Release

func Release(workDir string) (freed int64, err error)

Release deletes the project's reserve and returns the bytes it held, so a write that just failed for want of space can be tried again. Releasing a reserve that is not there frees nothing and is not an error: two writes that fail in the same moment both release, and the second finds it gone.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL