Throughout the CoreFoundation framework source, POSIX filesystem API calls (e.g. open()
, stat()
, et al…) are wrapped in an idiom wherein a descriptor on /dev/autofs_nowait
is acquired – with open(…, 0)
– before the POSIX calls are made; afterwards the descriptor is close()
’d before the scope exits.
What is the benefit of doing this? What are the risks?
Does acquiring the /dev/autofs_nowait
descriptor have any affect on, or is it effected by, flags to any thusly-wrapped open()
calls (like e.g. O_NONBLOCK
)?
/dev
on my machine, running OS X 10.10.5 has other “autofs” entries:
… none of which have man
pages available. If these file-like devices might offer benefits in this vein I would be interested to hear about their use as well, as it may pertain.
Addendum: I could not find much on this subject; a Google Plus post from 2011 claims that:
[t]his file is a special device that's monitored by the autofs filesystem implementation in the kernel. When opened, the autofs filesystem will not block that process on any I/O operations on an autofs file system.
I am not quite sure what that means (they were specifically talking about how launchd
works, FWIW) but I was curious about this myself, so I wrote a quick context-manager-y RAII struct to try it out – untargeted profiling shows tests with POSIX calls completing faster but within general hashmarks; I’ll investigate this tactic with a finer-toothed comb after I get more background on how it all works.
These devices allowed the implementor(s) to avoid to define a new syscall
or ioctl
for the functionality, and maybe it was implemented that way because it was simpler, requires updating less code, and does not change the VFS API, which may have been the concerns at the time.
When you open /dev/autofs_nowait
and traverse a path, you trigger auto-mounts, but don't wait for them to finish (otherwise your process blocks until the filesystem is mounted or after the operation times out), so you may receive a ENOENT
when opening a file even if everything goes fine.
OTOH, /dev/autofs_notrigger
makes the process not even trigger the auto-mounting.
That is all those devices do. The thing is that, in Darwin's implementation, open
may block when traversing the filesystem even with O_NONBLOCK
or O_NDELAY
.
You can follow the flow from the vfs, from the open
operation of a vnode
:
vn_open
-> vn_open_auth
->namei
-> lookup
-> ...Down that path there's no handling of the (non)blocking behavior.