Skip to content
Mingye Wang edited this page Apr 30, 2021 · 30 revisions

This page describes the general automount mechanism of macOS, and how it may apply to filesystems that use osxfuse.

The automount mechanism of macOS operates through filesystem bundles specifying rules to probe, mount, and fix physical filesystems. They are located in /Library/Filesystems/*.fs (or the /System equivalent for built-in ones), and the crux of it lies in, as with other Bundles, Contents/Info.plist.

Data structures: The filesystem properties of Info.plist

To define a bundle as a filesystem bundle, the following information is needed under the top-level plist:

<key>CFBundlePackageType</key>
<string>fs  </string>
<key>CFBundleSignature</key>
<string>????</string>

Its behavior is then defined using the top-level keys FSMediaTypes and FSPersonalities, with the observed data structure of:

// Defines how to probe for filesystems.
typealias FSMediaTypes = [GuessFS: FSMediaType]
// A name of unknown importance.
typealias GuessFS = String
struct FSMediaType {
  var FSMediaProperties: FSMediaProperties
  // Can be empty.
  var FSProbeArguments: String
  // Just executable name. Unknown what the PATH is relative to.
  // See https://opensource.apple.com/source/ntfs/ntfs-94.200.1/util/ntfs.util.c.auto.html for expected behavior.
  var FSProbeExecutable: String
  // Presumably smaller means higher priority.
  var FSProbeOrder: Integer
}
struct FSMediaProperties {
  // If present, filter for matching GUID or MBR partition type name [IOFDiskPartitionScheme.h].
  var Content_Hint: String?
  // Whether to apply test to partitions or the entire disk. Defaults to false for both.
  var Leaf: Bool?
  var Whole: Bool?
}

// Usually only one dict member, but more complex cases exist (cd9660, hfs, fusefs...). Defines actions and properties.

// Subtype is 
typealias FSPersonalities = [String: FSPersonality]
struct FSPersonality {
  var FSName: String
  // Zero-based index to identify a personality when there are multiple, so a name can be chosen.
  var FSSubType: Integer

  // Utils: See notes on probe.
  var FSFormatExecutable: String?
  var FSFormatArguments: String?
  var FSMountExecutable: String?
  var FSMountArguments: String?
  var FSRepairExecutable: String?
  var FSRepairArguments: String?
  var FSVerificationExecutable: String?
  var FSVerificationArguments: String?

  // Format options.
  // Probably defines the MBR partition type on format.
  var FSFormatContentMask: String?
  // In bytes, I think.
  var FSFormatMaximumSize: Integer?
  var FSFormatMinimumSize: Integer?
  // Unknown purpose, udf.fs.
  var FSFormatInteractive: Bool?

  // Set for Encrypted APFS and HFS. Goes with FSVerificationExecutable.
  var FSLiveVerificationArguments: String?
  // Goes with FSVerificationExecutable. Undocumented, but pretty obvious syntax. (It's a plist XML!)
  var FSXMLOutputArgument: String?
  // Only seen for HFS and APFS. Obvious meaning, not-so-obvious implications.
  var FSfileObjectsAreCasePreserving: Bool?
  var FSfileObjectsAreCaseSensitive: Bool?
  var FSvolumeNameIsCasePreserving: Bool?
}

(This part is not written as a plist for obvious reasons.)

Other Contents in the bundle

Most filesystems have a way to change the mount icon of the fs. It's probably done via a manual call of the setIcon(_:forFile:options:) API in AppKit (with some volume-specific magic; see fileicon). osxfuse makes it open to change via volicon. With no icons, the .VolumeIcon.icns should take over.

The FS bundle does not directly have an executable under MacOS like kexts and apps do. Instead, all executables are placed under Resources, and the PATH for the plist executables above are prepended with it.

Open questions

  1. osxfuse already pretends to be its own fs via fusefs.fs. Can we still make a foo.fs that calls it? (Would it cause some logical error somewhere down the line?) Or must we patch its Info.plist instead?
  2. How is the mapping between FSMediaTypes and FSPersonalities defined? As in, how does the system know which personality to use after a MediaType probe hits?

Appendix A. What about Network Filesystems?

Network filesystems reside in /Library/Filesystems/NetFSPlugins/*.bundle, and are bona fide plug-ins (loadable bundles). Techie from the cradle has an article on how these really work. You will need to write a little bit of C to make it work; the ones in /Systems are as usual good examples.