Re: inotify_rm_watch() user-space safety requirements?
From: Heinrich Schuchardt
Date: Tue May 27 2014 - 15:32:32 EST
On 27.05.2014 19:25, Jeff Smith wrote:
inotify's behavior concerning events from removed watches (they do
happen) and watch descriptor reuse (beyond my knowledge) is currently
undocumented.
Although it mimics a standard multiplexing interface in most regards,
writing a robust user-space handler is comparatively more complex due
to the atypical delivery of "stale" wd events preceding an IN_IGNORE
event and a lack of guarantees about how quickly a wd can be reused
via inotify_add_watch(). Not being familiar with inotify/fsnotify
internals, it's not trivially obvious to me how the fsnotify_group
management is being done. Up to the present, I've maintained queues of
"dead" wd wrappers (or at least a counter) to filter stale events, but
I am clueless whether or not this is overkill.
If removed descriptors are reserved until the IN_IGNORE event is
drained from the read queue, could that be formally guaranteed? If
it's not, is it functionality that could ever reasonably be expected
to be added, short of some other form of new (optional?)
queue-filter-on-rm functionality? It's my experience that the
asynchronous handling of watch removals is a cost that seldom serves
much user benefit.
> Regards,
> Jeff
Hello Jeff,
I tried to dive a bit into the code. This is what I understand:
Function inotify_ignored_and_remove_idr is called after the mark has
been removed. This function puts an IN_IGNORED event onto the inotify
queue and removes the watch descriptor from the list of used watch
descriptors using function idr_remove.
With a test program I could receive the IN_IGNORED event. This behavior
is currently not documented in the manpages (inotify.7 and
inotify_rm_watch.2).
When inotify_add_watch is called it uses function idr_alloc_cyclic to
assign a watch descriptor ID. This function starts looking for an unused
id starting with the id after the last assigned watch descriptor.
This implies that in most cases inotify_add_watch will return a watch
descriptor different to the one released by a prior call to
inotify_rm_watch. But there is no guarantee.
I consider this a bug.
I CCed the maintainers of the inotify interface hoping that they can
provide a better solution.
Until such a solution is provided I suggest you use the following
workaround. After calling inotify_rm_watch read from the inotify file
descriptor until you reach the matching IN_IGNORED event.
Only thereafter you can safely call inotify_add_watch again.
Best regards
Heinrich Schuchardt
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/