Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

How can I get the system to use my FSModule for probing?

I've gotten to the point where I can use the mount(8) command line tool and the -t option to mount a file system using my FSKit file system extension, in which case I can see a process for my extension launch, probe, and perform the other necessary actions.

However, when plugging in my USB flash drive or trying to mount with diskutil mount, the file system does not mount:

$ diskutil mount disk20s3
Volume on disk20s3 failed to mount
If you think the volume is supported but damaged, try the "readOnly" option
$ diskutil mount readOnly disk20s3
Volume on disk20s3 failed to mount
If you think the volume is supported but damaged, try the "readOnly" option

Initially I thought it would be enough to just implement probeExtension(resource:replyHandler:) and the system would handle the rest, but this doesn't seem to be the case. Even a trivial implementation that always returns .usable doesn't cause the system to use my FSModule, even though I've enabled my extension in System Settings > General > Login Items & Extensions > File System Extensions.

From looking at some of the open source msdos and Disk Arb code, it seems like my app extension needs to list FSMediaTypes to probe. I eventually tried putting this in my Info.plist of the app extension:

<key>FSMediaTypes</key>
<dict>
	<key>EBD0A0A2-B9E5-4433-87C0-68B6B72699C7</key>
	<dict>
		<key>FSMediaProperties</key>
		<dict>
			<key>Content Hint</key>
			<string>EBD0A0A2-B9E5-4433-87C0-68B6B72699C7</string>
			<key>Leaf</key>
			<true/>
		</dict>
	</dict>
	<key>0FC63DAF-8483-4772-8E79-3D69D8477DE4</key>
	<dict>
		<key>FSMediaProperties</key>
		<dict>
			<key>Content Hint</key>
			<string>0FC63DAF-8483-4772-8E79-3D69D8477DE4</string>
			<key>Leaf</key>
			<true/>
		</dict>
	</dict>
	<key>Whole</key>
	<dict>
		<key>FSMediaProperties</key>
		<dict>
			<key>Leaf</key>
			<true/>
			<key>Whole</key>
			<true/>
		</dict>
	</dict>
	<key>ext4</key>
	<dict>
		<key>FSMediaProperties</key>
		<dict>
			<key>Content Hint</key>
			<string>ext4</string>
			<key>Leaf</key>
			<true/>
		</dict>
	</dict>
</dict>
</plist>

(For reference, the partition represented by disk20s3 has a Content Hint of 0FC63DAF-8483-4772-8E79-3D69D8477DE4 and Leaf is True which I verified using IORegistryExplorer.app from the Xcode additional tools.)

Looking in Console it does appear now that the system is trying to use my module (ExtendFS_fskit) to probe when I plug in my USB drive, but I never see a process for my extension actually launch when trying to attach to it from Xcode by name (unlike when I use mount(8), where I can do this). However I do see a Can't find the extension for <private> error which I'm not sure is related but does sound like the system can't find the extension for some reason.

The below messages are when filtering for "FSKit":

default	19:14:53.455826-0400	diskarbitrationd	probed disk, id = /dev/disk20s3, with ExtendFS_fskit, ongoing.
default	19:14:53.456038-0400	fskitd	Incomming connection, entitled 1
default	19:14:53.456064-0400	fskitd	[0x7d4172e40] activating connection: mach=false listener=false peer=true name=com.apple.filesystems.fskitd.peer[350].0x7d4172e40
default	19:14:53.456123-0400	fskitd	Hello FSClient! entitlement yes
default	19:14:53.455902-0400	diskarbitrationd	[0x7461d8dc0] activating connection: mach=true listener=false peer=false name=com.apple.filesystems.fskitd
default	19:14:53.456151-0400	diskarbitrationd	Setting remote protocol to all XPC
default	19:14:53.456398-0400	fskitd	About to get current agent for 501
default	19:14:53.457185-0400	diskarbitrationd	probed disk, id = /dev/disk20s3, with ExtendFS_fskit, failure.
error	19:14:53.456963-0400	fskitd	-[fskitdXPCServer applyResource:targetBundle:instanceID:initiatorAuditToken:authorizingAuditToken:isProbe:usingBlock:]: Can't find the extension for <private>

(I only see these messages after plugging my USB drive in. When running diskutil mount, I see no messages in the console when filtering by FSKit, diskarbitrationd, or ExtendFS afterward. It just fails.)

Is there a step I'm missing to get this to work, or would this be an FSKit bug/current limitation?

Is there a step I'm missing to get this to work, or would this be an FSKit bug/current limitation?

I haven't had a chance to look into this yet and I'm not sure when I will (given WWDC prep) but in the meantime please file a bug on this then post the bug number once it's filed. As you're seeing, there are significant gaps in the FSKit documentation and we need bugs filed to get those addressed.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

@DTS Engineer No worries, I'm sure this is a busy time for all of you. Filed FB17772372, sample project included.

As a side note, you only need "-F" with mount when you have BOTH an FSKit implementation and a KEXT implementation with the same short name. By default, any existing KEXT implementations are preferred over FSKit implementations.

When a short name matches only an FSKit implementation, it will be selected by the mount(8) command.

@DTS Engineer No worries, I'm sure this is a busy time for all of you. Filed FB17772372, sample project included.

I was able to get the engineering team to look at your bug and here's where things stand:

  1. There is a bug on our side (specifically in diskarbitrationd) which is causing probe to incorrectly fail. I obviously can't comment on release schedules or plans, but the bug is considered a high priority.

  2. The project you included does not implement FSManageableResourceMaintenanceOperations, but DiskArb requires a success from startCheck(task:options:) in order to automount. Note that you can test/run this particular task using /sbin/fsck_fskit.

Per the engineering team, once both of those are resolved (to be clear, #1 being entirely our bug), DiskArb should automount that volume/driver. To be clear, #2 may have been a choice on your part to minimize the test project (which is perfectly reasonable), but I want to pass that back to you just to make sure you were aware of the issue.

Also, as a minor note on FSManageableResourceMaintenanceOperations, while diskutil does not currently have full integration with FSKit, you can test/use startFormat(task:options:) by running /sbin/newfs_fskit.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Note also that diskarbitrationd requires that a file system implement check (fsck) in order to be mounted via DA.

For FSKit, a module should conform to FSManageableResourceMaintenanceOperations and implement startCheckWithTask:options:error:.

This method accepts a task, and attempts to start a check on the container. This method is called after a loadResource:, which supplied the resource(s). It should parse the command options options and assess. If there are no errors in the command options, the method should start the check. Otherwise it should return an error (throw in Swift, *error = in ObjC).

startCheckWithTask: (and startFormatWithTask:) either returns an NSProgress * when the task starts, or it returns an error.

The check (or format) must be performed on another thread – asynchronously.

Once a task successfully starts, the module reports task completion by calling the didCompleteWithError: method on the supplied task. Pass in nil for successful completion and an error for failure.

The two command line options required by DiskArbitration are -y and -q. -q performs a "quick" check. This check should quickly assess the file system to see if it needs repair. If this check fails, DiskArbitration will perform a full check with -y before minting the file system. If that check passes, DiskArbitration will mount the file system. Otherwise it will not.

A common flow for -q is to assess that the superblock looks ok (right signature?) and assess if the file system is flagged as dirty.

The fsck_fskit -t shortname command can start a check operation.

The same flow applies for formatting. A module conforms to FSManageableResourceMaintenanceOperations, implements the required method startCheckWithTask:options:error:, and then implements the optional method startFormatWithTask:options:error:. The newfs_fskit -t shortname tool can perform a format.

How can I get the system to use my FSModule for probing?
 
 
Q