Port f3probe, f3brew, and f3fix to macOS - #283
Conversation
9023d0c to
a8f17ee
Compare
|
For anyone who wants to try this on macOS without building manually, I have published a Homebrew tap pinned to this PR branch: Tap: https://github.com/sbrunner-atx/homebrew-f3 (README includes macOS usage notes: raw whole-disk device, unmount first, sudo). I will retire the tap once this is merged and the official formula picks up Full f3probe hardware-validation transcript (genuine SanDisk Ultra 128 GB, macOS 26.5 Intel) available on request. |
f3-drive-test-macos.sh drives a complete erase / f3write / f3read cycle on macOS with diskutil, adding what ad-hoc use of the tools tends to get wrong: - refuses to run on internal disks or partition slices, and asks for explicit confirmation naming the drive label before erasing - records the USB location ID and device serial number next to a user-chosen drive label, so logs stay attached to the physical drive even though macOS reassigns diskN numbers by connection order - unmounts and remounts between write and read so f3read measures the drive instead of the page cache - optional cooldown (--cooldown SEC, or --replug for a physical unplug) between write and read, and repeated read passes (--reads N), for diagnosing drives that drop off the bus under sustained I/O, e.g. from overheating: compare failure time across back-to-back passes - per-drive timestamped logs and a summary table of all read passes Only needs f3write/f3read (PATH or ../build), so it works on macOS with the stock tools, independent of the extra-tools port in #283. This grew out of diagnosing a batch of refurbished 128 GB drives where one unit passed a full 114 GB write but could not sustain more than about 90 seconds of reading before disconnecting - a failure mode that a single write/read pass with default settings does not isolate.
The probing algorithm (libprobe.c) is platform-independent; only the device-access layer in libdevs.c was Linux-specific. This commit adds an __APPLE__ backend: - open() with F_NOCACHE replaces O_DIRECT (with _DARWIN_C_SOURCE so the Darwin extensions stay visible despite _POSIX_C_SOURCE) - DKIOCGETBLOCKCOUNT/DKIOCGETBLOCKSIZE replace BLKGETSIZE64/BLKSSZGET - whole-disk detection by device-name convention (/dev/rdiskN vs /dev/rdiskNsM) replaces the udev devtype check - manual USB reset (used by f3brew only; f3probe uses RT_NONE) is implemented by polling the device node instead of a udev monitor - software USB reset (USBDEVFS_RESET) reports EOPNOTSUPP on macOS - posix_fadvise(DONTNEED) is skipped; F_NOCACHE already bypasses the page cache f3fix on macOS is a new libparted-free backend (f3fix_darwin.c) that writes the MBR directly: fixing a fake drive only ever needs a single MBR partition ending at the last good sector reported by f3probe. MBR only for now; GPT is unnecessary for this use case. The Linux build is unchanged: all __APPLE__ additions are guarded and the Linux path compiles the same objects with no new warnings. Tested on macOS 26.5 (Intel, MacBookPro16,1): make extra builds all three tools with clang and brew argp-standalone, and f3probe --debug-unit-test reports Perfect. Closes AltraMayor#8. Closes AltraMayor#135.
a8f17ee to
0929ebe
Compare
|
Rebased onto current master; builds clean on macOS with I see #285 covers much of the same ground for f3probe and f3brew. Rather than have you compare two black boxes, here is my honest read:
Testing was on Intel macOS against five physical SanDisk Ultra 128 GB drives, three good and two defective. The bad ones accept a full-capacity write and then drop off the USB bus 37 to 100 seconds into read-back. f3probe reported the good ones correctly: usable size = announced size, 114.60 GB. One gap I should name: the two defective drives went back to the seller before I thought to run f3probe against them, so I have no transcript of the port's error paths under a mid-probe disconnect. If that matters to you, say so and I will reproduce it the next time a drive fails on me. Happy to rebase the f3fix part on top of #285 so it lands separately, if that is easier for you to review. |
|
Hi @sbrunner-atx, Given your effort to port all three extra tools to macOS, I'm assuming that you're willing to join forces to get your code merged. My main concern with the proposed code at this point is the widespread of #if defined(__linux__)
#include "linux_libdevs.c"
#elif defined(__APPLE__)
#include "darwin_libdevs.c"
#else
#error "Platform not supported"
#endifI'm open to evaluating other ways to organize the code if you have alternative approaches to propose. If you choose to move forward with this work, keep this pull request open and create another pull request following the new approach to organize the code and only port Finally, we should invite the developers of pull requests #279 and #285 to collaborate with us. They can help by reviewing code, testing, and, perhaps, even writing some of the code. Their help would be important because I'm not a Mac developer and don't have a Mac. If we all pull this off, we may motivate other developers to port the extra tools to their platforms. So many more users will benefit from the extra tools on their platform. |
What
Ports the three extra tools - f3probe, f3brew, and f3fix - to macOS, as invited by #8 and requested in #135.
How
The probing algorithm (libprobe.c) is already platform-independent; only the device-access layer needed work. All changes are behind APPLE guards:
f3fix on macOS is a new libparted-free backend (f3fix_darwin.c) that writes the MBR directly - fixing a fake drive only ever needs a single MBR partition ending at the last good sector from f3probe. MBR only for now; GPT support could follow if there is demand.
Validation
On macOS 26.5 (Intel, MacBookPro16,1), clang + brew argp-standalone:
The Linux build is unchanged: gcc on Ubuntu compiles all targets with no new warnings, and the Linux code path is untouched.
Notes