Skip to content

Ship static/index.html as a UFS webroot image, uploaded with IND$FILE #252

Description

@mgrossmann

static/index.html is in the repository and in no release artifact. The
4.0.0 package installs a server whose DOCROOT=/www has nothing behind it.

Static content lives on a UFS disk, and a UFS disk cannot travel the way the
rest of the package does:

  • SMP cannot carry it. There is no element type for a DSORG=PS, RECFM=U, BLKSIZE=4096 image (++MOD/MAC/SRC/MACUPD/SRCUPD/ZAP is the whole set), and
    it is site content an APPLY must never touch.
  • XMIT cannot carry it either. xmit370 create packs a directory into a
    PDS with --recfm fb|f, LRECL 80. Beyond the tooling: TSO RECEIVE allocates
    its own target and refuses to merge into an existing dataset, so it is a
    first-install-only transport for something that gets updated.

So the disk ships as a file in the dist archive and is uploaded with
IND$FILE from the operator's 3270 emulator — the one path that needs
neither mvsMF nor ftpd on the target.

Verified before writing any of this

  • IND$FILE is present on the reference system (SYS2.CMDLIB).
  • Binary is the default (no ASCII/CRLF), and RECFM then defaults to U
    (ind_file370 c/indparse.c:249-256).
  • Blocking is exact: RECFM=U goes through __fputc, which flushes at BLKSIZE
    (libc370 src/clib/@@fputc.c:24), so BLKSIZE(4096) writes 4096-byte
    blocks. A 1 MB image is 256 whole blocks, no remainder.
  • A pre-allocated dataset is the safe path: IND$FILE allocates an existing
    dataset DISP=SHR and takes its DCB, and only falls back to NEW CATALOG when
    it does not exist (ind_file370 c/indmain.c:190-200, :273). That makes the
    upload independent of which IND$FILE build the system carries.
  • Wrong blocking is caught at mount: ufsd checks 1 << blksize_shift against
    the dataset BLKSIZE and answers UFSD062E SUPERBLOCK VALIDATION FAILED
    (ufsd src/ufsd#sbl.c:69).
  • DISP=SHR is the trap: IND$FILE will rewrite a dataset UFSD has mounted.
    UNMOUNT PATH=/www has to be a numbered step, not a footnote.
  • Encoding needs no decision and no conversion. http_send_file() translates
    UFS files with the hard-coded IBM-1047 table, independent of CODEPAGE=
    (src/httpfile.c:70-71), which is exactly what ufsd-utils cp writes.
    Measured end-to-end: ufsd-utils cp -> stored bytes -> ibm1047_etoa gives
    back static/index.html byte for byte, UTF-8 sequences included. Over all
    256 byte values only 0x85 and 0xF7 fail to round-trip.
  • httpget.c:68 appends index.html for a directory request, so / serves
    the shipped page.

What to do

  • make webroot builds dist/httpd-webroot.img from static/ with
    ufsd-utils (pinned release, fetched into .mbt/tools/ when not on
    PATH — CI runs the shared mbt workflow and cannot install it otherwise).
    1 MB = 256 blocks, 62 inodes; explicit --owner/--group so the
    artifact does not carry the build machine's userid.
  • package and dist depend on it; [distribution] extra puts it in the
    zip/tar.gz. Publish the SHA256 rather than claiming reproducibility --
    the image carries creation timestamps.
  • samplib/httpwebr: allocation job for HTTPD.@VRM@.WEBROOT.UFS
    (SPACE=(4096,256), DCB=(DSORG=PS,RECFM=U,BLKSIZE=4096), primary
    extent only, mirroring ufsd's UFSFMT ALLOC step).
  • docs/installation.md: a numbered section for the webroot disk --
    allocate, upload with IND$FILE, mount at /www, verify, and the
    unmount-before-re-upload rule.
  • smp-todo.md O3: replace U1-U6 with the decided path.

Not in this change

CODEPAGE=IBM1047 in the shipped HTTPPRM0 was considered and rejected on
measurement. cc370 compiles string literals in CP037 (common/src/mvs370.c
mvs_a2e_tab), and CODEPAGE= governs exactly those. Under IBM1047 a [
compiled as 0xBA leaves as 0xDD, which would break every mvsMF array
response -- the primary route in the shipped configuration -- plus httpd's own
login form and error pages. Live check on the reference system: [ currently
arrives as 0x5B under the CP037 default. Static UFS files are unaffected
either way because they never consult the setting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions