4 Commits
Author SHA1 Message Date
TheWitness fcfd944a4a docs: enshrine script/process lifecycle design principles (#630)
## What
Adds a *Script and process execution design principles (do not regress)*
section to `.github/instructions/instructions.md` codifying three
invariants for script and PHP Script Server execution:

1. One read attempt per command, no looping to EOF.
2. Never block the polling thread in `waitpid()` — single non-blocking
WNOHANG attempt, then hand off to the async abandoned-pid sweep.
3. Script timeouts must go through `nft_popen()`/`nft_pchild()`
(pid-tracked), not a native `popen()`/`pclose()` fallback.

## Why
While investigating a reported poller slowdown, these three invariants
were each found violated: #614 turned `nft_pclose()` into a
bounded-but-blocking spin/sleep/SIGTERM/SIGKILL sequence on the polling
hot path, and 1.2.x's `nft_pclose()` has an unbounded blocking
`waitpid()` there. Writing this down so future AI-assisted changes don't
reintroduce either. Tracked in #632.

## What was tested
Docs-only change; no build/test impact.

Signed-off-by: TheWitness <thewitness@cacti.net>
2026-09-24 09:40:52 -05:00
TheWitness 4544dcab2d Fix a batch of unaddressed bugs (#594, #600, #605, #607, #575, #583, #580) (#627)
## Summary

A batch of small, independent, unaddressed bugs from the open-issue
backlog. None of these overlapped with any currently open PR's actual
diff (verified by inspecting each candidate PR's changes directly, not
just its declared `Closes` list).

## Fixes

- **`poll_host()` skips `mysql_thread_end()` when the device row is
missing** — the early `return` on `num_rows != 1` released both DB
connections and freed six allocations, but never called
`mysql_thread_end()`, unlike the other two exit paths. Added the missing
call.
- **SNMPv3 passphrase scrubbing flag never set** — `zero_sensitive` was
a function-local initialized to 0 and never assigned, so every guarded
`memset()` was dead code. Made scrubbing of this module's own heap
copies (`Apsz`/`Xpsz`) unconditional, and moved the wipe to immediately
precede each free (including both `generate_Ku()` error paths) after
review found the first pass still scrubbed before assignment. Left the
caller's `snmp_password`/`snmp_priv_passphrase` alone rather than also
scrubbing those in place — those are `host_t`-owned and get reused for
later session rebuilds against the same host, so zeroing them would have
broken subsequent polls.
- **`php_readpipe()` FD_SET without an FD_SETSIZE check** — `FD_SET()`
doesn't range-check, so a read descriptor at or above `FD_SETSIZE` (1024
on glibc) wrote past the end of the on-stack `fd_set`. Added a bounds
check; on an out-of-range descriptor it marks the result undefined and
closes the slot (a review finding caught the first version recursing
without bound through `php_init()` → `php_readpipe()` under sustained
descriptor exhaustion, so it no longer restarts synchronously from
here).
- **Signal handler never re-arms, so the second SIGPIPE kills the
poller** — every fatal signal reset itself to `SIG_DFL` and never
re-armed. That's the right idiom for a real fault (SIGSEGV and friends
re-execute and die with a core), but SIGPIPE is a routine, recurring
condition — a second one previously killed the whole poller. A review
finding pointed out that re-arming only at the end still left a window
(signal dispositions are process-wide) where another thread's SIGPIPE
could hit `SIG_DFL`; fixed by never resetting SIGPIPE's disposition in
the first place.
- **spine fails to link on Fedora: undefined reference to
`usmDESPrivProtocol`** — some distributions ship a `net-snmp-config.h`
that advertises DES as the default privacy protocol while the shipped
`libnetsnmp` doesn't export the symbol. Added an `AC_LINK_IFELSE` probe
for the actual symbol and guarded the fallback to use
`usmAESPrivProtocol` when it's absent.
- **Poller results ≥1024 bytes silently truncated to 1022** —
`db_escape()` capped its internal trim buffer at a fixed `DBL_BUFSIZE`
regardless of the caller's `max_size`, so raising
`--with-results-buffer` never helped. The trim buffer now scales with
`max_size` (a review finding caught the trim-size formula going
negative/zero for `max_size` 1-3), and `escaped_result` in `poll_host()`
is sized to `RESULTS_BUFFER * 2 + 1` instead of the fixed `DBL_BUFSIZE`.
(A very large escaped result can still hit the separate, already-tracked
row-size limit in #598/#618 — this fix only addresses the escaping-stage
truncation.)

## Also included

- **Seed `spine.conf` from `spine.conf.dist` on first install** — `make
install` only ever installed `spine.conf.dist`; nothing produced a live
`spine.conf`. Added an `install-data-hook` that copies it over only when
`spine.conf` doesn't already exist, plus a matching `uninstall-hook`
that only removes it again when it's still byte-identical to the `.dist`
(so a real uninstall never discards a customized config, while `make
distcheck`'s install/uninstall symmetry check still passes).

## Dropped from this PR

- A custom `codeql.yml` workflow (originally added for #580) was removed
— the repo already has GitHub's default CodeQL setup enabled and running
(`gh api repos/Cacti/spine/code-scanning/default-setup` → `state:
configured`), and a custom "advanced configuration" workflow cannot
coexist with it; GitHub rejected the SARIF upload and failed CI. #580's
underlying gap was already resolved out of band, so this PR no longer
claims to close it.

## Testing

Full build via WSL (`./bootstrap && ./configure --enable-warnings &&
make`) succeeds with no new warnings in `poller.c`, `snmp.c`, `php.c`,
`error.c`, or `sql.c` beyond two pre-existing, unrelated
`-Wformat-truncation` warnings in `php_init()`. Confirmed the
`usmDESPrivProtocol` configure probe correctly detects the missing
symbol in this build environment and takes the AES fallback path without
a link error. `make distcheck` passes end to end.

Closes #594
Closes #600
Closes #605
Closes #607
Closes #575
Closes #583
2026-09-22 10:10:14 -04:00
Thomas VincentandnetniV ff36da7ac8 fix: resolve content issues in spine.c, configure.ac, spine.conf.dist, and Copilot instructions (#437)
Fixes #438

Four targeted content fixes:

1. **spine.c**: replace `[WHERE?]` placeholder in doxygen comment and
expand `--help` output to list the actual spine.conf search order:
current directory, /etc/, /etc/cacti/, ../etc/.

2. **configure.ac**: raise AC_PREREQ from 2.63 to 2.69; remove obsolete
macros no longer needed in C99 builds (AC_C_CONST, AC_HEADER_TIME,
AC_STRUCT_TM, RETSIGTYPE block).

3. **spine.conf.dist**: document SNMP_Clientaddr, DB_SSL_Verify, and
RDB_SSL_Verify in the header comment block and add them as commented
example lines in the settings section.

4. **.github/instructions/instructions.md**: replace generic blueprint
template with spine-specific Copilot instructions (C99/POSIX, pthreads,
net-snmp, libmariadb, autotools, CI, commit conventions).

No behaviour changes. man page content improves automatically via
help2man.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: netniV <netniv@hotmail.com>
2026-03-11 20:39:14 +00:00
Sean Mancini 4cade52947 add copiolit instructions (#395)
This pull request introduces a new blueprint generator for creating
comprehensive `copilot-instructions.md` files, aimed at guiding GitHub
Copilot to generate code that strictly follows project-specific
standards, architecture, and technology versions. The blueprint is
technology-agnostic and ensures that generated instructions are based
solely on actual patterns found in the codebase, avoiding any
assumptions.

Key additions and improvements:

**Blueprint Generator and Configuration:**

- Added `.github/instructions/instructions.md`, which provides a
detailed, configurable template for generating `copilot-instructions.md`
files. The template supports variables for project type, architecture
style, code quality focus, documentation level, testing requirements,
and versioning approach.

**Instruction Structure and Guidance:**

- Outlined a core instruction structure that enforces strict adherence
to detected technology versions, project architecture, and codebase
patterns, with explicit prioritization of context files and code quality
standards.
- Included technology-specific sections for .NET, Java,
JavaScript/TypeScript, React, Angular, and Python, each with guidelines
to match exact versions and code patterns found in the codebase.

**Codebase Analysis and Implementation:**

- Provided detailed steps for analyzing the codebase to extract
technology versions, architectural style, code patterns, and quality
standards, ensuring the generated instructions are fully aligned with
the existing code. (F7dd6
2026-02-11 18:28:41 -05:00