I'm trying to use FSKit to create a File System Extension that can read MFS-formatted disk images, following the old MFSLives sample project for reference.
I have a well-formed MFS formatted img
file that I'm trying to mount, but I'm having trouble getting the system to actually use my FSModule
.
DiskImageMounter fails to mount the img
file, but I'm able to use it to attach the image as a device by clicking "Ignore" when it prompts me that it isn't able to read the disk. This is effectively the same as using the hdiutil
command in Terminal.
hdiutil attach -imagekey diskimage-class=CRawDiskImage -nomount Sample.img
I've read that FSKit isn't fully integrated with Disk Arbitration yet, so I decided to see if I could force the system to use my extension by using the mount
command.
mkdir /tmp/Sample
mount -F -t MFS disk54 /tmp/Sample
Watching the logs in Console, I can see that fskit_agent
sees my extension in its "New Modules List", and I see an MFS
process gets launched and logs messages from com.apple.running
and com.apple.xpc
. However, the logs from the MFS
process end there, and don't include any of my debug logs, which should be posted when my FSFileSystem
subclass is created or when probeResource
is called.
Ultimately the mount
command fails with exit code 69
and prints the following error message:
mount: Probing resource: The operation couldn’t be completed. Permission denied
mount: Unable to invoke task
I've checked everything I could think of:
- The extension is enabled in System Settings.
- The extension has the FSKit Module capability added in Xcode.
- The
Info.plist
sets theFSSupportsBlockResources
key toYES
. - The
Info.plist
sets both theFSName
andFSShortName
keys toMFS
. - The extension has its Team set to my developer account, with Xcode setting the Provisioning Profile and Signing Certificate automatically.
- The hosting app has its Team set to my developer account with the "Development" signing certificate.
I wanted to see if it was something with my project configuration or implementation, so I downloaded the KhaosT/FSKitSample project from GitHub. Once I got that building, I tried mounting a disk image using the MyFS extesnion, but my system wouldn't run that either.
Is there something about the system configuration I should be aware of to enable File System Extensions? I have my MFS extension showing up and enabled, but I'm not sure if there's something I'm missing that I still have to do.
Is there a capability or signing requirement I didn't list that's required for the extension to run? The documentation doesn't specify anything about the entitlements, signing capabilities, or Info.plist
keys, so I'm not sure what I should be looking for.
I'm running macOS Sequoia 15.6.1 on an M2 Max MacBook Pro, and I'm building my project with Xcode 26 beta 6.
I'm trying to use FSKit to create a File System Extension that can read MFS-formatted disk images, following the old MFSLives sample project for reference.
I think this is a lovely idea and greatly enjoy the idea that macOS might someday regain full read/write support for MFS.
DiskImageMounter fails to mount the img file, but I'm able to use it to attach the image as a device by clicking "Ignore" when it prompts me that it isn't able to read the disk. This is effectively the same as using the hdiutil command in Terminal.
So, looking over what you wrote, this is what immediately jumped out at me:
"diskimage-class=CRawDiskImage"
That shouldn't be necessary. Any DiskImage we shipped would have been in one of our standard DiskImage formats, so hdiutil should have attached the image without any additional argument. You're using it because without that argument, hdiutil fails because it doesn't recognize the image, and that's because it's using an old format we dropped support for at some point in the now distant past.
However, the problem here is that what "CRawDiskImage" is doing is treating the data file as raw disk data, which means it's ALSO including the original header data for the old disk image format, which throws off the offsets of the entire volume.
In any case, the solution here is to delete the first 0x54 (84d) bytes*.
*Thank you to Quinn for doing the legwork on this.
That makes the first bytes of the file:
0x4C4B6000 00860012
And, more importantly, it means that the data starting at byte 1024 is:
0xD2D79A4E FFC8C125
...so that the first two bytes of logical block 2 are the MFS volume signature:
enum {
kMFSSigWord = 0xD2D7
};
You'll also note that this makes the file 419,200 bytes, which is exactly 818 (512-byte) blocks, just like a real block storage device would be.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware