Documentation
¶
Overview ¶
Package gc owns the agent's eviction work: the lingering-ghost sweep (this file) and pressure-relief eviction (pressure.go).
Deleted metadata lingers so a dying VM's FIN/RST packets still classify. The sweep then deletes kernel-first, then userspace, which preserves the kernel ⊆ userspace subset at every instant.
docs/architecture/data-structures.md#map-lifecycle-invariants
Index ¶
- type FlowEvictor
- type FlowSettler
- type GhostSweeper
- type MacEvictor
- type MacFlowEvictor
- type MapGauge
- type Metrics
- func (m *Metrics) Collectors() []prometheus.Collector
- func (m *Metrics) IncPressureReliefRuns()
- func (m *Metrics) RecordPressureReliefEvictions(n int)
- func (m *Metrics) RecordResidualFlowEvictions(n int)
- func (m *Metrics) RecordSettledFlows(n int)
- func (m *Metrics) RecordTTLEvictions(n int)
- func (m *Metrics) SetGhostsActive(n int)
- type Options
- type PressureOptions
- type PressureReliever
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type FlowEvictor ¶
FlowEvictor deletes a flow entry from the kernel telemetry_map. Like MacEvictor it is the consumer-defined seam over a kernel map: the agent wires a *ebpf.Map adapter, tests wire a mock. Delete must be idempotent on a key that is already gone.
type FlowSettler ¶
type FlowSettler interface {
Settle(mode state.SettleMode, resolve func(bpf.FlowKey) (tenant, extNet, server string, ok bool)) int
}
FlowSettler folds flow rows into the settled-bytes accumulator. The sweep calls it at the last moment the MAC still resolves to its tenant, so the VM's lifetime bytes stay attributed. nil skips settling.
docs/architecture/data-structures.md#settled-bytes
type GhostSweeper ¶
type GhostSweeper struct {
// contains filtered or unexported fields
}
GhostSweeper periodically drops metadata entries whose 60s grace window has elapsed. Construct with New, then run GhostSweeper.Run on a long-lived goroutine.
func (*GhostSweeper) Run ¶
func (g *GhostSweeper) Run(ctx context.Context)
Run sweeps expired ghosts every interval until ctx is cancelled. It first blocks on boot.PhaseStateRestored so no eviction races the boot sequence; if the boot aborts (or ctx is cancelled) before that phase, Run returns without sweeping. There is no immediate first sweep: metadata is freshly populated at boot and ghosts need a full grace window to expire, so the first sweep fires one interval in.
type MacEvictor ¶
MacEvictor deletes a MAC entry from the kernel mac_tenant_map. It is the consumer-defined seam over the kernel map: the agent wires a thin *ebpf.Map adapter, and tests wire a recording mock. Delete must be idempotent — a MAC already gone from the kernel is not an error.
type MacFlowEvictor ¶
MacFlowEvictor deletes a swept VM's residual telemetry_map counters, which outlive its MAC and would otherwise re-drain as "unknown". nil skips cleanup; best-effort, so a failure just means one flow may fold to unknown once.
docs/architecture/data-structures.md#lingering-ghost
type MapGauge ¶
MapGauge refreshes the kernel mac_tenant_map current-entry gauge after the sweep deletes ghosts — cold-start sets it once, so without this it over-reports fill until the next reconcile. Consumer-defined seam; *bpf.Metrics satisfies it.
type Metrics ¶
type Metrics struct {
// contains filtered or unexported fields
}
Metrics holds the Prometheus instruments for the GC subsystem. The bundle owns both halves of the GC: the lingering-ghost sweep (this package's GhostSweeper) and pressure-relief eviction (run inside the scraper's drain goroutine, which holds a reference to this bundle). Keeping the lachesis_gc_evictions_total family in one place — rather than splitting it across two packages — means Prometheus registers each series once and the reason label is seeded whole.
The instruments are:
- lachesis_gc_evictions_total{reason} counter
- lachesis_gc_pressure_relief_runs_total counter
- lachesis_gc_settled_flows_total counter
- lachesis_lingering_ghosts_active gauge
func NewMetrics ¶
func NewMetrics() *Metrics
NewMetrics constructs the bundle with both eviction reasons seeded at zero so lachesis_gc_evictions_total{reason="ttl"} and {reason="pressure_relief"} both exist before either path first fires.
func (*Metrics) Collectors ¶
func (m *Metrics) Collectors() []prometheus.Collector
Collectors returns the underlying prometheus.Collector values for registration by the agent.
func (*Metrics) IncPressureReliefRuns ¶
func (m *Metrics) IncPressureReliefRuns()
IncPressureReliefRuns increments lachesis_gc_pressure_relief_runs_total by one — call once per pressure-relief pass.
func (*Metrics) RecordPressureReliefEvictions ¶
RecordPressureReliefEvictions adds n telemetry_map evictions to lachesis_gc_evictions_total{reason="pressure_relief"}.
func (*Metrics) RecordResidualFlowEvictions ¶
RecordResidualFlowEvictions adds n telemetry_map flows deleted because their VM's MAC was swept, to lachesis_gc_evictions_total{reason="ghost_residual_flow"}.
func (*Metrics) RecordSettledFlows ¶
RecordSettledFlows adds n folded GlobalState rows to lachesis_gc_settled_flows_total.
func (*Metrics) RecordTTLEvictions ¶
RecordTTLEvictions adds n lingering-ghost expiries to lachesis_gc_evictions_total{reason="ttl"}.
func (*Metrics) SetGhostsActive ¶
SetGhostsActive sets lachesis_lingering_ghosts_active to the number of entries still inside their grace window after a sweep.
type Options ¶
type Options struct {
Meta *metadata.ShardedMetadataMap
Evictor MacEvictor
FlowEvictor MacFlowEvictor
// Settler folds swept MACs' flow rows into the settled-bytes
// accumulator before their metadata (the tenant binding) is
// deleted. The agent wires its *state.GlobalState.
Settler FlowSettler
// Routers resolves each folded row's per-flow external_network
// label ([metadata.FlowExternalLabel]) so the fold lands in exactly
// the series the Collector was emitting. Optional (nil = per-VM
// fallback only — pre-per-flow unit tests).
Routers *metadata.RouterMACs
// Tunables supplies the live sweep cadence (hot-reload; applies at
// the next tick). REQUIRED — operational knobs have exactly one
// source; unit tests construct a store with the values they
// exercise.
Tunables *tunables.Store
// MapGauge refreshes the mac_tenant_map fill gauge after a sweep.
// Optional (nil skips); the agent wires its bpf metrics bundle.
MapGauge MapGauge
Seq *boot.Sequencer
Metrics *Metrics
}
Options bundles the inputs to New. Meta, Evictor, and Metrics are required; FlowEvictor is optional (nil skips residual-flow cleanup — used by tests without a kernel telemetry_map); Settler is optional (nil skips the settled-bytes fold — pre-fold unit tests); Seq is optional (nil skips the boot barrier — used by sweep-only unit tests); the sweep cadence is the live gc.ghost_sweep_interval tunable.
type PressureOptions ¶
type PressureOptions struct {
Evictor FlowEvictor
MaxEntries int
Metrics *Metrics
Tunables *tunables.Store
}
PressureOptions bundles the inputs to NewPressureReliever. All fields are required; MaxEntries must be positive (it is the fill-ratio denominator). The tuning values come from the shared tunables snapshot, validated at load/reload by config.GCConfig.
type PressureReliever ¶
type PressureReliever struct {
// contains filtered or unexported fields
}
PressureReliever evicts the oldest telemetry_map entries before the map fills, so the kernel never drops a counter on its own. It runs in the scraper's drain goroutine AFTER the readings are applied, so every evicted entry's bytes are already accounted ("flush before evict").
High/low watermark hysteresis with a per-pass cap: the map drains over a few scrapes rather than one long stall. All three bounds are hot-reloadable.
docs/architecture/data-structures.md#kernel-side-bpf-maps
func NewPressureReliever ¶
func NewPressureReliever(opts PressureOptions) *PressureReliever
NewPressureReliever constructs a reliever. MaxEntries is the kernel telemetry_map's compiled-in capacity (bpf.MapTelemetryMaxEntries).
func (*PressureReliever) Relieve ¶
func (p *PressureReliever) Relieve(drained map[bpf.FlowKey]bpf.FlowMetrics)
Relieve runs one pass over the just-drained readings, which are already in GlobalState. drained is read-only here: its key count IS the kernel population (read-don't-clear) and LastSeenNs is the eviction key. No-op outside a relief cycle.