feat(config-upgrade-snapshot): add configcompare tool, extend snapverify (task 8.4)
Build configcompare_paths(), an offline sibling to snapdiff/walcompare that recomputes each member's active-config sha256 fresh from its own on-disk workdir/name/conf bytes and reports identical vs. divergent (Req 4.2). Wire it as a cmd_configcompare CLI subcommand in test.c, matching its siblings, after review caught it shipped as an unreachable library function in round 1. Extend snapverify to match the current on-disk checkpoint format: bump SNAP_FORMAT_VERSION to 2, replace the stale raw queue-frame decode with the capnp length-prefixed walk, add host-frame and config-bytes-section structural walks, and decode (not just presence-check) the header's cfgref tag/sha. Without this fix snapverify rejected every checkpoint written by the current codebase.
This commit is contained in:
parent
c5d8ecbd7d
commit
1d09631df0
10 changed files with 997 additions and 47 deletions
|
|
@ -1,14 +1,20 @@
|
|||
#pragma once
|
||||
/*
|
||||
* snapverify.h — read-only checkpoint-file structural inspector/validator
|
||||
* (bug-1389 triage: OPCode_snapshotTransfer chunk-content corruption).
|
||||
* (bug-1389 triage: OPCode_snapshotTransfer chunk-content corruption;
|
||||
* extended by config-upgrade-snapshot task 8.4, Requirement 4.2, for the
|
||||
* SNAPSHOT_FORMAT_VERSION=2 host + config-bytes sections and to decode --
|
||||
* not merely report the presence of -- the header's cfgref tag/hash).
|
||||
*
|
||||
* Parses the on-disk checkpoint layout persist.c's load_snapshot() /
|
||||
* load_snapshot_entities() use (design.md "Checkpoint File Layout") WITHOUT
|
||||
* restoring any job/queue into a live cluster_t — a pure structural walk, so
|
||||
* it needs no jobmgr/qmgr context and is safe to run standalone against a
|
||||
* snap-*.capnp (locally generated) or snap-*.bin (received via
|
||||
* ha_handle_snapshot_chunk, ha.c) file on disk.
|
||||
* restoring any job/queue/host into a live cluster_t — a pure structural
|
||||
* walk, so it needs no jobmgr/qmgr/workermgr context and is safe to run
|
||||
* standalone against a snap-*.capnp (locally generated) or snap-*.bin
|
||||
* (received via ha_handle_snapshot_chunk, ha.c) file on disk. This tool
|
||||
* validates STRUCTURE only, never content: job/queue/host frame payloads
|
||||
* and the config-bytes section are walked past via their length prefix,
|
||||
* never capnp-decoded or interpreted.
|
||||
*
|
||||
* Strictly read-only: opens O_RDONLY, mutates nothing.
|
||||
*/
|
||||
|
|
@ -18,7 +24,17 @@
|
|||
|
||||
typedef struct {
|
||||
uint64_t checkpoint_lsn;
|
||||
int has_cfgref; /* config-ref tail present in the header */
|
||||
int has_cfgref; /* config-ref tail present in the header
|
||||
* (header[16] != 0) -- semantic presence,
|
||||
* distinct from cfgref_tag/cfgref_sha below
|
||||
* being decoded */
|
||||
uint64_t cfgref_tag; /* header cfgref tag, decoded whenever the
|
||||
* header extends to SNAP_HEADER_MAX bytes,
|
||||
* REGARDLESS of has_cfgref -- meaningful
|
||||
* only when has_cfgref is also 1 */
|
||||
uint8_t cfgref_sha[32]; /* header cfgref sha256, same decode-
|
||||
* unconditionally-but-gate-meaning-on-
|
||||
* has_cfgref discipline as cfgref_tag */
|
||||
int has_entity_section; /* fmt + job_count present past the header;
|
||||
* 0 = legacy position-only checkpoint */
|
||||
uint32_t format_version;
|
||||
|
|
@ -27,6 +43,22 @@ typedef struct {
|
|||
uint32_t queue_count; /* as declared in the file (0 if legacy, or if the
|
||||
* job-frame walk failed before reaching it) */
|
||||
uint32_t queues_ok; /* queue frames structurally walked before any failure */
|
||||
uint32_t host_count; /* as declared in the file (0 if legacy, or if an
|
||||
* earlier section's walk failed before reaching
|
||||
* it) */
|
||||
uint32_t hosts_ok; /* host frames structurally walked before any failure */
|
||||
int has_config_bytes_section; /* 1 iff the trailing config-bytes
|
||||
* section's 4-byte length field
|
||||
* itself was present and readable
|
||||
* (i.e. the file extends past the
|
||||
* host section at all) -- TRUE even
|
||||
* when that length decodes to 0, and
|
||||
* FALSE (not a failure) when the
|
||||
* file simply ends right after the
|
||||
* host section */
|
||||
uint32_t config_bytes_len; /* decoded length of the config-bytes
|
||||
* section; valid only when
|
||||
* has_config_bytes_section is 1 */
|
||||
off_t file_size;
|
||||
off_t consumed; /* bytes structurally accounted for */
|
||||
int ok; /* 1 = well-formed, consumed == file_size */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue