Symlinks became files, containing relative paths, within an app bundle, why? How to fix

afpfilesystemhfs+installsymlink

I discovered an interesting form of corruption within some application bundles which had been stored on a file server for months and years.

The application bundles were installers for various macOS versions, if it matters. I attempted to run Install macOS High Sierra.app. It ran for a few seconds, then hung. I had to Force Quit the installer from Activity Monitor. The relevant clue in the Console was:

2019-09-02 05:44:29.222 com.apple.xpc.launchd[1]:
(com.apple.install.osinstallersetupd[11106]) Could not find and/or
execute program specified by service: 2: No such file or directory:
/Applications/Install macOS High Sierra.app/Contents/Frameworks/OSInstallerSetup.framework/osinstallersetupd

Using the Terminal to explore the contents of the installer app (which is of course a Application Bundle directory), I found this where the installer was looking for osinstallersetupd:

% cd /Applications/Install\ macOS\ High\ Sierra.app/Contents/Frameworks/OSInstallerSetup.framework
% ls -l
total 16
-rwxrwxrwx  1 jdlh  admin   33  9 Jul  2018 OSInstallerSetup
-rwxrwxrwx  1 jdlh  admin   26  9 Jul  2018 Resources
drwxrwxrwx  4 jdlh  admin  136  9 Jul  2018 Versions
% more OSInstallerSetup 
Versions/Current/OSInstallerSetup
% more Resources 
Versions/Current/Resources

So interestingly, OSInstallerSetup and Resources were plain files, containing relative paths as text. I looked in the corresponding place in a freshly-downlowed, and correctly running, installer:

% ls -l /Applications/Install\ macOS\ Mojave.app/Contents/Frameworks/OSInstallerSetup.framework 
total 16
lrwxr-xr-x  1 root  wheel   33  2 Sep 05:23 OSInstallerSetup -> Versions/Current/OSInstallerSetup
lrwxr-xr-x  1 root  wheel   26  2 Sep 05:23 Resources -> Versions/Current/Resources
drwxr-xr-x  4 root  wheel  136  2 Sep 05:23 Versions

So it seems OSInstallerSetup and Resources were supposed to be symbolic links ("symlinks"), not files.

I had downloaded this installer in mid-2018 to my MacBook Pro, then copied it using Finder to the file server. The file server presents an AFP volume to my Macbook using netatalk software. I would expect the Finder to copy symbolic links correctly.

What might have caused this corruption? How can I detect other instances where it occurred, in this app and in others? Can I repair the corruption? It seems like it ought to be possible, given that the file which replaces the symlink has contains the relative path the symlink should have. How can I prevent it from happening again?

Best Answer

You might have been using Apple network-transport protocols, but the underlying file-system your server uses is not HFS or APFS, and probably isn't n-fork capable either. Symlinks in both of Apple's file-systems rely on inode referencing, and if the file-system doesn't have some form of compliance capability then items with metadata as fork references and inode lookups doesn't really have much chance of surviving intact.

This is why non-app-store software is often distributed in .dmg format, because they are a wholly self-contained island of Apple compliance stored as a single contiguous data-block, allowing it to pass through hostile servers and deadly file-systems with impugnity.

That's the cause – as for detection, only trying to run the suspect to see what happens. macOS installers are vastly complex, the bigger the app the greater the chance they'll rely on internal symlinking and thus the higher the possibility that they're now little more than useless bytes .... because you can't repair apps that have been damaged in such a manner.

Prevention: Turn apps & installers back into .dmg files (with a handy drop tool like QuickDMG for archival purposes.