Skip to content

vms-127: ACP mounts an ODS-2 volume executive-global (home/SCB validation, cross-process, epic vms-208) - #631

Merged
baron-3dl merged 1 commit into
mainfrom
work/vms-127-acp-mount
Aug 16, 2026
Merged

baron-3dl merged 1 commit into
mainfrom
work/vms-127-acp-mount

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

Third rung of epic vms-208 (Files-11 ODS-2 ACP in the executive). Builds on #623 (kernel-resident codec) and #624 (channel + mount table). The executive now GENUINELY validates and mounts a real ODS-2 volume, executive-global.

What this rung adds

Validation. vms_ioctl_acp_mount (kernel-core/vmsfs_acp.c) resolves the unit to its backing (major,minor) via a new internal vms_devtab_disk_backing(), then reads and validates the volume with the kernel-resident codec before recording it:

  • HOME block at LBN 1 → ods2_home_parse (strict): "DECFILE11B ", structure level 0x0201, both additive checksums.
  • SCB (BITMAP.SYS VBN1) located by the codec's INDEXF arithmetic + FM2 map walk (ods2_fh2_parse / ods2_fh2_map_walk) → ods2_scb_parse.
  • Non-ODS-2 media (e.g. a blank disk whose home block fails the format check) is REJECTED fail-honest with SS$_DEVNOTMOUNT, never recorded (INV-6 / Rule 9). The accept-vs-reject contrast on different media is the proof the executive actually reads and validates, not just records a name.

Executive-global, cross-process. A validated mount lives in the executive's mounted-volume table; a SECOND, re-exec'd process $ASSIGNs the unit and sees the SAME volume it never mounted — proven in the new suite. This deletes the userspace per-process passthrough.

Block read = synchronous bio, not the buffer cache. A new exec_blockdev_read_block shim opens the bdev read-only/non-exclusively and reads one block with submit_bio_wait. __bread/sb_bread assume a mounted-filesystem block size the ACP does not have when it reads a RAW disk before any mount — it hung on the raw virtio-blk device; submit_bio_wait is the direct, self-contained read. The shim is version-guarded across the 6.8 bdev_open_by_dev / 6.9+ bdev_file_open_by_dev split so it compiles on both the QEMU-test kernel (6.8) and the bootable kernel (6.12).

Codec gating (bootable dual-build). ods2_reader.o + -DOVMX_ODS2_KERNEL are linked into the out-of-tree vms.ko only. The in-tree bootable overlay does not yet carry the codec (the same flatten-safe-include follow-up vmsfs.ko owes), so vmsfs_acp.c gates its codec use on OVMX_ODS2_KERNEL and $MOUNT fail-honestly refuses there — no dangling symbol (avoids the #623 class of modpost breakage). No product path reaches the bootable ACP $MOUNT yet.

OVMX_SYSDISK_DEV

The userspace ods2_sysdisk.c adapter that used it was already reverted before this rung; no code references OVMX_SYSDISK_DEV (only design docs + this PR's explanatory comments). The executive-global mount is its conceptual replacement.

Negctl anchor

New genuine control acp-mount-nonods2-accepted in tests/qemu/facility_defects.sh (replaces the acp_validate_ods2() call with unconditional success → the blank-media REJECT assertions redden), named in suites_red: test_syssvc_acp_mount. FLOOR-NO-BUMP (floor untouched). facility_defects.sh coverage src tests/qemu PASSES.

Test-harness disk layout

tests/qemu/run_tests.sh: vda = DKA0: = genuine real-VAX ODS-2 volume (the system disk, seeded from the staged /ods2_real.img fixture), vdb = DKA100: = blank (the reject media + the unit INITIALIZE formats). DKA0: is the ODS-2 unit because sys_assign.c routes only the boot unit (DKA0:/SYS$SYSDEVICE) to the ACP today, so the cross-process $ASSIGN proof rides the boot unit.

Verification (all local, real /dev/vms — not deferred to CI)

Gate Result
test_syssvc_acp_mount vs real /dev/vms (QEMU/KVM) 10/10 — validate-accept, idempotent, reject blank SS$_DEVNOTMOUNT, reject-recorded-nothing, second re-exec'd process sees the executive-global mount + gets an executive file channel, dismount + fail-honest-after
test_syssvc_acp_channel (DKA0: = ODS-2 system disk) 11/11
test_kmod_disk (disk-layout change) 11/11, no regression
Out-of-tree vms.ko (6.8) with codec builds clean, modpost resolves all symbols
In-tree bootable overlay modpost (6.12) vms.ko + vmsfs.ko intree=Y, no undefined symbols
Debug build + ctest 195/195
facility_defects.sh coverage PASS

Alpha-portable: fixed-width types, no arch-specific layout; tools/cross-alpha/ untouched. NetBSD-vax boot path untouched (new shim is a contract-only twin there).

🤖 Generated with Claude Code

…tion, cross-process, epic vms-208)

The Files-11 (ODS-2) ACP $MOUNT now VALIDATES that a unit's backing block
device is a genuine ODS-2 volume before recording it, and records it in the
executive-global mounted-volume table every process sees -- deleting the
userspace per-process passthrough (INV-6, Rule 9).

Validation (kernel-resident codec): vms_ioctl_acp_mount resolves the unit to
its backing (major,minor) via a new internal vms_devtab_disk_backing(), reads
the HOME block (LBN 1) and the SCB (BITMAP.SYS VBN1, located by the codec's
INDEXF arithmetic + FM2 map walk) through a new exec_blockdev_read_block shim,
and validates them with ods2_home_parse / ods2_scb_parse (DECFILE11B, struclev
0x0201, checksums). Non-ODS-2 media is REJECTED fail-honest (SS$_DEVNOTMOUNT),
never recorded.

Block read uses a SYNCHRONOUS bio (submit_bio_wait), not the buffer cache:
__bread assumes a mounted-filesystem block size the ACP does not have when it
reads a raw disk pre-mount (it hung on the raw virtio-blk device). The shim is
version-guarded across the 6.8 bdev_open_by_dev / 6.9+ bdev_file_open_by_dev
split so it compiles on BOTH the QEMU-test kernel (6.8) and the bootable kernel
(6.12).

Codec gating: ods2_reader.o + OVMX_ODS2_KERNEL are linked into the out-of-tree
vms.ko only; the in-tree bootable overlay does not yet carry the codec (the
flatten-safe-include follow-up vmsfs.ko also owes), so vmsfs_acp.c gates its
codec use on OVMX_ODS2_KERNEL and $MOUNT fail-honestly refuses there. No product
path reaches the bootable ACP $MOUNT yet.

OVMX_SYSDISK_DEV: the userspace ods2_sysdisk.c adapter that used it was already
reverted; no code references it -- the executive-global mount is its replacement.

Proven against a real /dev/vms (QEMU kernel-executive harness, KVM):
  test_syssvc_acp_mount   10/10 (validate-accept DKA0: ODS-2, reject blank
                          DKA100:, SECOND re-exec'd process $ASSIGNs DKA0: and
                          sees the same executive-global mount, file channel)
  test_syssvc_acp_channel 11/11 (DKA0: is the ODS-2 system disk now)
  test_kmod_disk          11/11 (no regression from the disk-layout change)
Debug build + ctest: 195/195. Bootable in-tree modpost (6.12): vms.ko + vmsfs.ko
intree=Y, no undefined symbols. facility_defects coverage: PASS (new negctl
acp-mount-nonods2-accepted, FLOOR-NO-BUMP).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baron-3dl
baron-3dl merged commit 6588236 into main Aug 16, 2026
93 checks passed
baron-3dl added a commit that referenced this pull request Aug 17, 2026
… cross-build (#643)

* vms-6a7f: wire vmsfs_acp.c (Files-11 ACP handlers) onto the elf32-vax cross-build

The elf32-vax ILP32 convergence guard (build-vms-module-vax.sh) proved every
executive facility EXCEPT the Files-11 ODS-2 ACP -- vmsfs_acp.c and its
ods2_edit.c EDIT helpers were never compiled for a 32-bit target at all, so
LP64 Alpha was the only cross-arch signal on the ACP handlers and could not
catch an ILP32 width regression. This closes that gap:

- src/vmsfs/include/vmsfs/ods2.h: the OVMX_ODS2_KERNEL type-substrate include
  is now three-way (Linux / NetBSD kernel / userspace), the same split
  src/kernel/vmsfs/vmsfs_ondisk.h already carries (rd vms-9172/vms-bbf) and
  the same __linux__/__KERNEL__ detection vmsfs_backend.h uses. The NetBSD
  kernel branch is self-sufficient for offsetof (a guarded __builtin_offsetof
  fallback), since ods2_edit.c compiles as its own standalone TU and does not
  transitively pull <sys/systm.h>.

- src/kernel-netbsd/vms_internal.h: add struct vms_proc::file_channels
  (mirrors mbx_channels), the 6 missing SS$ status codes vmsfs_acp.c returns
  (ACCVIO/DEVNOTMOUNT/NOSUCHFILE/FILNOTACC/DEVICEFULL/DEVALLOC, values copied
  verbatim from src/kernel/vms_internal.h so both substrates agree), ACP
  facility prototypes, and the vms_devtab_disk_backing() forward declaration
  (device table is not ported to NetBSD yet -- a later, separate port).

- src/kernel-netbsd/vms_acp_nb.h (new): the NetBSD twin of src/kernel/
  vms_acp.h's ioctl arg structs, byte-identical layouts, mirroring the
  vms_mbx_nb.h precedent.

- src/kernel-netbsd/vms_netbsd.c: initialize file_channels alongside
  mbx_channels (release-all is deliberately NOT wired -- vmsfs_acp.c is not
  in the real module SRCS yet).

- tools/cross-vax/build-vms-module-vax.sh: add vmsfs_acp.c + ods2_edit.c to
  the compile set (-DOVMX_ODS2_KERNEL), a deliberate superset of
  src/kernel-netbsd/Makefile's real SRCS.

SCOPE: compile-coverage only, not runtime integration (vmsfs_acp.c is not
linked into the real NetBSD/vax loadable module or dispatched by
vms_netbsd.c's ioctl table -- that re-target is vms-d5d).

Verified: all 14 TUs (the prior 12 + vmsfs_acp.c + ods2_edit.c) compile
-Werror clean for elf32-vax and relocatable-link with no duplicate symbols;
every object confirmed elf32-vax/arch:vax. Retroactively covers the whole
accumulated ACP handler layer on main (mount/dmount/assign #631,
access/deaccess #633, readvb/writevb #640). Negctl (deliberately-broken TU)
still fails the gate. Sibling gates unaffected: build-vmsfs-core-vax.sh (codec,
vms-bb8) and build-vmsfs-mount-vax.sh (loadable vmsfs.kmod) both still pass.
Linux regression check: vms.ko (src/kernel/Makefile) builds clean against a
real 6.8.0 kernel with vmsfs_acp.o/ods2_reader.o/ods2_edit.o all compiling
under the unchanged Linux branch of the new ods2.h split. No width issue
found (compile clean; the args.buffer uint64_t->uintptr_t->void* casts in
READVBLK/WRITEVBLK are correct on ILP32).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* vms-6a7f: stage vms_acp_nb.h in tests/netbsd/Dockerfile for the in-guest amd64 module build

The new src/kernel-netbsd/vms_acp_nb.h (ACP ioctl arg-struct NetBSD twin) is
referenced by vms_internal.h, so the NetBSD/amd64 in-guest module build needs
it staged — but the Dockerfile's kmod header COPY list (which stages the
sibling *_nb.h headers) missed it, failing the "NetBSD/amd64 vms module
cross-compiles" staging check. Add the COPY line next to vms_mbx_nb.h, the
header it mirrors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant