vms-6ca: DLM rung H5 — the two-node SCS wire of the async DLM replies (block-then-grant on the requester) - #875
Conversation
…red-grant report The cross-node contention semantics (#873) proved block-then-grant on a single real /dev/vms. This adds the two executive halves the async-reply SCS wire needs: - MASTER side: vms_lock_dlm_xnode_deq now REPORTS the queued cross-node waiter that a release flipped to granted (its requester CSID + original req_lkid + master handle + granted mode), through the fields a DEQ otherwise leaves 0, so the daemon can WIRE a deferred GRANT to the requester without a second probe. The master lock entry now carries the requester's own lock handle (req_lkid). - REQUESTER side: VMS_DLM_OP_GRANT is implemented (was SS$_UNSUPPORTED). A GRANT / queued-reply the master sent back completes an executive-resident ORIGIN record — the requester-side proxy of the outstanding request, on its own list, never touched by the local lock manager. Its granted mode is set ONLY from what the master genuinely sent over SCS: a queued-reply (mode NL) leaves it pending, a deferred GRANT (mode EX) flips it NL->EX. GETLKI falls through to it, so the status flip is observable on the REQUESTER node. INV-6: genuine executive state, no fabricated grant. BLKAST as a receive op stays SS$_UNSUPPORTED — the BLKAST wire is deferred honestly on this rung (the block-then-grant round-trip is proven without it). test_syssvc_dlm_xnode.c extended to prove both halves against a real /dev/vms (x86_64 + Alpha LP64): the deferred-grant report on the block-then-grant $DEQ, and the requester-side queued->granted origin flip. vms.ko builds clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…r the live VC The scsd daemon now carries the async DLM replies over the real SCS wire, so the block-then-grant completes on the REQUESTER node across the network — not just in the master's local executive (#873). Node B (master): the GRANT frame it sends back now carries the granted mode honestly — a queued-reply carries NL (the requester stays genuinely pending), a grant carries the granted mode — plus the master's lock handle, so the requester can $DEQ the holder. On a cross-node $DEQ that flips a queued waiter to granted, B reads the executive's deferred-grant report and WIRES an unprompted deferred GRANT (SS$_NORMAL, the granted mode) to that requester (SCSD-I-DLMDEFER). Node A (requester, armed by OVMX_DLM_H5): drives block-then-grant over the wire — holds RESONE EX (#1), sends a second incompatible $ENQ (#2) that QUEUES on B, dispatches B's queued-reply into its OWN executive so #2's origin record is genuinely PENDING (GETLKI->NL, SCSD-I-DLMPEND), releases the holder (#1), and on B's deferred GRANT dispatches it into its executive — the origin record FLIPS NL->EX (GETLKI->EX, SCSD-I-DLMH5FLIP). The status flip is read from A's real executive, driven only by what the master sent over SCS. INV-6: no fabricated wire reply or grant; the BLKAST wire stays deferred (the holder releases on its own). scsd builds clean; vmsscs unit tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…r the wire Extends the H4 two-node real-/dev/vms harness to H5. Both nodes boot vms.ko and complete the VMS$VAXcluster join; node A is armed OVMX_DLM_ENQ=RESONE OVMX_DLM_H5=1 and drives the block-then-grant sequence over the live SCS wire: holds RESONE EX, a second incompatible $ENQ QUEUES on node B (B WIREs a queued-reply -> A's requester origin record PENDING, SCSD-I-DLMPEND), A releases the holder, node B WIREs the deferred GRANT off that real $DEQ (SCSD-I-DLMDEFER), and A's origin record FLIPS NL->EX (SCSD-I-DLMH5FLIP granted_mode=EX). H5 PASS asserts the status flip on the REQUESTER node A across the wire, plus B's deferred-grant wire — read from the nodes' own SCSD logs, never fabricated (INV-6). New Dockerfile.dlm-harness-h5 + init_dlm_h5.sh + run_dlm_harness_h5.sh; new dlm-harness-h5 CI job (path-filtered on the DLM sources + harness files); the existing dlm_harness filter already covers vms_lock.c + src/vmsscs/**. Shell + YAML syntax validated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tion in the compat ledger docs/compat/facilities/cluster-dlm.yaml (single-ledger source, INV-LEDGER): new cluster-dlm$async-reply-wire item for the H5 rung — the master WIREs the queued-reply + deferred GRANT over SCS, the requester-side GRANT RECEIVE completes an executive-resident origin record, and the NL->EX flip is observed on the requester. Notes the BLKAST wire deferred honestly and multi-peer deferred-grant routing as a later rung. Summary updated; H5 evidence points at the two-node harness. YAML validated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…re item Derived docs/compatibility-surface.md re-rendered from docs/compat/*.yaml via tools/compat/render_compat.py (INV-LEDGER: yaml is source, md is generated). 407 items now catalogued. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…(dark since #850) The job name added today by #850 (vms-dec) contained an unquoted mid-value colon ('... before Username: (vms-dec)'), which is invalid YAML. GitHub Actions could not parse ci.yml, so EVERY run of it — on main and every branch — completed with ZERO jobs (no Build & Test, no harnesses, nothing); the only checks still firing were the separate Ledger-drift and CodeQL workflows. Quoting the value restores the whole workflow. Pre-existing project-wide breakage, surfaced while wiring the H5 CI job (which could not run until ci.yml parsed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ir H0's stale selftest op Two fixes surfaced by re-enabling ci.yml: 1. scs_send_sites census: the new scsd_dlm_client_send_op() sender (node A's contending $ENQ + holder $DEQ) is added to the CHOKED half of the SEND SITE TABLE in scsd.c; the scsd_dlm_srv_msg_input entry now notes the deferred GRANT it also wires. test_scsd_send_sites: 109 checks, 0 failures. 2. DLM Harness H0 selftest: it drove a DEQ expecting SS$_UNSUPPORTED (2296), but rung 3 (#873, vms-904c) made DEQ real — a DEQ of an unknown handle now returns SS$_IVLOCKID (8484), so H0 had been red since #873 (hidden by the dark CI). The side-effect-free "executive reached, honest 2296" probe now uses BLKAST, whose receive op still honestly returns SS$_UNSUPPORTED (its wire is deferred, vms-6ca) and mutates no lock state. No run/init/ci grep change needed — still rc=2296 PASS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Green-by-SHA status + a project-wide CI repair this PR carriesvms-6ca is proven green. On the run for this branch (before the last two housekeeping commits), every vms-6ca job passed:
|
What
DLM epic vms-7fa rung H5 (rd vms-6ca): the two-node SCS wire transport of the async DLM replies, and the requester-side completion — the continuation of the cross-node contention rung (#873, vms-904c).
#873 proved the block-then-grant semantics on a single real
/dev/vmswith two CSIDs (an incompatible cross-node\$ENQQUEUES on the master, a cross-node\$DEQgrants it). It left deferred: the requester-side GRANT/queued RECEIVE ops (SS$_UNSUPPORTED) and the actual SCS wire delivery of the async replies to a live remote node. This PR builds that wire.The outcome (proven on a two-node live A↔B QEMU harness, both real
/dev/vms)Node A holds
RESONEEX; a second incompatible\$ENQQUEUES on node B (the master):SCSD-I-DLMPEND, read from A's own executive via GETLKI → NL), not a local fake.\$DEQ.\$DEQ,SCSD-I-DLMDEFER) → A's origin record FLIPS NL→EX (SCSD-I-DLMH5FLIP granted_mode=EX).The proof signal is the status flip observed on the REQUESTER node A across the wire — driven only by what the master genuinely sent. No fabricated wire delivery or grant (INV-6).
Layers
src/kernel-core/vms_lock.c, shared → Linux + NetBSD inherit):VMS_DLM_OP_GRANT, wasSS\$_UNSUPPORTED): completes an executive-resident origin record on the requesting node — its own list, never touched by the local lock manager; its granted mode is set only from what the master sent over SCS (queued-reply → NL/pending; deferred GRANT → EX). GETLKI falls through to it.vms_lock_dlm_xnode_deqnow names the queued cross-node waiter a release flipped to granted (requester CSID + original req_lkid + master handle + mode), so the daemon can wire the deferred GRANT.vms_dlm_xnode_argsstruct size is unchanged (no mirror/static_assert churn).src/vmsscs/scsd.c): B carries the granted mode honestly (queued-reply = NL) and WIREs the unprompted deferred GRANT off a real\$DEQ; A drives the block-then-grant sequence and dispatches every received reply into its own executive.Dockerfile.dlm-harness-h5+init_dlm_h5.sh+run_dlm_harness_h5.shextend the H4 two-node real-/dev/vmsharness; newdlm-harness-h5CI job. The fast executive-level proof (tests/qemu/test_syssvc_dlm_xnode.c) is extended to assert both halves against a real/dev/vmson x86_64 + Alpha LP64.docs/compat/facilities/cluster-dlm.yamlgains theasync-reply-wireitem.Deferred honestly (INV-6, not faked)
SS\$_UNSUPPORTED; the block-then-grant is proven without it (the holder releases on its own).SS\$_UNSUPPORTED.Local validation
vms.kobuilds clean with all executive changes.scsd_exebuilds clean;vmsscsunit tests (test_scsd_wire,test_scs_dlm) green — no regression.test_syssvc_dlm_xnode.ccompiles; H5 shell scripts +ci.yml+cluster-dlm.yamlvalidated.🤖 Generated with Claude Code