but it would be polling, which seems inefficient
I think this is what Disk Arbitration is for (see the documentation’s recommendation to use it and you may also find the archived documentation on it useful as well). The service itself still needs to launch before the disk mounts so that it can listen for these events, though. I think you could just use #3 and use Disk Arbitration to respond when your disk appears (and disappears, if you need to handle that) in an efficient way.
Topic:
App & System Services
SubTopic:
Core OS
Tags: