Skip to content

Package the driver with server-rs and test it in a Windows guest - #68

Closed
Chuccle wants to merge 33 commits into
masterfrom
package
Closed

Chuccle wants to merge 33 commits into
masterfrom
package

Conversation

@Chuccle

@Chuccle Chuccle commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Before: the driver and server-rs were built separately. Nothing checked that a given driver works with a given server, and the driver was only ever loaded on a developer's machine.

After: every push and PR builds one package with the signed driver plus server-rs for Linux and Windows, all from the pinned server-rs commit. A Windows Server 2022 guest under KVM then loads that package's driver and tests it against the packaged server. If the driver and server stop agreeing on the API, the build goes red.

How: one Linux entrypoint, tools/blorg, with its modules in tools/blorg.d/. CI and a person at a shell run the same commands:

  • blorg pins, blorg server, blorg package: check the schemas pins, cross-build server-rs (musl, mingw) and assemble the package with manifest.json.
  • blorg guest image | test | run | up | ssh | push | pull | snapshot | screenshot ...: the guest. It runs on any Linux host with KVM; GitHub's Linux runners are one such host.
  • blorg setup | check | doctor: the Linux-side checks.
  • blorg ci: drives the GitHub build from any shell with a token.
  • blorg container: runs any of the above in tools/Containerfile's image.

Everything that runs inside Windows is one script, tools/guest/Invoke-BlorgGuest.ps1 -Step .... guest.yml is a reusable workflow: build.yml calls it as its last job, and it can be dispatched against an earlier build. The golden image is cached by a hash of its own inputs, so changes that only touch the tests reuse it.

This replaces #63, #64, #66 and the packaging part of #65. The driver fix from #65 is #67, which this doesn't depend on. Docs (AGENTS.md and README) follow in this PR once the guest run is green.

server-rs becomes a submodule, so a BlorgFS commit names the exact server
it ships with. tools/blorg is the one Linux entrypoint, used by CI and by
hand alike:

  blorg pins      the driver and the pinned server compile the same schemas
  blorg server    cross-build the pinned server for Linux (musl) and
                  Windows (mingw)
  blorg package   assemble driver + both servers + manifest.json
  blorg setup / check / doctor
                  the Linux-side checks: driver compile check against the
                  WDK headers, server-rs tests and clippy
  blorg ci        drive the GitHub Actions build from any shell with a token
  blorg container the same in tools/Containerfile's image

build.yml gains a Linux job that checks the pins and builds the server,
and a package job that assembles blorg-package-windows-x64 from it and the
signed Windows driver. A v* tag matching VERSION publishes it as a release.
Dependabot moves the schemas and server-rs pins together.
The packaged driver is loaded into a real Windows Server 2022 kernel under
KVM/QEMU and tested against the packaged Linux server running on the host,
so a driver/server mismatch fails the build rather than a user.

  blorg guest image   unattended golden image, built once and cached
  blorg guest test    fresh guest -> install package -> volume, listing,
                      correctness and suites -> verdict and diagnostics
  blorg guest run     a script of blorg guest commands against the guest,
                      with a transcript
  blorg guest up/ssh/push/pull/snapshot/revert/screenshot/...
                      the controls those are built from

guest.yml runs it on a GitHub Linux runner. build.yml calls it as its last
job on the package it just built; it can also be dispatched against an
earlier build, optionally with a script. The same commands run on any Linux
host with KVM.

Everything that runs inside Windows is one script,
tools/guest/Invoke-BlorgGuest.ps1 -Step Image|Prepare|Test|Diagnostics.
tests/guest-suites/Errors.ps1 checks that server errors reach Windows
programs as the right error.
@Chuccle Chuccle self-assigned this Oct 3, 2026
Chuccle added 16 commits October 3, 2026 23:04
AGENTS.md gains a "Package and test guest" section: the package layout,
tools/blorg, the Linux-side checks, the test guest by hand and in CI.
README gets the short version. ci build is dropped: build.yml now ends
in the guest run, so ci test already follows it.
A minidump's !analyze reports BUGCHECK_CODE rather than the full dump's
'BugCheck' banner, so the verdict left Bugcheck empty for the guest's
0xD1.
…tor type

An unexpected HTTP status became STATUS_INVALID_PARAMETER unless it was
404. A 403 (host permissions, or a path the server refuses as escaping its
root) now surfaces as STATUS_ACCESS_DENIED, and a 416 (a read starting at
or past the file's current end: the file shrank under a cached size) as
STATUS_END_OF_FILE. Sandbox tests cover both.

HttpDeserializeDirectoryInfo declared the subdirectory vector as
FileEntryMetadata_vec_t; the schema's Directory.subdirectories is a
SubdirectoryMetadata vector.
DriverEntry passes ai_addr, which lives in paged pool. Reading it under
SocketPool.Lock touches pageable memory at DISPATCH_LEVEL: bugcheck 0xD1
at service start under Driver Verifier.
A connect completion arrives at DISPATCH_LEVEL, and the pump chained the
next WskSocketConnect from there. With no owning process the transport
captures the caller's security context in pageable code, so under Driver
Verifier the second pre-warm connect bugchecked 0xA in
SeCaptureSubjectContextEx. A completion above PASSIVE now hands the step
to a work item, and the step stays in flight until it has run, so teardown
still waits for it. The WSK model enforces the IRQL, so the sandbox catches
a connect issued above PASSIVE.
@Chuccle
Chuccle force-pushed the package branch 2 times, most recently from 74b6cd7 to 73fb2eb Compare October 4, 2026 01:31
// Teardown waits for a step whose work item has not run, so drain
// both until neither has anything left.
//
while (WskModelReleaseDeferred() + ShimDrainWorkItems() > 0)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Busy wait is quite yucky. We should yield the cpu maybe?

A send can complete inline, and on the failure path its completion frees
the request context before BlorgSendWskAsync returns. Writing
SendIssuedQpc after the call wrote into freed memory: bugcheck 0x50 in
HttpKick under Driver Verifier's special pool.
Comment thread src/Client.c
}
}

Ctx->SendIssuedQpc = BlorgStatisticsNow();

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check we don't do this in other Async calls

A query after a failed fetch keeps its search pattern and so skipped the
posts to the FSP, issuing the fetch from the FSD without the IRP marked
pending. Also correct the receive comment, which described the opposite of
the issue contract the code relies on.
rust-toolchain.toml pins the toolchain that builds server-rs; CI installs
it and keys its caches by it, and the container image is built with it.
The container pins rustup-init and its base image by hash. blorg server
builds only the pinned submodule.

guest.yml takes the package's run id from build.yml rather than reading
the event name, and re-tests the newest run whose Package job succeeded.
The self-test and a dispatched script keep separate transcripts. The
image fetches OpenSSH from its versioned release URL, and its key covers
the QEMU machine it installs on.

Drop the unused VolumeTester step, flatc_bin and container CMD, make
usage errors exit 2, document every setting, and bring README and
AGENTS.md in line with the code.

Chuccle commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner Author

Replaced by #70, which has the same content squashed into one commit on top of #69.

@Chuccle Chuccle closed this Oct 4, 2026
@Chuccle
Chuccle deleted the package branch October 4, 2026 17:00
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