Stopping Spotlight etc. from changing ZFS without permission

From OpenZFS on OS X
Jump to: navigation, search

The Issue[edit]

ZFS is a great solution for backing up data, and moving data between platforms (e.g. Linux and Mac OS X). However, if you connect an external ZFS drive to Mac OS X, you may be unpleasantly surprised to find that Spotlight, Finder etc. will modify the filesystems on the drive without asking (and even in violation of the user privileges granted by those filesystems). This goes against several basic principles that you probably expect:

  • the filesystem should not change unless you change data on the filesystem. E.g. simply plugging in the drive should not change the filesystem.
  • any attempted changes to the filesystem should obey the privilege rules set on that filesystem. E.g. if the current user plugging in the drive lacks write privileges to the filesystem, no changes should be allowed.

However, Spotlight, Finder etc. do not obey these expectations. This can lead to serious problems for standard ZFS activities such as snapshot based backup. For example, say you backup data by sending ZFS snapshots from one ZFS filesystem to another ZFS drive. When you try to push incremental snapshots to an existing filesystem, it may fail with messages like "data has been changed since snapshot XYZ" -- even if you never wrote to that backup filesystem since your last snapshot. Now you are in a quandary. You will have to manually investigate the backup filesystem(s) to see what all the changes are, and whether might be any changes that need to be preserved (rather than just rolled back). If you are used to working with ZFS on Linux this may initially baffle you, because on Linux a ZFS filesystem will not change in content unless you deliberately write data to it!

The following Mac OS X services will modify your ZFS filesystems silently:

  • Spotlight
  • Finder (.DS_Store, Trash)

Solutions[edit]

  • in general, if you are connecting an external ZFS drive to a Mac solely to READ data from it, just import it readonly. This is the one trivially easy way to avoid the whole problem, e.g.:

zpool import -o readonly=on tank

If that is not an option, then you are going to have clean up your ZFS filesystems (every time) after OS X has "dirtied" them:

  • always take a snapshot of ZFS filesystems BEFORE plugging them in to a Mac. This makes it relatively easy to know which changes are "OS X dirt" vs. previous data changes that you made before plugging into the Mac, and to rollback the dirt. For example: zfs diff -H tank@lastsnap tank will give you a list of new, modified and deleted files since lastsnap. Use Google to learn what Spotlight and Finder's hidden file names are.
  • if you did not deliberately make changes to a given ZFS filesystem while connected to the Mac, then just rollback to the latest snapshot (as your first action once you import that drive to a non-Mac host).
  • add "flag files" to each file system to prevent various OS X services from dirtying them. E.g. touch /tank/.metadata_never_index should prevent Spotlight indexing. We should collect a list here of all the rules for preventing such "dirty" services (further instructions).

A more extensive approach to add "flag files" and disable macOS services from polluting the file system:

# set the name of your ZFS pool on macOS, e.g.
zpool_name=tank
# Remove macOS specific files from Spotlight, fseventsd, and the Trashes, create dummy files instead
sudo rm -rfv /Volumes/$zpool_name/.{,_.}{fseventsd,Spotlight-V*,Trashes}
sudo mkdir -pv /Volumes/$zpool_name/.fseventsd
sudo touch /Volumes/$zpool_name/.fseventsd/no_log /Volumes/$zpool_name/.metadata_never_index /Volumes/$zpool_name/.Trashes
# Turn off Spotlight indexing and remove the .Spotlight-V* folders in newer macOS versions
sudo mdutil -i off /Volumes/$zpool_name
sudo mdutil -X /Volumes/$zpool_name
# Optionally, change ownership to current user to enable zfs volume operations w/o sudo
sudo chown -R "$USER" /Volumes/$zpool_name