| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
…ush()` to ensure safe indexing during host archival Ensure that chart indexes remain allocated for ongoing queries during archiving by introducing `rrdset_index_flush()` and delaying index destruction to `rrdhost_free_unlinked()`. Prevent potential null dereference by guarding index availability in `rrdset_find_and_acquire()`.
|
Sorry, something went wrong.
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Confidence score: 5/5
sequenceDiagram
participant Q as Query Consumer
participant RR as rrdset_find_and_acquire()
participant H as RRDHOST
participant IDX as rrdset_index (id + name)
participant SVC as service.c (archive)
participant FREE as rrdhost_free_unlinked()
Note over Q,FREE: Host lifecycle: archived → queries → free
SVC->>H: archive host (orphan→archived)
H->>H: rrdhost_cleanup_data_collection_and_health()
H->>IDX: rrdset_index_flush()
Note over IDX: Flush name index first, then id index<br/>Indexes remain allocated, host pointers valid
IDX-->>H: indexes emptied but alive
par In-flight query before archive
Q->>RR: find chart by id
RR->>H: check host->rrdset_root_index
alt Index allocated (normal)
RR->>IDX: dictionary_get() (locked)
IDX-->>RR: chart reference
RR-->>Q: acquired chart
else Index NULL (defense-in-depth)
RR-->>Q: NULL (race with free_unlinked)
end
and Query continues during/after archive
Q->>RR: Release acquired chart
RR->>IDX: rrdset_acquired_release()
Note over IDX: dict still valid, decrements refcount<br/>Chart freed when last ref drains
IDX-->>RR: released OK
and New query after archive
Q->>RR: find chart by id
RR->>IDX: dictionary_get() (locked)
Note over IDX: Dictionary is empty, flush already ran
IDX-->>RR: NULL
RR-->>Q: NULL (chart not found)
end
Note over H,FREE: Host eventually unlinked (no new queries can reach it)
FREE->>H: rrdhost_free_unlinked()
H->>IDX: rrdset_index_destroy()
Note over IDX: Now safe to free the dictionaries<br/>No in-flight queries hold acquired charts
IDX-->>H: indexes freed
H->>H: free remaining host resources
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Sorry, something went wrong.
…etdata#23074) fix(database): replace `rrdset_index_destroy()` with `rrdset_index_flush()` to ensure safe indexing during host archival Ensure that chart indexes remain allocated for ongoing queries during archiving by introducing `rrdset_index_flush()` and delaying index destruction to `rrdhost_free_unlinked()`. Prevent potential null dereference by guarding index availability in `rrdset_find_and_acquire()`.
…23074) fix(database): replace `rrdset_index_destroy()` with `rrdset_index_flush()` to ensure safe indexing during host archival Ensure that chart indexes remain allocated for ongoing queries during archiving by introducing `rrdset_index_flush()` and delaying index destruction to `rrdhost_free_unlinked()`. Prevent potential null dereference by guarding index availability in `rrdset_find_and_acquire()`.
| Back | FazBrowse Home | New Git URL |
Summary
Follow-up to #23056, which guarded the lookup side of the same problem.
The orphan→archived transition destroys the host's rrdset indexes and nulls
the pointers while queries may still be in flight, leaving two windows:
dictionary_destroy() defers destruction (referenced items), but
rrdset_index_destroy() nulls host->rrdset_root_index anyway, so
rrdset_acquired_release() dereferences NULL. Every data query holds
acquired charts for its full duration (query_target.c), so on parents
archiving hosts under constant query load this eventually fires.
the pointer check and its use, and nothing holds a reference, the dict is
freed immediately and the lookup calls into freed memory.
Fix: on archive, flush the indexes (name view first, then the id index) but
keep them allocated — lookups return NULL naturally, releases always see a
valid dictionary, and a lookup racing with the archive now races with a
normal locked flush instead of destruction. The indexes are destroyed only in
rrdhost_free_unlinked(), after the host is unlinked and unreachable.
Semantics are unchanged: flush is exactly what dictionary_destroy() already
did internally when deferring, so charts held by queries are still freed when
the last reference drains. Host reactivation (archived→live) now reuses the
surviving index instead of recreating it (rrdhost.c already guards init
with if (!host->rrdset_root_index)).
Summary by cubic
Prevent crashes during host archival by flushing RRD set indexes instead of destroying them. This removes a null-deref and TOCTOU window for in-flight queries and lets reactivated hosts reuse the same indexes.
Written for commit 7efe32c. Summary will update on new commits.