. "$BST_LIB" # Neither busybox nor toybox ships an hdparm applet on this image, so a bare # `hdparm` already is this port; the update-alternatives registration at # priority 100 is uncontested and /sbin/hdparm resolves to hdparm.hdparm. require hdparm hdparm/present tmp=${TMPDIR:-/tmp}/bst-hdparm.$$ idout="$tmp.id"; iderr="$tmp.iderr"; out="$tmp.out"; reg="$tmp.reg" # hdparm exists to drive block devices, and THIS KERNEL HAS NO BLOCK LAYER # (CONFIG_BLOCK is not set): no "Block devices:" section in /proc/devices, no # /proc/partitions, no /sys/block, and no block-special node anywhere in /dev. # So the suite splits in two. Everything that does not need a device is asserted # for real; everything that does is probed at RUNTIME and skips only when the # probe confirms the absence — if this machine ever gains a block device the # same cases run the real assertion instead of reporting a stale skip. blkdev="" for d in /dev/*; do if [ -b "$d" ]; then blkdev="$d"; break; fi done # ---------------------------------------------------------------- identity --- check_out hdparm/version "hdparm v9.65" hdparm -V # With no arguments hdparm prints its usage and exits EINVAL(22) — a documented # status, not a crash, so it is asserted as a value rather than "nonzero". check_rc hdparm/usage-rc 22 sh -c "hdparm > '$out' 2>&1" check_out hdparm/usage-text "get/set hard disk parameters" cat "$out" # -h is the same text on the success path. check_rc hdparm/help-rc 0 sh -c "hdparm -h > '$out' 2>&1" check_out hdparm/help-istdin "--Istdin" cat "$out" # update-alternatives owns the name; the real binary is hdparm.hdparm. check_out hdparm/alternative "hdparm.hdparm" readlink /sbin/hdparm # ------------------------------------------------- the IDENTIFY decoder ------ # --Istdin reads a 256-word ATA IDENTIFY block as ASCII hex and runs hdparm's # whole decoder over it with NO device and NO ioctl (it calls identify(-1,...), # and the two places that would touch the fd are guarded on fd == -1). That # makes it the one path on this target that exercises hdparm's largest body of # real logic end to end, so it carries most of this suite. The payload is a # synthetic drive whose every asserted field was chosen when it was generated, # so each case below is a round-trip through the decoder, not a tautology. hdparm --Istdin < "$BST_DATA/hdparm-identify.hex" > "$idout" 2>"$iderr" idrc=$? check_eq hdparm/istdin-rc 0 "$idrc" # The decode must be clean: this path talks to no device, so anything on stderr # would mean it tried to. if [ -s "$iderr" ]; then bst_notok hdparm/istdin-silent "stderr not empty: $(_bst_1line "$(cat "$iderr")")" else bst_ok hdparm/istdin-silent fi check_out hdparm/istdin-ata "ATA device, with non-removable media" cat "$idout" check_out hdparm/istdin-model "BRINTOS WASM32 TESTDISK" cat "$idout" check_out hdparm/istdin-serial "BST0000000000198" cat "$idout" check_out hdparm/istdin-firmware "BST9.65" cat "$idout" # The two capacity views are decoded from different word ranges — words 60/61 # for 28-bit LBA and words 100..103 for LBA48 — so they are asserted separately # even though this drive reports the same count in both. check_eq hdparm/istdin-lba 2097152 "$(grep 'LBA user addressable sectors' "$idout" | awk '{print $NF}')" check_eq hdparm/istdin-lba48 2097152 "$(grep 'LBA48 user addressable sectors' "$idout" | awk '{print $NF}')" # ...and the byte-size lines are computed from that count, so they check the # arithmetic rather than repeating the field. check_out hdparm/istdin-size-mib "device size with M = 1024*1024: 1024 MBytes" cat "$idout" check_out hdparm/istdin-size-mb "1073 MBytes (1 GB)" cat "$idout" check_out hdparm/istdin-sector-size "Logical Sector size: 512 bytes" cat "$idout" # Word 217 == 1 means non-rotating media; hdparm renders that as a phrase. check_out hdparm/istdin-rotation "Nominal Media Rotation Rate: Solid State Device" cat "$idout" # The starred entry is the SELECTED mode, decoded from word 88's high byte — # a different decode than the "supported" list beside it. check_out hdparm/istdin-udma-selected "*udma5" cat "$idout" check_out hdparm/istdin-pio "pio0 pio1 pio2 pio3 pio4" cat "$idout" # Feature-set decoding out of words 82..87. check_out hdparm/istdin-feature-lba48 "48-bit Address feature set" cat "$idout" check_out hdparm/istdin-feature-smart "SMART feature set" cat "$idout" # Word 255 is the integrity word: signature 0xA5 plus a checksum byte chosen so # all 512 bytes sum to 0 mod 256. "correct" means hdparm recomputed it and # agreed, which no other case here proves. check_out hdparm/istdin-checksum "Checksum: correct" cat "$idout" # A short block is refused, and the diagnostic names how much arrived. hdparm # exits with a nonzero status here; the value is whatever errno happened to # hold (see the design doc — upstream reports a stale errno on a plain EOF), so # only the message and the failure are asserted, not the number. head -2 "$BST_DATA/hdparm-identify.hex" > "$tmp.short" sh -c "hdparm --Istdin < '$tmp.short' > '$out' 2>&1" shortrc=$? if [ "$shortrc" -ne 0 ]; then bst_ok hdparm/istdin-short-rc else bst_notok hdparm/istdin-short-rc "a 16-word block was accepted (rc=0)"; fi check_out hdparm/istdin-short-msg "read only 16/256 IDENTIFY words from stdin" cat "$out" # ------------------------------------------- the device path reaches the OS --- # hdparm does not check that its argument is a block device: it opens whatever # path it is given and issues the ioctls. On this target that is exactly what # makes the path testable — every one of them comes back ENOTTY(25) from the # kernel with an errno hdparm can print, rather than trapping the way an # unresolved symbol would. A binary that died on the first ioctl would produce # none of this output, so these cases ARE the no-trap proof at runtime. : > "$reg" check_rc hdparm/notty-identify-rc 25 sh -c "hdparm -i '$reg' > '$out' 2>&1" check_out hdparm/notty-identify "HDIO_GET_IDENTITY failed: Inappropriate ioctl for device" cat "$out" check_rc hdparm/notty-geom-rc 25 sh -c "hdparm -g '$reg' > '$out' 2>&1" check_out hdparm/notty-geom "BLKGETSIZE failed: Inappropriate ioctl for device" cat "$out" check_rc hdparm/notty-rdonly-rc 25 sh -c "hdparm -r '$reg' > '$out' 2>&1" check_out hdparm/notty-rdonly "BLKROGET failed: Inappropriate ioctl for device" cat "$out" # -v drives several distinct ioctls in a single run; all four returning is a # stronger statement than any one of them, because it shows the process survives # repeated failed ioctls instead of dying on the first. sh -c "hdparm -v -i '$reg' > '$out' 2>&1" n=$(grep -c 'Inappropriate ioctl for device' "$out") if [ "$n" -ge 4 ]; then bst_ok hdparm/verbose-multi-ioctl else bst_notok hdparm/verbose-multi-ioctl "expected >=4 ioctl diagnostics, got $n"; fi # An absent path is ENOENT from open(), before any ioctl — a different failure # mode from the ones above and reported as such. check_rc hdparm/enoent-rc 2 sh -c "hdparm -i /dev/nosuchdisk > '$out' 2>&1" check_out hdparm/enoent "No such file or directory" cat "$out" # ------------------------------------------------- block-layer-gated cases --- # Each of these runs the real assertion the moment a block device exists. if [ -n "$blkdev" ]; then check hdparm/geometry hdparm -g "$blkdev" check hdparm/identify hdparm -I "$blkdev" else bst_skip hdparm/geometry "no block layer on this kernel (CONFIG_BLOCK not set): no /proc/partitions, no /sys/block, no block-special node in /dev — hdparm's primary function has no device to act on" bst_skip hdparm/identify "no block device to IDENTIFY; the decoder itself is covered by the istdin-* cases above" fi # --fibmap maps a file's extents, then looks its st_dev up among the block # nodes in /dev to name the device — so it needs the block layer even though its # argument is an ordinary file. It fails with hdparm's own message, not an # ioctl error. echo hello > "$tmp.fib" if [ -n "$blkdev" ]; then check hdparm/fibmap hdparm --fibmap "$tmp.fib" else sh -c "hdparm --fibmap '$tmp.fib' > '$out' 2>&1" if grep -q 'device not found in /dev' "$out"; then bst_skip hdparm/fibmap "no block layer: hdparm resolves the file's st_dev against /dev and finds no block node ('device not found in /dev')" else bst_notok hdparm/fibmap "expected the no-block-device diagnostic, got: $(_bst_1line "$(cat "$out")")" fi fi # The man page is packaged into hdparm-doc and this image installs no -doc # packages. Not a defect, and it flips green by itself if that ever changes. if [ -f /usr/share/man/man8/hdparm.8 ] || [ -f /usr/share/man/man8/hdparm.8.gz ]; then check_out hdparm/man-page "HDPARM" sh -c "zcat -f /usr/share/man/man8/hdparm.8* 2>/dev/null | head -40" else bst_skip hdparm/man-page "hdparm.8 ships in hdparm-doc; this image installs no -doc packages" fi # wiper.sh is dropped by the meta-brintos bbappend: its RDEPENDS drags in bash, # which does not build on wasm32-hwjs, and it TRIMs a real SSD that this target # cannot have. Assert it stayed out, so a recipe change that reinstates it is # caught here rather than by a stalled build. if [ -e /usr/bin/wiper.sh ]; then bst_notok hdparm/no-wiper "wiper.sh is installed; it pulls bash into the build closure" else bst_ok hdparm/no-wiper fi rm -f "$tmp".* "$reg" "$idout" "$iderr" "$out" 2>/dev/null