Ship the document root as a UFS disk image, uploaded with IND$FILE - #253
Merged
mgrossmann merged 4 commits intoAug 24, 2026
Merged
Conversation
static/index.html was in the repository and in no release artifact, so the
package installed a server whose DOCROOT had nothing behind it.
A UFS disk cannot travel the way the rest of the package does, and not for
lack of tooling. SMP has no element type for a DSORG=PS/RECFM=U image and
must never touch site content; TSO RECEIVE allocates its own target and
refuses to merge into an existing dataset, which makes it a
first-install-only transport for something an operator replaces. So the
image ships as a plain file in the archive and goes up over IND$FILE, which
needs nothing on the target beyond a 3270 session.
make webroot builds dist/httpd-webroot.img from static/ with a pinned
ufsd-utils (fetched into .mbt/tools/ when absent, because
release CI runs the shared workflow and cannot install
anything of its own). package and dist depend on it, and
[distribution] extra puts it in the zip/tar.gz.
samplib/httpwebr allocates HTTPD.@vrm@.WEBROOT.UFS -- SPACE=(4096,256),
RECFM=U BLKSIZE=4096, primary extent only.
installation.md 9 the operator's side: allocate, upload, mount, verify,
and unmount before replacing.
Measured rather than assumed:
Blocking RECFM=U buffers to BLKSIZE through __fputc (libc370
@@fputc.c:24), so BLKSIZE(4096) writes whole 4096-byte
blocks; the 1 MB image is 256 of them with no remainder.
Options binary is IND$FILE's default and RECFM then defaults to U
(ind_file370 indparse.c:249).
Pre-allocate IND$FILE allocates an existing dataset DISP=SHR and takes
its DCB (indmain.c:190, :273), so the documented upload
needs no options and does not depend on which IND$FILE
build a system carries.
The trap that same DISP=SHR rewrites a dataset UFSD has mounted, so
UNMOUNT is a numbered step rather than a footnote.
Detection a BLKSIZE mismatch surfaces at MOUNT as UFSD062E
(ufsd ufsd#sbl.c:69), not as a corrupt page.
Encoding nothing to configure: http_send_file() translates UFS files
with the hard-coded IBM-1047 table independent of CODEPAGE=
(httpfile.c:70), which is what ufsd-utils writes. The
round trip was measured byte for byte over the whole file
and over all 256 values; only 0x85 and 0xF7 do not survive.
The version in the dataset name settles what smp-todo called U6: a shipped
image cannot land on a webroot the site built for itself.
Fixes #252
The ranking said nothing open blocks 4.0.0, which was true and unhelpful: the release work is in smp-todo.md (the FMID check and the dry run), not in the tracker at all. Say so, and record that O3 closed with #252.
…ne changes The prerequisite list was files only. Adding one is covered -- make expands the wildcard when it parses the Makefile, so the new file is in the list and is newer than the image -- but deleting one is not: the image stays newer than everything still there, and the archive would go on shipping the file that was removed. A directory's mtime moves when an entry is added or removed, so the directories join the file list. Measured both ways with the image backdated so the comparison is not decided by whole-second timestamps: adding rebuilds, deleting rebuilds and drops the file from the image, an unchanged tree does nothing. Also two notes rather than behaviour: why the webroot dataset is the one name with a fourth qualifier, and that the emulator types IND$FILE into whatever field the cursor is on -- it does not find a command line for you.
dist/ is not a scratch directory: the release workflow publishes every file in it as a GitHub Release asset (`gh release create ... dist/*`). An image built there therefore shipped twice -- once inside the archive, where it belongs beside the README and the jobs, and once on its own as `httpd-webroot.img`, a name with no version in it sitting between httpd-<version>-load.xmit and httpd-<version>-dist.zip. Nothing else moves: `extra` takes the basename, so the file inside the archive is called what it was called before, and the installation guide is unchanged.
This was referenced Aug 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #252.
static/index.htmlwas in the repository and in no release artifact: thepackage installed a server whose
DOCROOThad nothing behind it.The transport, and why it is neither SMP nor XMIT
DSORG=PS/RECFM=Uimage, and site content iswhat an
APPLYmust never touch.dataset -- a first-install-only transport for something an operator replaces.
(
xmit370could not represent the format either: directory -> PDS,--recfm fb|f, LRECL 80.)So the image ships as a plain file in the archive and goes up over IND$FILE,
which needs nothing on the target beyond a 3270 session -- no mvsMF, no ftpd.
What is in the change
make webrootbuild/webroot/httpd-webroot.imgfromstatic/with a pinnedufsd-utils, fetched into.mbt/tools/when it is not on PATH. 1 MB = 256 blocks;--owner/--groupare set so a release artifact carries no build-machine userid.packageanddistdepend on it. Underbuild/, notdist/: the release workflow publishesdist/*as Release assets, and the image belongs in the archive rather than beside it under a version-less nameproject.toml[distribution] extraputs the image in the zip/tar.gz -- verified, the archive is 6 files nowsamplib/httpwebrHTTPD.@VRM@.WEBROOT.UFS:SPACE=(4096,256),RECFM=U BLKSIZE=4096, primary extent only. Substitution verified in the packed XMIT (HTTPD.V4R0M0D.WEBROOT.UFS)docs/installation.mdsmp-todo.mdMeasured, not assumed
__fputc(libc370@@fputc.c:24), soBLKSIZE(4096)writes whole 4096-byte blocks. The 1 MBimage is 256 of them, no remainder.
U(ind_file370
indparse.c:249).its DCB (
indmain.c:190,:273). That is why the documented upload carriesno options at all -- and why it does not depend on which IND$FILE build a
system has.
UNMOUNT PATH=/wwwis a numbered step in the doc, not a footnote.UFSD062E SUPERBLOCK VALIDATION FAILED(ufsdufsd#sbl.c:69), not as a corrupt page./serves it:httpget.c:68appendsindex.htmlto a directory request.Encoding: nothing to configure, and no HTTPPRM0 change
http_send_file()translates UFS files with the hard-coded IBM-1047 table,independent of
CODEPAGE=(src/httpfile.c:70) -- exactly whatufsd-utilswrites. Measured end to end:
ufsd-utils cp-> stored bytes ->ibm1047_etoareturns
static/index.htmlbyte for byte, UTF-8 sequences included. Over all256 byte values only
0x85and0xF7fail to round-trip; the Makefile says so.CODEPAGE=IBM1047in the shippedHTTPPRM0was considered and rejected onmeasurement. cc370 compiles literals in CP037 (
common/src/mvs370.c), andCODEPAGE=governs those: underIBM1047a[compiled as0xBAleaves as0xDD, which would break every mvsMF array response -- the primary route in theshipped configuration -- plus HTTPD's own login form and error pages. Checked
against a live server:
[currently arrives as0x5B.Verification
make package-- clean, 6 files in the archive, image includedmake dist-- re-renders with the image presentufsd-utils ls -l/info: 256 blocks,IBMUSER/SYSPROG,index.html3573 bytesHTTPWEBRpresent,@VRM@substitutedufsd-utilsbootstrap exercised from an empty.mbt/tools/Not verified on MVS: the upload itself.
IND$FILEis present on the referencesystem (
SYS2.CMDLIB), but a 3270 transfer is interactive -- every claim aboutits behaviour above comes from the ind_file370 sources.